Esempio n. 1
0
    def get_ordered_installable_revisions(self, trans, name, owner, **kwd):
        """
        GET /api/repositories/get_ordered_installable_revisions

        :param name: the name of the Repository
        :param owner: the owner of the Repository

        Returns the ordered list of changeset revision hash strings that are associated with installable revisions.
        As in the changelog, the list is ordered oldest to newest.
        """
        # Example URL: http://localhost:9009/api/repositories/get_installable_revisions?name=add_column&owner=test
        if name and owner:
            # Get the repository information.
            repository = suc.get_repository_by_name_and_owner(
                trans.app, name, owner)
            if repository is None:
                error_message = "Error in the Tool Shed repositories API in get_ordered_installable_revisions: "
                error_message += "cannot locate repository %s owned by %s." % (
                    str(name), str(owner))
                log.debug(error_message)
                return []
            repo = hg_util.get_repo_for_repository(trans.app,
                                                   repository=repository,
                                                   repo_path=None,
                                                   create=False)
            ordered_installable_revisions = suc.get_ordered_metadata_changeset_revisions(
                repository, repo, downloadable=True)
            return ordered_installable_revisions
        else:
            error_message = "Error in the Tool Shed repositories API in get_ordered_installable_revisions: "
            error_message += "invalid name %s or owner %s received." % (
                str(name), str(owner))
            log.debug(error_message)
            return []
Esempio n. 2
0
def check_status_and_reset_downloadable( trans, import_results_tups ):
    """Check the status of each imported repository and set downloadable to False if errors."""
    flush = False
    for import_results_tup in import_results_tups:
        ok, name_owner, message = import_results_tup
        name, owner = name_owner
        if not ok:
            repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
            # Do not allow the repository to be automatically installed if population resulted in errors.
            tip_changeset_revision = repository.tip( trans.app )
            repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans,
                                                                                     trans.security.encode_id( repository.id ),
                                                                                     tip_changeset_revision )
            if repository_metadata:
                if repository_metadata.downloadable:
                    repository_metadata.downloadable = False
                    trans.sa_session.add( repository_metadata )
                    if not flush:
                        flush = True
                # Do not allow dependent repository revisions to be automatically installed if population
                # resulted in errors.
                dependent_downloadable_revisions = suc.get_dependent_downloadable_revisions( trans, repository_metadata )
                for dependent_downloadable_revision in dependent_downloadable_revisions:
                    if dependent_downloadable_revision.downloadable:
                        dependent_downloadable_revision.downloadable = False
                        trans.sa_session.add( dependent_downloadable_revision )
                        if not flush:
                            flush = True
    if flush:
        trans.sa_session.flush()
Esempio n. 3
0
def handle_repository_dependency_elem(trans, elem):
    # <repository name="molecule_datatypes" owner="test" changeset_revision="1a070566e9c6" />
    error_message = ''
    name = elem.get('name')
    owner = elem.get('owner')
    if not name or not owner:
        error_message = handle_missing_repository_attribute(elem)
        return False, elem, error_message
    populated = False
    toolshed = elem.get('toolshed')
    if not toolshed:
        # Default the setting to the current tool shed.
        toolshed = str(url_for('/', qualified=True)).rstrip('/')
        elem.attrib['toolshed'] = toolshed
        populated = True
    changeset_revision = elem.get('changeset_revision')
    if not changeset_revision:
        # Populate the changeset_revision attribute with the latest installable metadata revision for the defined repository.
        # We use the latest installable revision instead of the latest metadata revision to ensure that the contents of the
        # revision are valid.
        repository = suc.get_repository_by_name_and_owner(
            trans.app, name, owner)
        if repository:
            repo_dir = repository.repo_path(trans.app)
            repo = hg.repository(suc.get_configured_ui(), repo_dir)
            lastest_installable_changeset_revision = suc.get_latest_downloadable_changeset_revision(
                trans, repository, repo)
            if lastest_installable_changeset_revision != suc.INITIAL_CHANGELOG_HASH:
                elem.attrib[
                    'changeset_revision'] = lastest_installable_changeset_revision
                populated = True
        else:
            error_message = 'Unable to locate repository with name %s and owner %s.  ' % (
                str(name), str(owner))
    return populated, elem, error_message
Esempio n. 4
0
def get_repository_dependency_tups_from_repository_metadata( app, repository_metadata, deprecated_only=False ):
    """
    Return a list of of tuples defining repository objects required by the received repository.  The returned
    list defines the entire repository dependency tree.  This method is called only from the Tool Shed.
    """
    dependency_tups = []
    if repository_metadata is not None:
        metadata = repository_metadata.metadata
        if metadata:
            repository_dependencies_dict = metadata.get( 'repository_dependencies', None )
            if repository_dependencies_dict is not None:
                repository_dependency_tups = repository_dependencies_dict.get( 'repository_dependencies', None )
                if repository_dependency_tups is not None:
                    # The value of repository_dependency_tups is a list of repository dependency tuples like this:
                    # ['http://localhost:9009', 'package_samtools_0_1_18', 'devteam', 'ef37fc635cb9', 'False', 'False']
                    for repository_dependency_tup in repository_dependency_tups:
                        toolshed, name, owner, changeset_revision, pir, oicct = \
                        common_util.parse_repository_dependency_tuple( repository_dependency_tup )
                        repository = suc.get_repository_by_name_and_owner( app, name, owner )
                        if repository:
                            if deprecated_only:
                                if repository.deprecated:
                                    dependency_tups.append( repository_dependency_tup )
                            else:
                                dependency_tups.append( repository_dependency_tup )
                        else:
                            log.debug( "Cannot locate repository %s owned by %s for inclusion in repository dependency tups." % \
                                ( name, owner ) )
    return dependency_tups
 def handle_key_rd_dicts_for_repository( self, current_repository_key, repository_key_rd_dicts ):
     key_rd_dict = repository_key_rd_dicts.pop( 0 )
     repository_dependency = key_rd_dict[ current_repository_key ]
     toolshed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \
         common_util.parse_repository_dependency_tuple( repository_dependency )
     if suc.tool_shed_is_this_tool_shed( toolshed ):
         required_repository = suc.get_repository_by_name_and_owner( self.app, name, owner )
         self.repository = required_repository
         repository_id = self.app.security.encode_id( required_repository.id )
         required_repository_metadata = \
             metadata_util.get_repository_metadata_by_repository_id_changeset_revision( self.app,
                                                                                        repository_id,
                                                                                        changeset_revision )
         self.repository_metadata = required_repository_metadata
         if required_repository_metadata:
             # The required_repository_metadata changeset_revision is installable.
             required_metadata = required_repository_metadata.metadata
             if required_metadata:
                 for current_repository_key_rd_dict in repository_key_rd_dicts:
                     if not self.in_key_rd_dicts( current_repository_key_rd_dict, self.key_rd_dicts_to_be_processed ):
                         # Add the current repository_dependency into self.key_rd_dicts_to_be_processed.
                         self.key_rd_dicts_to_be_processed.append( current_repository_key_rd_dict )
         if not self.in_key_rd_dicts( key_rd_dict, self.handled_key_rd_dicts ):
             # Add the current repository_dependency into self.handled_key_rd_dicts.
             self.handled_key_rd_dicts.append( key_rd_dict )
         if self.in_key_rd_dicts( key_rd_dict, self.key_rd_dicts_to_be_processed ):
             # Remove the current repository from self.key_rd_dicts_to_be_processed.
             self.key_rd_dicts_to_be_processed = self.remove_from_key_rd_dicts( key_rd_dict, self.key_rd_dicts_to_be_processed )
     else:
         # The repository is in a different tool shed, so build an url and send a request.
         error_message = "Repository dependencies are currently supported only within the same Tool Shed.  "
         error_message += "Ignoring repository dependency definition for tool shed "
         error_message += "%s, name %s, owner %s, changeset revision %s" % ( toolshed, name, owner, changeset_revision )
         log.debug( error_message )
Esempio n. 6
0
 def handle_request( self, trans, **kwd ):
     # The os command that results in this method being called will look something like:
     # hg clone http://[email protected]:9009/repos/test/convert_characters1
     hg_version = mercurial.__version__.version
     cmd = kwd.get( 'cmd', None )
     hgweb_config = trans.app.hgweb_config_manager.hgweb_config
     def make_web_app():
         hgwebapp = hgwebdir( hgweb_config )
         return hgwebapp
     wsgi_app = wsgiapplication( make_web_app )
     if hg_version >= '2.2.3' and cmd == 'pushkey':                
         # When doing an "hg push" from the command line, the following commands, in order, will be retrieved from environ, depending
         # upon the mercurial version being used.  In mercurial version 2.2.3, section 15.2. Command changes includes a new feature: 
         # pushkey: add hooks for pushkey/listkeys (see http://mercurial.selenic.com/wiki/WhatsNew#Mercurial_2.2.3_.282012-07-01.29).
         # We require version 2.2.3 since the pushkey hook was added in that version.
         # If mercurial version >= '2.2.3': capabilities -> batch -> branchmap -> unbundle -> listkeys -> pushkey
         path_info = kwd.get( 'path_info', None )
         if path_info:
             owner, name = path_info.split( '/' )
             repository = get_repository_by_name_and_owner( trans.app, name, owner )
             if repository:
                 if hg_version >= '2.2.3':
                     # Set metadata using the repository files on disk.
                     error_message, status = set_repository_metadata( trans, repository )
                     if status == 'ok' and error_message:
                         log.debug( "Successfully reset metadata on repository %s, but encountered problem: %s" % ( repository.name, error_message ) )
                     elif status != 'ok' and error_message:
                         log.debug( "Error resetting metadata on repository %s: %s" % ( repository.name, error_message ) )
     return wsgi_app
def validate_repository_name(app, name, user):
    """
    Validate whether the given name qualifies as a new TS repo name.
    Repository names must be unique for each user, must be at least two characters
    in length and must contain only lower-case letters, numbers, and the '_' character.
    """
    if name in ['None', None, '']:
        return 'Enter the required repository name.'
    if name in ['repos']:
        return "The term <b>%s</b> is a reserved word in the tool shed, so it cannot be used as a repository name." % name
    check_existing = suc.get_repository_by_name_and_owner(
        app, name, user.username)
    if check_existing is not None:
        if check_existing.deleted:
            return 'You own a deleted repository named <b>%s</b>, please choose a different name.' % escape(
                name)
        else:
            return "You already own a repository named <b>%s</b>, please choose a different name." % escape(
                name)
    if len(name) < 2:
        return "Repository names must be at least 2 characters in length."
    if len(name) > 80:
        return "Repository names cannot be more than 80 characters in length."
    if not (VALID_REPOSITORYNAME_RE.match(name)):
        return "Repository names must contain only lower-case letters, numbers and underscore."
    return ''
Esempio n. 8
0
 def get_ordered_installable_revisions(self, trans, name, owner, **kwd):
     """
     GET /api/repositories/get_ordered_installable_revisions
     
     :param name: the name of the Repository
     :param owner: the owner of the Repository
     
     Returns the ordered list of changeset revision hash strings that are associated with installable revisions.  As in the changelog, the
     list is ordered oldest to newest.
     """
     # Example URL: http://localhost:9009/api/repositories/get_installable_revisions?name=add_column&owner=test
     try:
         # Get the repository information.
         repository = suc.get_repository_by_name_and_owner(
             trans.app, name, owner)
         encoded_repository_id = trans.security.encode_id(repository.id)
         repo_dir = repository.repo_path(trans.app)
         repo = hg.repository(suc.get_configured_ui(), repo_dir)
         ordered_installable_revisions = suc.get_ordered_metadata_changeset_revisions(
             repository, repo, downloadable=True)
         return ordered_installable_revisions
     except Exception, e:
         message = "Error in the Tool Shed repositories API in get_ordered_installable_revisions: %s" % str(
             e)
         log.error(message, exc_info=True)
         trans.response.status = 500
         return message
