Skip to content

Commit 3ad68fd

Browse files
committed
Merge pull request #1392 from davebx/toolshed_decouple
Use the API to install repositories instead of loading the toolshed in an iframe.
2 parents 565f11f + ef960a6 commit 3ad68fd

File tree

13 files changed

+895
-62
lines changed

13 files changed

+895
-62
lines changed

lib/galaxy/webapps/galaxy/api/tool_shed_repositories.py

Lines changed: 115 additions & 17 deletions
Large diffs are not rendered by default.

lib/galaxy/webapps/galaxy/buildapp.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,8 @@ def uwsgi_app_factory():
147147
root = os.path.abspath(uwsgi.opt.get('galaxy_root', os.getcwd()))
148148
config_file = uwsgi.opt.get('galaxy_config_file', os.path.join(root, 'config', 'galaxy.ini'))
149149
global_conf = {
150-
'__file__' : config_file if os.path.exists(__file__) else None,
151-
'here' : root }
150+
'__file__': config_file if os.path.exists(__file__) else None,
151+
'here': root }
152152
parser = configparser.ConfigParser()
153153
parser.read(config_file)
154154
try:
@@ -627,6 +627,18 @@ def populate_api_routes( webapp, app ):
627627
new={ 'install_repository_revision': 'POST' },
628628
parent_resources=dict( member_name='tool_shed_repository', collection_name='tool_shed_repositories' ) )
629629

630+
webapp.mapper.connect( 'tool_shed_repository',
631+
'/api/tool_shed_repositories/:id/status',
632+
controller='tool_shed_repositories',
633+
action='status',
634+
conditions=dict( method=[ "GET" ] ) )
635+
636+
webapp.mapper.connect( 'install_repository',
637+
'/api/tool_shed_repositories/install',
638+
controller='tool_shed_repositories',
639+
action='install',
640+
conditions=dict( method=[ 'POST' ] ) )
641+
630642
# ==== Trace/Metrics Logger
631643
# Connect logger from app
632644
if app.trace_logger:

lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py

Lines changed: 68 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import shutil
55

66
from six import string_types
7-
from sqlalchemy import false, or_
7+
from sqlalchemy import or_
88

99
import tool_shed.repository_types.util as rt_util
1010
from admin import AdminGalaxy
@@ -192,6 +192,56 @@ def browse_tool_shed( self, trans, **kwd ):
192192
url = util.build_url( tool_shed_url, pathspec=[ 'repository', 'browse_valid_categories' ], params=params )
193193
return trans.response.send_redirect( url )
194194

