def update( self, trans, payload, **kwd ):
     """
     PUT /api/repository_revisions/{encoded_repository_metadata_id}/{payload}
     Updates the value of specified columns of the repository_metadata table based on the key / value pairs in payload.
     """
     repository_metadata_id = kwd.get( 'id', None )
     try:
         repository_metadata = metadata_util.get_repository_metadata_by_id( trans, repository_metadata_id )
         flush_needed = False
         for key, new_value in payload.items():
             if hasattr( repository_metadata, key ):
                 old_value = getattr( repository_metadata, key )
                 setattr( repository_metadata, key, new_value )
                 if key in [ 'tools_functionally_correct', 'time_last_tested' ]:
                     # Automatically update repository_metadata.time_last_tested.
                     repository_metadata.time_last_tested = datetime.datetime.utcnow()
                 flush_needed = True
         if flush_needed:
             trans.sa_session.add( repository_metadata )
             trans.sa_session.flush()
     except Exception, e:
         message = "Error in the Tool Shed repository_revisions API in update: %s" % str( e )
         log.error( message, exc_info=True )
         trans.response.status = 500
         return message
Exemple #2
0
 def update(self, trans, payload, **kwd):
     """
     PUT /api/repository_revisions/{encoded_repository_metadata_id}/{payload}
     Updates the value of specified columns of the repository_metadata table based on the key / value pairs in payload.
     """
     repository_metadata_id = kwd.get('id', None)
     try:
         repository_metadata = metadata_util.get_repository_metadata_by_id(
             trans, repository_metadata_id)
         flush_needed = False
         for key, new_value in payload.items():
             if hasattr(repository_metadata, key):
                 old_value = getattr(repository_metadata, key)
                 setattr(repository_metadata, key, new_value)
                 if key in [
                         'tools_functionally_correct', 'time_last_tested'
                 ]:
                     # Automatically update repository_metadata.time_last_tested.
                     repository_metadata.time_last_tested = datetime.datetime.utcnow(
                     )
                 flush_needed = True
         if flush_needed:
             trans.sa_session.add(repository_metadata)
             trans.sa_session.flush()
     except Exception, e:
         message = "Error in the Tool Shed repository_revisions API in update: %s" % str(
             e)
         log.error(message, exc_info=True)
         trans.response.status = 500
         return message
Exemple #3
0
 def delete_repository_metadata(self, trans, **kwd):
     message = escape(kwd.get("message", ""))
     status = kwd.get("status", "done")
     id = kwd.get("id", None)
     if id:
         ids = util.listify(id)
         count = 0
         for repository_metadata_id in ids:
             repository_metadata = metadata_util.get_repository_metadata_by_id(trans.app, repository_metadata_id)
             trans.sa_session.delete(repository_metadata)
             trans.sa_session.flush()
             count += 1
         if count:
             message = "Deleted %d repository metadata %s" % (count, inflector.cond_plural(len(ids), "record"))
     else:
         message = "No repository metadata ids received for deleting."
         status = "error"
     trans.response.send_redirect(
         web.url_for(
             controller="admin",
             action="browse_repository_metadata",
             message=util.sanitize_text(message),
             status=status,
         )
     )
