commit/galaxy-central: greg: Add baseline support for managin dependencies for tools included in installed tool shed repositories, enhance installed repository browsing to enable browsing files, and a bit of code cleanup.
1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/changeset/b1f35669f93c/ changeset: b1f35669f93c user: greg date: 2012-06-13 22:40:22 summary: Add baseline support for managin dependencies for tools included in installed tool shed repositories, enhance installed repository browsing to enable browsing files, and a bit of code cleanup. affected #: 12 files diff -r 599e16b18e34267a9563f47b1acaa234165482ea -r b1f35669f93c4163cf803d64beb37a1cb0d5381c lib/galaxy/model/__init__.py --- a/lib/galaxy/model/__init__.py +++ b/lib/galaxy/model/__init__.py @@ -2665,7 +2665,12 @@ self.deleted = deleted self.uninstalled = uninstalled self.dist_to_shed = dist_to_shed - def repo_path( self, app ): + def repo_files_directory( self, app ): + repo_path = self.repo_path( app ) + if repo_path: + return os.path.join( app.config.root, repo_path, self.name ) + return None + def repo_path( self, app ): tool_shed_url = self.tool_shed if tool_shed_url.find( ':' ) > 0: # Eliminate the port, if any, since it will result in an invalid directory name. @@ -2673,7 +2678,7 @@ tool_shed = tool_shed_url.rstrip( '/' ) for index, shed_tool_conf_dict in enumerate( app.toolbox.shed_tool_confs ): tool_path = shed_tool_conf_dict[ 'tool_path' ] - relative_path = os.path.join( tool_path, tool_shed, 'repos', self.owner, self.name, self.installed_changeset_revision ) + relative_path = os.path.join( app.config.root, tool_path, tool_shed, 'repos', self.owner, self.name, self.installed_changeset_revision ) if os.path.exists( relative_path ): return relative_path return None @@ -2686,6 +2691,46 @@ @property def includes_workflows( self ): return self.metadata and 'workflows' in self.metadata + @property + def installed_tool_dependencies( self ): + """Return the repository's tool dependencies that are currently installed.""" + installed_dependencies = [] + for tool_dependency in self.tool_dependencies: + if not tool_dependency.uninstalled: + installed_dependencies.append( tool_dependency ) + return installed_dependencies + @property + def missing_tool_dependencies( self ): + """Return the repository's tool dependencies that are not currently installed.""" + def add_missing_dependency( missing_dependencies_dict, name, version, type, installed_changeset_revision=None ): + missing_dependencies_dict[ name ] = dict( version=version, + type=type, + installed_changeset_revision=installed_changeset_revision ) + return missing_dependencies_dict + missing_dependencies = {} + # Get the dependency information from the metadata for comparison against the installed tool dependencies. + tool_dependencies = self.metadata.get( 'tool_dependencies', None ) + if tool_dependencies: + for dependency_key, requirements_dict in tool_dependencies.items(): + name = requirements_dict[ 'name' ] + version = requirements_dict[ 'version' ] + type = requirements_dict[ 'type' ] + if self.tool_dependencies: + found = False + for installed_dependency in self.tool_dependencies: + if installed_dependency.name==name and installed_dependency.version==version and installed_dependency.type==type: + found = True + if installed_dependency.uninstalled: + missing_dependencies = add_missing_dependency( missing_dependencies, + installed_dependency.name, + installed_dependency.version, + installed_dependency.type, + installed_dependency.installed_changeset_revision ) + break + if not found: + missing_dependencies = add_missing_dependency( missing_dependencies, name, version, type ) + return missing_dependencies + return None class ToolDependency( object ): def __init__( self, tool_shed_repository_id=None, installed_changeset_revision=None, name=None, version=None, type=None, uninstalled=False ): diff -r 599e16b18e34267a9563f47b1acaa234165482ea -r b1f35669f93c4163cf803d64beb37a1cb0d5381c lib/galaxy/tools/__init__.py --- a/lib/galaxy/tools/__init__.py +++ b/lib/galaxy/tools/__init__.py @@ -795,19 +795,15 @@ return tool_version.get_version_ids( self.app ) return [] @property - def installed_tool_dependencies( self ): - # If this tool is included in an installed tool shed repository and tool dependencies were installed along with the - # tool shed repository, then this method will return the repository's ToolDependency records. - if self.app.config.use_tool_dependencies: - if self.tool_shed: - tool_shed_repository = get_tool_shed_repository_by_shed_name_owner_changeset_revision( self.app, - self.tool_shed, - self.repository_name, - self.repository_owner, - self.installed_changeset_revision ) - if tool_shed_repository: - return tool_shed_repository.tool_dependencies - return None + def tool_shed_repository( self ): + # If this tool is included in an installed tool shed repository, return it. + if self.tool_shed: + return get_tool_shed_repository_by_shed_name_owner_changeset_revision( self.app, + self.tool_shed, + self.repository_name, + self.repository_owner, + self.installed_changeset_revision ) + return None def __get_job_run_config( self, run_configs, key, job_params=None ): # Look through runners/handlers to find one with matching parameters. available_configs = [] @@ -2333,6 +2329,10 @@ environment to include this tools requirements. """ commands = [] + if self.tool_shed_repository: + installed_tool_dependencies = self.tool_shed_repository.tool_dependencies + else: + installed_tool_dependencies = None for requirement in self.requirements: # TODO: currently only supporting requirements of type package, # need to implement some mechanism for mapping other types @@ -2342,7 +2342,7 @@ script_file, base_path, version = self.app.toolbox.dependency_manager.find_dep( name=requirement.name, version=requirement.version, type=requirement.type, - installed_tool_dependencies=self.installed_tool_dependencies ) + installed_tool_dependencies=installed_tool_dependencies ) if script_file is None and base_path is None: log.warn( "Failed to resolve dependency on '%s', ignoring", requirement.name ) elif script_file is None: diff -r 599e16b18e34267a9563f47b1acaa234165482ea -r b1f35669f93c4163cf803d64beb37a1cb0d5381c lib/galaxy/util/shed_util.py --- a/lib/galaxy/util/shed_util.py +++ b/lib/galaxy/util/shed_util.py @@ -29,6 +29,7 @@ '"' : '"', '&' : '&', '\'' : ''' } +MAX_CONTENT_SIZE = 32768 VALID_CHARS = set( string.letters + string.digits + "'\"-=_.()/+*^,:?!#[]%\\$@;{}" ) NOT_TOOL_CONFIGS = [ 'datatypes_conf.xml', 'tool_dependencies.xml' ] @@ -881,6 +882,37 @@ fh.close() return tmp_filename return None +def get_repository_file_contents( file_path ): + if is_gzip( file_path ): + to_html = to_html_str( '\ngzip compressed file\n' ) + elif is_bz2( file_path ): + to_html = to_html_str( '\nbz2 compressed file\n' ) + elif check_zip( file_path ): + to_html = to_html_str( '\nzip compressed file\n' ) + elif check_binary( file_path ): + to_html = to_html_str( '\nBinary file\n' ) + else: + to_html = '' + for i, line in enumerate( open( file_path ) ): + to_html = '%s%s' % ( to_html, to_html_str( line ) ) + if len( to_html ) > MAX_CONTENT_SIZE: + large_str = '\nFile contents truncated because file size is larger than maximum viewing size of %s\n' % util.nice_size( MAX_CONTENT_SIZE ) + to_html = '%s%s' % ( to_html, to_html_str( large_str ) ) + break + return to_html +def get_repository_files( trans, folder_path ): + contents = [] + for item in os.listdir( folder_path ): + # Skip .hg directories + if str( item ).startswith( '.hg' ): + continue + if os.path.isdir( os.path.join( folder_path, item ) ): + # Append a '/' character so that our jquery dynatree will function properly. + item = '%s/' % item + contents.append( item ) + if contents: + contents.sort() + return contents def get_repository_owner( cleaned_repository_url ): items = cleaned_repository_url.split( 'repos' ) repo_path = items[ 1 ] @@ -1313,6 +1345,27 @@ if not os.path.exists( work_dir ): os.makedirs( work_dir ) return work_dir +def open_repository_files_folder( trans, folder_path ): + try: + files_list = get_repository_files( trans, folder_path ) + except OSError, e: + if str( e ).find( 'No such file or directory' ) >= 0: + # We have a repository with no contents. + return [] + folder_contents = [] + for filename in files_list: + is_folder = False + if filename and filename[-1] == os.sep: + is_folder = True + if filename: + full_path = os.path.join( folder_path, filename ) + node = { "title": filename, + "isFolder": is_folder, + "isLazy": is_folder, + "tooltip": full_path, + "key": full_path } + folder_contents.append( node ) + return folder_contents def panel_entry_per_tool( tool_section_dict ): # Return True if tool_section_dict looks like this. # {<Tool guid> : [{ tool_config : <tool_config_file>, id: <ToolSection id>, version : <ToolSection version>, name : <TooSection name>}]} diff -r 599e16b18e34267a9563f47b1acaa234165482ea -r b1f35669f93c4163cf803d64beb37a1cb0d5381c lib/galaxy/web/controllers/admin_toolshed.py --- a/lib/galaxy/web/controllers/admin_toolshed.py +++ b/lib/galaxy/web/controllers/admin_toolshed.py @@ -174,40 +174,6 @@ return trans.response.send_redirect( url ) @web.expose @web.require_admin - def check_installed_tool_dependencies( self, trans, repository_id, relative_install_dir ): - """See if any tool dependencies need to be installed.""" - tool_dependencies_missing = False - repository = get_repository( trans, repository_id ) - if repository.includes_tool_dependencies: - # Get the tool_dependencies.xml file from the repository. - work_dir = make_tmp_directory() - tool_dependencies_config = get_config_from_repository( trans.app, - 'tool_dependencies.xml', - repository, - repository.changeset_revision, - work_dir, - install_dir=relative_install_dir ) - # Parse the tool_dependencies.xml config. - tree = ElementTree.parse( tool_dependencies_config ) - root = tree.getroot() - ElementInclude.include( root ) - fabric_version_checked = False - for elem in root: - if elem.tag == 'package': - package_name = elem.get( 'name', None ) - package_version = elem.get( 'version', None ) - if package_name and package_version: - install_dir = get_install_dir( trans.app, repository, repository.installed_changeset_revision, package_name, package_version ) - if not_installed( install_dir ): - tool_dependencies_missing = True - break - try: - shutil.rmtree( work_dir ) - except: - pass - return tool_dependencies_missing - @web.expose - @web.require_admin def deactivate_or_uninstall_repository( self, trans, **kwd ): params = util.Params( kwd ) message = util.restore_text( params.get( 'message', '' ) ) @@ -289,6 +255,12 @@ galaxy_url = url_for( '/', qualified=True ) url = '%srepository/find_workflows?galaxy_url=%s&webapp=galaxy&no_reset=true' % ( tool_shed_url, galaxy_url ) return trans.response.send_redirect( url ) + @web.json + def get_file_contents( self, trans, file_path ): + # Avoid caching + trans.response.headers['Pragma'] = 'no-cache' + trans.response.headers['Expires'] = '0' + return get_repository_file_contents( file_path ) @web.expose @web.require_admin def install_tool_dependencies( self, trans, **kwd ): @@ -594,16 +566,32 @@ trans.sa_session.add( repository ) trans.sa_session.flush() message = "Repository metadata has been reset." - tool_dependencies_missing = self.check_installed_tool_dependencies( trans, repository_id, relative_install_dir ) return trans.fill_template( '/admin/tool_shed_repository/manage_repository.mako', repository=repository, description=description, repo_files_dir=repo_files_dir, - tool_dependencies_missing=tool_dependencies_missing, message=message, status=status ) @web.expose @web.require_admin + def manage_tool_dependencies( self, trans, **kwd ): + params = util.Params( kwd ) + message = util.restore_text( params.get( 'message', '' ) ) + status = params.get( 'status', 'done' ) + repository_id = kwd[ 'id' ] + repository = get_repository( trans, repository_id ) + return trans.fill_template( '/admin/tool_shed_repository/manage_tool_dependencies.mako', + repository=repository, + message=message, + status=status ) + @web.json + def open_folder( self, trans, folder_path ): + # Avoid caching + trans.response.headers['Pragma'] = 'no-cache' + trans.response.headers['Expires'] = '0' + return open_repository_files_folder( trans, folder_path ) + @web.expose + @web.require_admin def reinstall_repository( self, trans, **kwd ): message = kwd.get( 'message', '' ) status = kwd.get( 'status', 'done' ) @@ -709,6 +697,8 @@ trans.sa_session.flush() if install_tool_dependencies: dependency_str = ' along with tool dependencies' + if error_message: + dependency_str += ', but with some errors installing the dependencies' else: dependency_str = ' without tool dependencies' message += 'The <b>%s</b> repository has been reinstalled%s. ' % ( repository.name, dependency_str ) @@ -822,8 +812,7 @@ message = "The installed repository named '%s' has been updated to change set revision '%s'. " % ( name, latest_changeset_revision ) # See if any tool dependencies can be installed. shed_tool_conf, tool_path, relative_install_dir = get_tool_panel_config_tool_path_install_dir( trans.app, repository ) - tool_dependencies_missing = self.check_installed_tool_dependencies( trans, trans.security.encode_id( repository.id ), relative_install_dir ) - if tool_dependencies_missing: + if repository.missing_tool_dependencies: message += "Select <b>Install tool dependencies</b> from the repository's pop-up menu to install tool dependencies." else: message = "The directory containing the installed repository named '%s' cannot be found. " % name diff -r 599e16b18e34267a9563f47b1acaa234165482ea -r b1f35669f93c4163cf803d64beb37a1cb0d5381c lib/galaxy/webapps/community/controllers/repository.py --- a/lib/galaxy/webapps/community/controllers/repository.py +++ b/lib/galaxy/webapps/community/controllers/repository.py @@ -2,7 +2,6 @@ from time import strftime from datetime import date, datetime from galaxy import util -from galaxy.datatypes.checkers import * from galaxy.web.base.controller import * from galaxy.web.form_builder import CheckboxField from galaxy.webapps.community import model @@ -10,7 +9,8 @@ from galaxy.web.framework.helpers import time_ago, iff, grids from galaxy.util.json import from_json_string, to_json_string from galaxy.model.orm import * -from galaxy.util.shed_util import get_changectx_for_changeset, get_configured_ui, make_tmp_directory, NOT_TOOL_CONFIGS, strip_path +from galaxy.util.shed_util import get_changectx_for_changeset, get_configured_ui, get_repository_file_contents, make_tmp_directory, NOT_TOOL_CONFIGS +from galaxy.util.shed_util import open_repository_files_folder, strip_path from galaxy.tool_shed.encoding_util import * from common import * @@ -20,7 +20,6 @@ log = logging.getLogger( __name__ ) -MAX_CONTENT_SIZE = 32768 VALID_REPOSITORYNAME_RE = re.compile( "^[a-z0-9\_]+$" ) README_FILES = [ 'readme', 'read_me', 'install' ] @@ -496,12 +495,10 @@ commit_message = util.restore_text( params.get( 'commit_message', 'Deleted selected files' ) ) repository = get_repository( trans, id ) repo = hg.repository( get_configured_ui(), repository.repo_path ) - current_working_dir = os.getcwd() # Update repository files for browsing. update_repository( repo ) is_malicious = changeset_is_malicious( trans, id, repository.tip ) return trans.fill_template( '/webapps/community/repository/browse_repository.mako', - repo=repo, repository=repository, commit_message=commit_message, is_malicious=is_malicious, @@ -1016,37 +1013,7 @@ # Avoid caching trans.response.headers['Pragma'] = 'no-cache' trans.response.headers['Expires'] = '0' - if is_gzip( file_path ): - to_html = to_html_str( '\ngzip compressed file\n' ) - elif is_bz2( file_path ): - to_html = to_html_str( '\nbz2 compressed file\n' ) - elif check_zip( file_path ): - to_html = to_html_str( '\nzip compressed file\n' ) - elif check_binary( file_path ): - to_html = to_html_str( '\nBinary file\n' ) - else: - to_html = '' - for i, line in enumerate( open( file_path ) ): - to_html = '%s%s' % ( to_html, to_html_str( line ) ) - if len( to_html ) > MAX_CONTENT_SIZE: - large_str = '\nFile contents truncated because file size is larger than maximum viewing size of %s\n' % util.nice_size( MAX_CONTENT_SIZE ) - to_html = '%s%s' % ( to_html, to_html_str( large_str ) ) - break - return to_html - def __get_files( self, trans, folder_path ): - contents = [] - for item in os.listdir( folder_path ): - # Skip .hg directories - if str( item ).startswith( '.hg' ): - continue - if os.path.isdir( os.path.join( folder_path, item ) ): - # Append a '/' character so that our jquery dynatree will - # function properly. - item = '%s/' % item - contents.append( item ) - if contents: - contents.sort() - return contents + return get_repository_file_contents( file_path ) @web.expose def get_readme( self, trans, **kwd ): """If the received changeset_revision includes a file named readme (case ignored), return it's contents.""" @@ -1558,34 +1525,13 @@ state.inputs = {} return state @web.json - def open_folder( self, trans, repository_id, key ): + def open_folder( self, trans, folder_path ): # The tool shed includes a repository source file browser, which currently depends upon # copies of the hg repository file store in the repo_path for browsing. # Avoid caching trans.response.headers['Pragma'] = 'no-cache' trans.response.headers['Expires'] = '0' - repository = trans.sa_session.query( trans.model.Repository ).get( trans.security.decode_id( repository_id ) ) - folder_path = key - try: - files_list = self.__get_files( trans, folder_path ) - except OSError, e: - if str( e ).find( 'No such file or directory' ) >= 0: - # We have a repository with no contents. - return [] - folder_contents = [] - for filename in files_list: - is_folder = False - if filename and filename[-1] == os.sep: - is_folder = True - if filename: - full_path = os.path.join( folder_path, filename ) - node = { "title": filename, - "isFolder": is_folder, - "isLazy": is_folder, - "tooltip": full_path, - "key": full_path } - folder_contents.append( node ) - return folder_contents + return open_repository_files_folder( trans, folder_path ) @web.expose def preview_tools_in_changeset( self, trans, repository_id, **kwd ): params = util.Params( kwd ) @@ -1769,7 +1715,6 @@ if params.get( 'select_files_to_delete_button', False ): if selected_files_to_delete: selected_files_to_delete = selected_files_to_delete.split( ',' ) - current_working_dir = os.getcwd() # Get the current repository tip. tip = repository.tip for selected_file in selected_files_to_delete: diff -r 599e16b18e34267a9563f47b1acaa234165482ea -r b1f35669f93c4163cf803d64beb37a1cb0d5381c templates/admin/tool_shed_repository/browse_repository.mako --- a/templates/admin/tool_shed_repository/browse_repository.mako +++ b/templates/admin/tool_shed_repository/browse_repository.mako @@ -2,6 +2,17 @@ <%namespace file="/message.mako" import="render_msg" /><%namespace file="/admin/tool_shed_repository/common.mako" import="*" /> +<%def name="stylesheets()"> + ${parent.stylesheets()} + ${h.css( "dynatree_skin/ui.dynatree" )} +</%def> + +<%def name="javascripts()"> + ${parent.javascripts()} + ${h.js( "ui.core", "jquery.dynatree" )} + ${common_javascripts(repository)} +</%def> + <br/><br/><ul class="manage-table-actions"><li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Repository Actions</a></li> @@ -9,6 +20,9 @@ <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='manage_repository', id=trans.security.encode_id( repository.id ) )}">Manage repository</a><a class="action-button" href="${h.url_for( controller='admin_toolshed', action='check_for_updates', id=trans.security.encode_id( repository.id ) )}">Get updates</a><a class="action-button" href="${h.url_for( controller='admin_toolshed', action='deactivate_or_uninstall_repository', id=trans.security.encode_id( repository.id ) )}">Deactivate or Uninstall</a> + %if repository.tool_dependencies: + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='manage_tool_dependencies', id=trans.security.encode_id( repository.id ) )}">Manage tool dependencies</a> + %endif </div></ul> @@ -16,4 +30,17 @@ ${render_msg( message, status )} %endif -${render_metadata( repository, can_reset_metadata=False )} +<div class="toolForm"> + <div class="toolFormTitle">Browse ${repository.name} revision ${repository.changeset_revision} files</div> + <div class="toolFormBody"> + <div class="form-row" > + <label>Contents:</label> + <div id="tree" > + Loading... + </div> + </div> + <div class="form-row"> + <div id="file_contents" class="toolParamHelp" style="clear: both;background-color:#FAFAFA;"></div> + </div> + </div> +</div> diff -r 599e16b18e34267a9563f47b1acaa234165482ea -r b1f35669f93c4163cf803d64beb37a1cb0d5381c templates/admin/tool_shed_repository/common.mako --- a/templates/admin/tool_shed_repository/common.mako +++ b/templates/admin/tool_shed_repository/common.mako @@ -1,154 +1,273 @@ -<%def name="render_metadata( repository, can_reset_metadata=False )"> +<%def name="common_javascripts(repository)"> + <script type="text/javascript"> + $(function(){ + $("#tree").ajaxComplete(function(event, XMLHttpRequest, ajaxOptions) { + _log("debug", "ajaxComplete: %o", this); // dom element listening + }); + // --- Initialize sample trees + $("#tree").dynatree({ + title: "${repository.name}", + rootVisible: true, + minExpandLevel: 0, // 1: root node is not collapsible + persist: false, + checkbox: true, + selectMode: 3, + onPostInit: function(isReloading, isError) { + //alert("reloading: "+isReloading+", error:"+isError); + logMsg("onPostInit(%o, %o) - %o", isReloading, isError, this); + // Re-fire onActivate, so the text is updated + this.reactivate(); + }, + fx: { height: "toggle", duration: 200 }, + // initAjax is hard to fake, so we pass the children as object array: + initAjax: {url: "${h.url_for( controller='admin_toolshed', action='open_folder' )}", + dataType: "json", + data: { folder_path: "${repository.repo_files_directory(trans.app)}" }, + }, + onLazyRead: function(dtnode){ + dtnode.appendAjax({ + url: "${h.url_for( controller='admin_toolshed', action='open_folder' )}", + dataType: "json", + data: { folder_path: dtnode.data.key }, + }); + }, + onSelect: function(select, dtnode) { + // Display list of selected nodes + var selNodes = dtnode.tree.getSelectedNodes(); + // convert to title/key array + var selKeys = $.map(selNodes, function(node) { + return node.data.key; + }); + }, + onActivate: function(dtnode) { + var cell = $("#file_contents"); + var selected_value; + if (dtnode.data.key == 'root') { + selected_value = "${repository.repo_files_directory(trans.app)}/"; + } else { + selected_value = dtnode.data.key; + }; + if (selected_value.charAt(selected_value.length-1) != '/') { + // Make ajax call + $.ajax( { + type: "POST", + url: "${h.url_for( controller='admin_toolshed', action='get_file_contents' )}", + dataType: "json", + data: { file_path: selected_value }, + success : function ( data ) { + cell.html( '<label>'+data+'</label>' ) + } + }); + } else { + cell.html( '' ); + }; + }, + }); + }); + </script> +</%def> + +<%def name="render_repository_contents( repository, can_reset_metadata=False )"><div class="toolForm"> - <div class="toolFormTitle">Repository contents</div> + <div class="toolFormTitle">${repository.name}</div><div class="toolFormBody"> - <% metadata = repository.metadata %> - %if metadata: - %if 'tools' in metadata: - <div class="form-row"> - <table width="100%"> - <tr bgcolor="#D8D8D8" width="100%"> - <td><b>Tools</b><i> - click the name to view tool related information</i></td> + <% + metadata = repository.metadata + missing_tool_dependencies = repository.missing_tool_dependencies + installed_tool_dependencies = repository.installed_tool_dependencies + %> + %if missing_tool_dependencies: + <div class="form-row"> + <table width="100%"> + <tr bgcolor="#D8D8D8" width="100%"> + <td><b>Missing tool dependencies</i></td> + </tr> + </table> + </div> + <div style="clear: both"></div> + <div class="form-row"> + <table class="grid"> + <tr> + <td><b>name</b></td> + <td><b>type</b></td> + <td><b>version</b></td> + </tr> + %for name, requirements_dict in missing_tool_dependencies.items(): + <tr> + <td>${requirements_dict[ 'name' ]}</td> + <td>${requirements_dict[ 'type' ]}</td> + <td>${requirements_dict[ 'version' ]}</td></tr> - </table> - </div> - <div class="form-row"> - <% tool_dicts = metadata[ 'tools' ] %> - <table class="grid"> + %endfor + </table> + </div> + <div style="clear: both"></div> + %endif + %if installed_tool_dependencies: + <div class="form-row"> + <table width="100%"> + <tr bgcolor="#D8D8D8" width="100%"> + <td><b>Installed tool dependencies</i></td> + </tr> + </table> + </div> + <div style="clear: both"></div> + <div class="form-row"> + <table class="grid"> + <tr> + <td><b>name</b></td> + <td><b>type</b></td> + <td><b>version</b></td> + </tr> + %for installed_tool_dependency in installed_tool_dependencies: <tr> - <td><b>name</b></td> - <td><b>description</b></td> - <td><b>version</b></td> - <td><b>requirements</b></td> + <td>${installed_tool_dependency.name}</td> + <td>${installed_tool_dependency.type}</td> + <td>${installed_tool_dependency.version}</td></tr> - %for tool_dict in tool_dicts: - <tr> - <td> - <a class="view-info" href="${h.url_for( controller='admin_toolshed', action='view_tool_metadata', repository_id=trans.security.encode_id( repository.id ), tool_id=tool_dict[ 'id' ] )}"> - ${tool_dict[ 'name' ]} - </a> - </td> - <td>${tool_dict[ 'description' ]}</td> - <td>${tool_dict[ 'version' ]}</td> - <td> + %endfor + </table> + </div> + <div style="clear: both"></div> + %endif + %if 'tools' in metadata: + <div class="form-row"> + <table width="100%"> + <tr bgcolor="#D8D8D8" width="100%"> + <td><b>Tools</b><i> - click the name to view information about the tool</i></td> + </tr> + </table> + </div> + <div class="form-row"> + <% tool_dicts = metadata[ 'tools' ] %> + <table class="grid"> + <tr> + <td><b>name</b></td> + <td><b>description</b></td> + <td><b>version</b></td> + <td><b>requirements</b></td> + </tr> + %for tool_dict in tool_dicts: + <tr> + <td> + <a class="view-info" href="${h.url_for( controller='admin_toolshed', action='view_tool_metadata', repository_id=trans.security.encode_id( repository.id ), tool_id=tool_dict[ 'id' ] )}"> + ${tool_dict[ 'name' ]} + </a> + </td> + <td>${tool_dict[ 'description' ]}</td> + <td>${tool_dict[ 'version' ]}</td> + <td> + <% + if 'requirements' in tool_dict: + requirements = tool_dict[ 'requirements' ] + else: + requirements = None + %> + %if requirements: <% - if 'requirements' in tool_dict: - requirements = tool_dict[ 'requirements' ] - else: - requirements = None + requirements_str = '' + for requirement_dict in tool_dict[ 'requirements' ]: + requirements_str += '%s (%s), ' % ( requirement_dict[ 'name' ], requirement_dict[ 'type' ] ) + requirements_str = requirements_str.rstrip( ', ' ) %> - %if requirements: - <% - requirements_str = '' - for requirement_dict in tool_dict[ 'requirements' ]: - requirements_str += '%s (%s), ' % ( requirement_dict[ 'name' ], requirement_dict[ 'type' ] ) - requirements_str = requirements_str.rstrip( ', ' ) - %> - ${requirements_str} - %else: - none - %endif - </td> - </tr> - %endfor - </table> - </div> - <div style="clear: both"></div> - %endif - %if 'workflows' in metadata: - ## metadata[ 'workflows' ] is a list of tuples where each contained tuple is - ## [ <relative path to the .ga file in the repository>, <exported workflow dict> ] - <div class="form-row"> - <table width="100%"> - <tr bgcolor="#D8D8D8" width="100%"> - <td><b>Workflows</b><i> - click the name to import</i></td> + ${requirements_str} + %else: + none + %endif + </td></tr> - </table> - </div> - <div style="clear: both"></div> - <div class="form-row"> - <% workflow_tups = metadata[ 'workflows' ] %> - <table class="grid"> + %endfor + </table> + </div> + <div style="clear: both"></div> + %endif + %if 'workflows' in metadata: + ## metadata[ 'workflows' ] is a list of tuples where each contained tuple is + ## [ <relative path to the .ga file in the repository>, <exported workflow dict> ] + <div class="form-row"> + <table width="100%"> + <tr bgcolor="#D8D8D8" width="100%"> + <td><b>Workflows</b><i> - click the name to import</i></td> + </tr> + </table> + </div> + <div style="clear: both"></div> + <div class="form-row"> + <% workflow_tups = metadata[ 'workflows' ] %> + <table class="grid"> + <tr> + <td><b>name</b></td> + <td><b>steps</b></td> + <td><b>format-version</b></td> + <td><b>annotation</b></td> + </tr> + <% index = 0 %> + %for workflow_tup in workflow_tups: + <% + import os.path + relative_path = workflow_tup[ 0 ] + full_path = os.path.abspath( relative_path ) + workflow_dict = workflow_tup[ 1 ] + workflow_name = workflow_dict[ 'name' ] + ## Initially steps were not stored in the metadata record. + steps = workflow_dict.get( 'steps', [] ) + format_version = workflow_dict[ 'format-version' ] + annotation = workflow_dict[ 'annotation' ] + %><tr> - <td><b>name</b></td> - <td><b>steps</b></td> - <td><b>format-version</b></td> - <td><b>annotation</b></td> + <td> + <div class="menubutton" style="float: left;" id="workflow-${index}-popup"> + ${workflow_name} + <div popupmenu="workflow-${index}-popup"> + <a class="action-button" href="${h.url_for( controller='workflow', action='import_workflow', installed_repository_file=full_path, repository_id=trans.security.encode_id( repository.id ) )}">Import to Galaxy</a> + </div> + </div> + </td> + <td> + %if steps: + ${len( steps )} + %else: + unknown + %endif + </td> + <td>${format_version}</td> + <td>${annotation}</td></tr> - <% index = 0 %> - %for workflow_tup in workflow_tups: - <% - import os.path - relative_path = workflow_tup[ 0 ] - full_path = os.path.abspath( relative_path ) - workflow_dict = workflow_tup[ 1 ] - workflow_name = workflow_dict[ 'name' ] - ## Initially steps were not stored in the metadata record. - steps = workflow_dict.get( 'steps', [] ) - format_version = workflow_dict[ 'format-version' ] - annotation = workflow_dict[ 'annotation' ] - %> - <tr> - <td> - <div class="menubutton" style="float: left;" id="workflow-${index}-popup"> - ${workflow_name} - <div popupmenu="workflow-${index}-popup"> - <a class="action-button" href="${h.url_for( controller='workflow', action='import_workflow', installed_repository_file=full_path, repository_id=trans.security.encode_id( repository.id ) )}">Import to Galaxy</a> - </div> - </div> - </td> - <td> - %if steps: - ${len( steps )} - %else: - unknown - %endif - </td> - <td>${format_version}</td> - <td>${annotation}</td> - </tr> - <% index += 1 %> - %endfor - </table> - </div> - <div style="clear: both"></div> - %endif - %if 'datatypes' in metadata: - <div class="form-row"> - <table width="100%"> - <tr bgcolor="#D8D8D8" width="100%"> - <td><b>Data types</b></td> + <% index += 1 %> + %endfor + </table> + </div> + <div style="clear: both"></div> + %endif + %if 'datatypes' in metadata: + <div class="form-row"> + <table width="100%"> + <tr bgcolor="#D8D8D8" width="100%"> + <td><b>Data types</b></td> + </tr> + </table> + </div> + <div style="clear: both"></div> + <div class="form-row"> + <% datatypes_dicts = metadata[ 'datatypes' ] %> + <table class="grid"> + <tr> + <td><b>extension</b></td> + <td><b>type</b></td> + <td><b>mimetype</b></td> + <td><b>subclass</b></td> + </tr> + %for datatypes_dict in datatypes_dicts: + <tr> + <td>${datatypes_dict.get( 'extension', ' ' )}</td> + <td>${datatypes_dict.get( 'dtype', ' ' )}</td> + <td>${datatypes_dict.get( 'mimetype', ' ' )}</td> + <td>${datatypes_dict.get( 'subclass', ' ' )}</td></tr> - </table> - </div> - <div style="clear: both"></div> - <div class="form-row"> - <% datatypes_dicts = metadata[ 'datatypes' ] %> - <table class="grid"> - <tr> - <td><b>extension</b></td> - <td><b>type</b></td> - <td><b>mimetype</b></td> - <td><b>subclass</b></td> - </tr> - %for datatypes_dict in datatypes_dicts: - <% - extension = datatypes_dict.get( 'extension', ' ' ) - dtype = datatypes_dict.get( 'dtype', ' ' ) - mimetype = datatypes_dict.get( 'mimetype', ' ' ) - subclass = datatypes_dict.get( 'subclass', ' ' ) - %> - <tr> - <td>${extension}</td> - <td>${dtype}</td> - <td>${mimetype}</td> - <td>${subclass}</td> - </tr> - %endfor - </table> - </div> - <div style="clear: both"></div> - %endif + %endfor + </table> + </div> + <div style="clear: both"></div> %endif %if can_reset_metadata: <form name="set_metadata" action="${h.url_for( controller='admin_toolshed', action='manage_repository', id=trans.security.encode_id( repository.id ) )}" method="post"> diff -r 599e16b18e34267a9563f47b1acaa234165482ea -r b1f35669f93c4163cf803d64beb37a1cb0d5381c templates/admin/tool_shed_repository/deactivate_or_uninstall_repository.mako --- a/templates/admin/tool_shed_repository/deactivate_or_uninstall_repository.mako +++ b/templates/admin/tool_shed_repository/deactivate_or_uninstall_repository.mako @@ -6,9 +6,12 @@ <ul class="manage-table-actions"><li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Repository Actions</a></li><div popupmenu="repository-${repository.id}-popup"> - <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='browse_repository', id=trans.security.encode_id( repository.id ) )}">Browse repository</a> + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='browse_repository', id=trans.security.encode_id( repository.id ) )}">Browse repository files</a><a class="action-button" href="${h.url_for( controller='admin_toolshed', action='manage_repository', id=trans.security.encode_id( repository.id ) )}">Manage repository</a><a class="action-button" href="${h.url_for( controller='admin_toolshed', action='check_for_updates', id=trans.security.encode_id( repository.id ) )}">Get updates</a> + %if repository.tool_dependencies: + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='manage_tool_dependencies', id=trans.security.encode_id( repository.id ) )}">Manage tool dependencies</a> + %endif </div></ul> diff -r 599e16b18e34267a9563f47b1acaa234165482ea -r b1f35669f93c4163cf803d64beb37a1cb0d5381c templates/admin/tool_shed_repository/manage_repository.mako --- a/templates/admin/tool_shed_repository/manage_repository.mako +++ b/templates/admin/tool_shed_repository/manage_repository.mako @@ -6,13 +6,13 @@ <ul class="manage-table-actions"><li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Repository Actions</a></li><div popupmenu="repository-${repository.id}-popup"> - <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='browse_repository', id=trans.security.encode_id( repository.id ) )}">Browse repository</a> + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='browse_repository', id=trans.security.encode_id( repository.id ) )}">Browse repository files</a><a class="action-button" href="${h.url_for( controller='admin_toolshed', action='check_for_updates', id=trans.security.encode_id( repository.id ) )}">Get updates</a> %if repository.includes_tools: <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='set_tool_versions', id=trans.security.encode_id( repository.id ) )}">Set tool versions</a> %endif - %if tool_dependencies_missing: - <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='install_missing_tool_dependencies', id=trans.security.encode_id( repository.id ) )}">Install tool dependencies</a> + %if repository.tool_dependencies: + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='manage_tool_dependencies', id=trans.security.encode_id( repository.id ) )}">Manage tool dependencies</a> %endif <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='deactivate_or_uninstall_repository', id=trans.security.encode_id( repository.id ) )}">Deactivate or Uninstall</a></div> @@ -64,5 +64,5 @@ </div></div><p/> -${render_metadata( repository, can_reset_metadata=True )} +${render_repository_contents( repository, can_reset_metadata=True )} <p/> diff -r 599e16b18e34267a9563f47b1acaa234165482ea -r b1f35669f93c4163cf803d64beb37a1cb0d5381c templates/admin/tool_shed_repository/manage_tool_dependencies.mako --- /dev/null +++ b/templates/admin/tool_shed_repository/manage_tool_dependencies.mako @@ -0,0 +1,56 @@ +<%inherit file="/base.mako"/> +<%namespace file="/message.mako" import="render_msg" /> + +<% import os %> + +<br/><br/> +<ul class="manage-table-actions"> + <li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Repository Actions</a></li> + <div popupmenu="repository-${repository.id}-popup"> + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='browse_repository', id=trans.security.encode_id( repository.id ) )}">Browse repository files</a> + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='check_for_updates', id=trans.security.encode_id( repository.id ) )}">Get updates</a> + %if repository.includes_tools: + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='set_tool_versions', id=trans.security.encode_id( repository.id ) )}">Set tool versions</a> + %endif + %if repository.missing_tool_dependencies: + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='install_missing_tool_dependencies', id=trans.security.encode_id( repository.id ) )}">Install missing tool dependencies</a> + %endif + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='deactivate_or_uninstall_repository', id=trans.security.encode_id( repository.id ) )}">Deactivate or Uninstall</a> + </div> +</ul> + +%if message: + ${render_msg( message, status )} +%endif + +<div class="toolForm"> + <div class="toolFormTitle">${repository.name} repository's installed tool dependencies</div> + <div class="toolFormBody"> + <div class="form-row"> + <table class="grid"> + %for tool_dependency in repository.tool_dependencies: + <% + name = tool_dependency.name + version = tool_dependency.version + type = tool_dependency.type + installed_changeset_revision = tool_dependency.installed_changeset_revision + uninstalled = tool_dependency.uninstalled + install_dir = os.path.abspath( os.path.join( trans.app.config.tool_dependency_dir, + name, + version, + repository.owner, + repository.name, + installed_changeset_revision ) ) + %> + <tr><td bgcolor="#D8D8D8"><b>Name</b></td><td bgcolor="#D8D8D8">${name}</td></tr> + <tr><th>Version</th><td>${version}</td></tr> + <tr><th>Type</th><td>${type}</td></tr> + <tr><th>Install directory</th><td>${install_dir}</td></tr> + <tr><th>Installed changeset revision</th><td>${installed_changeset_revision}</td></tr> + <tr><th>Uninstalled</th><td>${uninstalled}</td></tr> + %endfor + </table> + <div style="clear: both"></div> + </div> + </div> +</div> diff -r 599e16b18e34267a9563f47b1acaa234165482ea -r b1f35669f93c4163cf803d64beb37a1cb0d5381c templates/admin/tool_shed_repository/view_tool_metadata.mako --- a/templates/admin/tool_shed_repository/view_tool_metadata.mako +++ b/templates/admin/tool_shed_repository/view_tool_metadata.mako @@ -5,9 +5,12 @@ <ul class="manage-table-actions"><li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Repository Actions</a></li><div popupmenu="repository-${repository.id}-popup"> - <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='browse_repository', id=trans.security.encode_id( repository.id ) )}">Browse repository</a> + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='browse_repository', id=trans.security.encode_id( repository.id ) )}">Browse repository files</a><a class="action-button" href="${h.url_for( controller='admin_toolshed', action='manage_repository', id=trans.security.encode_id( repository.id ) )}">Manage repository</a><a class="action-button" href="${h.url_for( controller='admin_toolshed', action='check_for_updates', id=trans.security.encode_id( repository.id ) )}">Get updates</a> + %if repository.tool_dependencies: + <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='manage_tool_dependencies', id=trans.security.encode_id( repository.id ) )}">Manage tool dependencies</a> + %endif <a class="action-button" href="${h.url_for( controller='admin_toolshed', action='deactivate_or_uninstall_repository', id=trans.security.encode_id( repository.id ) )}">Deactivate or Uninstall</a></div></ul> @@ -95,15 +98,27 @@ requirements = None %> %if requirements: - <% - requirements_str = '' - for requirement_dict in metadata[ 'requirements' ]: - requirements_str += '%s (%s), ' % ( requirement_dict[ 'name' ], requirement_dict[ 'type' ] ) - requirements_str = requirements_str.rstrip( ', ' ) - %><div class="form-row"><label>Requirements:</label> - ${requirements_str} + <table class="grid"> + <tr> + <td><b>name</b></td> + <td><b>version</b></td> + <td><b>type</b></td> + </tr> + %for requirement_dict in requirements: + <% + requirement_name = requirement_dict[ 'name' ] or 'not provided' + requirement_version = requirement_dict[ 'version' ] or 'not provided' + requirement_type = requirement_dict[ 'type' ] or 'not provided' + %> + <tr> + <td>${requirement_name}</td> + <td>${requirement_version}</td> + <td>${requirement_type}</td> + </tr> + %endfor + </table><div style="clear: both"></div></div> %endif diff -r 599e16b18e34267a9563f47b1acaa234165482ea -r b1f35669f93c4163cf803d64beb37a1cb0d5381c templates/webapps/community/repository/common.mako --- a/templates/webapps/community/repository/common.mako +++ b/templates/webapps/community/repository/common.mako @@ -22,13 +22,13 @@ // initAjax is hard to fake, so we pass the children as object array: initAjax: {url: "${h.url_for( controller='repository', action='open_folder' )}", dataType: "json", - data: { repository_id: "${trans.security.encode_id( repository.id )}", key: "${repository.repo_path}" }, + data: { folder_path: "${repository.repo_path}" }, }, onLazyRead: function(dtnode){ dtnode.appendAjax({ url: "${h.url_for( controller='repository', action='open_folder' )}", dataType: "json", - data: { repository_id: "${trans.security.encode_id( repository.id )}", key: dtnode.data.key }, + data: { folder_path: dtnode.data.key }, }); }, onSelect: function(select, dtnode) { Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.
participants (1)
-
Bitbucket