Esempio n. 9
0
def get_repository_status_from_tool_shed( trans, repository_info_dicts ):
    """
    For each exported repository archive contained in the capsule, inspect the Tool Shed to see if that repository already
    exists or if the current user is authorized to create the repository, and set a status appropriately.  If repository
    dependencies are included in the capsule, repositories may have various owners.  We will keep repositories associated
    with owners, so we need to restrict created repositories to those the current user can create.  If the current user is
    an admin or a member of the IUC, all repositories will be created no matter the owner.  Otherwise, only repositories
    whose associated owner is the current user will be created.
    """
    repository_status_info_dicts = []
    for repository_info_dict in repository_info_dicts:
        repository = suc.get_repository_by_name_and_owner( trans.app, repository_info_dict[ 'name' ], repository_info_dict[ 'owner' ] )
        if repository:
            if repository.deleted:
                repository_info_dict[ 'status' ] = 'Exists, deleted'
            elif repository.deprecated:
                repository_info_dict[ 'status' ] = 'Exists, deprecated'
            else:
                repository_info_dict[ 'status' ] = 'Exists'
        else:
            # No repository with the specified name and owner currently exists, so make sure the current user can create one.
            if trans.user_is_admin():
                repository_info_dict[ 'status' ] = None
            elif trans.app.security_agent.user_can_import_repository_archive( trans.user, repository_info_dict[ 'owner' ] ):
                repository_info_dict[ 'status' ] = None
            else:
                repository_info_dict[ 'status' ] = 'Not authorized to import'
        repository_status_info_dicts.append( repository_info_dict )
    return repository_status_info_dicts
Esempio n. 10
0
 def handle_key_rd_dicts_for_repository( self, current_repository_key, repository_key_rd_dicts ):
     key_rd_dict = repository_key_rd_dicts.pop( 0 )
     repository_dependency = key_rd_dict[ current_repository_key ]
     toolshed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \
         common_util.parse_repository_dependency_tuple( repository_dependency )
     if suc.tool_shed_is_this_tool_shed( toolshed ):
         required_repository = suc.get_repository_by_name_and_owner( self.app, name, owner )
         self.repository = required_repository
         repository_id = self.app.security.encode_id( required_repository.id )
         required_repository_metadata = \
             metadata_util.get_repository_metadata_by_repository_id_changeset_revision( self.app,
                                                                                        repository_id,
                                                                                        changeset_revision )
         self.repository_metadata = required_repository_metadata
         if required_repository_metadata:
             # The required_repository_metadata changeset_revision is installable.
             required_metadata = required_repository_metadata.metadata
             if required_metadata:
                 for current_repository_key_rd_dict in repository_key_rd_dicts:
                     if not self.in_key_rd_dicts( current_repository_key_rd_dict, self.key_rd_dicts_to_be_processed ):
                         # Add the current repository_dependency into self.key_rd_dicts_to_be_processed.
                         self.key_rd_dicts_to_be_processed.append( current_repository_key_rd_dict )
         if not self.in_key_rd_dicts( key_rd_dict, self.handled_key_rd_dicts ):
             # Add the current repository_dependency into self.handled_key_rd_dicts.
             self.handled_key_rd_dicts.append( key_rd_dict )
         if self.in_key_rd_dicts( key_rd_dict, self.key_rd_dicts_to_be_processed ):
             # Remove the current repository from self.key_rd_dicts_to_be_processed.
             self.key_rd_dicts_to_be_processed = self.remove_from_key_rd_dicts( key_rd_dict, self.key_rd_dicts_to_be_processed )
     else:
         # The repository is in a different tool shed, so build an url and send a request.
         error_message = "Repository dependencies are currently supported only within the same Tool Shed.  "
         error_message += "Ignoring repository dependency definition for tool shed "
         error_message += "%s, name %s, owner %s, changeset revision %s" % ( toolshed, name, owner, changeset_revision )
         log.debug( error_message )
Esempio n. 11
0
def get_dependencies_for_metadata_revision( app, metadata ):
    dependencies = []
    for shed, name, owner, changeset, prior, _ in metadata[ 'repository_dependencies' ]:
        required_repository = suc.get_repository_by_name_and_owner( app, name, owner )
        metadata_entry = suc.get_repository_metadata_by_changeset_revision( app, app.security.encode_id( required_repository.id ), changeset )
        dependencies.append( metadata_entry )
    return dependencies
Esempio n. 12
0
    def get_ordered_installable_revisions( self, trans, name, owner, **kwd ):
        """
        GET /api/repositories/get_ordered_installable_revisions

        :param name: the name of the Repository
        :param owner: the owner of the Repository

        Returns the ordered list of changeset revision hash strings that are associated with installable revisions.
        As in the changelog, the list is ordered oldest to newest.
        """
        # Example URL: http://localhost:9009/api/repositories/get_installable_revisions?name=add_column&owner=test
        if name and owner:
            # Get the repository information.
            repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
            if repository is None:
                error_message = "Error in the Tool Shed repositories API in get_ordered_installable_revisions: "
                error_message += "cannot locate repository %s owned by %s." % ( str( name ), str( owner ) )
                log.debug( error_message )
                return []
            repo = hg_util.get_repo_for_repository( trans.app, repository=repository, repo_path=None, create=False )
            ordered_installable_revisions = suc.get_ordered_metadata_changeset_revisions( repository, repo, downloadable=True )
            return ordered_installable_revisions
        else:
            error_message = "Error in the Tool Shed repositories API in get_ordered_installable_revisions: "
            error_message += "invalid name %s or owner %s received." % ( str( name ), str( owner ) )
            log.debug( error_message )
            return []
Esempio n. 13
0
def validate_repository_name(app, name, user):
    """
    Validate whether the given name qualifies as a new TS repo name.
    Repository names must be unique for each user, must be at least two characters
    in length and must contain only lower-case letters, numbers, and the '_' character.
    """
    if name in ["None", None, ""]:
        return "Enter the required repository name."
    if name in ["repos"]:
        return (
            "The term <b>%s</b> is a reserved word in the tool shed, so it cannot be used as a repository name." % name
        )
    check_existing = suc.get_repository_by_name_and_owner(app, name, user.username)
    if check_existing is not None:
        if check_existing.deleted:
            return "You own a deleted repository named <b>%s</b>, please choose a different name." % escape(name)
        else:
            return "You already own a repository named <b>%s</b>, please choose a different name." % escape(name)
    if len(name) < 2:
        return "Repository names must be at least 2 characters in length."
    if len(name) > 80:
        return "Repository names cannot be more than 80 characters in length."
    if not (VALID_REPOSITORYNAME_RE.match(name)):
        return "Repository names must contain only lower-case letters, numbers and underscore."
    return ""
Esempio n. 14
0
    def handle_request(self, trans, **kwd):
        # The os command that results in this method being called will look something like:
        # hg clone http://[email protected]:9009/repos/test/convert_characters1
        hg_version = mercurial.__version__.version
        cmd = kwd.get('cmd', None)
        hgweb_config = trans.app.hgweb_config_manager.hgweb_config

        def make_web_app():
            hgwebapp = hgwebdir(hgweb_config)
            return hgwebapp

        wsgi_app = wsgiapplication(make_web_app)
        if hg_version >= '2.2.3' and cmd == 'pushkey':
            # When doing an "hg push" from the command line, the following commands, in order, will be
            # retrieved from environ, depending upon the mercurial version being used.  In mercurial
            # version 2.2.3, section 15.2. Command changes includes a new feature:
            # pushkey: add hooks for pushkey/listkeys
            # (see http://mercurial.selenic.com/wiki/WhatsNew#Mercurial_2.2.3_.282012-07-01.29).
            # We require version 2.2.3 since the pushkey hook was added in that version.
            # If mercurial version >= '2.2.3': capabilities -> batch -> branchmap -> unbundle -> listkeys -> pushkey
            path_info = kwd.get('path_info', None)
            if path_info:
                owner, name = path_info.split('/')
                repository = get_repository_by_name_and_owner(
                    trans.app, name, owner)
                if repository:
                    if hg_version >= '2.2.3':
                        # Update the repository on disk to the tip revision, because the web upload
                        # form uses the on-disk working directory. If the repository is not updated
                        # on disk, pushing from the command line and then uploading  via the web
                        # interface will result in a new head being created.
                        repo = hg.repository(ui.ui(),
                                             repository.repo_path(trans.app))
                        update_repository(repo, ctx_rev=None)
                        repository_clone_url = generate_clone_url_for_repository_in_tool_shed(
                            trans.user, repository)
                        # Set metadata using the repository files on disk.
                        rmm = repository_metadata_manager.RepositoryMetadataManager(
                            app=trans.app,
                            user=trans.user,
                            repository=repository,
                            changeset_revision=repository.tip(trans.app),
                            repository_clone_url=repository_clone_url,
                            relative_install_dir=repository.repo_path(
                                trans.app),
                            repository_files_dir=None,
                            resetting_all_metadata_on_repository=False,
                            updating_installed_repository=False,
                            persist=False)
                        error_message, status = rmm.set_repository_metadata(
                            trans.request.host)
                        if status == 'ok' and error_message:
                            log.debug( "Successfully reset metadata on repository %s owned by %s, but encountered problem: %s" % \
                                       ( str( repository.name ), str( repository.user.username ), error_message ) )
                        elif status != 'ok' and error_message:
                            log.debug( "Error resetting metadata on repository %s owned by %s: %s" % \
                                       ( str( repository.name ), str( repository.user.username ), error_message ) )
        return wsgi_app
Esempio n. 15
0
def get_repository_ids( trans, repo_info_dicts ):
    repository_ids = []
    for repo_info_dict in repo_info_dicts:
        for repository_name, repo_info_tup in repo_info_dict.items():
            description, repository_clone_url, changeset_revision, ctx_rev, repository_owner, repository_dependencies, tool_dependencies = \
                suc.get_repo_info_tuple_contents( repo_info_tup )
            repository = suc.get_repository_by_name_and_owner( trans.app, repository_name, repository_owner )
            repository_ids.append( trans.security.encode_id( repository.id ) )
    return repository_ids
Esempio n. 16
0
def get_dependencies_for_metadata_revision(app, metadata):
    dependencies = []
    for shed, name, owner, changeset, prior, _ in metadata[
            'repository_dependencies']:
        required_repository = suc.get_repository_by_name_and_owner(
            app, name, owner)
        metadata_entry = suc.get_repository_metadata_by_changeset_revision(
            app, app.security.encode_id(required_repository.id), changeset)
        dependencies.append(metadata_entry)
    return dependencies