Exemple #4
0
def generate_workflow_image(trans, workflow_name, repository_metadata_id=None, repository_id=None):
    """
    Return an svg image representation of a workflow dictionary created when the workflow was exported.  This method is called
    from both Galaxy and the tool shed.  When called from the tool shed, repository_metadata_id will have a value and repository_id
    will be None.  When called from Galaxy, repository_metadata_id will be None and repository_id will have a value.
    """
    workflow_name = encoding_util.tool_shed_decode(workflow_name)
    if trans.webapp.name == 'tool_shed':
        # We're in the tool shed.
        repository_metadata = metadata_util.get_repository_metadata_by_id(trans.app, repository_metadata_id)
        repository_id = trans.security.encode_id(repository_metadata.repository_id)
        changeset_revision = repository_metadata.changeset_revision
        metadata = repository_metadata.metadata
    else:
        # We're in Galaxy.
        repository = repository_util.get_tool_shed_repository_by_id(trans.app, repository_id)
        changeset_revision = repository.changeset_revision
        metadata = repository.metadata
    # metadata[ 'workflows' ] is a list of tuples where each contained tuple is
    # [ <relative path to the .ga file in the repository>, <exported workflow dict> ]
    for workflow_tup in metadata['workflows']:
        workflow_dict = workflow_tup[1]
        if workflow_dict['name'] == workflow_name:
            break
    if 'tools' in metadata:
        tools_metadata = metadata['tools']
    else:
        tools_metadata = []
    workflow, missing_tool_tups = get_workflow_from_dict(trans=trans,
                                                         workflow_dict=workflow_dict,
                                                         tools_metadata=tools_metadata,
                                                         repository_id=repository_id,
                                                         changeset_revision=changeset_revision)
    workflow_canvas = WorkflowCanvas()
    canvas = workflow_canvas.canvas
    # Store px width for boxes of each step.
    for step in workflow.steps:
        step.upgrade_messages = {}
        module = module_factory.from_workflow_step(trans, repository_id, changeset_revision, tools_metadata, step)
        tool_errors = module.type == 'tool' and not module.tool
        module_data_inputs = get_workflow_data_inputs(step, module)
        module_data_outputs = get_workflow_data_outputs(step, module, workflow.steps)
        module_name = get_workflow_module_name(module, missing_tool_tups)
        workflow_canvas.populate_data_for_step(
            step,
            module_name,
            module_data_inputs,
            module_data_outputs,
            tool_errors=tool_errors
        )
    workflow_canvas.add_steps(highlight_errors=True)
    workflow_canvas.finish()
    trans.response.set_content_type("image/svg+xml")
    return canvas.tostring()
    def update(self, trans, payload, **kwd):
        """
        PUT /api/repository_revisions/{encoded_repository_metadata_id}/{payload}
        Updates the value of specified columns of the repository_metadata table based on the key / value pairs in payload.

        :param id: the encoded id of the `RepositoryMetadata` object
        """
        repository_metadata_id = kwd.get('id', None)
        if repository_metadata_id is None:
            raise HTTPBadRequest(detail="Missing required parameter 'id'.")
        repository_metadata = metadata_util.get_repository_metadata_by_id(
            trans.app, repository_metadata_id)
        if repository_metadata is None:
            decoded_repository_metadata_id = trans.security.decode_id(
                repository_metadata_id)
            log.debug('Cannot locate repository_metadata with id %s' %
                      str(decoded_repository_metadata_id))
            return {}
        else:
            decoded_repository_metadata_id = repository_metadata.id
        flush_needed = False
        for key, new_value in payload.items():
            if key == 'time_last_tested':
                repository_metadata.time_last_tested = datetime.datetime.utcnow(
                )
                flush_needed = True
            elif hasattr(repository_metadata, key):
                # log information when setting attributes associated with the Tool Shed's install and test framework.
                if key in [
                        'do_not_test', 'includes_tools',
                        'missing_test_components', 'test_install_error',
                        'tools_functionally_correct'
                ]:
                    log.debug(
                        'Setting repository_metadata column %s to value %s for changeset_revision %s via the Tool Shed API.'
                        % (str(key), str(new_value),
                           str(repository_metadata.changeset_revision)))
                setattr(repository_metadata, key, new_value)
                flush_needed = True
        if flush_needed:
            log.debug(
                'Updating repository_metadata record with id %s and changeset_revision %s.'
                % (str(decoded_repository_metadata_id),
                   str(repository_metadata.changeset_revision)))
            trans.sa_session.add(repository_metadata)
            trans.sa_session.flush()
            trans.sa_session.refresh(repository_metadata)
        repository_metadata_dict = repository_metadata.to_dict(
            view='element', value_mapper=self.__get_value_mapper(trans))
        repository_metadata_dict['url'] = web.url_for(
            controller='repository_revisions',
            action='show',
            id=repository_metadata_id)
        return repository_metadata_dict
