Esempio n. 1
0
class TFile(GangaObject):

    """Test File object with well known equality properties -i.e. Does not reply on proxy!"""

    _category = 'files'
    _exportmethods = ['__eq__', '__cmp__', '__hash__', '__iadd__', '__imul__']
    _name = 'TFile'
    _schema = File._schema.inherit_copy()
    _schema.datadict['added'] = SimpleItem(defvalue=False)
    _schema.datadict['multiplied'] = SimpleItem(defvalue=False)

    def __eq__(self, other):
        if not isType(other, TFile):
            return False
        return self.name == other.name and self.subdir == other.subdir

    def __cmp__(self, other):
        """A hacky but correct cmp function."""
        self_comb = self.name + self.subdir
        other_comb = other.name + other.subdir
        return cmp(self_comb, other_comb)

    def __hash__(self):
        return self.name.__hash__() + self.subdir.__hash__()

    def __iadd__(self, other):
        self.added = True
        return self

    def __imul__(self, other):
        self.multiplied = True
        return self
Esempio n. 2
0
class GListApp(IApplication):
    """Test File object with well known equality properties -i.e. Does not reply on proxy!"""
    # summary_print
    _category = 'applications'
    _exportedmethods = ['configure']
    _name = 'GListApp'
    _schema = Schema(
        Version(1, 0), {
            'bound_print_comp':
            ComponentItem(
                'files',
                defvalue=[],
                sequence=1,
                summary_print='_print_summary_bound_comp',
                typelist=['str', 'Ganga.test.GPI.GangaList.TFile.TFile']),
            'bound_print_simple':
            SimpleItem(defvalue=[],
                       sequence=1,
                       summary_print='_print_summary_bound_simple'),
            'no_summary':
            SimpleItem(defvalue=[],
                       sequence=1,
                       summary_sequence_maxlen=-1,
                       typelist=['str']),
            'seq':
            SimpleItem(defvalue=[], sequence=1, typelist=['int']),
            'gList':
            SimpleItem(defvalue=[], sequence=1, typelist=['str']),
            'gListComp':
            ComponentItem('files', defvalue=[], sequence=1),
            'simple_print':
            SimpleItem(defvalue='',
                       summary_print='_print_summary_simple_print'),
            'comp_print':
            ComponentItem('backends',
                          defvalue=None,
                          summary_print='_print_summary_comp_print')
        })

    def configure(self, master_appconfig):
        return (None, None)

    def _print_summary_bound_comp(self, value, verbosity_level):
        return '_print_summary_bound_comp'

    def _print_summary_bound_simple(self, value, verbosity_level):
        return '_print_summary_bound_simple'

    def _print_summary_simple_print(self, value, verbosity_level):
        return '_print_summary_simple_print'

    def _print_summary_comp_print(self, value, verbosity_level):
        return '_print_summary_comp_print'
Esempio n. 3
0
class Bender(GaudiBase):
    """The Bender application handler

    The user specifies a module file (via Bender.module) which contains a
    Bender python module and the number of events they want to run on
    (via Bender.events).  The user's module is then run on the data by
    calling:

    USERMODULE.configure(EventSelectorInput,FileCatalogCatalogs)
    USERMODULE.run(NUMEVENTS)
    """

    _name = 'Bender'
    _category = 'applications'
    _exportmethods = GaudiBase._exportmethods[:]
    _exportmethods += ['prepare', 'unprepare']

    _schema = GaudiBase._schema.inherit_copy()
    docstr = 'The package the application belongs to (e.g. "Sim", "Phys")'
    _schema.datadict['package'] = SimpleItem(defvalue=None,
                                             typelist=['str', 'type(None)'],
                                             doc=docstr)
    docstr = 'The package where your top level requirements file is read '  \
             'from. Can be written either as a path '  \
             '\"Tutorial/Analysis/v6r0\" or in traditional notation '  \
             '\"Analysis v6r0 Tutorial\"'
    _schema.datadict['masterpackage'] = SimpleItem(
        defvalue=None, typelist=['str', 'type(None)'], doc=docstr)
    docstr = 'Extra options to be passed onto the SetupProject command '\
             'used for configuring the environment. As an example '\
             'setting it to \'--dev\' will give access to the DEV area. '\
             'For full documentation of the available options see '\
             'https://twiki.cern.ch/twiki/bin/view/LHCb/SetupProject'
    _schema.datadict['setupProjectOptions'] = SimpleItem(
        defvalue='', typelist=['str', 'type(None)'], doc=docstr)
    docstr = 'The name of the module to import. A copy will be made ' \
             'at submission time'
    _schema.datadict['module'] = FileItem(preparable=1,
                                          defvalue=File(),
                                          doc=docstr)
    docstr = 'The name of the Gaudi application (Bender)'
    _schema.datadict['project'] = SimpleItem(preparable=1,
                                             defvalue='Bender',
                                             hidden=1,
                                             protected=1,
                                             typelist=['str'],
                                             doc=docstr)
    docstr = 'The number of events '
    _schema.datadict['events'] = SimpleItem(defvalue=-1,
                                            typelist=['int'],
                                            doc=docstr)
    docstr = 'Parameres for module '
    _schema.datadict['params'] = SimpleItem(
        defvalue={},
        typelist=['dict', 'str', 'int', 'bool', 'float'],
        doc=docstr)
    _schema.version.major += 2
    _schema.version.minor += 0

    #def __init__(self):
    #    super(Bender, self).__init__()

    def _get_default_version(self, gaudi_app):
        return guess_version(self, gaudi_app)

    def _auto__init__(self):
        if (not self.appname) and (not self.project):
            self.project = 'Bender'  # default
        if (not self.appname):
            self.appname = self.project
        self._init()

    def _getshell(self):

        import EnvironFunctions
        return EnvironFunctions._getshell(self)

    def prepare(self, force=False):
        super(Bender, self).prepare(force)
        self._check_inputs()

        share_dir = os.path.join(
            expandfilename(getConfig('Configuration')['gangadir']), 'shared',
            getConfig('Configuration')['user'], self.is_prepared.name)
        fillPackedSandbox([self.module],
                          os.path.join(
                              share_dir, 'inputsandbox',
                              '_input_sandbox_%s.tar' % self.is_prepared.name))

        gzipFile(
            os.path.join(share_dir, 'inputsandbox',
                         '_input_sandbox_%s.tar' % self.is_prepared.name),
            os.path.join(share_dir, 'inputsandbox',
                         '_input_sandbox_%s.tgz' % self.is_prepared.name),
            True)

        # add the newly created shared directory into the metadata system if
        # the app is associated with a persisted object
        self.checkPreparedHasParent(self)
        self.post_prepare()
        logger.debug("Finished Preparing Application in %s" % share_dir)

    def master_configure(self):
        return (None, StandardJobConfig())

    def configure(self, master_appconfig):

        # self._configure()
        modulename = split(self.module.name)[-1].split('.')[0]
        script = """
from copy import deepcopy
from Gaudi.Configuration import *
importOptions('data.py')
import %s as USERMODULE
EventSelectorInput = deepcopy(EventSelector().Input)
FileCatalogCatalogs = deepcopy(FileCatalog().Catalogs)
EventSelector().Input=[]
FileCatalog().Catalogs=[]\n""" % modulename

        script_configure = "USERMODULE.configure(EventSelectorInput,FileCatalogCatalogs%s)\n"
        if self.params:
            param_string = ",params=%s" % self.params
        else:
            param_string = ""

        script_configure = script_configure % param_string
        script += script_configure

        script += "USERMODULE.run(%d)\n" % self.events
        script += getXMLSummaryScript()
        # add summary.xml
        outputsandbox_temp = XMLPostProcessor._XMLJobFiles()
        outputsandbox_temp += unique(self.getJobObject().outputsandbox)
        outputsandbox = unique(outputsandbox_temp)

        input_files = []
        input_files += [FileBuffer('gaudipython-wrapper.py', script)]
        logger.debug("Returning StandardJobConfig")
        return (None,
                StandardJobConfig(inputbox=input_files,
                                  outputbox=outputsandbox))

    def _check_inputs(self):
        """Checks the validity of user's entries for GaudiPython schema"""
        # Always check for None OR empty
        #logger.info("self.module: %s" % str(self.module))
        if isType(self.module, str):
            self.module = File(self.module)
        if self.module.name == None:
            raise ApplicationConfigurationError(
                "Application Module not requested")
        elif self.module.name == "":
            raise ApplicationConfigurationError(
                "Application Module not requested")
        else:
            # Always check we've been given a FILE!
            self.module.name = fullpath(self.module.name)
            if not os.path.isfile(self.module.name):
                msg = 'Module file %s not found.' % self.module.name
                raise ApplicationConfigurationError(msg)

    def postprocess(self):
        XMLPostProcessor.postprocess(self, logger)