Esempio n. 17
0
def get_repository_ids(trans, repo_info_dicts):
    """Return a list of repository ids associated with each dictionary in the received repo_info_dicts."""
    repository_ids = []
    for repo_info_dict in repo_info_dicts:
        for repository_name, repo_info_tup in repo_info_dict.items():
            description, repository_clone_url, changeset_revision, ctx_rev, repository_owner, repository_dependencies, tool_dependencies = suc.get_repo_info_tuple_contents(
                repo_info_tup
            )
            repository = suc.get_repository_by_name_and_owner(trans.app, repository_name, repository_owner)
            repository_ids.append(trans.security.encode_id(repository.id))
    return repository_ids
    def export(self, trans, payload, **kwd):
        """
        POST /api/repository_revisions/export
        Creates and saves a gzip compressed tar archive of a repository and optionally all of its repository dependencies.

        The following parameters are included in the payload.
        :param tool_shed_url (required): the base URL of the Tool Shed from which the Repository is to be exported
        :param name (required): the name of the Repository
        :param owner (required): the owner of the Repository
        :param changeset_revision (required): the changeset_revision of the RepositoryMetadata object associated with the Repository
        :param export_repository_dependencies (optional): whether to export repository dependencies - defaults to False
        :param download_dir (optional): the local directory to which to download the archive - defaults to /tmp
        """
        tool_shed_url = payload.get('tool_shed_url', '')
        if not tool_shed_url:
            raise HTTPBadRequest(
                detail="Missing required parameter 'tool_shed_url'.")
        tool_shed_url = tool_shed_url.rstrip('/')
        name = payload.get('name', '')
        if not name:
            raise HTTPBadRequest(detail="Missing required parameter 'name'.")
        owner = payload.get('owner', '')
        if not owner:
            raise HTTPBadRequest(detail="Missing required parameter 'owner'.")
        changeset_revision = payload.get('changeset_revision', '')
        if not changeset_revision:
            raise HTTPBadRequest(
                detail="Missing required parameter 'changeset_revision'.")
        export_repository_dependencies = payload.get(
            'export_repository_dependencies', False)
        # We'll currently support only gzip-compressed tar archives.
        file_type = 'gz'
        export_repository_dependencies = util.asbool(
            export_repository_dependencies)
        # Get the repository information.
        repository = suc.get_repository_by_name_and_owner(
            trans.app, name, owner)
        if repository is None:
            error_message = 'Cannot locate repository with name %s and owner %s,' % (
                str(name), str(owner))
            log.debug(error_message)
            return None, error_message
        repository_id = trans.security.encode_id(repository.id)
        erm = capsule_manager.ExportRepositoryManager(
            app=trans.app,
            user=trans.user,
            tool_shed_url=tool_shed_url,
            repository=repository,
            changeset_revision=changeset_revision,
            export_repository_dependencies=export_repository_dependencies,
            using_api=True)
        return erm.export_repository()
Esempio n. 19
0
    def handle_request( self, trans, **kwd ):
        # The os command that results in this method being called will look something like:
        # hg clone http://[email protected]:9009/repos/test/convert_characters1
        hg_version = mercurial.__version__.version
        cmd = kwd.get( 'cmd', None )
        hgweb_config = trans.app.hgweb_config_manager.hgweb_config

        def make_web_app():
            hgwebapp = hgwebdir( hgweb_config )
            return hgwebapp
        wsgi_app = wsgiapplication( make_web_app )
        if hg_version >= '2.2.3' and cmd == 'pushkey':
            # When doing an "hg push" from the command line, the following commands, in order, will be
            # retrieved from environ, depending upon the mercurial version being used.  In mercurial
            # version 2.2.3, section 15.2. Command changes includes a new feature:
            # pushkey: add hooks for pushkey/listkeys
            # (see http://mercurial.selenic.com/wiki/WhatsNew#Mercurial_2.2.3_.282012-07-01.29).
            # We require version 2.2.3 since the pushkey hook was added in that version.
            # If mercurial version >= '2.2.3': capabilities -> batch -> branchmap -> unbundle -> listkeys -> pushkey
            path_info = kwd.get( 'path_info', None )
            if path_info:
                owner, name = path_info.split( '/' )
                repository = get_repository_by_name_and_owner( trans.app, name, owner )
                if repository:
                    if hg_version >= '2.2.3':
                        # Update the repository on disk to the tip revision, because the web upload
                        # form uses the on-disk working directory. If the repository is not updated
                        # on disk, pushing from the command line and then uploading  via the web
                        # interface will result in a new head being created.
                        repo = hg.repository( ui.ui(), repository.repo_path( trans.app ) )
                        update_repository( repo, ctx_rev=None )
                        repository_clone_url = generate_clone_url_for_repository_in_tool_shed( trans.user, repository )
                        # Set metadata using the repository files on disk.
                        rmm = repository_metadata_manager.RepositoryMetadataManager( app=trans.app,
                                                                                     user=trans.user,
                                                                                     repository=repository,
                                                                                     changeset_revision=repository.tip( trans.app ),
                                                                                     repository_clone_url=repository_clone_url,
                                                                                     relative_install_dir=repository.repo_path( trans.app ),
                                                                                     repository_files_dir=None,
                                                                                     resetting_all_metadata_on_repository=False,
                                                                                     updating_installed_repository=False,
                                                                                     persist=False )
                        error_message, status = rmm.set_repository_metadata( trans.request.host )
                        if status == 'ok' and error_message:
                            log.debug( "Successfully reset metadata on repository %s owned by %s, but encountered problem: %s" %
                                       ( str( repository.name ), str( repository.user.username ), error_message ) )
                        elif status != 'ok' and error_message:
                            log.debug( "Error resetting metadata on repository %s owned by %s: %s" %
                                       ( str( repository.name ), str( repository.user.username ), error_message ) )
        return wsgi_app
Esempio n. 20
0
def get_components_from_repo_info_dict( trans, repo_info_dict ):
    """
    Return the repository and the associated latest installable changeset_revision (including updates) for the repository defined by the received
    repo_info_dict.
    """
    for repository_name, repo_info_tup in repo_info_dict.items():
        # There should only be one entry in the received repo_info_dict.
        description, repository_clone_url, changeset_revision, ctx_rev, repository_owner, repository_dependencies, tool_dependencies = \
            suc.get_repo_info_tuple_contents( repo_info_tup )
        repository = suc.get_repository_by_name_and_owner( trans.app, repository_name, repository_owner )
        repository_metadata = suc.get_current_repository_metadata_for_changeset_revision( trans, repository, changeset_revision )
        if repository_metadata:
            return repository, repository_metadata.changeset_revision
    return None, None
    def export( self, trans, payload, **kwd ):
        """
        POST /api/repository_revisions/export
        Creates and saves a gzip compressed tar archive of a repository and optionally all of it's repository dependencies.

        The following parameters are included in the payload.
        :param tool_shed_url (required): the base URL of the Tool Shed from which the Repository was installed
        :param name (required): the name of the Repository
        :param owner (required): the owner of the Repository
        :param changset_revision (required): the changset_revision of the RepositoryMetadata object associated with the Repository
        :param export_repository_dependencies (optional): whether to export repository dependencies - defaults to False
        :param download_dir (optional): the local directory to which to download the archive - defaults to /tmp
        """
        tool_shed_url = payload.get( 'tool_shed_url', '' )
        if not tool_shed_url:
            raise HTTPBadRequest( detail="Missing required parameter 'tool_shed_url'." )
        tool_shed_url = tool_shed_url.rstrip( '/' )
        name = payload.get( 'name', '' )
        if not name:
            raise HTTPBadRequest( detail="Missing required parameter 'name'." )
        owner = payload.get( 'owner', '' )
        if not owner:
            raise HTTPBadRequest( detail="Missing required parameter 'owner'." )
        changeset_revision = payload.get( 'changeset_revision', '' )
        if not changeset_revision:
            raise HTTPBadRequest( detail="Missing required parameter 'changeset_revision'." )
        export_repository_dependencies = payload.get( 'export_repository_dependencies', False )
        try:
            # We'll currently support only gzip-compressed tar archives.
            file_type = 'gz'
            export_repository_dependencies = util.string_as_bool( export_repository_dependencies )
            # Get the repository information.
            repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
            repository_id = trans.security.encode_id( repository.id )
            response = export_util.export_repository( trans,
                                                      tool_shed_url,
                                                      repository_id,
                                                      str( repository.name ),
                                                      changeset_revision,
                                                      file_type,
                                                      export_repository_dependencies,
                                                      api=True )
            return response
        except Exception, e:
            message = "Error in the Tool Shed repository_revisions API in export: %s" % str( e )
            log.error( message, exc_info=True )
            trans.response.status = 500
            return message
Esempio n. 22
0
def handle_repository_dependency_elem( trans, elem, unpopulate=False ):
    # <repository name="molecule_datatypes" owner="test" changeset_revision="1a070566e9c6" />
    error_message = ''
    name = elem.get( 'name' )
    owner = elem.get( 'owner' )
    # The name and owner attributes are always required, so if either are missing, return the error message.
    if not name or not owner:
        error_message = handle_missing_repository_attribute( elem )
        return False, elem, error_message
    revised = False
    toolshed = elem.get( 'toolshed' )
    changeset_revision = elem.get( 'changeset_revision' )
    if unpopulate:
        # We're exporting the repository, so eliminate all toolshed and changeset_revision attributes from the <repository> tag.
        if toolshed or changeset_revision:
            attributes = odict()
            attributes[ 'name' ] = name
            attributes[ 'owner' ] = owner
            attributes[ 'prior_installation_required' ] = elem.get( 'prior_installation_required', 'False' )
            elem = xml_util.create_element( 'repository', attributes=attributes, sub_elements=None )
            revised = True
        return revised, elem, error_message
    # From here on we're populating the toolshed and changeset_revisions if necessary.
    if not toolshed:
        # Default the setting to the current tool shed.
        toolshed = str( url_for( '/', qualified=True ) ).rstrip( '/' )
        elem.attrib[ 'toolshed' ] = toolshed
        revised = True
    if not changeset_revision:
        # Populate the changeset_revision attribute with the latest installable metadata revision for the defined repository.
        # We use the latest installable revision instead of the latest metadata revision to ensure that the contents of the
        # revision are valid.
        repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
        if repository:
            repo_dir = repository.repo_path( trans.app )
            repo = hg.repository( suc.get_configured_ui(), repo_dir )
            lastest_installable_changeset_revision = suc.get_latest_downloadable_changeset_revision( trans, repository, repo )
            if lastest_installable_changeset_revision != suc.INITIAL_CHANGELOG_HASH:
                elem.attrib[ 'changeset_revision' ] = lastest_installable_changeset_revision
                revised = True
            else:
                error_message = 'Invalid latest installable changeset_revision %s ' % str( lastest_installable_changeset_revision )
                error_message += 'retrieved for repository %s owned by %s.  ' % ( str( name ), str( owner ) )
        else:
            error_message = 'Unable to locate repository with name %s and owner %s.  ' % ( str( name ), str( owner ) )
    return revised, elem, error_message
Esempio n. 23
0
    def export( self, trans, payload, **kwd ):
        """
        POST /api/repository_revisions/export
        Creates and saves a gzip compressed tar archive of a repository and optionally all of its repository dependencies.

        The following parameters are included in the payload.
        :param tool_shed_url (required): the base URL of the Tool Shed from which the Repository is to be exported
        :param name (required): the name of the Repository
        :param owner (required): the owner of the Repository
        :param changeset_revision (required): the changeset_revision of the RepositoryMetadata object associated with the Repository
        :param export_repository_dependencies (optional): whether to export repository dependencies - defaults to False
        :param download_dir (optional): the local directory to which to download the archive - defaults to /tmp
        """
        tool_shed_url = payload.get( 'tool_shed_url', '' )
        if not tool_shed_url:
            raise HTTPBadRequest( detail="Missing required parameter 'tool_shed_url'." )
        tool_shed_url = tool_shed_url.rstrip( '/' )
        name = payload.get( 'name', '' )
        if not name:
            raise HTTPBadRequest( detail="Missing required parameter 'name'." )
        owner = payload.get( 'owner', '' )
        if not owner:
            raise HTTPBadRequest( detail="Missing required parameter 'owner'." )
        changeset_revision = payload.get( 'changeset_revision', '' )
        if not changeset_revision:
            raise HTTPBadRequest( detail="Missing required parameter 'changeset_revision'." )
        export_repository_dependencies = payload.get( 'export_repository_dependencies', False )
        # We'll currently support only gzip-compressed tar archives.
        file_type = 'gz'
        export_repository_dependencies = util.asbool( export_repository_dependencies )
        # Get the repository information.
        repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
        if repository is None:
            error_message = 'Cannot locate repository with name %s and owner %s,' % ( str( name ), str( owner ) )
            log.debug( error_message )
            return None, error_message
        repository_id = trans.security.encode_id( repository.id )
        erm = capsule_manager.ExportRepositoryManager( app=trans.app,
                                                       user=trans.user,
                                                       tool_shed_url=tool_shed_url,
                                                       repository=repository,
                                                       changeset_revision=changeset_revision,
                                                       export_repository_dependencies=export_repository_dependencies,
                                                       using_api=True )
        return erm.export_repository()