def generate_workflow_image( trans, workflow_name, repository_metadata_id=None, repository_id=None ):
    """
    Return an svg image representation of a workflow dictionary created when the workflow was exported.  This method is called
    from both Galaxy and the tool shed.  When called from the tool shed, repository_metadata_id will have a value and repository_id
    will be None.  When called from Galaxy, repository_metadata_id will be None and repository_id will have a value.
    """
    workflow_name = encoding_util.tool_shed_decode( workflow_name )
    if trans.webapp.name == 'tool_shed':
        # We're in the tool shed.
        repository_metadata = metadata_util.get_repository_metadata_by_id( trans.app, repository_metadata_id )
        repository_id = trans.security.encode_id( repository_metadata.repository_id )
        changeset_revision = repository_metadata.changeset_revision
        metadata = repository_metadata.metadata
    else:
        # We're in Galaxy.
        repository = suc.get_tool_shed_repository_by_id( trans.app, repository_id )
        changeset_revision = repository.changeset_revision
        metadata = repository.metadata
    # metadata[ 'workflows' ] is a list of tuples where each contained tuple is
    # [ <relative path to the .ga file in the repository>, <exported workflow dict> ]
    for workflow_tup in metadata[ 'workflows' ]:
        workflow_dict = workflow_tup[1]
        if workflow_dict[ 'name' ] == workflow_name:
            break
    if 'tools' in metadata:
        tools_metadata = metadata[ 'tools' ]
    else:
        tools_metadata = []
    workflow, missing_tool_tups = get_workflow_from_dict( trans=trans,
                                                          workflow_dict=workflow_dict,
                                                          tools_metadata=tools_metadata,
                                                          repository_id=repository_id,
                                                          changeset_revision=changeset_revision )
    workflow_canvas = WorkflowCanvas()
    canvas = workflow_canvas.canvas
    # Store px width for boxes of each step.
    for step in workflow.steps:
        step.upgrade_messages = {}
        module = module_factory.from_workflow_step( trans, repository_id, changeset_revision, tools_metadata, step )
        tool_errors = module.type == 'tool' and not module.tool
        module_data_inputs = get_workflow_data_inputs( step, module )
        module_data_outputs = get_workflow_data_outputs( step, module, workflow.steps )
        module_name = get_workflow_module_name( module, missing_tool_tups )
        workflow_canvas.populate_data_for_step(
            step,
            module_name,
            module_data_inputs,
            module_data_outputs,
            tool_errors=tool_errors
        )
    workflow_canvas.add_steps( highlight_errors=True )
    workflow_canvas.finish( )
    trans.response.set_content_type( "image/svg+xml" )
    return canvas.tostring()