Esempio n. 4
0
class BenderScript(GaudiBase):    
    """The application handler for BenderScript
    
    The user specifies:
    - script file(s) which contain BenderScript scripts,
    - configuration/Configurables files, to be used for 'importOptions'
    - set of command line arguments
    
    At least one 'script' or 'import' file is required.
    
    The application executes the following line:
    
    bender {scripts} {arguments} --import {imports} --no-color --no-castor --import=data.py --batch
    
    e.g.
    
    bender script1.py  --import import1.py -w -p5 --no-color --no-castor --import=data.py --batch
    
    where data.py a file with input data and xml catalog, automatically generated by Ganga/DIRAC
    
    """
     
    _name           = 'BenderScript'
    _category       = 'applications'
    _exportmethods  = GaudiBase._exportmethods[:]
    _exportmethods += ['prepare', 'unprepare']
    
    _schema = GaudiBase._schema.inherit_copy()
    
    _schema.datadict['package'] = SimpleItem(
        defvalue = None,
        typelist = ['str', 'type(None)'],
        doc      = """The package the application belongs to (e.g. 'Sim', 'Phys')
        """
        )
    _schema.datadict['masterpackage'] = SimpleItem (
        defvalue = None,
        typelist = [ 'str', 'type(None)' ],
        doc      = """The package where your top level requirements file is read from.
        Can be written either as a path 'Tutorial/Analysis/v6r0' or in traditional notation 
        'Analysis v6r0 Tutorial'
        """
        )
    
    _schema.datadict['setupProjectOptions'] = SimpleItem(
        defvalue = ''     ,
        typelist = [ 'str', 'type(None)'],
        doc      = """Extra options to be passed onto the SetupProject command
        used for configuring the environment. As an example 
        setting it to '--dev' will give access to the DEV area. 
        For full documentation of the available options see 
        https://twiki.cern.ch/twiki/bin/view/LHCb/SetupProject
        """
        )
    
    _schema.datadict['scripts'] = FileItem(
        preparable      = 1      ,
        sequence        = 1      ,
        strict_sequence = 0      ,
        defvalue        = []     ,
        doc             = """The names of the script files to execute.
        A copy will be made at submission time
        """
        )
    
    _schema.datadict['imports'] = FileItem (
        preparable      =  1     ,
        sequence        =  1     ,
        strict_sequence =  0     ,
        defvalue        = []     ,
        doc             = """The names of the files to be used for 'importOptions'.
        A copy will be made at submission time
        """
        )
    
    _schema.datadict['commands'] = SimpleItem(
        defvalue = []      ,
        typelist = ['str'] ,
        sequence =  1      ,
        doc      = """The commands to be executed,
        e.g. [ 'run(10)' , 'print ls()' , 'print dir()' ]
        """
        )
    
    _schema.datadict['arguments'] = SimpleItem(
        defvalue = []      ,
        typelist = ['str'] ,
        sequence =  1      ,
        doc      = """List of command-line arguments for bender script,
        e.g. ['-w','-p5'], etc.
        For python scripts and configuration/Configurable files for 'importOptions'
        it is much better to use the separate options 'scripts' and 'imports'
        Following arguments will be appended automatically:  --no-color, --no-castor and --batch
        """
        )
    
    _schema.version.major += 2
    _schema.version.minor += 0
    
    #def __init__(self):
    #    super(BenderScrip, self).__init__()

    def _get_default_version(self, gaudi_app):
        return guess_version(self, gaudi_app)

    def _auto__init__(self):
        if not self.appname : self.appname = 'Bender'
        self._init()

    def _getshell(self):

        import EnvironFunctions
        return EnvironFunctions._getshell(self)

    def prepare(self, force=False):

        super(BenderScript, self).prepare(force)
        self._check_inputs()

        
        share_dir = os.path.join (
            expandfilename ( getConfig('Configuration')['gangadir'] ) ,
            'shared'                            ,
            getConfig('Configuration')['user']  ,
            self.is_prepared.name               )
        
        input_sandbox_tar = os.path.join ( share_dir , 'inputsandbox',
                                           '_input_sandbox_%s.tar' % self.is_prepared.name ) 
        input_sandbox_tgz = os.path.join ( share_dir , 'inputsandbox',
                                           '_input_sandbox_%s.tgz' % self.is_prepared.name ) 
        
        fillPackedSandbox ( self.scripts + self.imports , input_sandbox_tar  ) 
        gzipFile          ( input_sandbox_tar , input_sandbox_tgz , True     )
        
        # add the newly created shared directory into the metadata system if
        # the app is associated with a persisted object
        self.checkPreparedHasParent(self)
        self.post_prepare()
        logger.debug("Finished Preparing Application in %s" % share_dir)

    def master_configure(self):
        return (None, StandardJobConfig())

    def configure(self, master_appconfig):
        
        ## strip leading and trailing blanks from arguments 
        self.arguments = [ a.strip() for a in self.arguments ]

        ## strip leading and trailing blanks from the command 
        self.commands  = [ a.strip() for a in self.commands  ]
        
        ## the script layout
        the_script    = layout.format (
            scripts   = [ os.path.join ( f.subdir , os.path.basename ( f.name ) ) for f in self.scripts ] , 
            imports   = [ os.path.join ( f.subdir , os.path.basename ( f.name ) ) for f in self.imports ] , 
            arguments = self.arguments  ,
            command   = self.commands    
            )

        print 'SCRIPT:\n', the_script
        
        # add summary.xml
        outputsandbox_temp  = XMLPostProcessor._XMLJobFiles()
        outputsandbox_temp += unique(self.getJobObject().outputsandbox)
        outputsandbox       = unique(outputsandbox_temp)
        
        input_files  = []
        input_files += [ FileBuffer('gaudipython-wrapper.py', the_script ) ]
        logger.debug("Returning StandardJobConfig")
        return (None, StandardJobConfig(inputbox=input_files,
                                        outputbox=outputsandbox))
    
    def _check_inputs(self):
        """Checks the validity of user's entries for BenderScript schema"""
        
        if not self.scripts and not self.imports : 
            raise ApplicationConfigurationError("Application scripts/imports are not defined")
        
        if isinstance ( self.scripts , str ) : self.scripts = [ File ( self.scripts ) ]
        if isinstance ( self.imports , str ) : self.imports = [ File ( self.imports ) ]
        
        for f in self.scripts : f.name = fullpath ( f.name )
        for f in self.imports : f.name = fullpath ( f.name )

    
    def postprocess(self):
        XMLPostProcessor.postprocess(self, logger)
