mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Enhancements to Tool client-server interactions: (a) use DictifiableMixin to dictify toolbox, tools, and tool inputs + outputs; (b) integrate code from visual analytics module with tool/parameter code base and remove VA module; (c) harmonize class names for tool panel on server and client side; (d) update client-side tool panel code and trackster code to work with server-side enhancements. Pack scripts.
This commit is contained in:
@@ -1508,7 +1508,7 @@ class DatasetInstance( object ):
|
||||
|
||||
return msg
|
||||
|
||||
class HistoryDatasetAssociation( DatasetInstance, UsesAnnotations ):
|
||||
class HistoryDatasetAssociation( DatasetInstance, DictifiableMixin, UsesAnnotations ):
|
||||
"""
|
||||
Resource class that creates a relation between a dataset and a user history.
|
||||
"""
|
||||
|
||||
@@ -193,7 +193,7 @@ class DictifiableMixin:
|
||||
try:
|
||||
visible_keys = self.__getattribute__( 'dict_' + view + '_visible_keys' )
|
||||
except AttributeError:
|
||||
raise Exception( 'Unknown API view: %s' % view )
|
||||
raise Exception( 'Unknown DictifiableMixin view: %s' % view )
|
||||
for key in visible_keys:
|
||||
try:
|
||||
item = self.__getattribute__( key )
|
||||
|
||||
@@ -59,6 +59,7 @@ from galaxy.util.odict import odict
|
||||
from galaxy.util.template import fill_template
|
||||
from galaxy.web import url_for
|
||||
from galaxy.web.form_builder import SelectField
|
||||
from galaxy.model.item_attrs import DictifiableMixin
|
||||
from tool_shed.util import shed_util_common
|
||||
from .loader import load_tool, template_macro_params
|
||||
|
||||
@@ -92,7 +93,7 @@ class StdioErrorLevel( object ):
|
||||
class ToolNotFoundException( Exception ):
|
||||
pass
|
||||
|
||||
class ToolBox( object ):
|
||||
class ToolBox( object, DictifiableMixin ):
|
||||
"""Container for a collection of tools"""
|
||||
|
||||
def __init__( self, config_filenames, tool_root_dir, app ):
|
||||
@@ -701,7 +702,7 @@ class ToolBox( object ):
|
||||
"""
|
||||
return self.app.model.context
|
||||
|
||||
def to_dict( self, trans, in_panel=True, **kwds ):
|
||||
def dictify( self, trans, in_panel=True, **kwds ):
|
||||
"""
|
||||
Dictify toolbox.
|
||||
"""
|
||||
@@ -722,11 +723,11 @@ class ToolBox( object ):
|
||||
# Produce panel.
|
||||
rval = []
|
||||
for elt in panel_elts:
|
||||
rval.append( elt.to_dict( trans, for_link=True ) )
|
||||
rval.append( elt.dictify( trans, link_details=True ) )
|
||||
else:
|
||||
tools = []
|
||||
for id, tool in self.tools_by_id.items():
|
||||
tools.append( tool.to_dict( trans, for_link=True ) )
|
||||
tools.append( tool.dictify( trans, link_details=True ) )
|
||||
rval = tools
|
||||
|
||||
return rval
|
||||
@@ -787,11 +788,14 @@ def _filter_for_panel( item, filters, context ):
|
||||
|
||||
|
||||
|
||||
class ToolSection( object ):
|
||||
class ToolSection( object, DictifiableMixin ):
|
||||
"""
|
||||
A group of tools with similar type/purpose that will be displayed as a
|
||||
group in the user interface.
|
||||
"""
|
||||
|
||||
dict_collection_visible_keys = ( 'id', 'name', 'version' )
|
||||
|
||||
def __init__( self, elem=None ):
|
||||
f = lambda elem, val: elem is not None and elem.get( val ) or ''
|
||||
self.name = f( elem, 'name' )
|
||||
@@ -807,27 +811,33 @@ class ToolSection( object ):
|
||||
copy.elems = self.elems.copy()
|
||||
return copy
|
||||
|
||||
def to_dict( self, trans, for_link=False ):
|
||||
def dictify( self, trans, link_details=False ):
|
||||
""" Return a dict that includes section's attributes. """
|
||||
|
||||
section_dict = super( ToolSection, self ).dictify()
|
||||
section_elts = []
|
||||
for key, val in self.elems.items():
|
||||
section_elts.append( val.to_dict( trans, for_link=for_link ) )
|
||||
return { 'type': 'section', 'id': self.id, 'name': self.name, 'version': self.version, 'elems': section_elts }
|
||||
if isinstance( val, ToolSectionLabel ):
|
||||
section_elts.append( val.dictify() )
|
||||
else:
|
||||
section_elts.append( val.dictify( trans, link_details=link_details ) )
|
||||
section_dict[ 'elems' ] = section_elts
|
||||
|
||||
class ToolSectionLabel( object ):
|
||||
return section_dict
|
||||
|
||||
class ToolSectionLabel( object, DictifiableMixin ):
|
||||
"""
|
||||
A label for a set of tools that can be displayed above groups of tools
|
||||
and sections in the user interface
|
||||
"""
|
||||
|
||||
dict_collection_visible_keys = ( 'id', 'text', 'version' )
|
||||
|
||||
def __init__( self, elem ):
|
||||
self.text = elem.get( "text" )
|
||||
self.id = elem.get( "id" )
|
||||
self.version = elem.get( "version" ) or ''
|
||||
|
||||
def to_dict( self, trans, **kwargs ):
|
||||
""" Return a dict that includes label's attributes. """
|
||||
return { 'type': 'label', 'id': self.id, 'name': self.text, 'version': self.version }
|
||||
|
||||
class DefaultToolState( object ):
|
||||
"""
|
||||
Keeps track of the state of a users interaction with a tool between
|
||||
@@ -874,7 +884,7 @@ class DefaultToolState( object ):
|
||||
self.rerun_remap_job_id = None
|
||||
self.inputs = params_from_strings( tool.inputs, values, app, ignore_errors=True )
|
||||
|
||||
class ToolOutput( object ):
|
||||
class ToolOutput( object, DictifiableMixin ):
|
||||
"""
|
||||
Represents an output datasets produced by a tool. For backward
|
||||
compatibility this behaves as if it were the tuple::
|
||||
@@ -882,6 +892,8 @@ class ToolOutput( object ):
|
||||
(format, metadata_source, parent)
|
||||
"""
|
||||
|
||||
dict_collection_visible_keys = ( 'name', 'format', 'label', 'hidden' )
|
||||
|
||||
def __init__( self, name, format=None, format_source=None, metadata_source=None,
|
||||
parent=None, label=None, filters = None, actions = None, hidden=False ):
|
||||
self.name = name
|
||||
@@ -912,14 +924,6 @@ class ToolOutput( object ):
|
||||
def __iter__( self ):
|
||||
return iter( ( self.format, self.metadata_source, self.parent ) )
|
||||
|
||||
def to_dict( self ):
|
||||
return {
|
||||
'name': self.name,
|
||||
'format': self.format,
|
||||
'label': self.label,
|
||||
'hidden': self.hidden
|
||||
}
|
||||
|
||||
class ToolRequirement( object ):
|
||||
"""
|
||||
Represents an external requirement that must be available for the tool to run (for example, a program, package, or library).
|
||||
@@ -930,13 +934,14 @@ class ToolRequirement( object ):
|
||||
self.type = type
|
||||
self.version = version
|
||||
|
||||
class Tool( object ):
|
||||
class Tool( object, DictifiableMixin ):
|
||||
"""
|
||||
Represents a computational tool that can be executed through Galaxy.
|
||||
"""
|
||||
|
||||
tool_type = 'default'
|
||||
default_tool_action = DefaultToolAction
|
||||
dict_collection_visible_keys = ( 'id', 'name', 'version', 'description' )
|
||||
|
||||
def __init__( self, config_file, root, app, guid=None, repository_id=None ):
|
||||
"""Load a tool from the config named by `config_file`"""
|
||||
@@ -1225,7 +1230,6 @@ class Tool( object ):
|
||||
# Trackster configuration.
|
||||
trackster_conf = root.find( "trackster_conf" )
|
||||
if trackster_conf is not None:
|
||||
from galaxy.visualization.genome.visual_analytics import TracksterConfig
|
||||
self.trackster_conf = TracksterConfig.parse( trackster_conf )
|
||||
else:
|
||||
self.trackster_conf = None
|
||||
@@ -2944,66 +2948,29 @@ class Tool( object ):
|
||||
self.sa_session.flush()
|
||||
return primary_datasets
|
||||
|
||||
def to_dict( self, trans, for_link=False, for_display=False ):
|
||||
def dictify( self, trans, link_details=False, io_details=False ):
|
||||
""" Returns dict of tool. """
|
||||
|
||||
# Basic information
|
||||
tool_dict = { 'id': self.id, 'name': self.name,
|
||||
'version': self.version, 'description': self.description }
|
||||
|
||||
if for_link:
|
||||
# Create tool link.
|
||||
tool_dict = super( Tool, self ).dictify()
|
||||
|
||||
# Add link details.
|
||||
if link_details:
|
||||
# Add details for creating a hyperlink to the tool.
|
||||
if not self.tool_type.startswith( 'data_source' ):
|
||||
link = url_for( '/tool_runner', tool_id=self.id )
|
||||
else:
|
||||
link = url_for( self.action, **self.get_static_param_values( trans ) )
|
||||
|
||||
# Basic information
|
||||
tool_dict.update( { 'type': 'tool', 'link': link,
|
||||
tool_dict.update( { 'link': link,
|
||||
'min_width': self.uihints.get( 'minwidth', -1 ),
|
||||
'target': self.target } )
|
||||
|
||||
if for_display:
|
||||
# Dictify inputs.
|
||||
inputs = []
|
||||
for name, input in self.inputs.items():
|
||||
param_dict = { 'name' : name, 'label' : input.label }
|
||||
if isinstance( input, DataToolParameter ):
|
||||
param_dict.update( { 'type' : 'data', 'html' : urllib.quote( input.get_html( trans ) ) } )
|
||||
elif isinstance( input, SelectToolParameter ):
|
||||
# Get options, value.
|
||||
options = input.get_options( trans, [] )
|
||||
value = options[0][1]
|
||||
for option in options:
|
||||
if option[2]:
|
||||
# Found selected option.
|
||||
value = option[1]
|
||||
|
||||
# Pack input.
|
||||
param_dict.update( { 'type' : 'select',
|
||||
'html' : urllib.quote( input.get_html( trans ) ),
|
||||
'options': options,
|
||||
'value': value
|
||||
} )
|
||||
elif isinstance( input, Conditional ):
|
||||
# TODO.
|
||||
pass
|
||||
elif isinstance( input, ( IntegerToolParameter, FloatToolParameter ) ):
|
||||
param_dict.update( { 'type' : 'number', 'init_value' : input.value,
|
||||
'html' : urllib.quote( input.get_html( trans ) ),
|
||||
'min': input.min,
|
||||
'max': input.max,
|
||||
'value': input.value
|
||||
} )
|
||||
else:
|
||||
param_dict.update( { 'type' : '??', 'init_value' : input.value, \
|
||||
'html' : urllib.quote( input.get_html( trans ) ) } )
|
||||
inputs.append( param_dict )
|
||||
|
||||
tool_dict[ 'inputs' ] = inputs
|
||||
|
||||
# Dictify outputs.
|
||||
pass
|
||||
# Add input and output details.
|
||||
if io_details:
|
||||
tool_dict[ 'inputs' ] = [ input.dictify( trans ) for input in self.inputs.values() ]
|
||||
tool_dict[ 'outputs' ] = [ output.dictify() for output in self.outputs.values() ]
|
||||
|
||||
return tool_dict
|
||||
|
||||
@@ -3240,6 +3207,31 @@ for tool_class in [ Tool, DataDestinationTool, SetMetadataTool, DataSourceTool,
|
||||
|
||||
# ---- Utility classes to be factored out -----------------------------------
|
||||
|
||||
class TracksterConfig:
|
||||
""" Trackster configuration encapsulation. """
|
||||
|
||||
def __init__( self, actions ):
|
||||
self.actions = actions
|
||||
|
||||
@staticmethod
|
||||
def parse( root ):
|
||||
actions = []
|
||||
for action_elt in root.findall( "action" ):
|
||||
actions.append( SetParamAction.parse( action_elt ) )
|
||||
return TracksterConfig( actions )
|
||||
|
||||
class SetParamAction:
|
||||
""" Set parameter action. """
|
||||
|
||||
def __init__( self, name, output_name ):
|
||||
self.name = name
|
||||
self.output_name = output_name
|
||||
|
||||
@staticmethod
|
||||
def parse( elt ):
|
||||
""" Parse action from element. """
|
||||
return SetParamAction( elt.get( "name" ), elt.get( "output_name" ) )
|
||||
|
||||
class BadValue( object ):
|
||||
def __init__( self, value ):
|
||||
self.value = value
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Basic tool parameters.
|
||||
"""
|
||||
|
||||
import logging, string, sys, os, os.path
|
||||
import logging, string, sys, os, os.path, urllib
|
||||
from elementtree.ElementTree import XML, Element
|
||||
from galaxy import config, datatypes, util
|
||||
from galaxy.web import form_builder
|
||||
@@ -12,16 +12,19 @@ from sanitize import ToolParameterSanitizer
|
||||
import validation, dynamic_options
|
||||
# For BaseURLToolParameter
|
||||
from galaxy.web import url_for
|
||||
from galaxy.model.item_attrs import DictifiableMixin
|
||||
import galaxy.model
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class ToolParameter( object ):
|
||||
class ToolParameter( object, DictifiableMixin ):
|
||||
"""
|
||||
Describes a parameter accepted by a tool. This is just a simple stub at the
|
||||
moment but in the future should encapsulate more complex parameters (lists
|
||||
of valid choices, validation logic, ...)
|
||||
"""
|
||||
dict_collection_visible_keys = ( 'name', 'type', 'label', 'help' )
|
||||
|
||||
def __init__( self, tool, param, context=None ):
|
||||
self.tool = tool
|
||||
self.refresh_on_change = False
|
||||
@@ -167,6 +170,15 @@ class ToolParameter( object ):
|
||||
for validator in self.validators:
|
||||
validator.validate( value, history )
|
||||
|
||||
def dictify( self, trans, view='collection', value_mapper=None ):
|
||||
""" Dictify tool parameter. This can be overridden by subclasses. """
|
||||
|
||||
tool_dict = super( ToolParameter, self ).dictify()
|
||||
tool_dict[ 'html' ] = urllib.quote( self.get_html( trans ) )
|
||||
if hasattr( self, 'value' ):
|
||||
tool_dict[ 'value' ] = self.value
|
||||
return tool_dict
|
||||
|
||||
@classmethod
|
||||
def build( cls, tool, param ):
|
||||
"""Factory method to create parameter of correct type"""
|
||||
@@ -223,6 +235,9 @@ class IntegerToolParameter( TextToolParameter ):
|
||||
...
|
||||
ValueError: An integer is required
|
||||
"""
|
||||
|
||||
dict_colletion_visible_keys = ToolParameter.dict_collection_visible_keys + ( 'min', 'max' )
|
||||
|
||||
def __init__( self, tool, elem ):
|
||||
TextToolParameter.__init__( self, tool, elem )
|
||||
if self.value:
|
||||
@@ -276,7 +291,7 @@ class IntegerToolParameter( TextToolParameter ):
|
||||
return int( self.value )
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
class FloatToolParameter( TextToolParameter ):
|
||||
"""
|
||||
Parameter that takes a real number value.
|
||||
@@ -293,6 +308,9 @@ class FloatToolParameter( TextToolParameter ):
|
||||
...
|
||||
ValueError: A real number is required
|
||||
"""
|
||||
|
||||
dict_collection_visible_keys = ToolParameter.dict_collection_visible_keys + ( 'min', 'max' )
|
||||
|
||||
def __init__( self, tool, elem ):
|
||||
TextToolParameter.__init__( self, tool, elem )
|
||||
self.min = elem.get( 'min' )
|
||||
@@ -854,6 +872,24 @@ class SelectToolParameter( ToolParameter ):
|
||||
else:
|
||||
return []
|
||||
|
||||
def dictify( self, trans, view='collection', value_mapper=None ):
|
||||
d = super( SelectToolParameter, self ).dictify( trans )
|
||||
|
||||
# Get options, value.
|
||||
options = self.get_options( trans, [] )
|
||||
value = options[0][1]
|
||||
for option in options:
|
||||
if option[2]:
|
||||
# Found selected option.
|
||||
value = option[1]
|
||||
|
||||
d.update( {
|
||||
'options': options,
|
||||
'value': value
|
||||
} )
|
||||
return d
|
||||
|
||||
|
||||
class GenomeBuildParameter( SelectToolParameter ):
|
||||
"""
|
||||
Select list that sets the last used genome build for the current history
|
||||
@@ -1680,7 +1716,7 @@ class DataToolParameter( ToolParameter ):
|
||||
if call_attribute:
|
||||
ref = ref()
|
||||
return ref
|
||||
|
||||
|
||||
class HiddenDataToolParameter( HiddenToolParameter, DataToolParameter ):
|
||||
"""
|
||||
Hidden parameter that behaves as a DataToolParameter. As with all hidden
|
||||
@@ -1689,6 +1725,7 @@ class HiddenDataToolParameter( HiddenToolParameter, DataToolParameter ):
|
||||
def __init__( self, tool, elem ):
|
||||
DataToolParameter.__init__( self, tool, elem )
|
||||
self.value = "None"
|
||||
self.type = "hidden_data"
|
||||
|
||||
def get_initial_value( self, trans, context ):
|
||||
return None
|
||||
|
||||
@@ -15,30 +15,44 @@ from galaxy.util import relpath
|
||||
from galaxy.util import sanitize_for_filename
|
||||
from galaxy.util.bunch import Bunch
|
||||
from galaxy.util.expressions import ExpressionContext
|
||||
from galaxy.model.item_attrs import DictifiableMixin
|
||||
|
||||
class Group( object, DictifiableMixin ):
|
||||
|
||||
dict_collection_visible_keys = ( 'name', 'type' )
|
||||
|
||||
class Group( object ):
|
||||
def __init__( self ):
|
||||
self.name = None
|
||||
self.type = 'group'
|
||||
|
||||
@property
|
||||
def visible( self ):
|
||||
return True
|
||||
|
||||
def value_to_basic( self, value, app ):
|
||||
"""
|
||||
Convert value to a (possibly nested) representation using only basic
|
||||
types (dict, list, tuple, str, unicode, int, long, float, bool, None)
|
||||
"""
|
||||
return value
|
||||
|
||||
def value_from_basic( self, value, app, ignore_errors=False ):
|
||||
"""
|
||||
Convert a basic representation as produced by `value_to_basic` back
|
||||
into the preferred value form.
|
||||
"""
|
||||
return value
|
||||
|
||||
def get_initial_value( self, trans, context ):
|
||||
"""
|
||||
Return the initial state/value for this group
|
||||
"""
|
||||
raise TypeError( "Not implemented" )
|
||||
|
||||
def dictify( self, trans, view='collection', value_mapper=None ):
|
||||
# TODO: need to dictify conditions.
|
||||
group_dict = super( Group, self ).dictify( view=view, value_mapper=value_mapper )
|
||||
return group_dict
|
||||
|
||||
class Repeat( Group ):
|
||||
type = "repeat"
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
import urllib
|
||||
|
||||
from galaxy.tools.parameters.basic import IntegerToolParameter, FloatToolParameter, SelectToolParameter
|
||||
from galaxy.tools.parameters.dynamic_options import DynamicOptions
|
||||
|
||||
class TracksterConfig:
|
||||
""" Trackster configuration encapsulation. """
|
||||
|
||||
def __init__( self, actions ):
|
||||
self.actions = actions
|
||||
|
||||
@staticmethod
|
||||
def parse( root ):
|
||||
actions = []
|
||||
for action_elt in root.findall( "action" ):
|
||||
actions.append( SetParamAction.parse( action_elt ) )
|
||||
return TracksterConfig( actions )
|
||||
|
||||
class SetParamAction:
|
||||
""" Set parameter action. """
|
||||
|
||||
def __init__( self, name, output_name ):
|
||||
self.name = name
|
||||
self.output_name = output_name
|
||||
|
||||
@staticmethod
|
||||
def parse( elt ):
|
||||
""" Parse action from element. """
|
||||
return SetParamAction( elt.get( "name" ), elt.get( "output_name" ) )
|
||||
|
||||
def get_dataset_job( hda ):
|
||||
# Get dataset's job.
|
||||
job = None
|
||||
for job_output_assoc in hda.creating_job_associations:
|
||||
job = job_output_assoc.job
|
||||
break
|
||||
return job
|
||||
|
||||
def get_tool_def( trans, hda ):
|
||||
""" Returns definition of an interactive tool for an HDA. """
|
||||
|
||||
#FIXME: use tools.to_dict rather than custom code here.
|
||||
|
||||
job = get_dataset_job( hda )
|
||||
# TODO: could use this assertion to provide more information.
|
||||
# assert job is not None, 'Requested job has not been loaded.'
|
||||
if not job:
|
||||
return None
|
||||
tool = trans.app.toolbox.get_tool( job.tool_id )
|
||||
# TODO: could use this assertion to provide more information.
|
||||
# assert tool is not None, 'Requested tool has not been loaded.'
|
||||
if not tool:
|
||||
return None
|
||||
|
||||
# Tool must have a Trackster configuration.
|
||||
if not tool.trackster_conf:
|
||||
return None
|
||||
|
||||
# Get list of tool parameters that can be interactively modified.
|
||||
tool_params = []
|
||||
tool_param_values = dict( [ ( p.name, p.value ) for p in job.parameters ] )
|
||||
tool_param_values = tool.params_from_strings( tool_param_values, trans.app, ignore_errors=True )
|
||||
for name, input in tool.inputs.items():
|
||||
if type( input ) == IntegerToolParameter or type( input ) == FloatToolParameter:
|
||||
param_dict = { 'name' : name, 'label' : input.label, \
|
||||
'value' : tool_param_values.get( name, input.value ), \
|
||||
'type' : 'number', 'init_value' : input.value,
|
||||
'html' : urllib.quote( input.get_html() ) }
|
||||
if input.min:
|
||||
param_dict['min'] = input.min
|
||||
if input.max:
|
||||
param_dict['max'] = input.max
|
||||
tool_params.append( param_dict )
|
||||
elif type( input ) == SelectToolParameter and type( input.options ) != DynamicOptions:
|
||||
tool_params.append( { 'name' : name, 'label' : input.label, 'type' : 'select', \
|
||||
'value' : tool_param_values.get( name, '' ), \
|
||||
'html' : urllib.quote( input.get_html() ) } )
|
||||
|
||||
# If tool has parameters that can be interactively modified, return tool.
|
||||
if len( tool_params ) != 0:
|
||||
return { 'id': tool.id, 'name' : tool.name, 'inputs' : tool_params }
|
||||
return None
|
||||
@@ -73,7 +73,7 @@ class Genome( object ):
|
||||
self.len_file = len_file
|
||||
self.twobit_file = twobit_file
|
||||
|
||||
def to_dict( self, num=None, chrom=None, low=None ):
|
||||
def dictify( self, num=None, chrom=None, low=None ):
|
||||
"""
|
||||
Returns representation of self as a dictionary.
|
||||
"""
|
||||
@@ -289,7 +289,7 @@ class Genomes( object ):
|
||||
# Set up return value or log exception if genome not found for key.
|
||||
rval = None
|
||||
if genome:
|
||||
rval = genome.to_dict( num=num, chrom=chrom, low=low )
|
||||
rval = genome.dictify( num=num, chrom=chrom, low=low )
|
||||
else:
|
||||
log.exception( 'genome not found for key %s' % dbkey )
|
||||
|
||||
|
||||
@@ -32,12 +32,12 @@ from galaxy.workflow.modules import module_factory
|
||||
from galaxy.model.orm import eagerload, eagerload_all
|
||||
from galaxy.security.validate_user_input import validate_publicname
|
||||
from galaxy.util.sanitize_html import sanitize_html
|
||||
from galaxy.model.item_attrs import DictifiableMixin
|
||||
|
||||
from galaxy.datatypes.interval import ChromatinInteractions
|
||||
from galaxy.datatypes.data import Text
|
||||
|
||||
from galaxy.model import ExtendedMetadata, ExtendedMetadataIndex, LibraryDatasetDatasetAssociation
|
||||
from galaxy.visualization.genome.visual_analytics import get_tool_def
|
||||
from galaxy.model import ExtendedMetadata, ExtendedMetadataIndex, LibraryDatasetDatasetAssociation,HistoryDatasetAssociation
|
||||
|
||||
from galaxy.datatypes.display_applications import util as da_util
|
||||
from galaxy.datatypes.metadata import FileParameter
|
||||
@@ -704,6 +704,15 @@ class UsesHistoryDatasetAssociationMixin:
|
||||
|
||||
return changed
|
||||
|
||||
def get_hda_job( self, hda ):
|
||||
# Get dataset's job.
|
||||
job = None
|
||||
for job_output_assoc in hda.creating_job_associations:
|
||||
job = job_output_assoc.job
|
||||
break
|
||||
return job
|
||||
|
||||
|
||||
|
||||
class UsesLibraryMixin:
|
||||
|
||||
@@ -1105,6 +1114,37 @@ class UsesVisualizationMixin( UsesHistoryDatasetAssociationMixin, UsesLibraryMix
|
||||
encoded_id = trans.security.encode_id( vis.id )
|
||||
return { "vis_id": encoded_id, "url": url_for( controller='visualization', action=vis.type, id=encoded_id ) }
|
||||
|
||||
def get_tool_def( self, trans, hda ):
|
||||
""" Returns definition of an interactive tool for an HDA. """
|
||||
|
||||
job = self.get_hda_job( hda )
|
||||
if not job:
|
||||
return None
|
||||
tool = trans.app.toolbox.get_tool( job.tool_id )
|
||||
if not tool:
|
||||
return None
|
||||
|
||||
# Tool must have a Trackster configuration.
|
||||
if not tool.trackster_conf:
|
||||
return None
|
||||
|
||||
# Get tool definition and add input values from job.
|
||||
tool_dict = tool.dictify( trans, io_details=True )
|
||||
inputs_dict = tool_dict[ 'inputs' ]
|
||||
tool_param_values = dict( [ ( p.name, p.value ) for p in job.parameters ] )
|
||||
tool_param_values = tool.params_from_strings( tool_param_values, trans.app, ignore_errors=True )
|
||||
for t_input in inputs_dict:
|
||||
# Add value to tool.
|
||||
if 'name' in t_input:
|
||||
name = t_input[ 'name' ]
|
||||
if name in tool_param_values:
|
||||
value = tool_param_values[ name ]
|
||||
if isinstance( value, DictifiableMixin ):
|
||||
value = value.dictify()
|
||||
t_input[ 'value' ] = value
|
||||
|
||||
return tool_dict
|
||||
|
||||
def get_visualization_config( self, trans, visualization ):
|
||||
""" Returns a visualization's configuration. Only works for trackster visualizations right now. """
|
||||
config = None
|
||||
@@ -1137,7 +1177,7 @@ class UsesVisualizationMixin( UsesHistoryDatasetAssociationMixin, UsesLibraryMix
|
||||
"prefs": prefs,
|
||||
"mode": track_dict.get( 'mode', 'Auto' ),
|
||||
"filters": track_dict.get( 'filters', { 'filters' : track_data_provider.get_filters() } ),
|
||||
"tool": get_tool_def( trans, dataset ),
|
||||
"tool": self.get_tool_def( trans, dataset ),
|
||||
"tool_state": track_dict.get( 'tool_state', {} )
|
||||
}
|
||||
|
||||
@@ -1215,7 +1255,7 @@ class UsesVisualizationMixin( UsesHistoryDatasetAssociationMixin, UsesLibraryMix
|
||||
"dataset": trans.security.encode_dict_ids( dataset.dictify() ),
|
||||
"prefs": {},
|
||||
"filters": { 'filters' : track_data_provider.get_filters() },
|
||||
"tool": get_tool_def( trans, dataset ),
|
||||
"tool": self.get_tool_def( trans, dataset ),
|
||||
"tool_state": {}
|
||||
}
|
||||
|
||||
|
||||
@@ -199,7 +199,7 @@ class DatasetsController( BaseAPIController, UsesVisualizationMixin, UsesHistory
|
||||
data_dict = self.app.genomes.reference( trans, dbkey=dataset.dbkey, chrom=chrom, low=low, high=high )
|
||||
if data_dict:
|
||||
ref_seq = data_dict[ 'data' ]
|
||||
|
||||
|
||||
# Get and return data from data_provider.
|
||||
result = data_provider.get_data( chrom, int( low ), int( high ), int( start_val ), int( max_vals ),
|
||||
ref_seq=ref_seq, **kwargs )
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from galaxy import web, util
|
||||
from galaxy.web.base.controller import BaseAPIController, UsesHistoryDatasetAssociationMixin, UsesVisualizationMixin
|
||||
from galaxy.visualization.genome.visual_analytics import get_dataset_job
|
||||
from galaxy.visualization.genomes import GenomeRegion
|
||||
from galaxy.util.json import to_json_string, from_json_string
|
||||
from galaxy.visualization.data_providers.genome import *
|
||||
@@ -33,7 +32,7 @@ class ToolsController( BaseAPIController, UsesVisualizationMixin ):
|
||||
|
||||
# Create return value.
|
||||
try:
|
||||
return self.app.toolbox.to_dict( trans, in_panel=in_panel, trackster=trackster )
|
||||
return self.app.toolbox.dictify( trans, in_panel=in_panel, trackster=trackster )
|
||||
except Exception, exc:
|
||||
log.error( 'could not convert toolbox to dictionary: %s', str( exc ), exc_info=True )
|
||||
trans.response.status = 500
|
||||
@@ -46,7 +45,7 @@ class ToolsController( BaseAPIController, UsesVisualizationMixin ):
|
||||
Returns tool information, including parameters and inputs.
|
||||
"""
|
||||
try:
|
||||
return self.app.toolbox.tools_by_id[ id ].to_dict( trans, for_display=True )
|
||||
return self.app.toolbox.tools_by_id[ id ].dictify( trans, for_display=True )
|
||||
except Exception, exc:
|
||||
log.error( 'could not convert tool (%s) to dictionary: %s', id, str( exc ), exc_info=True )
|
||||
trans.response.status = 500
|
||||
@@ -217,7 +216,7 @@ class ToolsController( BaseAPIController, UsesVisualizationMixin ):
|
||||
# job's previous parameters and incoming parameters. Incoming parameters
|
||||
# have priority.
|
||||
#
|
||||
original_job = get_dataset_job( original_dataset )
|
||||
original_job = self.get_hda_job( original_dataset )
|
||||
tool = trans.app.toolbox.get_tool( original_job.tool_id )
|
||||
if not tool:
|
||||
return trans.app.model.Dataset.conversion_messages.NO_TOOL
|
||||
|
||||
@@ -14,7 +14,6 @@ from galaxy.datatypes.interval import Bed
|
||||
from galaxy.util.json import from_json_string
|
||||
from galaxy.util.sanitize_html import sanitize_html
|
||||
from galaxy.visualization.genomes import decode_dbkey
|
||||
from galaxy.visualization.genome.visual_analytics import get_dataset_job
|
||||
from galaxy.visualization.data_providers.phyloviz import PhylovizDataProvider
|
||||
from galaxy.visualization.genomes import GenomeRegion
|
||||
|
||||
@@ -865,7 +864,7 @@ class VisualizationController( BaseUIController, SharableMixin, UsesAnnotations,
|
||||
else:
|
||||
# Loading new visualization.
|
||||
dataset = self.get_hda_or_ldda( trans, hda_ldda, dataset_id )
|
||||
job = get_dataset_job( dataset )
|
||||
job = self.get_hda_job( dataset )
|
||||
viz_config = {
|
||||
'dataset_id': dataset_id,
|
||||
'tool_id': job.tool_id,
|
||||
@@ -874,7 +873,7 @@ class VisualizationController( BaseUIController, SharableMixin, UsesAnnotations,
|
||||
|
||||
# Add tool, dataset attributes to config based on id.
|
||||
tool = trans.app.toolbox.get_tool( viz_config[ 'tool_id' ] )
|
||||
viz_config[ 'tool' ] = tool.to_dict( trans, for_display=True )
|
||||
viz_config[ 'tool' ] = tool.dictify( trans, for_display=True )
|
||||
viz_config[ 'dataset' ] = dataset.dictify()
|
||||
|
||||
return trans.fill_template_mako( "visualization/sweepster.mako", config=viz_config )
|
||||
|
||||
+24
-22
@@ -268,12 +268,12 @@ var ToolCollection = Backbone.Collection.extend({
|
||||
/**
|
||||
* Label or section header in tool panel.
|
||||
*/
|
||||
var ToolPanelLabel = Backbone.Model.extend(VisibilityMixin);
|
||||
var ToolSectionLabel = Backbone.Model.extend(VisibilityMixin);
|
||||
|
||||
/**
|
||||
* Section of tool panel with elements (labels and tools).
|
||||
*/
|
||||
var ToolPanelSection = Backbone.Model.extend({
|
||||
var ToolSection = Backbone.Model.extend({
|
||||
defaults: {
|
||||
elems: [],
|
||||
open: false
|
||||
@@ -292,7 +292,7 @@ var ToolPanelSection = Backbone.Model.extend({
|
||||
var all_hidden = true,
|
||||
cur_label;
|
||||
_.each(this.attributes.elems, function(elt) {
|
||||
if (elt instanceof ToolPanelLabel) {
|
||||
if (elt instanceof ToolSectionLabel) {
|
||||
cur_label = elt;
|
||||
cur_label.hide();
|
||||
}
|
||||
@@ -315,7 +315,7 @@ var ToolPanelSection = Backbone.Model.extend({
|
||||
}
|
||||
}
|
||||
});
|
||||
_.extend(ToolPanelSection.prototype, VisibilityMixin);
|
||||
_.extend(ToolSection.prototype, VisibilityMixin);
|
||||
|
||||
/**
|
||||
* Tool search that updates results when query is changed. Result value of null
|
||||
@@ -399,18 +399,20 @@ var ToolPanel = Backbone.Model.extend({
|
||||
var self = this,
|
||||
// Helper to recursively parse tool panel.
|
||||
parse_elt = function(elt_dict) {
|
||||
var type = elt_dict.type;
|
||||
if (type === 'tool') {
|
||||
var type = elt_dict.model_class;
|
||||
// There are many types of tools; for now, anything that ends in 'Tool'
|
||||
// is treated as a generic tool.
|
||||
if ( type.indexOf('Tool') === type.length - 4 ) {
|
||||
return self.attributes.tools.get(elt_dict.id);
|
||||
}
|
||||
else if (type === 'section') {
|
||||
else if (type === 'ToolSection') {
|
||||
// Parse elements.
|
||||
var elems = _.map(elt_dict.elems, parse_elt);
|
||||
elt_dict.elems = elems;
|
||||
return new ToolPanelSection(elt_dict);
|
||||
return new ToolSection(elt_dict);
|
||||
}
|
||||
else if (type === 'label') {
|
||||
return new ToolPanelLabel(elt_dict);
|
||||
else if (type === 'ToolSectionLabel') {
|
||||
return new ToolSectionLabel(elt_dict);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -419,7 +421,7 @@ var ToolPanel = Backbone.Model.extend({
|
||||
|
||||
clear_search_results: function() {
|
||||
this.get('layout').each(function(panel_elt) {
|
||||
if (panel_elt instanceof ToolPanelSection) {
|
||||
if (panel_elt instanceof ToolSection) {
|
||||
panel_elt.clear_search_results();
|
||||
}
|
||||
else {
|
||||
@@ -438,7 +440,7 @@ var ToolPanel = Backbone.Model.extend({
|
||||
|
||||
var cur_label = null;
|
||||
this.get('layout').each(function(panel_elt) {
|
||||
if (panel_elt instanceof ToolPanelLabel) {
|
||||
if (panel_elt instanceof ToolSectionLabel) {
|
||||
cur_label = panel_elt;
|
||||
cur_label.hide();
|
||||
}
|
||||
@@ -495,12 +497,12 @@ var ToolLinkView = BaseView.extend({
|
||||
/**
|
||||
* Panel label/section header.
|
||||
*/
|
||||
var ToolPanelLabelView = BaseView.extend({
|
||||
var ToolSectionLabelView = BaseView.extend({
|
||||
tagName: 'div',
|
||||
className: 'toolPanelLabel',
|
||||
className: 'ToolSectionLabel',
|
||||
|
||||
render: function() {
|
||||
this.$el.append( $("<span/>").text(this.model.attributes.name) );
|
||||
this.$el.append( $("<span/>").text(this.model.attributes.text) );
|
||||
return this;
|
||||
}
|
||||
});
|
||||
@@ -508,7 +510,7 @@ var ToolPanelLabelView = BaseView.extend({
|
||||
/**
|
||||
* Panel section.
|
||||
*/
|
||||
var ToolPanelSectionView = BaseView.extend({
|
||||
var ToolSectionView = BaseView.extend({
|
||||
tagName: 'div',
|
||||
className: 'toolSectionWrapper',
|
||||
template: Handlebars.templates.panel_section,
|
||||
@@ -528,8 +530,8 @@ var ToolPanelSectionView = BaseView.extend({
|
||||
tool_view.render();
|
||||
section_body.append(tool_view.$el);
|
||||
}
|
||||
else if (elt instanceof ToolPanelLabel) {
|
||||
var label_view = new ToolPanelLabelView({model: elt});
|
||||
else if (elt instanceof ToolSectionLabel) {
|
||||
var label_view = new ToolSectionLabelView({model: elt});
|
||||
label_view.render();
|
||||
section_body.append(label_view.$el);
|
||||
}
|
||||
@@ -630,8 +632,8 @@ var ToolPanelView = Backbone.View.extend({
|
||||
|
||||
// Render panel.
|
||||
this.model.get('layout').each(function(panel_elt) {
|
||||
if (panel_elt instanceof ToolPanelSection) {
|
||||
var section_title_view = new ToolPanelSectionView({model: panel_elt});
|
||||
if (panel_elt instanceof ToolSection) {
|
||||
var section_title_view = new ToolSectionView({model: panel_elt});
|
||||
section_title_view.render();
|
||||
self.$el.append(section_title_view.$el);
|
||||
}
|
||||
@@ -640,8 +642,8 @@ var ToolPanelView = Backbone.View.extend({
|
||||
tool_view.render();
|
||||
self.$el.append(tool_view.$el);
|
||||
}
|
||||
else if (panel_elt instanceof ToolPanelLabel) {
|
||||
var label_view = new ToolPanelLabelView({model: panel_elt});
|
||||
else if (panel_elt instanceof ToolSectionLabel) {
|
||||
var label_view = new ToolSectionLabelView({model: panel_elt});
|
||||
label_view.render();
|
||||
self.$el.append(label_view.$el);
|
||||
}
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1634,7 +1634,17 @@ var TracksterTool = Backbone.RelationalModel.extend({
|
||||
key: 'tool',
|
||||
relatedModel: tools_mod.Tool
|
||||
}
|
||||
]
|
||||
],
|
||||
|
||||
initialize: function(options) {
|
||||
// HACK: remove data and group tool inputs because Trackster
|
||||
// does not work with them right now.
|
||||
var tool = this.get('tool'),
|
||||
incompatible_inputs = tool.get('inputs').filter( function(input) {
|
||||
return ( [ 'data', 'hidden_data', 'group'].indexOf( input.get('type') ) !== -1);
|
||||
});
|
||||
tool.get('inputs').remove(incompatible_inputs);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -1692,6 +1702,7 @@ var TracksterToolView = Backbone.View.extend({
|
||||
// Add name, inputs.
|
||||
var name_div = $("<div class='tool-name'>").appendTo(parent_div).text(tool.get('name'));
|
||||
tool.get('inputs').each(function(param) {
|
||||
// Render parameter.
|
||||
var param_view = new ToolParameterView({ model: param });
|
||||
param_view.render();
|
||||
parent_div.append(param_view.$el);
|
||||
@@ -2479,11 +2490,8 @@ extend(Track.prototype, Drawable.prototype, {
|
||||
Drawable.prototype.action_icons_def[2]
|
||||
],
|
||||
|
||||
can_draw: function() {
|
||||
if ( this.dataset.id && Drawable.prototype.can_draw.call(this) ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
can_draw: function() {
|
||||
return this.dataset && Drawable.prototype.can_draw.call(this);
|
||||
},
|
||||
|
||||
build_container_div: function () {
|
||||
|
||||
@@ -25,12 +25,12 @@
|
||||
hidden: false
|
||||
}),
|
||||
tools = new tools_mod.ToolCollection(
|
||||
${ h.to_json_string( trans.app.toolbox.to_dict( trans, in_panel=False ) ) }
|
||||
${ h.to_json_string( trans.app.toolbox.dictify( trans, in_panel=False ) ) }
|
||||
),
|
||||
tool_panel = new tools_mod.ToolPanel({
|
||||
tool_search: tool_search,
|
||||
tools: tools,
|
||||
layout: ${h.to_json_string( trans.app.toolbox.to_dict( trans ) )}
|
||||
layout: ${h.to_json_string( trans.app.toolbox.dictify( trans ) )}
|
||||
}),
|
||||
tool_panel_view = new tools_mod.ToolPanelView({ model: tool_panel });
|
||||
|
||||
|
||||
Reference in New Issue
Block a user