Skip to content

Commit c082112

Browse files
authored
Merge pull request #104 from rhpvorderman/refactor_shedtools
Done: Refactor shedtools
2 parents 49e00a4 + c652146 commit c082112

8 files changed

Lines changed: 820 additions & 886 deletions

File tree

docs/commands/shed-tools.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ Usage
88

99
.. argparse::
1010
:module: ephemeris.shed_tools
11-
:func: _parser
11+
:func: parser
1212
:prog: shed-tools

ephemeris/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def get_galaxy_connection(args, file=None, log=None, login_required=True):
2828
"""
2929
Return a Galaxy connection, given a user or an API key.
3030
If not given gets the arguments from the file.
31-
If either is missing returns None.
31+
If either is missing raise ValueError.
3232
"""
3333
if file:
3434
file_content = load_yaml_file(file)
@@ -45,7 +45,8 @@ def get_galaxy_connection(args, file=None, log=None, login_required=True):
4545
return galaxy.GalaxyInstance(url=galaxy_url, key=api_key)
4646
elif not login_required:
4747
return galaxy.GalaxyInstance(url=galaxy_url)
48-
return None
48+
else:
49+
raise ValueError("Missing api key or user & password combination, in order to make a galaxy connection.")
4950

5051

5152
def load_yaml_file(filename):

ephemeris/get_tool_list_from_galaxy.py

Lines changed: 100 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
#!/usr/bin/env python
22
"""Tool to extract a tool list from galaxy."""
33

4-
54
from argparse import ArgumentDefaultsHelpFormatter
65
from argparse import ArgumentParser
76
from distutils.version import StrictVersion
87

98
import yaml
109
from bioblend.galaxy.tools import ToolClient
10+
from bioblend.galaxy.toolshed import ToolShedClient
1111

1212
from . import get_galaxy_connection
1313
from .common_parser import get_common_args
@@ -59,16 +59,15 @@ def __init__(self, gi,
5959
include_tool_panel_section_id=False,
6060
skip_tool_panel_section_name=True,
6161
skip_changeset_revision=False,
62-
get_data_managers=False):
62+
get_data_managers=False,
63+
get_all_tools=False):
6364
self.gi = gi
65+
6466
self.include_tool_panel_section_id = include_tool_panel_section_id
6567
self.skip_tool_panel_section_name = skip_tool_panel_section_name
6668
self.skip_changeset_revision = skip_changeset_revision
6769
self.get_data_managers = get_data_managers
68-
self.repository_list = self.get_repositories()
69-
self.repository_list = self.merge_tool_changeset_revisions()
70-
self.filter_section_name_or_id_or_changeset()
71-
self.tool_list = {"tools": self.repository_list}
70+
self.get_all_tools = get_all_tools
7271

7372
@property
7473
def toolbox(self):
@@ -86,7 +85,8 @@ def installed_tool_list(self):
8685
tool_client = ToolClient(self.gi)
8786
return tool_client.get_tools()
8887