Esempio n. 5
0
class GangaList(GangaObject):

    _category = 'internal'
    _exportmethods = [
        '__add__', '__contains__', '__delitem__', '__delslice__', '__eq__',
        '__ge__', '__getitem__', '__getslice__', '__gt__', '__iadd__',
        '__imul__', '__iter__', '__le__', '__len__', '__lt__', '__mul__',
        '__ne__', '__reversed__', '__radd__', '__rmul__', '__setitem__',
        '__setslice__', 'append', 'count', 'extend', 'index', 'insert', 'pop',
        'remove', 'reverse', 'sort', '__hash__', 'get'
    ]
    _hidden = 1
    _enable_plugin = 1
    _name = 'GangaList'
    _schema = Schema(
        Version(1, 0), {
            '_list':
            SimpleItem(
                defvalue=[], doc='The raw list', hidden=1,
                category='internal'),
            '_is_preparable':
            SimpleItem(defvalue=False,
                       doc='defines if prepare lock is checked',
                       hidden=1),
        })
    _enable_config = 1

    def __init__(self):
        self._is_a_ref = False
        super(GangaList, self).__init__()

    # convenience methods
    @staticmethod
    def is_list(obj):
        """
        This returns a boolean as to if this object is a list or not
        Args:
            obj (object): object to be tested against known list types
        """
        result = (obj is not None) and isType(obj, (GangaList, list, tuple))
        return result

    @staticmethod
    def has_proxy_element(_list):
        """
        Returns if a proxy object has crept into the list
        Args:
            _list (list): Any iterable object
        """
        return all([isProxy(l) for l in _list])

    ## Attempt to prevent raw assignment of _list causing Proxied objects to get inside the GangaList
    def _attribute_filter__set__(self, name, value):
        logger.debug("GangaList filter")
        if name == "_list":
            if self.is_list(value):
                if self.has_proxy_element(value):
                    returnable_list = [stripProxy(l) for l in value]
                    my_parent = self._getParent()
                    for elem in returnable_list:
                        if isinstance(elem, GangaObject):
                            elem._setParent(my_parent)
                        return
                    return returnable_list
                else:
                    return value
            elif self._list is None:
                return None
            else:
                raise GangaException(
                    "Attempting to assign a non list item: %s to a GangaList._list!"
                    % str(value))
        else:
            return super(GangaList, self)._attribute_filter__set__(name, value)

    def _on_attribute__set__(self, obj_type, attrib_name):
        if self._is_a_ref is True:
            new_list = []
            for i in self._list:
                if hasattr(i, '_on_attribute__set__'):
                    new_list.append(
                        i._on_attribute__set__(obj_type, attrib_name))
                else:
                    new_list.append(i)

            self._list = new_list
            self._is_a_ref = False
        return self

    def _getParent(self):
        return super(GangaList, self)._getParent()

    def _setParent(self, parent):
        """
        Set the parent of this object and it's children to the given parent
        Args:
            parent (GangaObject): Sets this object as the parent of the list and it's children
        """
        super(GangaList, self)._setParent(parent)
        for elem in self._list:
            if isinstance(elem, GangaObject):
                elem._setParent(parent)

    def get(self, to_match):
        def matching_filter(item):
            if '_list_get__match__' in dir(item):
                return item._list_get__match__(to_match)
            return to_match == item

        return makeGangaListByRef(filter(matching_filter, self._list),
                                  preparable=self._is_preparable)

    def _export_get(self, to_match):
        return addProxy(self.get(stripProxy(to_match)))

    def strip_proxy(self, obj, filter=False):
        """Removes proxies and calls shortcut if needed"""
        def applyFilter(obj, item):
            category = item['category']
            this_filter = allComponentFilters[category]
            filter_obj = this_filter(obj, item)
            if filter_obj is None:
                raise TypeMismatchError('%s is not of type %s.' %
                                        (str(obj), category))
            return filter_obj

        raw_obj = stripProxy(obj)
        # apply a filter if possible
        if filter is True:
            parent = self._getParent()
            item = self.findSchemaParentSchemaEntry(parent)
            if item and item.isA(ComponentItem):  # only filter ComponentItems
                category = item['category']
                if isinstance(raw_obj, GangaObject):
                    if raw_obj._category != category:
                        raw_obj = applyFilter(raw_obj, item)
                    raw_obj._setParent(parent)
                else:
                    raw_obj = applyFilter(raw_obj, item)
        return raw_obj

    def strip_proxy_list(self, obj_list, filter=False):

        if isType(obj_list, GangaList):
            return getProxyAttr(obj_list, '_list')
        result = [self.strip_proxy(l, filter=filter) for l in obj_list]
        return result

    def getCategory(self):
        """Returns a list of categories for the objects in the list. Returns [] for an empty list."""
        def return_cat(elem):
            if hasattr(elem, 'category'):
                return elem._category
            else:
                return type(elem)

        return unique([return_cat(l) for l in self._list])

    def _readonly(self):
        """
        Return if this object is read-only based upon the Schema
        """
        if self._is_preparable and hasattr(self, '_getParent'):
            if self._getParent()._category == 'applications' and hasattr(
                    self._getParent(), 'is_prepared'):
                from Ganga.GPIDev.Lib.File.File import ShareDir
                return (isinstance(self._getParent().is_prepared, ShareDir)
                        or super(GangaList, self)._readonly())
        return super(GangaList, self)._readonly()

    def checkReadOnly(self):
        """Puts a hook in to stop mutable access to readonly jobs."""
        if self._readonly():
            raise ReadOnlyObjectError(
                'object %s is readonly and attribute "%s" cannot be modified now'
                % (repr(self), getName(self)))
        else:
            self._getSessionLock()
            # TODO: BUG: This should only be set _after_ the change has been
            # done! This can lead to data loss!
            self._setDirty()

    # list methods
    # All list methods should be overridden in a way that makes
    # sure that no proxy objects end up in the list, and no
    # unproxied objects make it out.

    def __add__(self, obj_list):
        # Savanah 32342
        if not self.is_list(obj_list):
            raise TypeError('Type %s can not be concatinated to a GangaList' %
                            type(obj_list))

        return makeGangaList(self._list.__add__(
            self.strip_proxy_list(obj_list, True)),
                             preparable=self._is_preparable)

    def _export___add__(self, obj_list):
        self.checkReadOnly()
        return addProxy(self.__add__(obj_list))

    def __contains__(self, obj):
        return self._list.__contains__(self.strip_proxy(obj))

    def __clone__(self):
        """ clone this object in a similar way to copy """
        # TODO deterine if silently calling __copy__ is more correct
        return makeGangaListByRef(_list=copy.copy(self._list),
                                  preparable=self._is_preparable)

    def __copy__(self):
        """Bypass any checking when making the copy"""
        return makeGangaListByRef(_list=copy.copy(self._list),
                                  preparable=self._is_preparable)

    def __delitem__(self, obj):
        self._list.__delitem__(self.strip_proxy(obj))

    def _export___delitem__(self, obj):
        self.checkReadOnly()
        self.__delitem__(obj)

    def __delslice__(self, start, end):
        self._list.__delslice__(start, end)

    def _export___delslice__(self, start, end):
        self.checkReadOnly()
        self.__delslice__(start, end)

    def __deepcopy__(self, memo=None):
        """Bypass any checking when making the copy"""
        #logger.info("memo: %s" % str(memo))
        #logger.info("self.len: %s" % str(len(self._list)))
        if self._list != []:
            return makeGangaListByRef(_list=copy.deepcopy(self._list, memo),
                                      preparable=self._is_preparable)
        else:
            new_list = GangaList()
            new_list._is_preparable = self._is_preparable
            return new_list

    def __getListToCompare(self, input_list):

        # if the arg isn't a list, just give it back
        if not self.is_list(self.strip_proxy(input_list)):
            return input_list

        # setup up the list correctly
        tmp_list = input_list
        if isType(input_list, GangaList):
            # GangaLists should never contain proxied objects so just return the list
            return stripProxy(input_list)._list
        elif isinstance(input_list, tuple):
            tmp_list = list(input_list)

        # Now return the list after stripping any objects of proxies
        return self.strip_proxy_list(tmp_list)

    def __eq__(self, obj_list):
        if obj_list is self:  # identity check
            return True
        return self._list == self.__getListToCompare(obj_list)

    def __ge__(self, obj_list):
        return self._list.__ge__(self.__getListToCompare(obj_list))

    def __getitem__(self, index):
        return self._list.__getitem__(index)

    def _export___getitem__(self, index):
        return addProxy(self.__getitem__(index))

    def __getslice__(self, start, end):
        return makeGangaList(_list=self._list.__getslice__(start, end),
                             preparable=self._is_preparable)

    def _export___getslice__(self, start, end):
        return addProxy(self.__getslice__(start, end))

    def __gt__(self, obj_list):
        return self._list.__gt__(self.strip_proxy_list(obj_list))

    def __hash__(self):
        logger.info("hash")
        result = 0
        for element in result:
            result ^= hash(element)
        return result

    def __iadd__(self, obj_list):
        self._list.__iadd__(self.strip_proxy_list(obj_list, True))
        return self

    def _export___iadd__(self, obj_list):
        self.checkReadOnly()
        return addProxy(self.__iadd__(obj_list))

    def __imul__(self, number):
        self._list.__imul__(number)
        return self

    def _export___imul__(self, number):
        self.checkReadOnly()
        return addProxy(self.__imul__(number))

    def __iter__(self):
        return self._list.__iter__()

    def _export___iter__(self):
        return GangaListIter(iter(self._list))

    def __le__(self, obj_list):
        return self._list.__le__(self.strip_proxy_list(obj_list))

    def __len__(self):
        return len(self._list)

    def __lt__(self, obj_list):
        return self._list.__lt__(self.strip_proxy_list(obj_list))

    def __mul__(self, number):
        return makeGangaList(self._list.__mul__(number),
                             preparable=self._is_preparable)

    def _export___mul__(self, number):
        return addProxy(self.__mul__(number))

    def __ne__(self, obj_list):
        if obj_list is self:  # identity check
            return False
        result = True
        if self.is_list(obj_list):
            result = self._list.__ne__(self.strip_proxy_list(obj_list))
        return result

    def __reversed__(self):
        """Implements the __reversed__ list method introduced in 2.4"""
        return reversed(self._list)

    def _export___reversed__(self):
        return GangaListIter(self.__reversed__())

    def __radd__(self, obj):
        return obj + self._list

    def _export___radd__(self, obj):
        # return the proxied objects
        cp = [i for i in self._export___iter__()]
        return obj + cp

    def __rmul__(self, number):
        return makeGangaList(self._list.__rmul__(number),
                             preparable=self._is_preparable)

    def _export___rmul__(self, number):
        return addProxy(self.__rmul__(number))

    def __setitem__(self, index, obj):
        self._list.__setitem__(index, self.strip_proxy(obj, True))

    def _export___setitem__(self, index, obj):
        self.checkReadOnly()
        self.__setitem__(index, obj)

    def __setslice__(self, start, end, obj_list):
        self._list.__setslice__(start, end,
                                self.strip_proxy_list(obj_list, True))

    def _export___setslice__(self, start, end, obj_list):
        self.checkReadOnly()
        self.__setslice__(start, end, obj_list)

    def __repr__(self):
        #logger.info("__repr__")
        #return self.toString()
        #import traceback
        #traceback.print_stack()
        containsObj = False
        for elem in self._list:
            if isinstance(elem, GangaObject):
                containsObj = True
                break
        if containsObj is False:
            return self.toString()
        else:
            return str("<GangaList at: %s>" % str(hex(abs(id(self)))))
        #return str("<GangaList at: %s>" % str(hex(abs(id(self)))))

    def __str__(self):
        #logger.info("__str__")
        return self.toString()

    def append(self, obj, my_filter=True):
        if isType(obj, GangaList):
            stripped_o = stripProxy(obj)
            stripped_o._setParent(self._getParent())
            self._list.append(stripped_o)
            return
        elem = self.strip_proxy(obj, my_filter)
        list_objs = (list, tuple)
        if isType(elem, GangaObject):
            stripped_e = stripProxy(elem)
            stripped_e._setParent(self._getParent())
            self._list.append(stripped_e)
        elif isType(elem, list_objs):
            new_list = []

            def my_append(_obj):
                if isType(_obj, GangaObject):
                    stripped_o = stripProxy(_obj)
                    stripped_o._setParent(self._getParent())
                    return stripped_o
                else:
                    return _obj

            self._list.append([my_append(l) for l in elem])
        else:
            self._list.append(elem)

    def _export_append(self, obj):
        self.checkReadOnly()
        self.append(obj)

    def count(self, obj):
        return self._list.count(self.strip_proxy(obj))

    def extend(self, ittr):
        for i in ittr:
            self.append(i)

    def _export_extend(self, ittr):
        self.checkReadOnly()
        self.extend(ittr)

    def index(self, obj):
        return self._list.index(self.strip_proxy(obj))

    def insert(self, index, obj):
        if isType(obj, GangaObject):
            stripProxy(obj)._setParent(stripProxy(self)._getParent())
        self._list.insert(index, self.strip_proxy(obj, True))

    def _export_insert(self, index, obj):
        self.checkReadOnly()
        self.insert(index, obj)

    def pop(self, index=-1):
        return self._list.pop(index)

    def _export_pop(self, index=-1):
        self.checkReadOnly()
        return addProxy(self.pop(index))

    def remove(self, obj):
        """
        Remove a given object from a list
        Args:
            obj (unknown): Remove this object from the list if it exists
        """
        self._list.remove(self.strip_proxy(obj))

    def _export_remove(self, obj):
        """
        Remove an object from a list after checking if it's read-only
        Args:
            obj (unknown): Remove this object from the list if it exists
        """
        self.checkReadOnly()
        self.remove(obj)

    def reverse(self):
        self._list.reverse()

    def _export_reverse(self):
        self.checkReadOnly()
        self.reverse()

    def sort(self, cmpfunc=None):
        # TODO: Should comparitor have access to unproxied objects?
        self._list.sort(cmpfunc)

    def _export_sort(self, cmpfunc=None):
        """
        Args:
            compfunc (function): Function to be used in sorting list elements
        """
        self.checkReadOnly()
        self.sort(cmpfunc)

    # now some more ganga specific methods
    def findSchemaParentSchemaEntry(self, parent):
        """Finds the schema entry for this GangaList
        Args:
            parent (GangaObject): This is the parent object which controls this object
        """
        result = None
        if parent and parent._schema:
            for k, v in parent._schema.allItems():
                if getattr(parent, k) is self:
                    result = v
                    break
        return result

    def printSummaryTree(self,
                         level=0,
                         verbosity_level=0,
                         whitespace_marker='',
                         out=sys.stdout,
                         selection='',
                         interactive=False):
        """
        This funtion displays a summary of the contents of this file.
        (Docs from Gaga.GPIDev.Base.Objects # TODO determine how mch of this may be duplicated from there)
        Args:
            level (int): the hierachy level we are currently at in the object tree.
            verbosity_level (int): How verbose the print should be. Currently this is always 0.
            whitespace_marker (str): If printing on multiple lines, this allows the default indentation to be replicated.
                                     The first line should never use this, as the substitution is 'name = %s' % printSummaryTree()
            out (stream): An output stream to print to. The last line of output should be printed without a newline.'
            selection: See VPrinter for an explaintion of this.
            interactive (bool): Is this printing code being called from the interactive IPython prompt?
        """
        parent = self._getParent()
        schema_entry = self.findSchemaParentSchemaEntry(parent)

        if parent is None:
            full_print(self, out)
            return

        if schema_entry:
            self_len = len(self)
            print_summary = schema_entry['summary_print']
            maxLen = schema_entry['summary_sequence_maxlen']

            if print_summary:
                fp = getattr(parent, print_summary)
                str_val = fp(self._list, verbosity_level)
                out.write(str_val)
                return

            if (maxLen != -1) and (self_len > maxLen):
                out.write(decorateListEntries(self_len,
                                              getName(type(self[0]))))
                return
            else:
                summary_print(self, out)
                return

        out.write(str(self._list))
        return

    def toString(self):
        """Returns a simple str of the _list."""
        returnable_str = "["
        for element in self._list:
            if isType(element, GangaObject):
                returnable_str += repr(stripProxy(element))
            else:
                returnable_str += "'"
                returnable_str += str(stripProxy(element))
                returnable_str += "'"
            returnable_str += ", "
        returnable_str += "]"
        return returnable_str

    @synchronised
    def accept(self, visitor):
        """
        accept a visitor pattern - overrides GangaObject because we need to process _list as a ComponentItem in this
        case to allow save/load of nested lists to work.
        Could just get away with SimpleItem checks here but have included Shared and Component just in case these
        are added in the future

        # TODO investigate if it's possible to call GangaObject.accept for 90% of this functionality rather than duplicating it here

        This accepts a VPrinter or VStreamer class instance visitor which is used to display the contents of the object according the Schema
        Args:
            visitor (VPrinter, VStreamer): An instance which will produce a display of this contents of this object
        """
        visitor.nodeBegin(self)

        for (name, item) in self._schema.simpleItems():
            if name == "_list":
                visitor.componentAttribute(self, name, getattr(self, name), 1)
            elif item['visitable']:
                visitor.simpleAttribute(self, name, getattr(self, name),
                                        item['sequence'])

        for (name, item) in self._schema.sharedItems():
            if item['visitable']:
                visitor.sharedAttribute(self, name, getattr(self, name),
                                        item['sequence'])

        for (name, item) in self._schema.componentItems():
            if item['visitable']:
                visitor.componentAttribute(self, name, getattr(self, name),
                                           item['sequence'])

        visitor.nodeEnd(self)

    def _setFlushed(self):
        """Set flushed like the Node but do the _list by hand to avoid problems"""
        self._dirty = False
        for elem in self._list:
            if isinstance(elem, Node):
                elem._setFlushed()
        super(GangaList, self)._setFlushed()