Esempio n. 24
0
    def add_repository_registry_entry(self, trans, payload, **kwd):
        """
        POST /api/repositories/add_repository_registry_entry
        Adds appropriate entries to the repository registry for the repository defined by the received name and owner.

        :param key: the user's API key
        
        The following parameters are included in the payload.
        :param tool_shed_url (required): the base URL of the Tool Shed containing the Repository
        :param name (required): the name of the Repository
        :param owner (required): the owner of the Repository
        """
        response_dict = {}
        if not trans.user_is_admin():
            response_dict['status'] = 'error'
            response_dict[
                'message'] = "You are not authorized to add entries to this Tool Shed's repository registry."
            return response_dict
        tool_shed_url = payload.get('tool_shed_url', '')
        if not tool_shed_url:
            raise HTTPBadRequest(
                detail="Missing required parameter 'tool_shed_url'.")
        tool_shed_url = tool_shed_url.rstrip('/')
        name = payload.get('name', '')
        if not name:
            raise HTTPBadRequest(detail="Missing required parameter 'name'.")
        owner = payload.get('owner', '')
        if not owner:
            raise HTTPBadRequest(detail="Missing required parameter 'owner'.")
        repository = suc.get_repository_by_name_and_owner(
            trans.app, name, owner)
        if repository is None:
            error_message = 'Cannot locate repository with name %s and owner %s,' % (
                str(name), str(owner))
            log.debug(error_message)
            response_dict['status'] = 'error'
            response_dict['message'] = error_message
            return response_dict
        # Update the repository registry.
        trans.app.repository_registry.add_entry(repository)
        response_dict['status'] = 'ok'
        response_dict[ 'message' ] = 'Entries for repository %s owned by %s have been added to the Tool Shed repository registry.' \
            % ( name, owner )
        return response_dict
Esempio n. 25
0
    def remove_repository_registry_entry(self, trans, payload, **kwd):
        """
        POST /api/repositories/remove_repository_registry_entry
        Removes appropriate entries from the repository registry for the repository defined by the received name and owner.

        :param key: the user's API key
        
        The following parameters are included in the payload.
        :param tool_shed_url (required): the base URL of the Tool Shed containing the Repository
        :param name (required): the name of the Repository
        :param owner (required): the owner of the Repository
        """
        response_dict = {}
        if not trans.user_is_admin():
            response_dict["status"] = "error"
            response_dict[
                "message"
            ] = "You are not authorized to remove entries from this Tool Shed's repository registry."
            return response_dict
        tool_shed_url = payload.get("tool_shed_url", "")
        if not tool_shed_url:
            raise HTTPBadRequest(detail="Missing required parameter 'tool_shed_url'.")
        tool_shed_url = tool_shed_url.rstrip("/")
        name = payload.get("name", "")
        if not name:
            raise HTTPBadRequest(detail="Missing required parameter 'name'.")
        owner = payload.get("owner", "")
        if not owner:
            raise HTTPBadRequest(detail="Missing required parameter 'owner'.")
        repository = suc.get_repository_by_name_and_owner(trans.app, name, owner)
        if repository is None:
            error_message = "Cannot locate repository with name %s and owner %s," % (str(name), str(owner))
            log.debug(error_message)
            response_dict["status"] = "error"
            response_dict["message"] = error_message
            return response_dict
        # Update the repository registry.
        trans.app.repository_registry.remove_entry(repository)
        response_dict["status"] = "ok"
        response_dict["message"] = (
            "Entries for repository %s owned by %s have been removed from the Tool Shed repository registry."
            % (name, owner)
        )
        return response_dict
def validate_repository_name( app, name, user ):
    # Repository names must be unique for each user, must be at least four characters
    # in length and must contain only lower-case letters, numbers, and the '_' character.
    if name in [ 'None', None, '' ]:
        return 'Enter the required repository name.'
    if name in [ 'repos' ]:
        return "The term <b>%s</b> is a reserved word in the tool shed, so it cannot be used as a repository name." % name
    check_existing = suc.get_repository_by_name_and_owner( app, name, user.username )
    if check_existing is not None:
        if check_existing.deleted:
            return 'You have a deleted repository named <b>%s</b>, so choose a different name.' % name
        else:
            return "You already have a repository named <b>%s</b>, so choose a different name." % name
    if len( name ) < 4:
        return "Repository names must be at least 4 characters in length."
    if len( name ) > 80:
        return "Repository names cannot be more than 80 characters in length."
    if not( VALID_REPOSITORYNAME_RE.match( name ) ):
        return "Repository names must contain only lower-case letters, numbers and underscore <b>_</b>."
    return ''
def validate_repository_name( app, name, user ):
    # Repository names must be unique for each user, must be at least four characters
    # in length and must contain only lower-case letters, numbers, and the '_' character.
    if name in [ 'None', None, '' ]:
        return 'Enter the required repository name.'
    if name in [ 'repos' ]:
        return "The term <b>%s</b> is a reserved word in the tool shed, so it cannot be used as a repository name." % name
    check_existing = suc.get_repository_by_name_and_owner( app, name, user.username )
    if check_existing is not None:
        if check_existing.deleted:
            return 'You have a deleted repository named <b>%s</b>, so choose a different name.' % name
        else:
            return "You already have a repository named <b>%s</b>, so choose a different name." % name
    if len( name ) < 4:
        return "Repository names must be at least 4 characters in length."
    if len( name ) > 80:
        return "Repository names cannot be more than 80 characters in length."
    if not( VALID_REPOSITORYNAME_RE.match( name ) ):
        return "Repository names must contain only lower-case letters, numbers and underscore <b>_</b>."
    return ''
Esempio n. 28
0
    def add_repository_registry_entry( self, trans, payload, **kwd ):
        """
        POST /api/repositories/add_repository_registry_entry
        Adds appropriate entries to the repository registry for the repository defined by the received name and owner.

        :param key: the user's API key
        
        The following parameters are included in the payload.
        :param tool_shed_url (required): the base URL of the Tool Shed containing the Repository
        :param name (required): the name of the Repository
        :param owner (required): the owner of the Repository
        """
        response_dict = {}
        if not trans.user_is_admin():
            response_dict[ 'status' ] = 'error'
            response_dict[ 'message' ] = "You are not authorized to add entries to this Tool Shed's repository registry."
            return response_dict
        tool_shed_url = payload.get( 'tool_shed_url', '' )
        if not tool_shed_url:
            raise HTTPBadRequest( detail="Missing required parameter 'tool_shed_url'." )
        tool_shed_url = tool_shed_url.rstrip( '/' )
        name = payload.get( 'name', '' )
        if not name:
            raise HTTPBadRequest( detail="Missing required parameter 'name'." )
        owner = payload.get( 'owner', '' )
        if not owner:
            raise HTTPBadRequest( detail="Missing required parameter 'owner'." )
        repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
        if repository is None:
            error_message = 'Cannot locate repository with name %s and owner %s,' % ( str( name ), str( owner ) )
            log.debug( error_message )
            response_dict[ 'status' ] = 'error'
            response_dict[ 'message' ] = error_message
            return response_dict
        # Update the repository registry.
        trans.app.repository_registry.add_entry( repository )
        response_dict[ 'status' ] = 'ok'
        response_dict[ 'message' ] = 'Entries for repository %s owned by %s have been added to the Tool Shed repository registry.' \
            % ( name, owner )
        return response_dict
Esempio n. 29
0
    def get_ordered_installable_revisions( self, trans, name, owner, **kwd ):
        """
        GET /api/repositories/get_ordered_installable_revisions

        :param name: the name of the Repository
        :param owner: the owner of the Repository

        Returns the ordered list of changeset revision hash strings that are associated with installable revisions.  As in the changelog, the
        list is ordered oldest to newest.
        """
        # Example URL: http://localhost:9009/api/repositories/get_installable_revisions?name=add_column&owner=test
        try:
            # Get the repository information.
            repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
            repo_dir = repository.repo_path( trans.app )
            repo = hg.repository( suc.get_configured_ui(), repo_dir )
            ordered_installable_revisions = suc.get_ordered_metadata_changeset_revisions( repository, repo, downloadable=True )
            return ordered_installable_revisions
        except Exception, e:
            message = "Error in the Tool Shed repositories API in get_ordered_installable_revisions: %s" % str( e )
            log.error( message, exc_info=True )
            trans.response.status = 500
            return message
Esempio n. 30
0
    def handle_request(self, trans, **kwd):
        # The os command that results in this method being called will look something like:
        # hg clone http://[email protected]:9009/repos/test/convert_characters1
        hg_version = mercurial.__version__.version
        cmd = kwd.get('cmd', None)
        hgweb_config = trans.app.hgweb_config_manager.hgweb_config

        def make_web_app():
            hgwebapp = hgwebdir(hgweb_config)
            return hgwebapp

        wsgi_app = wsgiapplication(make_web_app)
        if hg_version >= '2.2.3' and cmd == 'pushkey':
            # When doing an "hg push" from the command line, the following commands, in order, will be retrieved from environ, depending
            # upon the mercurial version being used.  In mercurial version 2.2.3, section 15.2. Command changes includes a new feature:
            # pushkey: add hooks for pushkey/listkeys (see http://mercurial.selenic.com/wiki/WhatsNew#Mercurial_2.2.3_.282012-07-01.29).
            # We require version 2.2.3 since the pushkey hook was added in that version.
            # If mercurial version >= '2.2.3': capabilities -> batch -> branchmap -> unbundle -> listkeys -> pushkey
            path_info = kwd.get('path_info', None)
            if path_info:
                owner, name = path_info.split('/')
                repository = get_repository_by_name_and_owner(
                    trans.app, name, owner)
                if repository:
                    if hg_version >= '2.2.3':
                        # Set metadata using the repository files on disk.
                        error_message, status = set_repository_metadata(
                            trans, repository)
                        if status == 'ok' and error_message:
                            log.debug(
                                "Successfully reset metadata on repository %s, but encountered problem: %s"
                                % (repository.name, error_message))
                        elif status != 'ok' and error_message:
                            log.debug(
                                "Error resetting metadata on repository %s: %s"
                                % (repository.name, error_message))
        return wsgi_app