Exemple #7
0
 def browse_repository_metadata( self, trans, **kwd ):
     if 'operation' in kwd:
         operation = kwd[ 'operation' ].lower()
         if operation == "delete":
             return self.delete_repository_metadata( trans, **kwd )
         if operation == "view_or_manage_repository_revision":
             # The received id is a RepositoryMetadata object id, so we need to get the
             # associated Repository and redirect to view_or_manage_repository with the
             # changeset_revision.
             repository_metadata = metadata_util.get_repository_metadata_by_id( trans, kwd[ 'id' ] )
             repository = repository_metadata.repository
             kwd[ 'id' ] = trans.security.encode_id( repository.id )
             kwd[ 'changeset_revision' ] = repository_metadata.changeset_revision
             kwd[ 'operation' ] = 'view_or_manage_repository'
             return trans.response.send_redirect( web.url_for( controller='repository',
                                                               action='browse_repositories',
                                                               **kwd ) )
     return self.repository_metadata_grid( trans, **kwd )
 def browse_repository_metadata( self, trans, **kwd ):
     if 'operation' in kwd:
         operation = kwd[ 'operation' ].lower()
         if operation == "delete":
             return self.delete_repository_metadata( trans, **kwd )
         if operation == "view_or_manage_repository_revision":
             # The received id is a RepositoryMetadata object id, so we need to get the
             # associated Repository and redirect to view_or_manage_repository with the
             # changeset_revision.
             repository_metadata = metadata_util.get_repository_metadata_by_id( trans.app, kwd[ 'id' ] )
             repository = repository_metadata.repository
             kwd[ 'id' ] = trans.security.encode_id( repository.id )
             kwd[ 'changeset_revision' ] = repository_metadata.changeset_revision
             kwd[ 'operation' ] = 'view_or_manage_repository'
             return trans.response.send_redirect( web.url_for( controller='repository',
                                                               action='browse_repositories',
                                                               **kwd ) )
     return self.repository_metadata_grid( trans, **kwd )
    def show(self, trans, id, **kwd):
        """
        GET /api/repository_revisions/{encoded_repository_metadata_id}
        Displays information about a repository_metadata record in the Tool Shed.

        :param id: the encoded id of the `RepositoryMetadata` object
        """
        # Example URL: http://localhost:9009/api/repository_revisions/bb125606ff9ea620
        repository_metadata = metadata_util.get_repository_metadata_by_id(trans.app, id)
        if repository_metadata is None:
            log.debug('Cannot locate repository_metadata with id %s' % str(id))
            return {}
        encoded_repository_id = trans.security.encode_id(repository_metadata.repository_id)
        repository_metadata_dict = repository_metadata.to_dict(view='element',
                                                               value_mapper=self.__get_value_mapper(trans))
        repository_metadata_dict['url'] = web.url_for(controller='repositories',
                                                      action='show',
                                                      id=encoded_repository_id)
        return repository_metadata_dict
    def show(self, trans, id, **kwd):
        """
        GET /api/repository_revisions/{encoded_repository_metadata_id}
        Displays information about a repository_metadata record in the Tool Shed.

        :param id: the encoded id of the `RepositoryMetadata` object
        """
        # Example URL: http://localhost:9009/api/repository_revisions/bb125606ff9ea620
        repository_metadata = metadata_util.get_repository_metadata_by_id(trans.app, id)
        if repository_metadata is None:
            log.debug('Cannot locate repository_metadata with id %s' % str(id))
            return {}
        encoded_repository_id = trans.security.encode_id(repository_metadata.repository_id)
        repository_metadata_dict = repository_metadata.to_dict(view='element',
                                                               value_mapper=self.__get_value_mapper(trans))
        repository_metadata_dict['url'] = web.url_for(controller='repositories',
                                                      action='show',
                                                      id=encoded_repository_id)
        return repository_metadata_dict
    def update( self, trans, payload, **kwd ):
        """
        PUT /api/repository_revisions/{encoded_repository_metadata_id}/{payload}
        Updates the value of specified columns of the repository_metadata table based on the key / value pairs in payload.

        :param id: the encoded id of the `RepositoryMetadata` object
        """
        repository_metadata_id = kwd.get( 'id', None )
        if repository_metadata_id is None:
            raise HTTPBadRequest( detail="Missing required parameter 'id'." )
        repository_metadata = metadata_util.get_repository_metadata_by_id( trans.app, repository_metadata_id )
        if repository_metadata is None:
            decoded_repository_metadata_id = trans.security.decode_id( repository_metadata_id )
            log.debug( 'Cannot locate repository_metadata with id %s' % str( decoded_repository_metadata_id ) )
            return {}
        else:
            decoded_repository_metadata_id = repository_metadata.id
        flush_needed = False
        for key, new_value in payload.items():
            if key == 'time_last_tested':
                repository_metadata.time_last_tested = datetime.datetime.utcnow()
                flush_needed = True
            elif hasattr( repository_metadata, key ):
                # log information when setting attributes associated with the Tool Shed's install and test framework.
                if key in [ 'do_not_test', 'includes_tools', 'missing_test_components', 'test_install_error',
                            'tools_functionally_correct' ]:
                    log.debug( 'Setting repository_metadata column %s to value %s for changeset_revision %s via the Tool Shed API.' %
                               ( str( key ), str( new_value ), str( repository_metadata.changeset_revision ) ) )
                setattr( repository_metadata, key, new_value )
                flush_needed = True
        if flush_needed:
            log.debug( 'Updating repository_metadata record with id %s and changeset_revision %s.' %
                       ( str( decoded_repository_metadata_id ), str( repository_metadata.changeset_revision ) ) )
            trans.sa_session.add( repository_metadata )
            trans.sa_session.flush()
            trans.sa_session.refresh( repository_metadata )
        repository_metadata_dict = repository_metadata.to_dict( view='element',
                                                                value_mapper=self.__get_value_mapper( trans ) )
        repository_metadata_dict[ 'url' ] = web.url_for( controller='repository_revisions',
                                                         action='show',
                                                         id=repository_metadata_id )
        return repository_metadata_dict
 def show( self, trans, id, **kwd ):
     """
     GET /api/repository_revisions/{encoded_repository_metadata_id}
     Displays information about a repository_metadata record in the Tool Shed.
     
     :param id: the encoded id of the `RepositoryMetadata` object
     """
     # Example URL: http://localhost:9009/api/repository_revisions/bb125606ff9ea620
     try:
         repository_metadata = metadata_util.get_repository_metadata_by_id( trans, id )
         repository_metadata_dict = repository_metadata.as_dict( value_mapper=default_value_mapper( trans, repository_metadata ) )
         repository_metadata_dict[ 'url' ] = web.url_for( controller='repository_revisions',
                                                          action='show',
                                                          id=trans.security.encode_id( repository_metadata.id ) )
         return repository_metadata_dict
     except Exception, e:
         message = "Error in the Tool Shed repository_revisions API in show: %s" % str( e )
         log.error( message, exc_info=True )
         trans.response.status = 500
         return message