Esempio n. 6
0
class GListApp(IPrepareApp):
    """Test File object with well known equality properties -i.e. Does not reply on proxy!"""
    # summary_print
    _category = 'applications'
    _exportedmethods = ['configure']
    _name = 'GListApp'
    _schema = Schema(
        Version(1, 0), {
            'bound_print_comp':
            ComponentItem(
                'files',
                defvalue=[],
                sequence=1,
                summary_print='_print_summary_bound_comp',
                typelist=['str', 'Ganga.test.GPI.GangaList.TFile.TFile']),
            'bound_print_simple':
            SimpleItem(defvalue=[],
                       sequence=1,
                       summary_print='_print_summary_bound_simple'),
            'no_summary':
            SimpleItem(defvalue=[],
                       sequence=1,
                       summary_sequence_maxlen=-1,
                       typelist=['str']),
            'seq':
            SimpleItem(defvalue=[], sequence=1, typelist=['int']),
            'gList':
            SimpleItem(defvalue=[], sequence=1, typelist=['str']),
            'gListComp':
            ComponentItem('files', defvalue=[], sequence=1),
            'simple_print':
            SimpleItem(defvalue='',
                       summary_print='_print_summary_simple_print'),
            'comp_print':
            ComponentItem('backends',
                          defvalue=None,
                          summary_print='_print_summary_comp_print'),
            'is_prepared':
            SimpleItem(
                defvalue=None,
                strict_sequence=0,
                visitable=1,
                copyable=1,
                hidden=0,
                typelist=['type(None)', 'bool', ShareDir],
                protected=0,
                comparable=1,
                doc=
                'Location of shared resources. Presence of this attribute implies the application has been prepared.'
            ),
        })

    def configure(self, master_appconfig):
        return (None, None)

    def _print_summary_bound_comp(self, value, verbosity_level):
        return '_print_summary_bound_comp'

    def _print_summary_bound_simple(self, value, verbosity_level):
        return '_print_summary_bound_simple'

    def _print_summary_simple_print(self, value, verbosity_level):
        return '_print_summary_simple_print'

    def _print_summary_comp_print(self, value, verbosity_level):
        return '_print_summary_comp_print'
