mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
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:
@@ -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 ):
|
||||
"""
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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():
|
||||
|
||||
Reference in New Issue
Block a user