Esempio n. 31
0
 def get_updated_changeset_revisions_for_repository_dependencies(
         self, key_rd_dicts):
     updated_key_rd_dicts = []
     for key_rd_dict in key_rd_dicts:
         key = key_rd_dict.keys()[0]
         repository_dependency = key_rd_dict[key]
         rd_toolshed, \
         rd_name, \
         rd_owner, \
         rd_changeset_revision, \
         rd_prior_installation_required, \
         rd_only_if_compiling_contained_td = \
             common_util.parse_repository_dependency_tuple( repository_dependency )
         if suc.tool_shed_is_this_tool_shed(rd_toolshed):
             repository = suc.get_repository_by_name_and_owner(
                 self.app, rd_name, rd_owner)
             if repository:
                 repository_id = self.app.security.encode_id(repository.id)
                 repository_metadata = \
                     metadata_util.get_repository_metadata_by_repository_id_changeset_revision( self.app,
                                                                                                repository_id,
                                                                                                rd_changeset_revision )
                 if repository_metadata:
                     # The repository changeset_revision is installable, so no updates are available.
                     new_key_rd_dict = {}
                     new_key_rd_dict[key] = repository_dependency
                     updated_key_rd_dicts.append(key_rd_dict)
                 else:
                     # The repository changeset_revision is no longer installable, so see if there's been an update.
                     repo = hg_util.get_repo_for_repository(
                         self.app,
                         repository=repository,
                         repo_path=None,
                         create=False)
                     changeset_revision = suc.get_next_downloadable_changeset_revision(
                         repository, repo, rd_changeset_revision)
                     repository_metadata = \
                         metadata_util.get_repository_metadata_by_repository_id_changeset_revision( self.app,
                                                                                                    repository_id,
                                                                                                    changeset_revision )
                     if repository_metadata:
                         new_key_rd_dict = {}
                         new_key_rd_dict[ key ] = \
                             [ rd_toolshed, \
                               rd_name, \
                               rd_owner, \
                               repository_metadata.changeset_revision, \
                               rd_prior_installation_required, \
                               rd_only_if_compiling_contained_td ]
                         # We have the updated changset revision.
                         updated_key_rd_dicts.append(new_key_rd_dict)
                     else:
                         repository_components_tuple = container_util.get_components_from_key(
                             key)
                         components_list = suc.extract_components_from_tuple(
                             repository_components_tuple)
                         toolshed, repository_name, repository_owner, repository_changeset_revision = components_list[
                             0:4]
                         # For backward compatibility to the 12/20/12 Galaxy release.
                         if len(components_list) == 4:
                             prior_installation_required = 'False'
                             rd_only_if_compiling_contained_td = 'False'
                         elif len(components_list) == 5:
                             rd_only_if_compiling_contained_td = 'False'
                         message = "The revision %s defined for repository %s owned by %s is invalid, so repository " % \
                             ( str( rd_changeset_revision ), str( rd_name ), str( rd_owner ) )
                         message += "dependencies defined for repository %s will be ignored." % str(
                             repository_name)
                         log.debug(message)
             else:
                 repository_components_tuple = container_util.get_components_from_key(
                     key)
                 components_list = suc.extract_components_from_tuple(
                     repository_components_tuple)
                 toolshed, repository_name, repository_owner, repository_changeset_revision = components_list[
                     0:4]
                 message = "The revision %s defined for repository %s owned by %s is invalid, so repository " % \
                     ( str( rd_changeset_revision ), str( rd_name ), str( rd_owner ) )
                 message += "dependencies defined for repository %s will be ignored." % str(
                     repository_name)
                 log.debug(message)
     return updated_key_rd_dicts
 def get_updated_changeset_revisions_for_repository_dependencies( self, key_rd_dicts ):
     updated_key_rd_dicts = []
     for key_rd_dict in key_rd_dicts:
         key = key_rd_dict.keys()[ 0 ]
         repository_dependency = key_rd_dict[ key ]
         rd_toolshed, rd_name, rd_owner, rd_changeset_revision, \
             rd_prior_installation_required, \
             rd_only_if_compiling_contained_td = \
             common_util.parse_repository_dependency_tuple( repository_dependency )
         if suc.tool_shed_is_this_tool_shed( rd_toolshed ):
             repository = suc.get_repository_by_name_and_owner( self.app, rd_name, rd_owner )
             if repository:
                 repository_id = self.app.security.encode_id( repository.id )
                 repository_metadata = \
                     metadata_util.get_repository_metadata_by_repository_id_changeset_revision( self.app,
                                                                                                repository_id,
                                                                                                rd_changeset_revision )
                 if repository_metadata:
                     # The repository changeset_revision is installable, so no updates are available.
                     new_key_rd_dict = {}
                     new_key_rd_dict[ key ] = repository_dependency
                     updated_key_rd_dicts.append( key_rd_dict )
                 else:
                     # The repository changeset_revision is no longer installable, so see if there's been an update.
                     repo = hg_util.get_repo_for_repository( self.app, repository=repository, repo_path=None, create=False )
                     changeset_revision = suc.get_next_downloadable_changeset_revision( repository, repo, rd_changeset_revision )
                     repository_metadata = \
                         metadata_util.get_repository_metadata_by_repository_id_changeset_revision( self.app,
                                                                                                    repository_id,
                                                                                                    changeset_revision )
                     if repository_metadata:
                         new_key_rd_dict = {}
                         new_key_rd_dict[ key ] = \
                             [ rd_toolshed,
                               rd_name,
                               rd_owner,
                               repository_metadata.changeset_revision,
                               rd_prior_installation_required,
                               rd_only_if_compiling_contained_td ]
                         # We have the updated changeset revision.
                         updated_key_rd_dicts.append( new_key_rd_dict )
                     else:
                         repository_components_tuple = container_util.get_components_from_key( key )
                         components_list = suc.extract_components_from_tuple( repository_components_tuple )
                         toolshed, repository_name, repository_owner, repository_changeset_revision = components_list[ 0:4 ]
                         # For backward compatibility to the 12/20/12 Galaxy release.
                         if len( components_list ) in (4, 5):
                             rd_only_if_compiling_contained_td = 'False'
                         message = "The revision %s defined for repository %s owned by %s is invalid, so repository " % \
                             ( str( rd_changeset_revision ), str( rd_name ), str( rd_owner ) )
                         message += "dependencies defined for repository %s will be ignored." % str( repository_name )
                         log.debug( message )
             else:
                 repository_components_tuple = container_util.get_components_from_key( key )
                 components_list = suc.extract_components_from_tuple( repository_components_tuple )
                 toolshed, repository_name, repository_owner, repository_changeset_revision = components_list[ 0:4 ]
                 message = "The revision %s defined for repository %s owned by %s is invalid, so repository " % \
                     ( str( rd_changeset_revision ), str( rd_name ), str( rd_owner ) )
                 message += "dependencies defined for repository %s will be ignored." % str( repository_name )
                 log.debug( message )
     return updated_key_rd_dicts
 def handle_elem(self, elem):
     """Populate or unpopulate the changeset_revision and toolshed attributes of repository tags."""
     # <repository name="molecule_datatypes" owner="test" changeset_revision="1a070566e9c6" />
     # <repository changeset_revision="xxx" name="package_xorg_macros_1_17_1" owner="test" toolshed="yyy">
     #    <package name="xorg_macros" version="1.17.1" />
     # </repository>
     error_message = ''
     name = elem.get('name')
     owner = elem.get('owner')
     # The name and owner attributes are always required, so if either are missing, return the error message.
     if not name or not owner:
         error_message = self.check_tag_attributes(elem)
         return False, elem, error_message
     altered = False
     toolshed = elem.get('toolshed')
     changeset_revision = elem.get('changeset_revision')
     # Over a short period of time a bug existed which caused the prior_installation_required attribute
     # to be set to False and included in the <repository> tag when a repository was exported along with
     # its dependencies.  The following will eliminate this problematic attribute upon import.
     prior_installation_required = elem.get('prior_installation_required')
     if prior_installation_required is not None and not asbool(
             prior_installation_required):
         del elem.attrib['prior_installation_required']
     sub_elems = [child_elem for child_elem in list(elem)]
     if len(sub_elems) > 0:
         # At this point, a <repository> tag will point only to a package.
         # <package name="xorg_macros" version="1.17.1" />
         # Coerce the list to an odict().
         sub_elements = odict()
         packages = []
         for sub_elem in sub_elems:
             sub_elem_type = sub_elem.tag
             sub_elem_name = sub_elem.get('name')
             sub_elem_version = sub_elem.get('version')
             if sub_elem_type and sub_elem_name and sub_elem_version:
                 packages.append((sub_elem_name, sub_elem_version))
         sub_elements['packages'] = packages
     else:
         # Set to None.
         sub_elements = None
     if self.unpopulate:
         # We're exporting the repository, so eliminate all toolshed and changeset_revision attributes
         # from the <repository> tag.
         if toolshed or changeset_revision:
             attributes = odict()
             attributes['name'] = name
             attributes['owner'] = owner
             prior_installation_required = elem.get(
                 'prior_installation_required')
             if asbool(prior_installation_required):
                 attributes['prior_installation_required'] = 'True'
             new_elem = xml_util.create_element('repository',
                                                attributes=attributes,
                                                sub_elements=sub_elements)
             altered = True
         return altered, new_elem, error_message
     # From here on we're populating the toolshed and changeset_revision attributes if necessary.
     if not toolshed:
         # Default the setting to the current tool shed.
         toolshed = str(url_for('/', qualified=True)).rstrip('/')
         elem.attrib['toolshed'] = toolshed
         altered = True
     if not changeset_revision:
         # Populate the changeset_revision attribute with the latest installable metadata revision for
         # the defined repository.  We use the latest installable revision instead of the latest metadata
         # revision to ensure that the contents of the revision are valid.
         repository = suc.get_repository_by_name_and_owner(
             self.app, name, owner)
         if repository:
             repo = hg_util.get_repo_for_repository(self.app,
                                                    repository=repository,
                                                    repo_path=None,
                                                    create=False)
             lastest_installable_changeset_revision = \
                 suc.get_latest_downloadable_changeset_revision( self.app, repository, repo )
             if lastest_installable_changeset_revision != hg_util.INITIAL_CHANGELOG_HASH:
                 elem.attrib[
                     'changeset_revision'] = lastest_installable_changeset_revision
                 altered = True
             else:
                 error_message = 'Invalid latest installable changeset_revision %s ' % \
                     str( lastest_installable_changeset_revision )
                 error_message += 'retrieved for repository %s owned by %s.  ' % (
                     str(name), str(owner))
         else:
             error_message = 'Unable to locate repository with name %s and owner %s.  ' % (
                 str(name), str(owner))
     return altered, elem, error_message
Esempio n. 34
0
def create_repo_info_dict(app,
                          repository_clone_url,
                          changeset_revision,
                          ctx_rev,
                          repository_owner,
                          repository_name=None,
                          repository=None,
                          repository_metadata=None,
                          tool_dependencies=None,
                          repository_dependencies=None):
    """
    Return a dictionary that includes all of the information needed to install a repository into a local
    Galaxy instance.  The dictionary will also contain the recursive list of repository dependencies defined
    for the repository, as well as the defined tool dependencies.

    This method is called from Galaxy under four scenarios:
    1. During the tool shed repository installation process via the tool shed's get_repository_information()
    method.  In this case both the received repository and repository_metadata will be objects, but
    tool_dependencies and repository_dependencies will be None.
    2. When getting updates for an installed repository where the updates include newly defined repository
    dependency definitions.  This scenario is similar to 1. above. The tool shed's get_repository_information()
    method is the caller, and both the received repository and repository_metadata will be objects, but
    tool_dependencies and repository_dependencies will be None.
    3. When a tool shed repository that was uninstalled from a Galaxy instance is being reinstalled with no
    updates available.  In this case, both repository and repository_metadata will be None, but tool_dependencies
    and repository_dependencies will be objects previously retrieved from the tool shed if the repository includes
    definitions for them.
    4. When a tool shed repository that was uninstalled from a Galaxy instance is being reinstalled with updates
    available.  In this case, this method is reached via the tool shed's get_updated_repository_information()
    method, and both repository and repository_metadata will be objects but tool_dependencies and
    repository_dependencies will be None.
    """
    repo_info_dict = {}
    repository = suc.get_repository_by_name_and_owner(app, repository_name,
                                                      repository_owner)
    if app.name == 'tool_shed':
        # We're in the tool shed.
        repository_metadata = suc.get_repository_metadata_by_changeset_revision(
            app, app.security.encode_id(repository.id), changeset_revision)
        if repository_metadata:
            metadata = repository_metadata.metadata
            if metadata:
                tool_shed_url = str(web.url_for('/',
                                                qualified=True)).rstrip('/')
                rb = relation_builder.RelationBuilder(app, repository,
                                                      repository_metadata,
                                                      tool_shed_url)
                # Get a dictionary of all repositories upon which the contents of the received repository depends.
                repository_dependencies = rb.get_repository_dependencies_for_changeset_revision(
                )
                tool_dependencies = metadata.get('tool_dependencies', {})
    if tool_dependencies:
        new_tool_dependencies = {}
        for dependency_key, requirements_dict in tool_dependencies.items():
            if dependency_key in ['set_environment']:
                new_set_environment_dict_list = []
                for set_environment_dict in requirements_dict:
                    set_environment_dict['repository_name'] = repository_name
                    set_environment_dict['repository_owner'] = repository_owner
                    set_environment_dict[
                        'changeset_revision'] = changeset_revision
                    new_set_environment_dict_list.append(set_environment_dict)
                new_tool_dependencies[
                    dependency_key] = new_set_environment_dict_list
            else:
                requirements_dict['repository_name'] = repository_name
                requirements_dict['repository_owner'] = repository_owner
                requirements_dict['changeset_revision'] = changeset_revision
                new_tool_dependencies[dependency_key] = requirements_dict
        tool_dependencies = new_tool_dependencies
    # Cast unicode to string, with the exception of description, since it is free text and can contain special characters.
    repo_info_dict[str(
        repository.name)] = (repository.description, str(repository_clone_url),
                             str(changeset_revision), str(ctx_rev),
                             str(repository_owner), repository_dependencies,
                             tool_dependencies)
    return repo_info_dict