195+
@web.expose
196+
@web.require_admin
197+
def browse_toolsheds( self, trans, **kwd ):
198+
message = escape( kwd.get( 'message', '' ) )
199+
return trans.fill_template( '/webapps/galaxy/admin/toolsheds.mako',
200+
message=message,
201+
status='error' )
202+
203+
@web.expose
204+
@web.require_admin
205+
def browse_toolshed( self, trans, **kwd ):
206+
tool_shed_url = kwd.get( 'tool_shed_url', '' )
207+
tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry( trans.app, tool_shed_url )
208+
url = common_util.url_join( tool_shed_url, pathspec=[ 'api', 'categories' ] )
209+
categories = json.loads( common_util.tool_shed_get( trans.app, url ) )
210+
repositories = []
211+
url = common_util.url_join( tool_shed_url, pathspec=[ 'api', 'repositories' ] )
212+
for repo in json.loads( common_util.tool_shed_get( trans.app, url ) ):
213+
repositories.append( dict( value=repo[ 'id' ], label='%s/%s' % ( repo[ 'owner' ], repo[ 'name' ] ) ) )
214+
return trans.fill_template( '/admin/tool_shed_repository/browse_categories.mako',
215+
tool_shed_url=tool_shed_url,
216+
categories=categories,
217+
repositories=json.dumps( repositories ) )
218+
219+
@web.expose
220+
@web.require_admin
221+
def browse_tool_shed_category( self, trans, **kwd ):
222+
tool_shed_url = kwd.get( 'tool_shed_url', '' )
223+
category_id = kwd.get( 'category_id', '' )
224+
url = common_util.url_join( tool_shed_url )
225+
json_data = json.loads( common_util.tool_shed_get( trans.app, url, pathspec=[ 'api', 'categories', category_id, 'repositories' ] ) )
226+
for idx, repository in enumerate( json_data[ 'repositories' ] ):
227+
try:
228+
metadata = json.loads( common_util.tool_shed_get( trans.app,
229+
url,
230+
pathspec=[ 'api', 'repositories', repository[ 'id' ], 'metadata' ],
231+
params=dict( recursive=False ) ) )
232+
json_data[ 'repositories' ][ idx ][ 'metadata' ] = metadata
233+
except:
234+
json_data[ 'repositories' ][ idx ][ 'metadata' ] = { 'tools_functionally_correct': True }
235+
236+
repositories = []
237+
url = common_util.url_join( tool_shed_url, pathspec=[ 'api', 'repositories' ] )
238+
for repo in json.loads( common_util.tool_shed_get( trans.app, url ) ):
239+
repositories.append( dict( value=repo[ 'id' ], label='%s/%s' % ( repo[ 'owner' ], repo[ 'name' ] ) ) )
240+
return trans.fill_template( '/admin/tool_shed_repository/browse_category.mako',
241+
tool_shed_url=tool_shed_url,
242+
category=json_data,
243+
repositories=json.dumps( repositories ) )
244+
195245
@web.expose
196246
@web.require_admin
197247
def browse_tool_sheds( self, trans, **kwd ):
@@ -1222,6 +1272,21 @@ def prepare_for_install( self, trans, **kwd ):
12221272
message=message,
12231273
status=status )
12241274

1275+
@web.expose
1276+
@web.require_admin
1277+
def preview_repository( self, trans, **kwd ):
1278+
tool_shed_url = kwd.get( 'tool_shed_url', '' )
1279+
tsr_id = kwd.get( 'tsr_id', '' )
1280+
toolshed_data = json.loads( common_util.tool_shed_get( trans.app, tool_shed_url, pathspec=[ 'api', 'repositories', tsr_id ] ) )
1281+
toolshed_data[ 'metadata' ] = json.loads( common_util.tool_shed_get( trans.app, tool_shed_url, pathspec=[ 'api', 'repositories', tsr_id, 'metadata' ] ) )
1282+
shed_tool_conf_select_field = tool_util.build_shed_tool_conf_select_field( trans.app )
1283+
tool_panel_section_select_field = tool_util.build_tool_panel_section_select_field( trans.app )
1284+
return trans.fill_template( '/admin/tool_shed_repository/preview_repository.mako',
1285+
tool_shed_url=tool_shed_url,
1286+
toolshed_data=toolshed_data,
1287+
tool_panel_section_select_field=tool_panel_section_select_field,
1288+
shed_tool_conf_select_field=shed_tool_conf_select_field )
1289+
12251290
@web.expose
12261291
@web.require_admin
12271292
def purge_repository( self, trans, **kwd ):
@@ -2008,41 +2073,8 @@ def update_to_changeset_revision( self, trans, **kwd ):
20082073