89-
def get_repositories(self):
88+
@property
89+
def repository_list(self):
9090
"""
9191
Toolbox elements returned by api/tools may be of class ToolSection or Tool.
9292
Parse these accordingly to get a list of repositories.
@@ -104,54 +104,107 @@ def record_repo(tool_elem):
104104
for tool in self.installed_tool_list:
105105
if tool.get("model_class") == 'DataManagerTool':
106106
repositories.append(get_repo_from_tool(tool))
107+
108+
if self.get_all_tools:
109+
tools_with_panel = repositories[:]
110+
tsc = ToolShedClient(self.gi)
111+
repos = tsc.get_repositories()
112+
# Hereafter follows a gruesomely ineffecient algorithm.
113+
# The for loop and if statement are needed to retrieve tool_panel
114+
# section labels and ids.
115+
# If someone knows a more effecient way around this problem it
116+
# will be greatly appreciated.
117+
for repo in repos:
118+
if not repo['deleted']:
119+
for repo_with_panel in tools_with_panel:
120+
tool_panel_section_id = None
121+
tool_panel_section_label = None
122+
if the_same_repository(repo_with_panel, repo, check_revision=False):
123+
tool_panel_section_id = repo_with_panel.get('tool_panel_section_id')
124+
tool_panel_section_label = repo_with_panel.get('tool_panel_section_label')
125+
break
126+
repositories.append(
127+
dict(name=repo.get('name'),
128+
owner=repo.get('owner'),
129+
tool_shed_url=repo.get('tool_shed'),
130+
revisions=[repo.get('changeset_revision')],
131+
tool_panel_section_label=tool_panel_section_label,
132+
tool_panel_section_id=tool_panel_section_id)
133+
)
107134
return repositories
108135

109-
def merge_tool_changeset_revisions(self):
110-
"""
111-
Each installed changeset revision of a tool is listed individually.
112-
Merge revisions of the same tool into a list.
113-
"""
114-
repositories = {}
115-
repo_key_template = "{tool_shed_url}|{name}|{owner}|{tool_panel_section_id}|{tool_panel_section_label}"
116-
for tool in self.repository_list:
117-
repo_key = repo_key_template.format(**tool)
118-
if repo_key in repositories:
119-
repositories[repo_key].extend(tool['revisions'])
120-
else:
121-
repositories[repo_key] = tool['revisions']
122-
new_repository_list = []
123-
for repo_key, changeset_revisions in repositories.items():
124-
changeset_revisions = list(set(changeset_revisions))
125-
tool_shed_url, name, owner, tool_panel_section_id, tool_panel_section_label = repo_key.split('|')
126-
new_repository_list.append(
127-
{'tool_shed_url': tool_shed_url,
128-
'name': name,
129-
'owner': owner,
130-
'tool_panel_section_id': tool_panel_section_id,
131-
'tool_panel_section_label': tool_panel_section_label,
132-
'revisions': changeset_revisions}
133-
)
134-
return new_repository_list
135-
136-
def filter_section_name_or_id_or_changeset(self):
137-
repo_list = []
138-
for repo in self.repository_list:
136+
@property
137+
def tool_list(self):
138+
repo_list = self.repository_list
139+
repo_list = merge_repository_changeset_revisions(repo_list)
140+
repo_list = self.filter_section_name_or_id_or_changeset(repo_list)
141+
return {"tools": repo_list}
142+
143+
def filter_section_name_or_id_or_changeset(self, repository_list):
144+
new_repo_list = []
145+
for repo in repository_list:
139146
if self.skip_tool_panel_section_name:
140147
del repo['tool_panel_section_label']
141148
if not self.include_tool_panel_section_id:
142149
del repo['tool_panel_section_id']
143150
if self.skip_changeset_revision:
144151
del repo['revisions']
145-
repo_list.append(repo)
146-
self.repository_list = repo_list
152+
new_repo_list.append(repo)
153+
return new_repo_list
147154

148155
def write_to_yaml(self, output_file):
149156
with open(output_file, "w") as output:
150157
output.write(yaml.safe_dump(self.tool_list, default_flow_style=False))
151158

152159

160+
def the_same_repository(repo_1_info, repo_2_info, check_revision=True):
161+
"""
162+
Given two dicts containing info about repositories, determine if they are the same
163+
repository.
164+
Each of the dicts must have the following keys: `changeset_revisions`( if check revisions is true), `name`, `owner`, and
165+
(either `tool_shed` or `tool_shed_url`).
166+
"""
167+
# Sort from most unique to least unique for fast comparison.
168+
if not check_revision or repo_1_info.get('changeset_revision') == repo_2_info.get('changeset_revision'):
169+
if repo_1_info.get('name') == repo_2_info.get('name'):
170+
if repo_1_info.get('owner') == repo_2_info.get('owner'):
171+
t1ts = repo_1_info.get('tool_shed', repo_1_info.get('tool_shed_url', None))
172+
t2ts = repo_2_info.get('tool_shed', repo_2_info.get('tool_shed_url', None))
173+
if t1ts in t2ts or t2ts in t1ts:
174+
return True
175+
return False
176+
177+
178+
def merge_repository_changeset_revisions(repository_list):
179+
"""
180+
Each installed changeset revision of a tool is listed individually.
181+
Merge revisions of the same tool into a list.
182+
"""
183+
repositories = {}
184+
repo_key_template = "{tool_shed_url}|{name}|{owner}|{tool_panel_section_id}|{tool_panel_section_label}"
185+
for repo in repository_list:
186+
repo_key = repo_key_template.format(**repo)
187+
if repo_key in repositories:
188+
repositories[repo_key].extend(repo['revisions'])
189+
else:
190+
repositories[repo_key] = repo['revisions']
191+
new_repository_list = []
192+
for repo_key, changeset_revisions in repositories.items():
193+
changeset_revisions = list(set(changeset_revisions))
194+
tool_shed_url, name, owner, tool_panel_section_id, tool_panel_section_label = repo_key.split('|')
195+
new_repository_list.append(
196+
{'tool_shed_url': tool_shed_url,
197+
'name': name,
198+
'owner': owner,
199+
'tool_panel_section_id': tool_panel_section_id,
200+
'tool_panel_section_label': tool_panel_section_label,
201+
'revisions': changeset_revisions}
202+
)
203+
return new_repository_list
204+
205+
153206
def _parser():
154-
'''Creates the parser object.'''
207+
"""Creates the parser object."""
155208
parent = get_common_args(login_required=True)
156209
parser = ArgumentParser(parents=[parent],
157210
formatter_class=ArgumentDefaultsHelpFormatter)
@@ -175,7 +228,11 @@ def _parser():
175228
)
176229
parser.add_argument("--get_data_managers",
177230
action="store_true",
178-
help="Include the data managers in the tool list. Requires login details")
231+
help="Include the data managers in the tool list. Requires admin login details")
232+
parser.add_argument("--get_all_tools",
233+
action="store_true",
234+
help="Get all tools and revisions, not just those which are present on the web ui."
235+
"Requires login details.")
179236
return parser
180237

181238

@@ -218,7 +275,8 @@ def main():
218275
include_tool_panel_section_id=options.include_tool_panel_id,
219276
skip_tool_panel_section_name=options.skip_tool_panel_name,
220277
skip_changeset_revision=options.skip_changeset_revision,
221-
get_data_managers=options.get_data_managers)
278+
get_data_managers=options.get_data_managers,
279+
get_all_tools=options.get_all_tools)
222280
gi_to_tool_yaml.write_to_yaml(options.output)
223281

224282

0 commit comments

Comments
 (0)