Esempio n. 35
0
    def get_repository_revision_install_info( self, trans, name, owner, changeset_revision, **kwd ):
        """
        GET /api/repositories/get_repository_revision_install_info

        :param name: the name of the Repository
        :param owner: the owner of the Repository
        :param changeset_revision: the changeset_revision of the RepositoryMetadata object associated with the Repository

        Returns a list of the following dictionaries::
        - a dictionary defining the Repository.  For example:
        {
            "deleted": false,
            "deprecated": false,
            "description": "add_column hello",
            "id": "f9cad7b01a472135",
            "long_description": "add_column hello",
            "name": "add_column",
            "owner": "test",
            "private": false,
            "times_downloaded": 6,
            "url": "/api/repositories/f9cad7b01a472135",
            "user_id": "f9cad7b01a472135"
        }
        - a dictionary defining the Repository revision (RepositoryMetadata).  For example:
        {
            "changeset_revision": "3a08cc21466f",
            "downloadable": true,
            "has_repository_dependencies": false,
            "has_repository_dependencies_only_if_compiling_contained_td": false,
            "id": "f9cad7b01a472135",
            "includes_datatypes": false,
            "includes_tool_dependencies": false,
            "includes_tools": true,
            "includes_tools_for_display_in_tool_panel": true,
            "includes_workflows": false,
            "malicious": false,
            "repository_id": "f9cad7b01a472135",
            "url": "/api/repository_revisions/f9cad7b01a472135"
        }
        - a dictionary including the additional information required to install the repository.  For example:
        {
            "add_column": [
                "add_column hello",
                "http://test@localhost:9009/repos/test/add_column",
                "3a08cc21466f",
                "1",
                "test",
                {},
                {}
            ]
        }
        """
        # Example URL: 
        # http://<xyz>/api/repositories/get_repository_revision_install_info?name=<n>&owner=<o>&changeset_revision=<cr>
        if name and owner and changeset_revision:
            # Get the repository information.
            repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
            if repository is None:
                log.debug( 'Cannot locate repository %s owned by %s' % ( str( name ), str( owner ) ) )
                return {}, {}, {}
            encoded_repository_id = trans.security.encode_id( repository.id )
            repository_dict = repository.to_dict( view='element',
                                                  value_mapper=self.__get_value_mapper( trans ) )
            repository_dict[ 'url' ] = web.url_for( controller='repositories',
                                                    action='show',
                                                    id=encoded_repository_id )
            # Get the repository_metadata information.
            repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans.app,
                                                                                     encoded_repository_id,
                                                                                     changeset_revision )
            if repository_metadata is None:
                # The changeset_revision column in the repository_metadata table has been updated with a new
                # value value, so find the changeset_revision to which we need to update.
                repo = hg_util.get_repo_for_repository( trans.app, repository=repository, repo_path=None, create=False )
                new_changeset_revision = suc.get_next_downloadable_changeset_revision( repository, repo, changeset_revision )
                repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans.app,
                                                                                         encoded_repository_id,
                                                                                         new_changeset_revision )
                changeset_revision = new_changeset_revision
            if repository_metadata is not None:
                encoded_repository_metadata_id = trans.security.encode_id( repository_metadata.id )
                repository_metadata_dict = repository_metadata.to_dict( view='collection',
                                                                        value_mapper=self.__get_value_mapper( trans ) )
                repository_metadata_dict[ 'url' ] = web.url_for( controller='repository_revisions',
                                                                 action='show',
                                                                 id=encoded_repository_metadata_id )
                # Get the repo_info_dict for installing the repository.
                repo_info_dict, \
                includes_tools, \
                includes_tool_dependencies, \
                includes_tools_for_display_in_tool_panel, \
                has_repository_dependencies, \
                has_repository_dependencies_only_if_compiling_contained_td = \
                    repository_util.get_repo_info_dict( trans.app,
                                                        trans.user,
                                                        encoded_repository_id,
                                                        changeset_revision )
                return repository_dict, repository_metadata_dict, repo_info_dict
            else:
                log.debug( "Unable to locate repository_metadata record for repository id %s and changeset_revision %s" % \
                    ( str( repository.id ), str( changeset_revision ) ) )
                return repository_dict, {}, {}
        else:
            debug_msg = "Error in the Tool Shed repositories API in get_repository_revision_install_info: "
            debug_msg += "Invalid name %s or owner %s or changeset_revision %s received." % \
                ( str( name ), str( owner ), str( changeset_revision ) )
            log.debug( debug_msg )
            return {}, {}, {}
Esempio n. 36
0
 def get_repository_revision_install_info( self, trans, name, owner, changeset_revision, **kwd ):
     """
     GET /api/repositories/get_repository_revision_install_info
     
     :param name: the name of the Repository
     :param owner: the owner of the Repository
     :param changset_revision: the changset_revision of the RepositoryMetadata object associated with the Repository
     
     Returns a list of the following dictionaries::
     - a dictionary defining the Repository.  For example:
     {
         "deleted": false, 
         "deprecated": false, 
         "description": "add_column hello", 
         "id": "f9cad7b01a472135", 
         "long_description": "add_column hello", 
         "name": "add_column", 
         "owner": "test", 
         "private": false, 
         "times_downloaded": 6, 
         "url": "/api/repositories/f9cad7b01a472135", 
         "user_id": "f9cad7b01a472135"
     }
     - a dictionary defining the Repository revision (RepositoryMetadata).  For example:
     {
         "changeset_revision": "3a08cc21466f", 
         "downloadable": true, 
         "has_repository_dependencies": false, 
         "id": "f9cad7b01a472135", 
         "includes_datatypes": false, 
         "includes_tool_dependencies": false, 
         "includes_tools": true,
         "includes_tools_for_display_in_tool_panel": true,
         "includes_workflows": false, 
         "malicious": false, 
         "repository_id": "f9cad7b01a472135", 
         "url": "/api/repository_revisions/f9cad7b01a472135"
     }
     - a dictionary including the additional information required to install the repository.  For example:
     {
         "add_column": [
             "add_column hello", 
             "http://test@localhost:9009/repos/test/add_column", 
             "3a08cc21466f", 
             "1", 
             "test", 
             {}, 
             {}
         ]
     }
     """
     # Example URL: http://localhost:9009/api/repositories/get_repository_revision_install_info?name=add_column&owner=test&changeset_revision=3a08cc21466f
     try:
         # Get the repository information.
         repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
         encoded_repository_id = trans.security.encode_id( repository.id )
         repository_dict = repository.get_api_value( view='element', value_mapper=default_repository_value_mapper( trans, repository ) )
         repository_dict[ 'url' ] = web.url_for( controller='repositories',
                                                 action='show',
                                                 id=encoded_repository_id )
         # Get the repository_metadata information.
         repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, encoded_repository_id, changeset_revision )
         if not repository_metadata:
             # The changeset_revision column in the repository_metadata table has been updated with a new value value, so find the
             # changeset_revision to which we need to update.
             repo_dir = repository.repo_path( trans.app )
             repo = hg.repository( suc.get_configured_ui(), repo_dir )
             new_changeset_revision = suc.get_next_downloadable_changeset_revision( repository, repo, changeset_revision )
             repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans, encoded_repository_id, new_changeset_revision )
             changeset_revision = new_changeset_revision
         if repository_metadata:
             encoded_repository_metadata_id = trans.security.encode_id( repository_metadata.id )
             repository_metadata_dict = repository_metadata.get_api_value( view='collection',
                                                                           value_mapper=default_repository_metadata_value_mapper( trans, repository_metadata ) )
             repository_metadata_dict[ 'url' ] = web.url_for( controller='repository_revisions',
                                                              action='show',
                                                              id=encoded_repository_metadata_id )
             # Get the repo_info_dict for installing the repository.
             repo_info_dict, includes_tools, includes_tool_dependencies, includes_tools_for_display_in_tool_panel, has_repository_dependencies = \
                 repository_util.get_repo_info_dict( trans, encoded_repository_id, changeset_revision )
             return repository_dict, repository_metadata_dict, repo_info_dict
         else:
             message = "Unable to locate repository_metadata record for repository id %d and changeset_revision %s" % ( repository.id, changeset_revision )
             log.error( message, exc_info=True )
             trans.response.status = 500
             return repository_dict, {}, {}
     except Exception, e:
         message = "Error in the Tool Shed repositories API in get_repository_revision_install_info: %s" % str( e )
         log.error( message, exc_info=True )
         trans.response.status = 500
         return message