Esempio n. 7
0
class GangaList(GangaObject):

    _category = 'internal'
    _exportmethods = [
        '__add__', '__contains__', '__delitem__', '__delslice__', '__eq__',
        '__ge__', '__getitem__', '__getslice__', '__gt__', '__iadd__',
        '__imul__', '__iter__', '__le__', '__len__', '__lt__', '__mul__',
        '__ne__', '__reversed__', '__radd__', '__rmul__', '__setitem__',
        '__setslice__', 'append', 'count', 'extend', 'index', 'insert', 'pop',
        'remove', 'reverse', 'sort', '__hash__', 'get'
    ]
    _hidden = 1
    _enable_plugin = 1
    _name = 'GangaList'
    _schema = Schema(
        Version(1, 0), {
            '_list':
            ComponentItem(
                defvalue=[], doc='The raw list', hidden=1,
                category='internal'),
            '_is_preparable':
            SimpleItem(defvalue=False,
                       doc='defines if prepare lock is checked',
                       hidden=1),
        })
    _enable_config = 1
    _data = {}

    def __init__(self):
        self._is_a_ref = False
        super(GangaList, self).__init__()

    def __construct__(self, args):

        #super(GangaList, self).__construct__(args)

        if len(args) == 1:
            if isType(args[0], (len, GangaList, tuple)):
                for element_i in args[0]:
                    self._list.expand(self.strip_proxy(element_i))
            elif args[0] is None:
                self._list = None
            else:
                raise GangaException(
                    "Construct: Attempting to assign a non list item: %s to a GangaList._list!"
                    % str(args[0]))
        else:
            super(GangaList, self).__construct__(args)

        return

    # convenience methods
    @staticmethod
    def is_list(obj):
        result = (obj is not None) and isType(obj, (GangaList, list, tuple))
        return result

    @staticmethod
    def has_proxy_element(_list):
        return all([isProxy(element) for element in _list])

    ## Attempt to prevent raw assignment of _list causing Proxied objects to get inside the GangaList
    def _attribute_filter__set__(self, name, value):
        logger.debug("GangaList filter")
        if name == "_list":
            if self.is_list(value):
                if self.has_proxy_element(value):
                    returnable_list = [
                        stripProxy(element) for element in value
                    ]
                    for elem in returnable_list:
                        if isType(elem, GangaObject):
                            elem._setParent(self._getParent())
                    return returnable_list
                else:
                    return value
            elif self._list is None:
                return None
            else:
                raise GangaException(
                    "Attempting to assign a non list item: %s to a GangaList._list!"
                    % str(value))
        else:
            return super(GangaList, self)._attribute_filter__set__(name, value)

    def _on_attribute__set__(self, obj_type, attrib_name):
        if self._is_a_ref is True:
            new_list = []
            for i in self._list:
                if hasattr(i, '_on_attribute__set__'):
                    new_list.append(
                        i._on_attribute__set__(obj_type, attrib_name))
                    continue
                new_list.append(i)
            self._list = new_list
            self._is_a_ref = False
        return self

    def _getParent(self):
        return super(GangaList, self)._getParent()

    def _setParent(self, parent):
        super(GangaList, self)._setParent(parent)
        for element in self._list:
            if isType(element, GangaObject):
                stripProxy(element)._setParent(parent)

    def get(self, to_match):
        def matching_filter(item):
            if '_list_get__match__' in dir(item):
                return item._list_get__match__(to_match)
            return to_match == item

        return makeGangaListByRef(filter(matching_filter, self._list),
                                  preparable=self._is_preparable)

    def _export_get(self, to_match):
        return addProxy(self.get(stripProxy(to_match)))

    def strip_proxy(self, obj, filter=False):
        """Removes proxies and calls shortcut if needed"""
        def applyFilter(obj, item):
            category = item['category']
            this_filter = allComponentFilters[category]
            filter_obj = this_filter(obj, item)
            if filter_obj is None:
                raise TypeMismatchError('%s is not of type %s.' %
                                        (str(obj), category))
            return filter_obj

        raw_obj = stripProxy(obj)
        # apply a filter if possible
        if filter is True:
            parent = self._getParent()
            item = self.findSchemaParentSchemaEntry(parent)
            if item and item.isA(ComponentItem):  # only filter ComponentItems
                category = item['category']
                if isType(raw_obj, GangaObject):
                    if raw_obj._category != category:
                        raw_obj = applyFilter(raw_obj, item)
                    raw_obj._setParent(parent)
                else:
                    raw_obj = applyFilter(raw_obj, item)
        return raw_obj

    def strip_proxy_list(self, obj_list, filter=False):

        if isType(obj_list, GangaList):
            return getProxyAttr(obj_list, '_list')
        result = []
        for o in obj_list:
            result.append(self.strip_proxy(o, filter))
        return result

    def getCategory(self):
        """Returns a list of categories for the objects in the list. Returns [] for an empty list."""

        result = []
        for o in self._list:
            if hasattr(stripProxy(o), 'category'):
                category = o._category
                if not category in result:
                    result.append(category)
            else:
                result.append(type(o))
        return result

    def _readonly(self):
        if self._is_preparable and hasattr(self, '_getParent'):
            if self._getParent()._category == 'applications' and hasattr(
                    self._getParent(), 'is_prepared'):
                from Ganga.GPIDev.Lib.File.File import ShareDir
                return (isType(self._getParent().is_prepared, ShareDir)
                        or super(GangaList, self)._readonly())
        return super(GangaList, self)._readonly()

    def checkReadOnly(self):
        """Puts a hook in to stop mutable access to readonly jobs."""
        if self._readonly():
            raise ReadOnlyObjectError(
                'object %s is readonly and attribute "%s" cannot be modified now'
                % (repr(self), getName(self)))
        else:
            self._getWriteAccess()
            # TODO: BUG: This should only be set _after_ the change has been
            # done! This can lead to data loss!
            self._setDirty()

    # list methods
    # All list methods should be overridden in a way that makes
    # sure that no proxy objects end up in the list, and no
    # unproxied objects make it out.

    def __add__(self, obj_list):
        # Savanah 32342
        if not self.is_list(obj_list):
            raise TypeError('Type %s can not be concatinated to a GangaList' %
                            type(obj_list))

        return makeGangaList(self._list.__add__(
            self.strip_proxy_list(obj_list, True)),
                             preparable=self._is_preparable)

    def _export___add__(self, obj_list):
        self.checkReadOnly()
        return addProxy(self.__add__(obj_list))

    def __contains__(self, obj):
        return self._list.__contains__(self.strip_proxy(obj))