Exemple #13
0
 def delete_repository_metadata( self, trans, **kwd ):
     message = kwd.get( 'message', ''  )
     status = kwd.get( 'status', 'done' )
     id = kwd.get( 'id', None )
     if id:
         ids = util.listify( id )
         count = 0
         for repository_metadata_id in ids:
             repository_metadata = metadata_util.get_repository_metadata_by_id( trans, repository_metadata_id )
             trans.sa_session.delete( repository_metadata )
             trans.sa_session.flush()
             count += 1
         if count:
             message = "Deleted %d repository metadata %s" % ( count, inflector.cond_plural( len( ids ), "record" ) )
     else:
         message = "No repository metadata ids received for deleting."
         status = 'error'
     trans.response.send_redirect( web.url_for( controller='admin',
                                                action='browse_repository_metadata',
                                                message=util.sanitize_text( message ),
                                                status=status ) )
 def delete_repository_metadata( self, trans, **kwd ):
     message = kwd.get( 'message', ''  )
     status = kwd.get( 'status', 'done' )
     id = kwd.get( 'id', None )
     if id:
         ids = util.listify( id )
         count = 0
         for repository_metadata_id in ids:
             repository_metadata = metadata_util.get_repository_metadata_by_id( trans.app, repository_metadata_id )
             trans.sa_session.delete( repository_metadata )
             trans.sa_session.flush()
             count += 1
         if count:
             message = "Deleted %d repository metadata %s" % ( count, inflector.cond_plural( len( ids ), "record" ) )
     else:
         message = "No repository metadata ids received for deleting."
         status = 'error'
     trans.response.send_redirect( web.url_for( controller='admin',
                                                action='browse_repository_metadata',
                                                message=util.sanitize_text( message ),
                                                status=status ) )
Exemple #15
0
 def show(self, trans, id, **kwd):
     """
     GET /api/repository_revisions/{encoded_repository_metadata_id}
     Displays information about a repository_metadata record in the Tool Shed.
     
     :param id: the encoded id of the `RepositoryMetadata` object
     """
     # Example URL: http://localhost:9009/api/repository_revisions/bb125606ff9ea620
     try:
         repository_metadata = metadata_util.get_repository_metadata_by_id(
             trans, id)
         repository_metadata_dict = repository_metadata.as_dict(
             value_mapper=default_value_mapper(trans, repository_metadata))
         repository_metadata_dict['url'] = web.url_for(
             controller='repository_revisions',
             action='show',
             id=trans.security.encode_id(repository_metadata.id))
         return repository_metadata_dict
     except Exception, e:
         message = "Error in the Tool Shed repository_revisions API in show: %s" % str(
             e)
         log.error(message, exc_info=True)
         trans.response.status = 500
         return message