Esempio n. 37
0
def create_repo_info_dict( app, repository_clone_url, changeset_revision, ctx_rev, repository_owner, repository_name=None,
                           repository=None, repository_metadata=None, tool_dependencies=None, repository_dependencies=None ):
    """
    Return a dictionary that includes all of the information needed to install a repository into a local
    Galaxy instance.  The dictionary will also contain the recursive list of repository dependencies defined
    for the repository, as well as the defined tool dependencies.

    This method is called from Galaxy under four scenarios:
    1. During the tool shed repository installation process via the tool shed's get_repository_information()
    method.  In this case both the received repository and repository_metadata will be objects, but
    tool_dependencies and repository_dependencies will be None.
    2. When getting updates for an installed repository where the updates include newly defined repository
    dependency definitions.  This scenario is similar to 1. above. The tool shed's get_repository_information()
    method is the caller, and both the received repository and repository_metadata will be objects, but
    tool_dependencies and repository_dependencies will be None.
    3. When a tool shed repository that was uninstalled from a Galaxy instance is being reinstalled with no
    updates available.  In this case, both repository and repository_metadata will be None, but tool_dependencies
    and repository_dependencies will be objects previously retrieved from the tool shed if the repository includes
    definitions for them.
    4. When a tool shed repository that was uninstalled from a Galaxy instance is being reinstalled with updates
    available.  In this case, this method is reached via the tool shed's get_updated_repository_information()
    method, and both repository and repository_metadata will be objects but tool_dependencies and
    repository_dependencies will be None.
    """
    repo_info_dict = {}
    repository = suc.get_repository_by_name_and_owner( app, repository_name, repository_owner )
    if app.name == 'tool_shed':
        # We're in the tool shed.
        repository_metadata = suc.get_repository_metadata_by_changeset_revision( app,
                                                                                 app.security.encode_id( repository.id ),
                                                                                 changeset_revision )
        if repository_metadata:
            metadata = repository_metadata.metadata
            if metadata:
                tool_shed_url = str( web.url_for( '/', qualified=True ) ).rstrip( '/' )
                rb = relation_builder.RelationBuilder( app, repository, repository_metadata, tool_shed_url )
                # Get a dictionary of all repositories upon which the contents of the received repository depends.
                repository_dependencies = rb.get_repository_dependencies_for_changeset_revision()
                tool_dependencies = metadata.get( 'tool_dependencies', {} )
    if tool_dependencies:
        new_tool_dependencies = {}
        for dependency_key, requirements_dict in tool_dependencies.items():
            if dependency_key in [ 'set_environment' ]:
                new_set_environment_dict_list = []
                for set_environment_dict in requirements_dict:
                    set_environment_dict[ 'repository_name' ] = repository_name
                    set_environment_dict[ 'repository_owner' ] = repository_owner
                    set_environment_dict[ 'changeset_revision' ] = changeset_revision
                    new_set_environment_dict_list.append( set_environment_dict )
                new_tool_dependencies[ dependency_key ] = new_set_environment_dict_list
            else:
                requirements_dict[ 'repository_name' ] = repository_name
                requirements_dict[ 'repository_owner' ] = repository_owner
                requirements_dict[ 'changeset_revision' ] = changeset_revision
                new_tool_dependencies[ dependency_key ] = requirements_dict
        tool_dependencies = new_tool_dependencies
    # Cast unicode to string, with the exception of description, since it is free text and can contain special characters.
    repo_info_dict[ str( repository.name ) ] = ( repository.description,
                                                 str( repository_clone_url ),
                                                 str( changeset_revision ),
                                                 str( ctx_rev ),
                                                 str( repository_owner ),
                                                 repository_dependencies,
                                                 tool_dependencies )
    return repo_info_dict
Esempio n. 38
0
 def get_repository_revision_install_info(self, trans, name, owner,
                                          changeset_revision, **kwd):
     """
     GET /api/repositories/get_repository_revision_install_info
     
     :param name: the name of the Repository
     :param owner: the owner of the Repository
     :param changset_revision: the changset_revision of the RepositoryMetadata object associated with the Repository
     
     Returns a list of the following dictionaries::
     - a dictionary defining the Repository.  For example:
     {
         "deleted": false, 
         "deprecated": false, 
         "description": "add_column hello", 
         "id": "f9cad7b01a472135", 
         "long_description": "add_column hello", 
         "name": "add_column", 
         "owner": "test", 
         "private": false, 
         "times_downloaded": 6, 
         "url": "/api/repositories/f9cad7b01a472135", 
         "user_id": "f9cad7b01a472135"
     }
     - a dictionary defining the Repository revision (RepositoryMetadata).  For example:
     {
         "changeset_revision": "3a08cc21466f", 
         "downloadable": true, 
         "has_repository_dependencies": false, 
         "id": "f9cad7b01a472135", 
         "includes_datatypes": false, 
         "includes_tool_dependencies": false, 
         "includes_tools": true,
         "includes_tools_for_display_in_tool_panel": true,
         "includes_workflows": false, 
         "malicious": false, 
         "repository_id": "f9cad7b01a472135", 
         "url": "/api/repository_revisions/f9cad7b01a472135"
     }
     - a dictionary including the additional information required to install the repository.  For example:
     {
         "add_column": [
             "add_column hello", 
             "http://test@localhost:9009/repos/test/add_column", 
             "3a08cc21466f", 
             "1", 
             "test", 
             {}, 
             {}
         ]
     }
     """
     # Example URL: http://localhost:9009/api/repositories/get_repository_revision_install_info?name=add_column&owner=test&changeset_revision=3a08cc21466f
     try:
         # Get the repository information.
         repository = suc.get_repository_by_name_and_owner(
             trans.app, name, owner)
         encoded_repository_id = trans.security.encode_id(repository.id)
         repository_dict = repository.get_api_value(
             view='element',
             value_mapper=default_repository_value_mapper(
                 trans, repository))
         repository_dict['url'] = web.url_for(controller='repositories',
                                              action='show',
                                              id=encoded_repository_id)
         # Get the repository_metadata information.
         repository_metadata = suc.get_repository_metadata_by_changeset_revision(
             trans, encoded_repository_id, changeset_revision)
         if not repository_metadata:
             # The changeset_revision column in the repository_metadata table has been updated with a new value value, so find the
             # changeset_revision to which we need to update.
             repo_dir = repository.repo_path(trans.app)
             repo = hg.repository(suc.get_configured_ui(), repo_dir)
             new_changeset_revision = suc.get_next_downloadable_changeset_revision(
                 repository, repo, changeset_revision)
             repository_metadata = suc.get_repository_metadata_by_changeset_revision(
                 trans, encoded_repository_id, new_changeset_revision)
             changeset_revision = new_changeset_revision
         if repository_metadata:
             encoded_repository_metadata_id = trans.security.encode_id(
                 repository_metadata.id)
             repository_metadata_dict = repository_metadata.get_api_value(
                 view='collection',
                 value_mapper=default_repository_metadata_value_mapper(
                     trans, repository_metadata))
             repository_metadata_dict['url'] = web.url_for(
                 controller='repository_revisions',
                 action='show',
                 id=encoded_repository_metadata_id)
             # Get the repo_info_dict for installing the repository.
             repo_info_dict, includes_tools, includes_tool_dependencies, includes_tools_for_display_in_tool_panel, has_repository_dependencies = \
                 repository_util.get_repo_info_dict( trans, encoded_repository_id, changeset_revision )
             return repository_dict, repository_metadata_dict, repo_info_dict
         else:
             message = "Unable to locate repository_metadata record for repository id %d and changeset_revision %s" % (
                 repository.id, changeset_revision)
             log.error(message, exc_info=True)
             trans.response.status = 500
             return repository_dict, {}, {}
     except Exception, e:
         message = "Error in the Tool Shed repositories API in get_repository_revision_install_info: %s" % str(
             e)
         log.error(message, exc_info=True)
         trans.response.status = 500
         return message
Esempio n. 39
0
    def get_repository_revision_install_info(self, trans, name, owner,
                                             changeset_revision, **kwd):
        """
        GET /api/repositories/get_repository_revision_install_info

        :param name: the name of the Repository
        :param owner: the owner of the Repository
        :param changeset_revision: the changeset_revision of the RepositoryMetadata object associated with the Repository

        Returns a list of the following dictionaries::
        - a dictionary defining the Repository.  For example:
        {
            "deleted": false,
            "deprecated": false,
            "description": "add_column hello",
            "id": "f9cad7b01a472135",
            "long_description": "add_column hello",
            "name": "add_column",
            "owner": "test",
            "private": false,
            "times_downloaded": 6,
            "url": "/api/repositories/f9cad7b01a472135",
            "user_id": "f9cad7b01a472135"
        }
        - a dictionary defining the Repository revision (RepositoryMetadata).  For example:
        {
            "changeset_revision": "3a08cc21466f",
            "downloadable": true,
            "has_repository_dependencies": false,
            "has_repository_dependencies_only_if_compiling_contained_td": false,
            "id": "f9cad7b01a472135",
            "includes_datatypes": false,
            "includes_tool_dependencies": false,
            "includes_tools": true,
            "includes_tools_for_display_in_tool_panel": true,
            "includes_workflows": false,
            "malicious": false,
            "repository_id": "f9cad7b01a472135",
            "url": "/api/repository_revisions/f9cad7b01a472135"
        }
        - a dictionary including the additional information required to install the repository.  For example:
        {
            "add_column": [
                "add_column hello",
                "http://test@localhost:9009/repos/test/add_column",
                "3a08cc21466f",
                "1",
                "test",
                {},
                {}
            ]
        }
        """
        # Example URL:
        # http://<xyz>/api/repositories/get_repository_revision_install_info?name=<n>&owner=<o>&changeset_revision=<cr>
        if name and owner and changeset_revision:
            # Get the repository information.
            repository = suc.get_repository_by_name_and_owner(
                trans.app, name, owner)
            if repository is None:
                log.debug('Cannot locate repository %s owned by %s' %
                          (str(name), str(owner)))
                return {}, {}, {}
            encoded_repository_id = trans.security.encode_id(repository.id)
            repository_dict = repository.to_dict(
                view='element', value_mapper=self.__get_value_mapper(trans))
            repository_dict['url'] = web.url_for(controller='repositories',
                                                 action='show',
                                                 id=encoded_repository_id)
            # Get the repository_metadata information.
            repository_metadata = suc.get_repository_metadata_by_changeset_revision(
                trans.app, encoded_repository_id, changeset_revision)
            if repository_metadata is None:
                # The changeset_revision column in the repository_metadata table has been updated with a new
                # value value, so find the changeset_revision to which we need to update.
                repo = hg_util.get_repo_for_repository(trans.app,
                                                       repository=repository,
                                                       repo_path=None,
                                                       create=False)
                new_changeset_revision = suc.get_next_downloadable_changeset_revision(
                    repository, repo, changeset_revision)
                repository_metadata = suc.get_repository_metadata_by_changeset_revision(
                    trans.app, encoded_repository_id, new_changeset_revision)
                changeset_revision = new_changeset_revision
            if repository_metadata is not None:
                encoded_repository_metadata_id = trans.security.encode_id(
                    repository_metadata.id)
                repository_metadata_dict = repository_metadata.to_dict(
                    view='collection',
                    value_mapper=self.__get_value_mapper(trans))
                repository_metadata_dict['url'] = web.url_for(
                    controller='repository_revisions',
                    action='show',
                    id=encoded_repository_metadata_id)
                # Get the repo_info_dict for installing the repository.
                repo_info_dict, \
                includes_tools, \
                includes_tool_dependencies, \
                includes_tools_for_display_in_tool_panel, \
                has_repository_dependencies, \
                has_repository_dependencies_only_if_compiling_contained_td = \
                    repository_util.get_repo_info_dict( trans.app,
                                                        trans.user,
                                                        encoded_repository_id,
                                                        changeset_revision )
                return repository_dict, repository_metadata_dict, repo_info_dict
            else:
                log.debug( "Unable to locate repository_metadata record for repository id %s and changeset_revision %s" % \
                    ( str( repository.id ), str( changeset_revision ) ) )
                return repository_dict, {}, {}
        else:
            debug_msg = "Error in the Tool Shed repositories API in get_repository_revision_install_info: "
            debug_msg += "Invalid name %s or owner %s or changeset_revision %s received." % \
                ( str( name ), str( owner ), str( changeset_revision ) )
            log.debug(debug_msg)
            return {}, {}, {}