#    def __clone__(self):
#        return makeGangaListByRef(_list=copy.copy(self._list), preparable=self._is_preparable)

    def __copy__(self):
        """Bypass any checking when making the copy"""
        return makeGangaListByRef(_list=copy.copy(self._list),
                                  preparable=self._is_preparable)

    def __delitem__(self, obj):
        self._list.__delitem__(self.strip_proxy(obj))

    def _export___delitem__(self, obj):
        self.checkReadOnly()
        self.__delitem__(obj)

    def __delslice__(self, start, end):
        self._list.__delslice__(start, end)

    def _export___delslice__(self, start, end):
        self.checkReadOnly()
        self.__delslice__(start, end)

    def __deepcopy__(self, memo):
        """Bypass any checking when making the copy"""
        #logger.info("memo: %s" % str(memo))
        #logger.info("self.len: %s" % str(len(self._list)))
        if self._list != []:
            return makeGangaListByRef(_list=copy.deepcopy(self._list),
                                      preparable=self._is_preparable)
        else:
            new_list = GangaList()
            new_list._is_preparable = self._is_preparable
            return new_list
        #super(GangaList, self).__deepcopy__(memo)

    @staticmethod
    def __getListToCompare(input_list):
        if isType(input_list, GangaList):
            return stripProxy(input_list)._list
        elif isinstance(input_list, tuple):
            return list(input_list)
        else:
            return input_list

    def __eq__(self, obj_list):
        if obj_list is self:  # identity check
            return True
        return self._list == self.__getListToCompare(obj_list)

    def __ge__(self, obj_list):
        return self._list.__ge__(self.__getListToCompare(obj_list))

    def __getitem__(self, index):
        return self._list.__getitem__(index)

    def _export___getitem__(self, index):
        return addProxy(self.__getitem__(index))

    def __getslice__(self, start, end):
        return makeGangaList(_list=self._list.__getslice__(start, end),
                             preparable=self._is_preparable)

    def _export___getslice__(self, start, end):
        return addProxy(self.__getslice__(start, end))

    def __gt__(self, obj_list):
        return self._list.__gt__(self.strip_proxy_list(obj_list))

    def __hash__(self):
        logger.info("hash")
        result = 0
        for element in self:
            result ^= hash(element)
        return result
        # return self._list.__hash__()

    def __iadd__(self, obj_list):
        self._list.__iadd__(self.strip_proxy_list(obj_list, True))
        return self

    def _export___iadd__(self, obj_list):
        self.checkReadOnly()
        return addProxy(self.__iadd__(obj_list))

    def __imul__(self, number):
        self._list.__imul__(number)
        return self

    def _export___imul__(self, number):
        self.checkReadOnly()
        return addProxy(self.__imul__(number))

    def __iter__(self):
        return self._list.__iter__()

    def _export___iter__(self):
        return GangaListIter(iter(self._list))

    def __le__(self, obj_list):
        return self._list.__le__(self.strip_proxy_list(obj_list))

    def __len__(self):
        return len(self._list)

    def __lt__(self, obj_list):
        return self._list.__lt__(self.strip_proxy_list(obj_list))

    def __mul__(self, number):
        return makeGangaList(self._list.__mul__(number),
                             preparable=self._is_preparable)

    def _export___mul__(self, number):
        return addProxy(self.__mul__(number))

    def __ne__(self, obj_list):
        if obj_list is self:  # identity check
            return True
        result = True
        if self.is_list(obj_list):
            result = self._list.__ne__(self.strip_proxy_list(obj_list))
        return result

    def __reversed__(self):
        """Implements the __reversed__ list method introduced in 2.4"""
        return reversed(self._list)

    def _export___reversed__(self):
        return GangaListIter(self.__reversed__())

    def __radd__(self, obj):
        return obj + self._list

    def _export___radd__(self, obj):
        # return the proxied objects
        cp = []
        for i in self._export___iter__():
            cp.append(i)
        return obj + cp

    def __rmul__(self, number):
        return makeGangaList(self._list.__rmul__(number),
                             preparable=self._is_preparable)

    def _export___rmul__(self, number):
        return addProxy(self.__rmul__(number))

    def __setitem__(self, index, obj):
        self._list.__setitem__(index, self.strip_proxy(obj, True))

    def _export___setitem__(self, index, obj):
        self.checkReadOnly()
        self.__setitem__(index, obj)

    def __setslice__(self, start, end, obj_list):
        self._list.__setslice__(start, end,
                                self.strip_proxy_list(obj_list, True))

    def _export___setslice__(self, start, end, obj_list):
        self.checkReadOnly()
        self.__setslice__(start, end, obj_list)

    def __repr__(self):
        #logger.info("__repr__")
        #return self.toString()
        #import traceback
        #traceback.print_stack()
        containsObj = False
        for elem in self._list:
            if isType(elem, GangaObject):
                containsObj = True
                break
        if containsObj is False:
            return self.toString()
        else:
            return str("<GangaList at: %s>" % str(hex(abs(id(self)))))
        #return str("<GangaList at: %s>" % str(hex(abs(id(self)))))

    def __str__(self):
        #logger.info("__str__")
        return self.toString()

    def append(self, obj, my_filter=True):
        if isType(obj, GangaList):
            self._list.append(obj._list)
            return
        elem = self.strip_proxy(obj, my_filter)
        list_objs = (list, tuple)
        if isType(elem, GangaObject):
            stripProxy(elem)._setParent(self._getParent())
            self._list.append(elem)
        elif isinstance(elem, list_objs):
            new_list = []
            for _obj in elem:
                if isType(_obj, GangaObject):
                    new_list.append(stripProxy(_obj))
                    stripProxy(_obj)._setParent(self._getParent())
                else:
                    new_list.append(_obj)
            self._list.append(new_list)
        else:
            self._list.append(elem)

    def _export_append(self, obj):
        self.checkReadOnly()
        self.append(obj)

    def count(self, obj):
        return self._list.count(self.strip_proxy(obj))

    def extend(self, ittr):
        for i in ittr:
            self.append(i)

    def _export_extend(self, ittr):
        self.checkReadOnly()
        self.extend(ittr)

    def index(self, obj):
        return self._list.index(self.strip_proxy(obj))

    def insert(self, index, obj):
        if isType(obj, GangaObject):
            stripProxy(obj)._setParent(stripProxy(self)._getParent())
        self._list.insert(index, self.strip_proxy(obj, True))

    def _export_insert(self, index, obj):
        self.checkReadOnly()
        self.insert(index, obj)

    def pop(self, index=-1):
        return self._list.pop(index)

    def _export_pop(self, index=-1):
        self.checkReadOnly()
        return addProxy(self.pop(index))

    def remove(self, obj):
        self._list.remove(self.strip_proxy(obj))

    def _export_remove(self, obj):
        self.checkReadOnly()
        self.remove(obj)

    def reverse(self):
        self._list.reverse()

    def _export_reverse(self):
        self.checkReadOnly()
        self.reverse()

    def sort(self, cmpfunc=None):
        # TODO: Should comparitor have access to unproxied objects?
        self._list.sort(cmpfunc)

    def _export_sort(self, cmpfunc=None):
        self.checkReadOnly()
        self.sort(cmpfunc)

    # now some more ganga specific methods
    def findSchemaParentSchemaEntry(self, parent):
        """Finds the schema entry for this GangaList"""
        result = None
        if parent and parent._schema:
            for k, v in parent._schema.allItems():
                if getattr(parent, k) is self:
                    result = v
                    break
        return result

    def printSummaryTree(self,
                         level=0,
                         verbosity_level=0,
                         whitespace_marker='',
                         out=sys.stdout,
                         selection='',
                         interactive=False):
        parent = self._getParent()
        schema_entry = self.findSchemaParentSchemaEntry(parent)

        if parent is None:
            full_print(self, out)
            return

        if schema_entry:
            self_len = len(self)
            print_summary = schema_entry['summary_print']
            maxLen = schema_entry['summary_sequence_maxlen']

            if print_summary:
                fp = getattr(parent, print_summary)
                str_val = fp(self._list, verbosity_level)
                out.write(str_val)
                return

            if (maxLen != -1) and (self_len > maxLen):
                out.write(decorateListEntries(self_len,
                                              getName(type(self[0]))))
                return
            else:
                summary_print(self, out)
                return

        out.write(str(self._list))
        return

    def toString(self):
        """Returns a simple str of the _list."""
        returnable_str = "["
        for element in self._list:
            if isType(element, GangaObject):
                returnable_str += repr(stripProxy(element))
            else:
                returnable_str += "'"
                returnable_str += str(stripProxy(element))
                returnable_str += "'"
            returnable_str += ", "
        returnable_str += "]"
        return returnable_str