Exemple #16
0
def generate_workflow_image(trans, workflow_name, repository_metadata_id=None, repository_id=None):
    """
    Return an svg image representation of a workflow dictionary created when the workflow was exported.  This method is called
    from both Galaxy and the tool shed.  When called from the tool shed, repository_metadata_id will have a value and repository_id
    will be None.  When called from Galaxy, repository_metadata_id will be None and repository_id will have a value.
    """
    workflow_name = encoding_util.tool_shed_decode(workflow_name)
    if trans.webapp.name == "tool_shed":
        # We're in the tool shed.
        repository_metadata = metadata_util.get_repository_metadata_by_id(trans, repository_metadata_id)
        repository_id = trans.security.encode_id(repository_metadata.repository_id)
        changeset_revision = repository_metadata.changeset_revision
        metadata = repository_metadata.metadata
    else:
        # We're in Galaxy.
        repository = suc.get_tool_shed_repository_by_id(trans, repository_id)
        changeset_revision = repository.changeset_revision
        metadata = repository.metadata
    # metadata[ 'workflows' ] is a list of tuples where each contained tuple is
    # [ <relative path to the .ga file in the repository>, <exported workflow dict> ]
    for workflow_tup in metadata["workflows"]:
        workflow_dict = workflow_tup[1]
        if workflow_dict["name"] == workflow_name:
            break
    if "tools" in metadata:
        tools_metadata = metadata["tools"]
    else:
        tools_metadata = []
    workflow, missing_tool_tups = get_workflow_from_dict(
        trans=trans,
        workflow_dict=workflow_dict,
        tools_metadata=tools_metadata,
        repository_id=repository_id,
        changeset_revision=changeset_revision,
    )
    data = []
    canvas = svgfig.canvas(style="stroke:black; fill:none; stroke-width:1px; stroke-linejoin:round; text-anchor:left")
    text = svgfig.SVG("g")
    connectors = svgfig.SVG("g")
    boxes = svgfig.SVG("g")
    svgfig.Text.defaults["font-size"] = "10px"
    in_pos = {}
    out_pos = {}
    margin = 5
    # Spacing between input/outputs.
    line_px = 16
    # Store px width for boxes of each step.
    widths = {}
    max_width, max_x, max_y = 0, 0, 0
    for step in workflow.steps:
        step.upgrade_messages = {}
        module = module_factory.from_workflow_step(trans, repository_id, changeset_revision, tools_metadata, step)
        tool_errors = module.type == "tool" and not module.tool
        module_data_inputs = get_workflow_data_inputs(step, module)
        module_data_outputs = get_workflow_data_outputs(step, module, workflow.steps)
        step_dict = {
            "id": step.order_index,
            "data_inputs": module_data_inputs,
            "data_outputs": module_data_outputs,
            "position": step.position,
            "tool_errors": tool_errors,
        }
        input_conn_dict = {}
        for conn in step.input_connections:
            input_conn_dict[conn.input_name] = dict(id=conn.output_step.order_index, output_name=conn.output_name)
        step_dict["input_connections"] = input_conn_dict
        data.append(step_dict)
        x, y = step.position["left"], step.position["top"]
        count = 0
        module_name = get_workflow_module_name(module, missing_tool_tups)
        max_len = len(module_name) * 1.5
        text.append(svgfig.Text(x, y + 20, module_name, **{"font-size": "14px"}).SVG())
        y += 45
        for di in module_data_inputs:
            cur_y = y + count * line_px
            if step.order_index not in in_pos:
                in_pos[step.order_index] = {}
            in_pos[step.order_index][di["name"]] = (x, cur_y)
            text.append(svgfig.Text(x, cur_y, di["label"]).SVG())
            count += 1
            max_len = max(max_len, len(di["label"]))
        if len(module.get_data_inputs()) > 0:
            y += 15
        for do in module_data_outputs:
            cur_y = y + count * line_px
            if step.order_index not in out_pos:
                out_pos[step.order_index] = {}
            out_pos[step.order_index][do["name"]] = (x, cur_y)
            text.append(svgfig.Text(x, cur_y, do["name"]).SVG())
            count += 1
            max_len = max(max_len, len(do["name"]))
        widths[step.order_index] = max_len * 5.5
        max_x = max(max_x, step.position["left"])
        max_y = max(max_y, step.position["top"])
        max_width = max(max_width, widths[step.order_index])
    for step_dict in data:
        tool_unavailable = step_dict["tool_errors"]
        width = widths[step_dict["id"]]
        x, y = step_dict["position"]["left"], step_dict["position"]["top"]
        # Only highlight missing tools if displaying in the tool shed.
        if trans.webapp.name == "tool_shed" and tool_unavailable:
            fill = "#EBBCB2"
        else:
            fill = "#EBD9B2"
        boxes.append(svgfig.Rect(x - margin, y, x + width - margin, y + 30, fill=fill).SVG())
        box_height = (len(step_dict["data_inputs"]) + len(step_dict["data_outputs"])) * line_px + margin
        # Draw separator line.
        if len(step_dict["data_inputs"]) > 0:
            box_height += 15
            sep_y = y + len(step_dict["data_inputs"]) * line_px + 40
            text.append(svgfig.Line(x - margin, sep_y, x + width - margin, sep_y).SVG())
        # Define an input/output box.
        boxes.append(svgfig.Rect(x - margin, y + 30, x + width - margin, y + 30 + box_height, fill="#ffffff").SVG())
        for conn, output_dict in step_dict["input_connections"].iteritems():
            in_coords = in_pos[step_dict["id"]][conn]
            # out_pos_index will be a step number like 1, 2, 3...
            out_pos_index = output_dict["id"]
            # out_pos_name will be a string like 'o', 'o2', etc.
            out_pos_name = output_dict["output_name"]
            if out_pos_index in out_pos:
                # out_conn_index_dict will be something like:
                # 7: {'o': (824.5, 618)}
                out_conn_index_dict = out_pos[out_pos_index]
                if out_pos_name in out_conn_index_dict:
                    out_conn_pos = out_pos[out_pos_index][out_pos_name]
                else:
                    # Take any key / value pair available in out_conn_index_dict.
                    # A problem will result if the dictionary is empty.
                    if out_conn_index_dict.keys():
                        key = out_conn_index_dict.keys()[0]
                        out_conn_pos = out_pos[out_pos_index][key]
            adjusted = (out_conn_pos[0] + widths[output_dict["id"]], out_conn_pos[1])
            text.append(
                svgfig.SVG(
                    "circle",
                    cx=out_conn_pos[0] + widths[output_dict["id"]] - margin,
                    cy=out_conn_pos[1] - margin,
                    r=5,
                    fill="#ffffff",
                )
            )
            connectors.append(
                svgfig.Line(adjusted[0], adjusted[1] - margin, in_coords[0] - 10, in_coords[1], arrow_end="true").SVG()
            )
    canvas.append(connectors)
    canvas.append(boxes)
    canvas.append(text)
    width, height = (max_x + max_width + 50), max_y + 300
    canvas["width"] = "%s px" % width
    canvas["height"] = "%s px" % height
    canvas["viewBox"] = "0 0 %s %s" % (width, height)
    trans.response.set_content_type("image/svg+xml")
    return canvas.standalone_xml()
    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 = repository_util.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 = \
                    metadata_util.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.
                    new_changeset_revision = metadata_util.get_next_downloadable_changeset_revision(
                        trans.app, repository_dependency, changeset_revision)
                    if new_changeset_revision != changeset_revision:
                        repository_dependency_repository_metadata = \
                            metadata_util.get_repository_metadata_by_changeset_revision(trans.app,
                                                                                        repository_dependency_id,
                                                                                        new_changeset_revision)
                        changeset_revision = new_changeset_revision
                    else:
                        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
                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