20092074
@web.expose
20102075
@web.require_admin
2011-
def update_tool_shed_status_for_installed_repository( self, trans, all_installed_repositories=False, **kwd ):
2012-
message = escape( kwd.get( 'message', '' ) )
2013-
status = kwd.get( 'status', 'done' )
2014-
if all_installed_repositories:
2015-
success_count = 0
2016-
repository_names_not_updated = []
2017-
updated_count = 0
2018-
for repository in trans.install_model.context.query( trans.install_model.ToolShedRepository ) \
2019-
.filter( trans.install_model.ToolShedRepository.table.c.deleted == false() ):
2020-
ok, updated = \
2021-
repository_util.check_or_update_tool_shed_status_for_installed_repository( trans.app, repository )
2022-
if ok:
2023-
success_count += 1
2024-
else:
2025-
repository_names_not_updated.append( '<b>%s</b>' % escape( str( repository.name ) ) )
2026-
if updated:
2027-
updated_count += 1
2028-
message = "Checked the status in the tool shed for %d repositories. " % success_count
2029-
message += "Updated the tool shed status for %d repositories. " % updated_count
2030-
if repository_names_not_updated:
2031-
message += "Unable to retrieve status from the tool shed for the following repositories:\n"
2032-
message += ", ".join( repository_names_not_updated )
2033-
else:
2034-
repository_id = kwd.get( 'id', None )
2035-
repository = suc.get_tool_shed_repository_by_id( trans.app, repository_id )
2036-
ok, updated = \
2037-
repository_util.check_or_update_tool_shed_status_for_installed_repository( trans.app, repository )
2038-
if ok:
2039-
if updated:
2040-
message = "The tool shed status for repository <b>%s</b> has been updated." % escape( str( repository.name ) )
2041-
else:
2042-
message = "The status has not changed in the tool shed for repository <b>%s</b>." % escape( str( repository.name ) )
2043-
else:
2044-
message = "Unable to retrieve status from the tool shed for repository <b>%s</b>." % escape( str( repository.name ) )
2045-
status = 'error'
2076+
def update_tool_shed_status_for_installed_repository( self, trans, **kwd ):
2077+
message, status = repository_util.check_for_updates( trans.app, trans.install_model, kwd.get( 'id', None ) )
20462078
return trans.response.send_redirect( web.url_for( controller='admin_toolshed',
20472079
action='browse_repositories',
20482080
message=message,

lib/galaxy/webapps/tool_shed/api/repositories.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,8 @@ def metadata( self, trans, id, **kwd ):
785785
metadata_dict[ 'tool_dependencies' ] = repository.get_tool_dependencies( changehash )
786786
else:
787787
metadata_dict[ 'tool_dependencies' ] = {}
788+
if metadata.includes_tools:
789+
metadata_dict[ 'tools' ] = metadata.metadata[ 'tools' ]
788790
all_metadata[ '%s:%s' % ( int( changeset ), changehash ) ] = metadata_dict
789791
return all_metadata
790792

lib/tool_shed/galaxy_install/install_manager.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ def __get_install_info_from_tool_shed( self, tool_shed_url, name, owner, changes
494494

495495
def __handle_repository_contents( self, tool_shed_repository, tool_path, repository_clone_url, relative_install_dir,
496496
tool_shed=None, tool_section=None, shed_tool_conf=None, reinstalling=False,
497-
tool_versions_response=None ):
497+
tool_versions_response=None, tool_panel_section_mapping={} ):
498498
"""
499499
Generate the metadata for the installed tool shed repository, among other things.
500500
This method is called when an administrator is installing a new repository or
@@ -572,7 +572,8 @@ def __handle_repository_contents( self, tool_shed_repository, tool_path, reposit
572572
owner=tool_shed_repository.owner,
573573
shed_tool_conf=shed_tool_conf,
574574
tool_panel_dict=tool_panel_dict,
575-
new_install=True )
575+
new_install=True,
576+
tool_panel_section_mapping=tool_panel_section_mapping )
576577
if 'data_manager' in irmm_metadata_dict:
577578
dmh = data_manager.DataManagerHandler( self.app )
578579
dmh.install_data_managers( self.app.config.shed_data_manager_config_file,
@@ -648,13 +649,20 @@ def initiate_repository_installation( self, installation_dict ):
648649
status = installation_dict[ 'status' ]
649650
tool_panel_section_id = installation_dict[ 'tool_panel_section_id' ]
650651
tool_panel_section_keys = installation_dict[ 'tool_panel_section_keys' ]
652+
tool_panel_section_mapping = installation_dict.get( 'tool_panel_section_mapping', {} )
651653
tool_path = installation_dict[ 'tool_path' ]
652654
tool_shed_url = installation_dict[ 'tool_shed_url' ]
653655
# Handle contained tools.
654656
if includes_tools_for_display_in_tool_panel and ( new_tool_panel_section_label or tool_panel_section_id ):
655657
self.tpm.handle_tool_panel_section( self.app.toolbox,
656658
tool_panel_section_id=tool_panel_section_id,
657659
new_tool_panel_section_label=new_tool_panel_section_label )
660+
if includes_tools_for_display_in_tool_panel and ( tool_panel_section_mapping is not None ):
661+
for tool_guid in tool_panel_section_mapping:
662+
if tool_panel_section_mapping[ tool_guid ][ 'action' ] == 'create':
663+
new_tool_panel_section_name = tool_panel_section_mapping[ tool_guid ][ 'tool_panel_section' ]
664+
log.debug( 'Creating tool panel section "%s" for tool %s' % ( new_tool_panel_section_name, tool_guid ) )
665+
self.tpm.handle_tool_panel_section( self.app.toolbox, None, tool_panel_section_mapping[ tool_guid ][ 'tool_panel_section' ] )
658666
encoded_repository_ids = [ self.app.security.encode_id( tsr.id ) for tsr in created_or_updated_tool_shed_repositories ]
659667
new_kwd = dict( includes_tools=includes_tools,
660668
includes_tools_for_display_in_tool_panel=includes_tools_for_display_in_tool_panel,
@@ -719,6 +727,7 @@ def __initiate_and_install_repositories( self, tool_shed_url, repository_revisio
719727
if install_tool_dependencies:
720728
self.__assert_can_install_dependencies()
721729
new_tool_panel_section_label = install_options.get( 'new_tool_panel_section_label', '' )
730+
tool_panel_section_mapping = install_options.get( 'tool_panel_section_mapping', {} )
722731
shed_tool_conf = install_options.get( 'shed_tool_conf', None )
723732
if shed_tool_conf:
724733
# Get the tool_path setting.
@@ -737,6 +746,7 @@ def __initiate_and_install_repositories( self, tool_shed_url, repository_revisio
737746
# for each repository being installed.
738747
installation_dict = dict( install_repository_dependencies=install_repository_dependencies,
739748
new_tool_panel_section_label=new_tool_panel_section_label,
749+
tool_panel_section_mapping=tool_panel_section_mapping,
740750
no_changes_checked=False,
741751
repo_info_dicts=repo_info_dicts,
742752
tool_panel_section_id=tool_panel_section_id,
@@ -761,6 +771,7 @@ def __initiate_and_install_repositories( self, tool_shed_url, repository_revisio
761771
status='done',
762772
tool_panel_section_id=tool_panel_section_id,
763773
tool_panel_section_keys=tool_panel_section_keys,
774+
tool_panel_section_mapping=tool_panel_section_mapping,
764775
tool_path=tool_path,
765776
tool_shed_url=tool_shed_url )
766777
# Prepare the repositories for installation. Even though this
@@ -783,13 +794,15 @@ def __initiate_and_install_repositories( self, tool_shed_url, repository_revisio
783794
tool_panel_section_keys=tool_panel_section_keys,
784795
repo_info_dicts=filtered_repo_info_dicts,
785796
install_tool_dependencies=install_tool_dependencies,
797+
tool_panel_section_mapping=tool_panel_section_mapping,
786798
)
787799
return self.install_repositories(tsr_ids, decoded_kwd, reinstalling=False)
788800

789801
def install_repositories( self, tsr_ids, decoded_kwd, reinstalling ):
790802
shed_tool_conf = decoded_kwd.get( 'shed_tool_conf', '' )
791803
tool_path = decoded_kwd[ 'tool_path' ]
792804
tool_panel_section_keys = util.listify( decoded_kwd[ 'tool_panel_section_keys' ] )
805+
tool_panel_section_mapping = decoded_kwd.get( 'tool_panel_section_mapping', {} )
793806
repo_info_dicts = util.listify( decoded_kwd[ 'repo_info_dicts' ] )
794807
install_tool_dependencies = decoded_kwd['install_tool_dependencies']
795808
filtered_repo_info_dicts = []
@@ -827,14 +840,15 @@ def install_repositories( self, tsr_ids, decoded_kwd, reinstalling ):
827840
shed_tool_conf=shed_tool_conf,
828841
tool_path=tool_path,
829842
install_tool_dependencies=install_tool_dependencies,
830-
reinstalling=reinstalling )
843+
reinstalling=reinstalling,
844+
tool_panel_section_mapping=tool_panel_section_mapping )
831845
installed_tool_shed_repositories.append( tool_shed_repository )
832846
else:
833847
raise RepositoriesInstalledException()
834848
return installed_tool_shed_repositories
835849

836850
def install_tool_shed_repository( self, tool_shed_repository, repo_info_dict, tool_panel_section_key, shed_tool_conf, tool_path,
837-
install_tool_dependencies, reinstalling=False ):
851+
install_tool_dependencies, reinstalling=False, tool_panel_section_mapping={} ):
838852
self.app.install_model.context.flush()
839853
if tool_panel_section_key:
840854
_, tool_section = self.app.toolbox.get_section( tool_panel_section_key )
@@ -878,7 +892,8 @@ def install_tool_shed_repository( self, tool_shed_repository, repo_info_dict, to
878892
tool_section=tool_section,
879893
shed_tool_conf=shed_tool_conf,
880894
tool_versions_response=tool_versions_response,
881-
reinstalling=reinstalling )
895+
reinstalling=reinstalling,
896+
tool_panel_section_mapping=tool_panel_section_mapping )
882897
self.install_model.context.refresh( tool_shed_repository )
883898
metadata = tool_shed_repository.metadata
884899
if 'tools' in metadata:

lib/tool_shed/galaxy_install/tools/tool_panel_manager.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,12 @@ def add_to_shed_tool_config( self, shed_tool_conf_dict, elem_list ):
3737
self.config_elems_to_xml_file( config_elems, shed_tool_conf, tool_path )
3838

3939
def add_to_tool_panel( self, repository_name, repository_clone_url, changeset_revision, repository_tools_tups, owner,
40-
shed_tool_conf, tool_panel_dict, new_install=True ):
40+
shed_tool_conf, tool_panel_dict, new_install=True, tool_panel_section_mapping={} ):
4141
"""A tool shed repository is being installed or updated so handle tool panel alterations accordingly."""
4242
# We need to change the in-memory version and the file system version of the shed_tool_conf file.
4343
shed_tool_conf_dict = self.get_shed_tool_conf_dict( shed_tool_conf )
4444
tool_path = shed_tool_conf_dict[ 'tool_path' ]
45+
tool_panel_dict = self.update_tool_panel_dict( tool_panel_dict, tool_panel_section_mapping, repository_tools_tups )
4546
# Generate the list of ElementTree Element objects for each section or tool.
4647
elem_list = self.generate_tool_panel_elem_list( repository_name,
4748
repository_clone_url,
@@ -465,3 +466,14 @@ def remove_guids( self, guids_to_remove, shed_tool_conf, uninstall ):
465466
# Update the config_elems of the in-memory shed_tool_conf_dict.
466467
shed_tool_conf_dict[ 'config_elems' ] = config_elems
467468
toolbox.update_shed_config( shed_tool_conf_dict, integrated_panel_changes=uninstall )
469+
470+
def update_tool_panel_dict( self, tool_panel_dict, tool_panel_section_mapping, repository_tools_tups ):
471+
for tool_guid in tool_panel_dict:
472+
if tool_guid not in tool_panel_section_mapping:
473+
continue
474+
for idx, tool in enumerate( tool_panel_dict[ tool_guid ] ):
475+
section_name = tool_panel_section_mapping[ tool_guid ][ 'tool_panel_section' ]
476+
section_id = str( tool_panel_section_mapping[ tool_guid ][ 'tool_panel_section' ].lower().replace( ' ', '_' ) )
477+
tool_panel_dict[ tool_guid ][ idx ][ 'name' ] = section_name
478+
tool_panel_dict[ tool_guid ][ idx ][ 'id' ] = section_id
479+
return tool_panel_dict

0 commit comments

Comments
 (0)