Esempio n. 8
0
class AMIDataset(DQ2Dataset):
    '''ATLAS DDM Dataset With AMI Connection'''

    _category = 'datasets'
    _name = 'AMIDataset'

    _schema = DQ2Dataset._schema.inherit_copy()
    _schema.datadict['logicalDatasetName'] = SimpleItem(defvalue='', doc='')
    _schema.datadict['project'] = SimpleItem(defvalue='Atlas_Production',
                                             doc='')
    _schema.datadict['processingStep'] = SimpleItem(
        defvalue='Atlas_Production', doc='')
    _schema.datadict['amiStatus'] = SimpleItem(defvalue='VALID', doc='')
    _schema.datadict['entity'] = SimpleItem(defvalue='dataset', doc='')
    _schema.datadict['metadata'] = SimpleItem(defvalue={}, doc="Metadata")
    _schema.datadict['provenance'] = SimpleItem(defvalue=[],
                                                typelist=['str'],
                                                sequence=1,
                                                doc='Dataset provenance chain')
    _schema.datadict['goodRunListXML'] = FileItem(
        doc='GoodRunList XML file to search on')

    _exportmethods = [
        'search', 'fill_provenance', 'get_datasets_metadata',
        'get_files_metadata', 'get_contents'
    ]

    def __init__(self):
        super(AMIDataset, self).__init__()

    def fill_provenance(self, extraargs=[]):

        dataType = ""
        if (len(extraargs) > 1):
            dataType = extraargs[1]

        self.provenance = []

        for d in self.dataset:

            logger.info("Filling provenance info for dataset %s...", d)

            prov = []
            self.provenance.append(prov)

            ds = d[:-1]

            argument = []
            argument.append("ListDatasetProvenance")
            argument.append("logicalDatasetName=" + ds)
            argument.append('-output=xml')

            result = amiclient.execute(argument)

            dom = result.getAMIdom()
            graph = dom.getElementsByTagName('graph')
            nFound = 0
            dictOfLists = {}
            for line in graph:
                nodes = line.getElementsByTagName('node')
                for node in nodes:
                    level = int(node.attributes['level'].value)
                    dataset = node.attributes['name'].value
                    if (len(dataType) > 0) and (dataset.find(dataType) >= 0):
                        # print only selected dataType
                        levelList = dictOfLists.get(level, [])
                        levelList.append(dataset)
                        dictOfLists[level] = levelList
                        nFound = nFound + 1
                    elif (len(dataType) == 0):
                        #print everything
                        levelList = dictOfLists.get(level, [])
                        levelList.append(dataset)
                        dictOfLists[level] = levelList
                        #print level,dictOfLists[level]
                        nFound = nFound + 1
            if (nFound == 0) and (len(dataType) > 0):
                logger.warning("No datasets found of type", dataType)
            else:
                keys = dictOfLists.keys()

                keys.sort()

                for key in keys:
                    datasetList = dictOfLists.get(key)
                    datasetList.sort()
                    #print "generation =",key
                    #for dataset in datasetList:
                    #    print " ",dataset
                    for dataset in datasetList:
                        prov.append("%s/" % dataset.strip())

    def search(self,
               pattern='',
               maxresults=config['MaxNumOfDatasets'],
               extraargs=[]):

        argument = []
        dsetList = []

        if self.goodRunListXML.name != '':

            # open the GRL
            if os.path.exists(self.goodRunListXML.name):
                logger.info("Good Run List '%s' file selected" %
                            self.goodRunListXML.name)
                grl_text = open(self.goodRunListXML.name).read()
            else:
                logger.error('Could not read Good Run List XML file')
                return []

            argument = []
            argument.append("GetGoodDatasetList")
            argument.append("prodStep=merge")
            #argument.append("dataType=%s" % self.dataType)
            argument.append("goodRunList=%s" % grl_text)
            argument.append("logicalDatasetName=%s" % self.logicalDatasetName)

        elif self.logicalDatasetName:
            pattern = self.logicalDatasetName

            pattern = pattern.replace("/", "")
            pattern = pattern.replace('*', '%')
            limit = "0,%d" % config['MaxNumOfDatasets']

            argument.append("SearchQuery")
            argument.append("entity=" + self.entity)

            argument.append(
                "glite=SELECT logicalDatasetName WHERE amiStatus='" +
                self.amiStatus + "' AND logicalDatasetName like '" + pattern +
                "' LIMIT " + limit)

            argument.append("project=" + self.project)
            argument.append("processingStep=" + self.processingStep)
            argument.append("mode=defaultField")
            argument.extend(extraargs)

        else:
            logger.error(
                "AMI search not set up correctly. No datasetname or good runs list supplied."
            )
            return []

        try:
            result = amiclient.execute(argument)
            if argument[0] == "GetGoodDatasetList":
                # GRL has different output
                res_text = result.output()
                dsetList = []
                for ln in res_text.split('\n'):
                    if ln.find("logicalDatasetName") != -1:
                        # add to the dataset list - check container...
                        if resolve_dataset_name(ln.split('=')[1].strip()):
                            dsetList.append(ln.split('=')[1].strip() + "/")
                        else:
                            dsetList.append(ln.split('=')[1].strip())

            else:
                resultDict = result.getDict()
                resultByRow = resultDict['Element_Info']
                for row, vals in resultByRow.iteritems():
                    dsName = str(vals['logicalDatasetName'])
                    # check with DQ2 since AMI doesn't store /
                    if resolve_dataset_name(dsName):
                        dsName += '/'
                    dsetList.append(dsName)

        except Exception as msg:
            logger.error(msg)

        return dsetList

    def get_datasets_metadata(self):
        datasets = self.search()
        metadata = []

        for dataset in datasets:
            dataset = dataset.replace("/", "")
            tmp = get_metadata(dataset=dataset)
            metadata.append(tmp)

        return metadata

    def get_files_metadata(self, all=False):
        datasets = self.search()
        metadata = {}

        for dataset in datasets:
            dataset = dataset.replace("/", "")
            job = self._getParent()
            file_info = get_file_metadata(dataset=dataset,
                                          all=all,
                                          numevtsperfile=0)
            metadata.update(file_info)

        return metadata