Exemple #18
0
def generate_workflow_image(trans,
                            workflow_name,
                            repository_metadata_id=None,
                            repository_id=None):
    """
    Return an svg image representation of a workflow dictionary created when the workflow was exported.  This method is called
    from both Galaxy and the tool shed.  When called from the tool shed, repository_metadata_id will have a value and repository_id
    will be None.  When called from Galaxy, repository_metadata_id will be None and repository_id will have a value.
    """
    workflow_name = encoding_util.tool_shed_decode(workflow_name)
    if trans.webapp.name == 'tool_shed':
        # We're in the tool shed.
        repository_metadata = metadata_util.get_repository_metadata_by_id(
            trans, repository_metadata_id)
        repository_id = trans.security.encode_id(
            repository_metadata.repository_id)
        changeset_revision = repository_metadata.changeset_revision
        metadata = repository_metadata.metadata
    else:
        # We're in Galaxy.
        repository = suc.get_tool_shed_repository_by_id(trans, repository_id)
        changeset_revision = repository.changeset_revision
        metadata = repository.metadata
    # metadata[ 'workflows' ] is a list of tuples where each contained tuple is
    # [ <relative path to the .ga file in the repository>, <exported workflow dict> ]
    for workflow_tup in metadata['workflows']:
        workflow_dict = workflow_tup[1]
        if workflow_dict['name'] == workflow_name:
            break
    if 'tools' in metadata:
        tools_metadata = metadata['tools']
    else:
        tools_metadata = []
    workflow, missing_tool_tups = get_workflow_from_dict(
        trans=trans,
        workflow_dict=workflow_dict,
        tools_metadata=tools_metadata,
        repository_id=repository_id,
        changeset_revision=changeset_revision)
    data = []
    canvas = svgfig.canvas(
        style=
        "stroke:black; fill:none; stroke-width:1px; stroke-linejoin:round; text-anchor:left"
    )
    text = svgfig.SVG("g")
    connectors = svgfig.SVG("g")
    boxes = svgfig.SVG("g")
    svgfig.Text.defaults["font-size"] = "10px"
    in_pos = {}
    out_pos = {}
    margin = 5
    # Spacing between input/outputs.
    line_px = 16
    # Store px width for boxes of each step.
    widths = {}
    max_width, max_x, max_y = 0, 0, 0
    for step in workflow.steps:
        step.upgrade_messages = {}
        module = module_factory.from_workflow_step(trans, repository_id,
                                                   changeset_revision,
                                                   tools_metadata, step)
        tool_errors = module.type == 'tool' and not module.tool
        module_data_inputs = get_workflow_data_inputs(step, module)
        module_data_outputs = get_workflow_data_outputs(
            step, module, workflow.steps)
        step_dict = {
            'id': step.order_index,
            'data_inputs': module_data_inputs,
            'data_outputs': module_data_outputs,
            'position': step.position,
            'tool_errors': tool_errors
        }
        input_conn_dict = {}
        for conn in step.input_connections:
            input_conn_dict[conn.input_name] = dict(
                id=conn.output_step.order_index, output_name=conn.output_name)
        step_dict['input_connections'] = input_conn_dict
        data.append(step_dict)
        x, y = step.position['left'], step.position['top']
        count = 0
        module_name = get_workflow_module_name(module, missing_tool_tups)
        max_len = len(module_name) * 1.5
        text.append(
            svgfig.Text(x, y + 20, module_name, **{
                "font-size": "14px"
            }).SVG())
        y += 45
        for di in module_data_inputs:
            cur_y = y + count * line_px
            if step.order_index not in in_pos:
                in_pos[step.order_index] = {}
            in_pos[step.order_index][di['name']] = (x, cur_y)
            text.append(svgfig.Text(x, cur_y, di['label']).SVG())
            count += 1
            max_len = max(max_len, len(di['label']))
        if len(module.get_data_inputs()) > 0:
            y += 15
        for do in module_data_outputs:
            cur_y = y + count * line_px
            if step.order_index not in out_pos:
                out_pos[step.order_index] = {}
            out_pos[step.order_index][do['name']] = (x, cur_y)
            text.append(svgfig.Text(x, cur_y, do['name']).SVG())
            count += 1
            max_len = max(max_len, len(do['name']))
        widths[step.order_index] = max_len * 5.5
        max_x = max(max_x, step.position['left'])
        max_y = max(max_y, step.position['top'])
        max_width = max(max_width, widths[step.order_index])
    for step_dict in data:
        tool_unavailable = step_dict['tool_errors']
        width = widths[step_dict['id']]
        x, y = step_dict['position']['left'], step_dict['position']['top']
        # Only highlight missing tools if displaying in the tool shed.
        if trans.webapp.name == 'tool_shed' and tool_unavailable:
            fill = "#EBBCB2"
        else:
            fill = "#EBD9B2"
        boxes.append(
            svgfig.Rect(x - margin, y, x + width - margin, y + 30,
                        fill=fill).SVG())
        box_height = (len(step_dict['data_inputs']) +
                      len(step_dict['data_outputs'])) * line_px + margin
        # Draw separator line.
        if len(step_dict['data_inputs']) > 0:
            box_height += 15
            sep_y = y + len(step_dict['data_inputs']) * line_px + 40
            text.append(
                svgfig.Line(x - margin, sep_y, x + width - margin,
                            sep_y).SVG())
        # Define an input/output box.
        boxes.append(
            svgfig.Rect(x - margin,
                        y + 30,
                        x + width - margin,
                        y + 30 + box_height,
                        fill="#ffffff").SVG())
        for conn, output_dict in step_dict['input_connections'].iteritems():
            in_coords = in_pos[step_dict['id']][conn]
            # out_pos_index will be a step number like 1, 2, 3...
            out_pos_index = output_dict['id']
            # out_pos_name will be a string like 'o', 'o2', etc.
            out_pos_name = output_dict['output_name']
            if out_pos_index in out_pos:
                # out_conn_index_dict will be something like:
                # 7: {'o': (824.5, 618)}
                out_conn_index_dict = out_pos[out_pos_index]
                if out_pos_name in out_conn_index_dict:
                    out_conn_pos = out_pos[out_pos_index][out_pos_name]
                else:
                    # Take any key / value pair available in out_conn_index_dict.
                    # A problem will result if the dictionary is empty.
                    if out_conn_index_dict.keys():
                        key = out_conn_index_dict.keys()[0]
                        out_conn_pos = out_pos[out_pos_index][key]
            adjusted = (out_conn_pos[0] + widths[output_dict['id']],
                        out_conn_pos[1])
            text.append(
                svgfig.SVG("circle",
                           cx=out_conn_pos[0] + widths[output_dict['id']] -
                           margin,
                           cy=out_conn_pos[1] - margin,
                           r=5,
                           fill="#ffffff"))
            connectors.append(
                svgfig.Line(adjusted[0],
                            adjusted[1] - margin,
                            in_coords[0] - 10,
                            in_coords[1],
                            arrow_end="true").SVG())
    canvas.append(connectors)
    canvas.append(boxes)
    canvas.append(text)
    width, height = (max_x + max_width + 50), max_y + 300
    canvas['width'] = "%s px" % width
    canvas['height'] = "%s px" % height
    canvas['viewBox'] = "0 0 %s %s" % (width, height)
    trans.response.set_content_type("image/svg+xml")
    return canvas.standalone_xml()
    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 = repository_util.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 = \
                    metadata_util.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 = metadata_util.get_next_downloadable_changeset_revision(repository_dependency,
                                                                                                    repo,
                                                                                                    changeset_revision)
                    if new_changeset_revision != changeset_revision:
                        repository_dependency_repository_metadata = \
                            metadata_util.get_repository_metadata_by_changeset_revision(trans.app,
                                                                                        repository_dependency_id,
                                                                                        new_changeset_revision)
                        changeset_revision = new_changeset_revision
                    else:
                        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
                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