Changeset 1557:a5831435c654

Show
Ignore:
Timestamp:
10/16/08 14:12:37 (3 months ago)
Author:
Dan Blankenberg <dan@bx.psu.edu>
branch:
default
Message:

Refactor internals of metadata.

Significantly reduce the number of objects created during interation (i.e. MetadataParameters? are created only once per spec).

Some oddness remains until it can be determined to be necessary or not, i.e.:
iter( metadata_collection ) != iter( metadata_collection.items() )

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • lib/galaxy/datatypes/data.py

    r1533 r1557  
    22from galaxy import util 
    33from cgi import escape 
    4 from galaxy.datatypes.metadata import * 
    5 from galaxy.datatypes.metadata import MetadataElement 
    6 from galaxy.datatypes import metadata 
     4import metadata 
     5from metadata import MetadataElement #import directly to maintain ease of use in Datatype class definitions 
    76 
    87log = logging.getLogger(__name__) 
     
    1817    """ 
    1918    def __init__( cls, name, bases, dict_ ): 
    20         cls.metadata_spec = MetadataSpecCollection() 
    21         for base in bases: 
    22             if hasattr(base, "metadata_spec"): 
    23                 cls.metadata_spec.update(base.metadata_spec) 
    24         Statement.process( cls ) 
     19        cls.metadata_spec = metadata.MetadataSpecCollection() 
     20        for base in bases: #loop through bases (class/types) of cls 
     21            if hasattr( base, "metadata_spec" ): #base of class Data (object) has no metadata 
     22                cls.metadata_spec.update( base.metadata_spec ) #add contents of metadata spec of base class to cls 
     23        metadata.Statement.process( cls ) 
    2524 
    2625class Data( object ): 
  • lib/galaxy/datatypes/metadata.py

    r1531 r1557  
    11import sys, logging 
    22 
    3 from galaxy.util.bunch import Bunch 
     3from galaxy.util import string_as_bool 
    44from galaxy.util.odict import odict 
    55from galaxy.web import form_builder 
    6 from types import * 
    76 
    87log = logging.getLogger( __name__ ) 
    98 
    10 # Taken in part from Elixir and how they do it: http://elixir.ematia.de 
    11  
    12 STATEMENTS = "__galaxy_statements__" 
     9STATEMENTS = "__galaxy_statements__" #this is the name of the property in a Datatype class where new metadata spec element Statements are stored 
    1310 
    1411class Statement( object ): 
    15     ''' 
     12    """ 
    1613    This class inserts its target into a list in the surrounding 
    1714    class.  the data.Data class has a metaclass which executes these 
    1815    statements.  This is how we shove the metadata element spec into 
    1916    the class. 
    20     ''' 
     17    """ 
    2118    def __init__( self, target ): 
    2219        self.target = target 
    2320    def __call__( self, *args, **kwargs ): 
    24         class_locals = sys._getframe(1).f_locals 
    25         statements = class_locals.setdefault(STATEMENTS, []) 
    26         statements.append((self, args, kwargs)) 
     21        class_locals = sys._getframe( 1 ).f_locals #get the locals dictionary of the frame object one down in the call stack (i.e. the Datatype class calling MetadataElement) 
     22        statements = class_locals.setdefault( STATEMENTS, [] ) #get and set '__galaxy_statments__' to an empty list if not in locals dict 
     23        statements.append( ( self, args, kwargs ) ) #add Statement containing info to populate a MetadataElementSpec 
    2724    @classmethod 
    2825    def process( cls, element ): 
    2926        for statement, args, kwargs in getattr( element, STATEMENTS, [] ): 
    30             statement.target( element, *args, **kwargs ) 
     27            statement.target( element, *args, **kwargs ) #statement.target is MetadataElementSpec, element is a Datatype class 
     28 
     29 
     30class MetadataCollection: 
     31    """ 
     32    MetadataCollection is not a collection at all, but rather a proxy 
     33    to the real metadata which is stored as a Dictionary. This class 
     34    handles processing the metadata elements when they are set and 
     35    retrieved, returning default values in cases when metadata is not set. 
     36    """ 
     37    def __init__(self, parent ): 
     38        self.parent = parent 
     39        #initialize dict if needed 
     40        if self.parent._metadata is None: 
     41            self.parent._metadata = {} 
     42    @property 
     43    def spec( self ): 
     44        return self.parent.datatype.metadata_spec 
     45    def __iter__( self ): 
     46        return self.parent._metadata.__iter__() 
     47    def get( self, key, default=None ): 
     48        try: 
     49            return self.__getattr__( key ) or default 
     50        except: 
     51            return default 
     52    def items(self): 
     53        return iter( [ ( k, self.get( k ) ) for k in self.spec.iterkeys() ] ) 
     54    def __str__(self): 
     55        return dict( self.items() ).__str__() 
     56    def __nonzero__( self ): 
     57        return bool( self.parent._metadata ) 
     58    def __getattr__( self, name ): 
     59        if name in self.spec: 
     60            if name in self.parent._metadata: 
     61                return self.spec[name].wrap( self.parent._metadata[name] ) 
     62            return self.spec[name].wrap( self.spec[name].default ) 
     63        if name in self.parent._metadata: 
     64            return self.parent._metadata[name] 
     65    def __setattr__( self, name, value ): 
     66        if name == "parent": 
     67            self.__dict__[name] = value 
     68        else: 
     69            if name in self.spec: 
     70                self.parent._metadata[name] = self.spec[name].unwrap( value ) 
     71            else: 
     72                self.parent._metadata[name] = value 
     73    def element_is_set( self, name ): 
     74        return bool( self.parent._metadata.get( name, False ) ) 
     75    def get_html_by_name( self, name, **kwd ): 
     76        if name in self.spec: 
     77            return self.spec[name].param.get_html( value=getattr( self, name ), context=self, **kwd ) 
     78 
    3179 
    3280class MetadataSpecCollection( odict ): 
    33     ''' 
     81    """ 
    3482    A simple extension of dict which allows cleaner access to items 
    3583    and allows the values to be iterated over directly as if it were a 
    3684    list.  append() is also implemented for simplicity and does not 
    3785    "append". 
    38     ''' 
    39     def __init__(self, dict = None): 
    40         odict.__init__(self, dict = None
     86    """ 
     87    def __init__( self, dict = None ): 
     88        odict.__init__( self, dict = None
    4189    def append( self, item ): 
    4290        self[item.name] = item 
     
    4492        return self.itervalues() 
    4593    def __getattr__( self, name ): 
    46         return self.get(name
     94        return self.get( name
    4795 
    4896class MetadataParameter( object ): 
    49     def __init__( self, spec, value, context ): 
    50         ''' 
     97    def __init__( self, spec ): 
     98        self.spec = spec 
     99         
     100    def get_html_field( self, value=None, context={}, other_values={}, **kwd ): 
     101        return form_builder.TextField( self.spec.name, value=value ) 
     102     
     103    def get_html( self, value, context={}, other_values={}, **kwd ): 
     104        """ 
    51105        The "context" is simply the metadata collection/bunch holding 
    52106        this piece of metadata. This is passed in to allow for 
     
    55109        example, a column assignment should validate against the 
    56110        number of columns in the dataset. 
    57         ''' 
    58         self.spec = spec 
    59         """Since strings are stored as unicode, we need to decode them for display""" 
    60         if isinstance( value, ListType ): 
    61             for i, elem in enumerate( value ): 
    62                 if type ( elem ) == unicode: 
    63                     value[i] = elem.decode( 'ascii' ) 
    64         elif isinstance ( value, basestring ): 
    65             if type( value ) == unicode: 
    66                 value = value.decode( 'ascii' ) 
    67         self.value = value 
    68         self.context = context 
    69         self.display = True 
    70  
    71     def __str__(self): 
    72         if self.value is None: 
    73             return str(self.spec.no_value) 
    74         return str(self.value) 
    75  
    76     @classmethod 
    77     def marshal( cls, value ): 
    78         ''' 
     111        """ 
     112        if self.spec.get("readonly"): 
     113            return value 
     114        if self.spec.get("optional"): 
     115            checked = False 
     116            if value: checked = "true" 
     117            checkbox = form_builder.CheckboxField( "is_" + self.spec.name, checked=checked ) 
     118            return checkbox.get_html() + self.get_html_field( value=value, context=context, other_values=other_values, **kwd ).get_html() 
     119        else: 
     120            return self.get_html_field( value=value, context=context, other_values=other_values, **kwd ).get_html() 
     121     
     122    def to_string( self, value ): 
     123        return str( value ) 
     124 
     125    @classmethod 
     126    def marshal ( cls, value ): 
     127        """ 
    79128        This method should/can be overridden to convert the incoming 
    80129        value to whatever type it is supposed to be. 
    81         ''' 
    82         return value 
    83  
    84     @classmethod 
    85     def validate( cls, value ): 
    86         ''' 
     130        """ 
     131        return value 
     132 
     133    def validate( self, value ): 
     134        """ 
    87135        Throw an exception if the value is invalid. 
    88         ''' 
     136        """ 
    89137        pass 
    90138 
    91     def get_html_field( self, value=None, other_values={} ): 
    92         return form_builder.TextField( self.spec.name, value=value or self.value ) 
    93  
    94     def get_html( self ): 
    95         if self.spec.get("readonly"): 
    96             return self.value 
    97         if self.spec.get("optional"): 
    98             checked = False 
    99             if self.value: checked = "true" 
    100             checkbox = form_builder.CheckboxField( "is_" + self.spec.name, checked=checked ) 
    101             return checkbox.get_html() + self.get_html_field().get_html() 
    102         else: 
    103             return self.get_html_field().get_html() 
    104  
    105     @classmethod 
    106     def unwrap( cls, form_value ): 
    107         value = cls.marshal(form_value) 
    108         cls.validate(value) 
    109         return value 
    110      
     139 
     140    def unwrap( self, form_value ): 
     141        """ 
     142        Turns a value into its storable form. 
     143        """ 
     144        value = self.marshal( form_value ) 
     145        self.validate( value ) 
     146        return value 
     147     
     148    def wrap( self, value ): 
     149        """ 
     150        Turns a value into its usable form. 
     151        """ 
     152        return value 
     153 
     154 
    111155class MetadataElementSpec( object ): 
    112     ''' 
     156    """ 
    113157    Defines a metadata element and adds it to the metadata_spec (which 
    114158    is a MetadataSpecCollection) of datatype. 
    115     ''' 
     159    """ 
    116160 
    117161    def __init__( self, datatype, name=None, desc=None, param=MetadataParameter, default=None, no_value = None, visible=True, **kwargs ): 
    118162        self.name = name 
    119163        self.desc = desc or name 
    120         self.param = param 
    121164        self.default = default 
    122165        self.no_value = no_value 
     
    124167        # Catch-all, allows for extra attributes to be set 
    125168        self.__dict__.update(kwargs) 
    126         datatype.metadata_spec.append( self ) 
     169        #set up param last, as it uses values set above 
     170        self.param = param( self ) 
     171        datatype.metadata_spec.append( self ) #add spec element to the spec 
    127172    def get( self, name ): 
    128173        return self.__dict__.get(name, None) 
    129     def hasAttribute( self, attribute ): 
    130         return ((self.permission & attribute) == attribute) 
    131     def wrap( self, value, context ): 
    132         return self.param( self, value, context ) 
    133     def unwrap( self, form_value, context ): 
    134         return self.param.unwrap( form_value ) 
    135              
    136  
    137 # Basic attributes for describing metadata elements 
    138 MetadataAttributes = Bunch( 
    139     READONLY = 1,  
    140     OPTIONAL = 2 
    141     ) 
    142      
    143  
    144 class MetadataCollection: 
    145     """ 
    146     MetadataCollection is not a collection at all, but rather a proxy 
    147     to the real metadata which is stored as a Bunch.  This class 
    148     handles updating the reference to the Bunch when it is changed (so 
    149     that SQLAlchemy knows to update it) as well as returning default 
    150     values in cases when metadata is not set. 
    151     """ 
    152     def __init__(self, parent, spec): 
    153         self.parent = parent 
    154         if spec is None: self.spec = MetadataSpecCollection() 
    155         else: self.spec = spec 
    156          
    157         #set default metadata values 
    158         if self.parent._metadata is None: 
    159             self.parent._metadata = {} 
    160          
    161     def __iter__(self): 
    162         return self.bunch.__iter__() 
    163     def get( self, key, default=None ): 
    164         try: 
    165             return self.bunch.get( key, default ) or self.spec[key].default 
    166         except: 
    167             return default 
    168     def items(self): 
    169         return iter( [(k, self.get(k)) for k in self.spec.iterkeys() ] ) 
    170     def __str__(self): 
    171         return dict( self.items() ).__str__() 
    172     def __nonzero__(self): 
    173         return self.bunch.__nonzero__() 
    174     def __getattr__(self, name): 
    175         if name == "bunch": 
    176             return self.parent._metadata 
    177         if name in self.bunch: 
    178             return self.bunch[name] 
    179         if name in self.spec: 
    180             return self.spec[name].default 
    181     def __setattr__(self, name, value): 
    182         if name in ["parent","spec"]: 
    183             self.__dict__[name] = value 
    184         elif name == "bunch": 
    185             self.parent._metadata = value 
    186         else: 
    187             self.bunch[name] = value 
    188     def element_is_set( self, name ): 
    189         return bool( self.bunch.get( name, False ) ) 
    190  
    191 MetadataElement = Statement(MetadataElementSpec) 
    192  
     174    def wrap( self, value ): 
     175        """ 
     176        Turns a stored value into its usable form. 
     177        """ 
     178        return self.param.wrap( value ) 
     179    def unwrap( self, value ): 
     180        """ 
     181        Turns an incoming value into its storable form. 
     182        """ 
     183        return self.param.unwrap( value ) 
     184 
     185MetadataElement = Statement( MetadataElementSpec ) 
    193186 
    194187""" 
     
    197190 
    198191class SelectParameter( MetadataParameter ): 
    199     def __init__( self, spec, value, context ): 
    200         MetadataParameter.__init__( self, spec, value, context ) 
    201         self.values = spec.get("values") 
    202      
    203     def __setattr__(self, name, value): 
    204         MetadataParameter.__setattr__(self, name, value) 
    205         if name in ['value']: 
    206             if value is None:  
    207                 MetadataParameter.__setattr__(self, name, []) 
    208             elif not isinstance(value, list): 
    209                 MetadataParameter.__setattr__(self, name, [value]) 
    210      
    211     def __iter__( self ): 
    212         return iter( self.value ) 
    213      
    214     def __str__(self): 
    215         if self.value in [None, []]: 
    216             return str(self.spec.no_value) 
    217         return ",".join(map(str,self.value)) 
    218      
    219     def get_html_field( self, value=None, other_values={} ): 
    220         field = form_builder.SelectField( self.spec.name, multiple=self.spec.get("multiple"), display=self.spec.get("display") ) 
    221         for value, label in self.values or [(value, value) for value in self.value]: 
     192    def __init__( self, spec ): 
     193        MetadataParameter.__init__( self, spec ) 
     194        self.values = self.spec.get( "values" ) 
     195        self.multiple = string_as_bool( self.spec.get( "multiple" ) ) 
     196     
     197    def to_string( self, value ): 
     198        if value in [ None, [] ]: 
     199            return str( self.spec.no_value ) 
     200        if not isinstance( value, list ): 
     201            value = [value] 
     202        return ",".join( map( str, value ) ) 
     203     
     204    def get_html_field( self, value=None, context={}, other_values={}, values=None, **kwd ): 
     205        field = form_builder.SelectField( self.spec.name, multiple=self.multiple, display=self.spec.get("display") ) 
     206        for val, label in self.values or values or [(val2, val2) for val2 in value]: 
    222207            try: 
    223                 if value in self.value
    224                     field.add_option( label, value, selected=True ) 
     208                if ( self.multiple and val in value ) or ( not self.multiple and val == value )
     209                    field.add_option( label, val, selected=True ) 
    225210                else: 
    226                     field.add_option( label, value, selected=False ) 
     211                    field.add_option( label, val, selected=False ) 
    227212            except TypeError: 
    228                 field.add_option( value, label, selected=False ) 
     213                field.add_option( val, label, selected=False ) 
    229214 
    230215        return field 
    231216 
    232     def get_html( self ): 
     217    def get_html( self, value, context={}, other_values={}, values=None, **kwd ): 
    233218        if self.spec.get("readonly"): 
    234             if self.value in [None, [] ]: 
    235                 return str(self.spec.no_value) 
    236             return ", ".join(map(str,self.value)) 
    237         return MetadataParameter.get_html(self) 
     219            if value in [ None, [] ]: 
     220                return str( self.spec.no_value ) 
     221            return ", ".join( map( str, value ) ) 
     222        return MetadataParameter.get_html( self, value, context=context, other_values=other_values, values=values, **kwd ) 
     223 
     224    def wrap( self, value ): 
     225        value = self.marshal( value ) #do we really need this (wasteful)? - yes because we are not sure that all existing selects have been stored previously as lists. Also this will handle the case where defaults/no_values are specified and are single non-list values. 
     226        if self.multiple: 
     227            return value 
     228        elif value: 
     229            return value[0] #single select, only return the first value 
     230        return None 
    238231 
    239232    @classmethod 
     
    241234        # Store select as list, even if single item 
    242235        if value is None: return [] 
    243         if not isinstance(value, list): return [value] 
     236        if not isinstance( value, list ): return [value] 
    244237        return value 
    245238     
    246239class RangeParameter( SelectParameter ): 
    247     def __init__( self, spec, value, context ): 
    248         SelectParameter.__init__( self, spec, value, context
     240    def __init__( self, spec ): 
     241        SelectParameter.__init__( self, spec
    249242        # The spec must be set with min and max values 
    250         _min = spec.get("min") or 1 
    251         _max = spec.get("max") or 1 
    252         step = self.spec.get("step") or 1 
    253         self.values = zip(range( _min, _max, step ), range( _min, _max, step )) 
    254  
     243        self.min = spec.get( "min" ) or 1 
     244        self.max = spec.get( "max" ) or 1 
     245        self.step = self.spec.get( "step" ) or 1 
     246 
     247    def get_html_field( self, value=None, context={}, other_values={}, values=None, **kwd ): 
     248        if values is None: 
     249            values = zip( range( self.min, self.max, self.step ), range( self.min, self.max, self.step )) 
     250        return SelectParameter.get_html_field( self, value=value, context=context, other_values=other_values, values=values, **kwd ) 
     251     
     252    def get_html( self, value, context={}, other_values={}, values=None, **kwd ): 
     253        if values is None: 
     254            values = zip( range( self.min, self.max, self.step ), range( self.min, self.max, self.step )) 
     255        return SelectParameter.get_html( self, value, context=context, other_values=other_values, values=values, **kwd ) 
     256     
    255257    @classmethod 
    256258    def marshal( cls, value ): 
    257         values = [int(x) for x in value] 
     259        value = SelectParameter.marshal( value ) 
     260        values = [ int(x) for x in value ] 
    258261        return values 
    259262     
    260263class ColumnParameter( RangeParameter ): 
    261     def __init__( self, spec, value, context ): 
    262         RangeParameter.__init__( self, spec, value, context ) 
    263         column_range = range( 1, context.metadata.columns+1, 1 ) 
    264         self.values = zip( column_range, column_range ) 
    265          
     264     
     265    def get_html_field( self, value=None, context={}, other_values={}, values=None, **kwd ): 
     266        if values is None and context: 
     267            column_range = range( 1, context.columns+1, 1 ) 
     268            values = zip( column_range, column_range ) 
     269        return RangeParameter.get_html_field( self, value=value, context=context, other_values=other_values, values=values, **kwd ) 
     270     
     271    def get_html( self, value, context={}, other_values={}, values=None, **kwd ): 
     272        if values is None and context: 
     273            column_range = range( 1, context.columns+1, 1 ) 
     274            values = zip( column_range, column_range ) 
     275        return RangeParameter.get_html( self, value, context=context, other_values=other_values, values=values, **kwd )  
     276     
     277class ColumnTypesParameter( MetadataParameter ): 
     278     
     279    def to_string( self, value ): 
     280        return ",".join( map( str, value ) ) 
     281 
     282class PythonObjectParameter( MetadataParameter ): 
     283    def __init__( self, spec ): 
     284        MetadataParameter.__init__( self, spec ) 
     285     
     286    def to_string( self, value ): 
     287        if not value: 
     288            return self.spec.to_string( self.spec.no_value ) 
     289        return self.spec.to_string( value ) 
     290     
     291    def get_html_field( self, value=None, context={}, other_values={}, **kwd ): 
     292        return form_builder.TextField( self.spec.name, value=self.to_string( value ) ) 
     293 
     294    def get_html( self, value=None, context={}, other_values={}, **kwd ): 
     295        return str( self ) 
     296 
    266297    @classmethod 
    267298    def marshal( cls, value ): 
    268         return int(value) 
    269  
    270 class ColumnTypesParameter( MetadataParameter ): 
    271     def __init__( self, spec, value, context ): 
    272         MetadataParameter.__init__( self, spec, value, context ) 
    273     def __str__(self): 
    274         return ",".join( map( str, self.value ) ) 
    275  
    276 class PythonObjectParameter( MetadataParameter ): 
    277     def __init__( self, spec, value, context ): 
    278         MetadataParameter.__init__( self, spec, value, context ) 
    279         self.value = value 
    280         self.display = False 
    281      
    282     def __str__(self): 
    283         if not self.value: 
    284             return self.spec.to_string( self.spec.no_value ) 
    285         return self.spec.to_string( self.value ) 
    286      
    287     def get_html_field( self, value=None, other_values={} ): 
    288         return form_builder.TextField( self.spec.name, value=str( self ) ) 
    289  
    290     def get_html( self ): 
    291         return str( self ) 
    292  
    293     @classmethod 
    294     def marshal( cls, value ): 
    295         return value 
    296  
     299        return value 
  • lib/galaxy/datatypes/sequence.py

    r1554 r1557  
    2525    """Add metadata elements""" 
    2626    MetadataElement( name="species", desc="Species", default=[], param=metadata.SelectParameter, multiple=True, readonly=True, no_value=None ) 
    27     MetadataElement( name="species_chromosomes", desc="Species Chromosomes", value={}, param=metadata.PythonObjectParameter, readonly=True, no_value={}, to_string=str
     27    MetadataElement( name="species_chromosomes", desc="Species Chromosomes", value={}, param=metadata.PythonObjectParameter, readonly=True, no_value={}, to_string=str, visible=False
    2828 
    2929class Fasta( Sequence ): 
  • lib/galaxy/datatypes/tabular.py

    r1531 r1557  
    1212from galaxy.datatypes import metadata 
    1313from galaxy.datatypes.metadata import MetadataElement 
    14 from galaxy.datatypes.metadata import MetadataAttributes 
    1514 
    1615log = logging.getLogger(__name__) 
  • lib/galaxy/model/__init__.py

    r1543 r1557  
    162162    def get_metadata( self ): 
    163163        if not hasattr( self, '_metadata_collection' ): 
    164             self._metadata_collection = MetadataCollection( self, self.datatype.metadata_spec
     164            self._metadata_collection = MetadataCollection( self
    165165        return self._metadata_collection 
    166166    def set_metadata( self, bunch ): 
     
    193193    def change_datatype( self, new_ext ): 
    194194        self.clear_associated_files() 
    195         if hasattr( self, '_metadata_collection' ): 
    196             del self._metadata_collection 
    197195        datatypes_registry.change_datatype( self, new_ext ) 
    198196    def get_size( self ): 
  • lib/galaxy/tools/__init__.py

    r1553 r1557  
    13141314                if rval is None: 
    13151315                    rval = self.metadata.spec[name].no_value 
    1316                 rval = self.metadata.spec[name].wrap( rval, self.metadata.parent ) 
     1316                rval = self.metadata.spec[name].param.to_string( rval ) 
     1317                setattr( self, name, rval ) #lets store this value, so we don't need to recalculate if needed again 
    13171318            return rval 
    13181319        def __nonzero__( self ): 
  • lib/galaxy/tools/parameters/basic.py

    r1544 r1557  
    831831                if dataset: 
    832832                    for meta_key, meta_dict in filter_value.iteritems(): 
    833                         if ",".join( dataset.metadata.get( meta_key ) ) == meta_dict['value']: 
     833                        if dataset.metadata.spec[meta_key].param.to_string( dataset.metadata.get( meta_key ) ) == meta_dict['value']: 
    834834                            options.extend( meta_dict['options'] ) 
    835835            return options 
  • lib/galaxy/tools/parameters/validation.py

    r1510 r1557  
    252252        if not value: return 
    253253        if hasattr( value, "metadata" ): 
    254             if str( getattr( value.datatype.metadata_spec, self.metadata_name ).wrap( value.metadata.get( self.metadata_name ), value ) ) in self.valid_values: 
     254            if value.metadata.spec[self.metadata_name].param.to_string( value.metadata.get( self.metadata_name ) ) in self.valid_values: 
    255255                return 
    256256        raise ValueError( self.message ) 
  • lib/galaxy/web/controllers/root.py

    r1551 r1557  
    220220             
    221221            # The following for loop will save all metadata_spec items 
    222             for name, spec in data.datatype.metadata_spec.items(): 
     222            for name, spec in data.metadata.spec.items(): 
    223223                if spec.get("readonly"): 
    224224                    continue 
     
    226226                if optional and optional == 'true': 
    227227                    # optional element... == 'true' actually means it is NOT checked (and therefore ommitted) 
    228                     setattr(data.metadata,name,None) 
     228                    setattr(data.metadata, name, None) 
    229229                else: 
    230                     setattr(data.metadata,name,spec.unwrap(p.get(name, None), p)
     230                    setattr( data.metadata, name, spec.unwrap( p.get (name, None) )
    231231 
    232232            data.datatype.after_edit( data ) 
     
    235235        elif p.detect: 
    236236            # The user clicked the Auto-detect button on the 'Edit Attributes' form 
    237             for name, spec in data.datatype.metadata_spec.items(): 
     237            for name, spec in data.metadata.spec.items(): 
    238238                # We need to be careful about the attributes we are resetting 
    239                 if name != 'name' and name != 'info' and name != 'dbkey'
     239                if name not in [ 'name', 'info', 'dbkey' ]
    240240                    if spec.get( 'default' ): 
    241                         setattr( data.metadata,name,spec.unwrap( spec.get( 'default' ), spec )
     241                        setattr( data.metadata, name, spec.unwrap( spec.get( 'default' ) )
    242242            data.datatype.set_meta( data ) 
    243243            data.datatype.after_edit( data ) 
     
    259259            # sets it properly in the metadata 
    260260            data.metadata.dbkey = data.dbkey 
    261         metadata = list() 
    262         # a list of MetadataParemeters 
    263         for name, spec in data.datatype.metadata_spec.items(): 
    264             if spec.visible: 
    265                 metadata.append( spec.wrap( data.metadata.get(name), data ) ) 
    266261        # let's not overwrite the imported datatypes module with the variable datatypes? 
     262        ### the built-in 'id' is overwritten in lots of places as well 
    267263        ldatatypes = [x for x in trans.app.datatypes_registry.datatypes_by_extension.iterkeys()] 
    268264        ldatatypes.sort() 
    269265        trans.log_event( "Opened edit view on dataset %s" % str(id) ) 
    270         return trans.fill_template( "/dataset/edit_attributes.mako", data=data, metadata=metadata, 
     266        return trans.fill_template( "/dataset/edit_attributes.mako", data=data, 
    271267                                    datatypes=ldatatypes, err=None ) 
    272268 
  • templates/dataset/edit_attributes.mako

    r1549 r1557  
    3939            <div style="clear: both"></div> 
    4040          </div>  
    41           %for element in metadata
    42               %if element.display
     41          %for name, spec in data.metadata.spec.items()
     42              %if spec.visible
    4343                <div class="form-row"> 
    4444                  <label> 
    45                       ${element.spec.desc}: 
     45                      ${spec.desc}: 
    4646                  </label> 
    4747                  <div style="float: left; width: 250px; margin-right: 10px;"> 
    48                       ${element.get_html()} 
     48                      ${data.metadata.get_html_by_name( name )} 
    4949                  </div> 
    5050                  <div style="clear: both"></div>