More metadata updates. Also going to change MetadataElement( ... ) to has_metadata, but in the next commit. Edit form coming soon.

This commit is contained in:
Ian Schenck
2007-07-09 16:13:26 +00:00
parent 0b0386b3b6
commit e4e50d6786
4 changed files with 87 additions and 15 deletions
+6 -5
View File
@@ -38,6 +38,12 @@ class Interval( Tabular ):
"""Provide the set of display formats supported by this datatype """
supported_display_apps = ['ucsc']
"""Add metadata elements"""
MetadataElement( name="chromCol" )
MetadataElement( name="startCol" )
MetadataElement( name="endCol" )
MetadataElement( name="strandCol" )
def missing_meta( self, dataset ):
"""Checks for empty meta values"""
for key, value in dataset.metadata.items():
@@ -170,11 +176,6 @@ class Bed( Interval ):
def init_meta( self, dataset, copy_from=None ):
Interval.init_meta( self, dataset, copy_from=copy_from )
dataset.metadata.chromCol = 1
dataset.metadata.startCol = 2
dataset.metadata.endCol = 3
dataset.metadata.strandCol = 6
dataset.mark_metadata_changed()
def set_meta( self, dataset ):
"""
+53 -9
View File
@@ -6,6 +6,12 @@ from cookbook.patterns import Bunch
STATEMENTS = "__galaxy_statements__"
class Statement( object ):
'''
This class inserts its target into a list in the surrounding
class. the data.Data class has a metaclass which executes these
statements. This is how we shove the metadata element spec into
the class.
'''
def __init__( self, target ):
self.target = target
def __call__( self, *args, **kwargs ):
@@ -18,6 +24,12 @@ class Statement( object ):
statement.target( element, *args, **kwargs )
class MetadataSpecCollection( dict ):
'''
A simple extension of dict which allows cleaner access to items
and allows the values to be iterated over directly as if it were a
list. append() is also implemented for simplicity and does not
"append".
'''
def append( self, item ):
self[item.name] = item
def iter( self ):
@@ -26,6 +38,17 @@ class MetadataSpecCollection( dict ):
return self[name]
class MetadataParameter( object ):
def __init__( self, metadata, context ):
'''
The "context" is simply the metadata collection/bunch holding
this piece of metadata. This is passed in to allow for
metadata to validate against each other (note: this could turn
into a huge, recursive mess if not done with care). For
example, a column assignment should validate against the
number of columns in the dataset.
'''
self.metadata = metadata
self.context = context
def marshal( self, value ):
'''
This method should/can be overridden to convert the incomming
@@ -39,8 +62,20 @@ class MetadataParameter( object ):
'''
pass
def get_html_field( self, value=None, other_values={} ):
raise TypeError("Abstract Method")
@classmethod
def build_param( cls, element, context ):
return element.param( element, context )
class MetadataElementSpec( object ):
READONLY = 1
'''
Defines a metadata element and adds it to the metadata_spec (which
is a MetadataSpecCollection) of datatype.
'''
def __init__( self, datatype, name=None, desc=None, param=MetadataParameter, attributes=None, default=None ):
self.name = name
self.desc = desc
@@ -53,6 +88,13 @@ class MetadataElementSpec( object ):
def wrap( self, metadata ):
return self.param(metadata)
# Basic attributes for describing metadata elements
MetadataAttributes = Bunch(
READONLY = 1
)
class MetadataCollection:
"""
MetadataCollection is not a collection at all, but rather a proxy
@@ -68,20 +110,20 @@ class MetadataCollection:
def __iter__(self):
return self.bunch.__iter__()
def get( self, key, default=None ):
if self.spec:
if self.spec.get(name, None):
default = default or self.spec[name].default
return self.bunch.get( key, default )
try:
return self.bunch.get( key, default ) or self.spec[key].default
except:
return default
def items(self):
return self.bunch.items()
return iter( [(k, self.get(k)) for k in self.spec.iterkeys() ] )
def __str__(self):
return self.bunch.__str__()
return dict( self.items() ).__str__()
def __nonzero__(self):
return self.bunch.__nonzero__()
def __getattr__(self, name):
try:
if self.bunch.get( name ):
return self.bunch.get( name )
except AttributeError, e:
else:
if self.spec.get(name, None):
return self.spec[name].default
else:
@@ -94,3 +136,5 @@ class MetadataCollection:
self.bunch = self.parent._metadata = Bunch( **self.bunch.__dict__ )
MetadataElement = Statement(MetadataElementSpec)
+4 -1
View File
@@ -96,7 +96,10 @@ class Registry( object ):
def change_datatype(self, data, ext ):
data.extension = ext
data.init_meta()
# call init_meta and copy metadata from itself. The datatype
# being converted *to* will handle any metadata copying and
# initialization.
data.init_meta( copy_from=data )
if data.has_data():
data.set_peek()
return data
+24
View File
@@ -10,6 +10,7 @@ import data
from galaxy import util
from cgi import escape
from galaxy.datatypes.metadata import MetadataElement
from galaxy.datatypes.metadata import MetadataAttributes
log = logging.getLogger(__name__)
@@ -20,6 +21,29 @@ class Tabular( data.Text ):
"""Provide the set of display formats supported by this datatype """
supported_display_apps = []
MetadataElement( name="columns",
default=0,
desc="Number of columns",
attributes=MetadataAttributes.READONLY )
def init_meta( self, dataset, copy_from=None ):
data.Text.init_meta( self, dataset, copy_from=copy_from )
try:
# This actually doesn't work at the moment. There needs
# to be hooks for the file corresponding to a dataset, so
# that when the file is written and closed, code can be
# run. That is idealy where this block would go.
maxcols = 0
count = 0
for line in open( dataset.file_name ):
count += 1
if count > 1000: break
cols = len( line.split("\t") )
if cols > maxcols: maxcols = cols
setattr( dataset.metadata, "columns", maxcols )
except:
pass
def missing_meta( self, dataset ):
"""Checks for empty meta values"""
for key, value in dataset.metadata.items():