Esempio n. 40
0
    def repository_dependencies(self, trans, id, **kwd):
        """
        GET /api/repository_revisions/{encoded repository_metadata id}/repository_dependencies

        Returns a list of dictionaries that each define a specific downloadable revision of a
        repository in the Tool Shed.  This method returns dictionaries with more information in
        them than other methods in this controller.  The information about repository_metdata is
        enhanced to include information about the repository (e.g., name, owner, etc) associated
        with the repository_metadata record.

        :param id: the encoded id of the `RepositoryMetadata` object
        """
        # Example URL: http://localhost:9009/api/repository_revisions/repository_dependencies/bb125606ff9ea620
        repository_dependencies_dicts = []
        repository_metadata = metadata_util.get_repository_metadata_by_id(
            trans.app, id)
        if repository_metadata is None:
            log.debug('Invalid repository_metadata id received: %s' % str(id))
            return repository_dependencies_dicts
        metadata = repository_metadata.metadata
        if metadata is None:
            log.debug(
                'The repository_metadata record with id %s has no metadata.' %
                str(id))
            return repository_dependencies_dicts
        if 'repository_dependencies' in metadata:
            rd_tups = metadata['repository_dependencies'][
                'repository_dependencies']
            for rd_tup in rd_tups:
                tool_shed, name, owner, changeset_revision = rd_tup[0:4]
                repository_dependency = suc.get_repository_by_name_and_owner(
                    trans.app, name, owner)
                if repository_dependency is None:
                    log.dbug(
                        'Cannot locate repository dependency %s owned by %s.' %
                        (name, owner))
                    continue
                repository_dependency_id = trans.security.encode_id(
                    repository_dependency.id)
                repository_dependency_repository_metadata = \
                    suc.get_repository_metadata_by_changeset_revision( trans.app, repository_dependency_id, changeset_revision )
                if repository_dependency_repository_metadata is None:
                    # The changeset_revision column in the repository_metadata table has been updated with a new
                    # value value, so find the changeset_revision to which we need to update.
                    repo = hg_util.get_repo_for_repository(
                        trans.app,
                        repository=repository_dependency,
                        repo_path=None,
                        create=False)
                    new_changeset_revision = suc.get_next_downloadable_changeset_revision(
                        repository_dependency, repo, changeset_revision)
                    repository_dependency_repository_metadata = \
                        suc.get_repository_metadata_by_changeset_revision( trans.app,
                                                                           repository_dependency_id,
                                                                           new_changeset_revision )
                    if repository_dependency_repository_metadata is None:
                        decoded_repository_dependency_id = trans.security.decode_id(
                            repository_dependency_id)
                        debug_msg = 'Cannot locate repository_metadata with id %d for repository dependency %s owned by %s ' % \
                            ( decoded_repository_dependency_id, str( name ), str( owner ) )
                        debug_msg += 'using either of these changeset_revisions: %s, %s.' % \
                            ( str( changeset_revision ), str( new_changeset_revision ) )
                        log.debug(debug_msg)
                        continue
                    else:
                        changeset_revision = new_changeset_revision
                repository_dependency_metadata_dict = \
                    repository_dependency_repository_metadata.to_dict( view='element',
                                                                       value_mapper=self.__get_value_mapper( trans ) )
                repository_dependency_dict = repository_dependency.to_dict(
                    view='element',
                    value_mapper=self.__get_value_mapper(trans))
                # We need to be careful with the entries in our repository_dependency_dict here since this Tool Shed API
                # controller is working with repository_metadata records.  The above to_dict() method returns a dictionary
                # with an id entry for the repository record.  However, all of the other methods in this controller have
                # the id entry associated with a repository_metadata record id.  To avoid confusion, we'll update the
                # repository_dependency_metadata_dict with entries from the repository_dependency_dict without using the
                # Python dictionary update() method because we do not want to overwrite existing entries.
                for k, v in repository_dependency_dict.items():
                    if k not in repository_dependency_metadata_dict:
                        repository_dependency_metadata_dict[k] = v
                repository_dependency_metadata_dict['url'] = web.url_for(
                    controller='repositories',
                    action='show',
                    id=repository_dependency_id)
                repository_dependencies_dicts.append(
                    repository_dependency_metadata_dict)
        return repository_dependencies_dicts
 def handle_elem( self, elem ):
     """Populate or unpopulate the changeset_revision and toolshed attributes of repository tags."""
     # <repository name="molecule_datatypes" owner="test" changeset_revision="1a070566e9c6" />
     # <repository changeset_revision="xxx" name="package_xorg_macros_1_17_1" owner="test" toolshed="yyy">
     #    <package name="xorg_macros" version="1.17.1" />
     # </repository>
     error_message = ''
     name = elem.get( 'name' )
     owner = elem.get( 'owner' )
     # The name and owner attributes are always required, so if either are missing, return the error message.
     if not name or not owner:
         error_message = self.check_tag_attributes( elem )
         return False, elem, error_message
     altered = False
     toolshed = elem.get( 'toolshed' )
     changeset_revision = elem.get( 'changeset_revision' )
     # Over a short period of time a bug existed which caused the prior_installation_required attribute
     # to be set to False and included in the <repository> tag when a repository was exported along with
     # its dependencies.  The following will eliminate this problematic attribute upon import.
     prior_installation_required = elem.get( 'prior_installation_required' )
     if prior_installation_required is not None and not asbool( prior_installation_required ):
         del elem.attrib[ 'prior_installation_required' ]
     sub_elems = [ child_elem for child_elem in list( elem ) ]
     if len( sub_elems ) > 0:
         # At this point, a <repository> tag will point only to a package.
         # <package name="xorg_macros" version="1.17.1" />
         # Coerce the list to an odict().
         sub_elements = odict()
         packages = []
         for sub_elem in sub_elems:
             sub_elem_type = sub_elem.tag
             sub_elem_name = sub_elem.get( 'name' )
             sub_elem_version = sub_elem.get( 'version' )
             if sub_elem_type and sub_elem_name and sub_elem_version:
                 packages.append( ( sub_elem_name, sub_elem_version ) )
         sub_elements[ 'packages' ] = packages
     else:
         # Set to None.
         sub_elements = None
     if self.unpopulate:
         # We're exporting the repository, so eliminate all toolshed and changeset_revision attributes
         # from the <repository> tag.
         if toolshed or changeset_revision:
             attributes = odict()
             attributes[ 'name' ] = name
             attributes[ 'owner' ] = owner
             prior_installation_required = elem.get( 'prior_installation_required' )
             if asbool( prior_installation_required ):
                 attributes[ 'prior_installation_required' ] = 'True'
             new_elem = xml_util.create_element( 'repository', attributes=attributes, sub_elements=sub_elements )
             altered = True
         return altered, new_elem, error_message
     # From here on we're populating the toolshed and changeset_revision attributes if necessary.
     if not toolshed:
         # Default the setting to the current tool shed.
         toolshed = str( url_for( '/', qualified=True ) ).rstrip( '/' )
         elem.attrib[ 'toolshed' ] = toolshed
         altered = True
     if not changeset_revision:
         # Populate the changeset_revision attribute with the latest installable metadata revision for
         # the defined repository.  We use the latest installable revision instead of the latest metadata
         # revision to ensure that the contents of the revision are valid.
         repository = suc.get_repository_by_name_and_owner( self.app, name, owner )
         if repository:
             repo = hg_util.get_repo_for_repository( self.app,
                                                     repository=repository,
                                                     repo_path=None,
                                                     create=False )
             lastest_installable_changeset_revision = \
                 suc.get_latest_downloadable_changeset_revision( self.app, repository, repo )
             if lastest_installable_changeset_revision != hg_util.INITIAL_CHANGELOG_HASH:
                 elem.attrib[ 'changeset_revision' ] = lastest_installable_changeset_revision
                 altered = True
             else:
                 error_message = 'Invalid latest installable changeset_revision %s ' % \
                     str( lastest_installable_changeset_revision )
                 error_message += 'retrieved for repository %s owned by %s.  ' % ( str( name ), str( owner ) )
         else:
             error_message = 'Unable to locate repository with name %s and owner %s.  ' % ( str( name ), str( owner ) )
     return altered, elem, error_message
    def repository_dependencies( self, trans, id, **kwd ):
        """
        GET /api/repository_revisions/{encoded repository_metadata id}/repository_dependencies

        Returns a list of dictionaries that each define a specific downloadable revision of a
        repository in the Tool Shed.  This method returns dictionaries with more information in
        them than other methods in this controller.  The information about repository_metdata is
        enhanced to include information about the repository (e.g., name, owner, etc) associated
        with the repository_metadata record.

        :param id: the encoded id of the `RepositoryMetadata` object
        """
        # Example URL: http://localhost:9009/api/repository_revisions/repository_dependencies/bb125606ff9ea620
        repository_dependencies_dicts = []
        repository_metadata = metadata_util.get_repository_metadata_by_id( trans, id )
        if repository_metadata is None:
            log.debug( 'Invalid repository_metadata id received: %s' % str( id ) )
            return repository_dependencies_dicts
        metadata = repository_metadata.metadata
        if metadata is None:
            log.debug( 'The repository_metadata record with id %s has no metadata.' % str ( id ) )
            return repository_dependencies_dicts
        if 'repository_dependencies' in metadata:
            rd_tups = metadata[ 'repository_dependencies' ][ 'repository_dependencies' ]
            for rd_tup in rd_tups:
                tool_shed, name, owner, changeset_revision = rd_tup[ 0:4 ]
                repository_dependency = suc.get_repository_by_name_and_owner( trans.app, name, owner )
                if repository_dependency is None:
                    log.dbug( 'Cannot locate repository dependency %s owned by %s.' % ( name, owner ) )
                    continue
                repository_dependency_id = trans.security.encode_id( repository_dependency.id )
                repository_dependency_repository_metadata = \
                    suc.get_repository_metadata_by_changeset_revision( trans, repository_dependency_id, changeset_revision )
                if repository_dependency_repository_metadata is None:
                    # The changeset_revision column in the repository_metadata table has been updated with a new
                    # value value, so find the changeset_revision to which we need to update.
                    repo_dir = repository_dependency.repo_path( trans.app )
                    repo = hg.repository( suc.get_configured_ui(), repo_dir )
                    new_changeset_revision = suc.get_next_downloadable_changeset_revision( repository_dependency,
                                                                                           repo,
                                                                                           changeset_revision )
                    repository_dependency_repository_metadata = \
                        suc.get_repository_metadata_by_changeset_revision( trans,
                                                                           repository_dependency_id,
                                                                           new_changeset_revision )
                    if repository_dependency_repository_metadata is None:
                        decoded_repository_dependency_id = trans.security.decode_id( repository_dependency_id )
                        debug_msg = 'Cannot locate repository_metadata with id %d for repository dependency %s owned by %s ' % \
                            ( decoded_repository_dependency_id, str( name ), str( owner ) )
                        debug_msg += 'using either of these changeset_revisions: %s, %s.' % \
                            ( str( changeset_revision ), str( new_changeset_revision ) )
                        log.debug( debug_msg )
                        continue
                    else:
                        changeset_revision = new_changeset_revision
                repository_dependency_repository_metadata_id = trans.security.encode_id( repository_dependency_repository_metadata.id )
                repository_dependency_metadata_dict = \
                    repository_dependency_repository_metadata.to_dict( view='element',
                                                                       value_mapper=self.__get_value_mapper( trans ) )
                repository_dependency_dict = repository_dependency.to_dict( view='element',
                                                                            value_mapper=self.__get_value_mapper( trans ) )
                # We need to be careful with the entries in our repository_dependency_dict here since this Tool Shed API
                # controller is working with repository_metadata records.  The above to_dict() method returns a dictionary
                # with an id entry for the repository record.  However, all of the other methods in this controller have
                # the id entry associated with a repository_metadata record id.  To avoid confusion, we'll update the
                # repository_dependency_metadata_dict with entries from the repository_dependency_dict without using the
                # Python dictionary update() method because we do not want to overwrite existing entries.
                for k, v in repository_dependency_dict.items():
                    if k not in repository_dependency_metadata_dict:
                        repository_dependency_metadata_dict[ k ] = v
                repository_dependency_metadata_dict[ 'url' ] = web.url_for( controller='repositories',
                                                                            action='show',
                                                                            id=repository_dependency_id )
                repository_dependencies_dicts.append( repository_dependency_metadata_dict )
        return repository_dependencies_dicts