Beispiel #1
0
class ProxiesDict(CaselessDefaultDict,Object): 
    ''' 
    Dictionary that stores PyTango.DeviceProxies/AttributeProxies
    
    It is like a normal dictionary but creates a new proxy each time 
        that the "get" method is called
        
    All keys translated to full tango URIs (fqdn=True by default)
        
    An earlier version is used in PyTangoArchiving.utils module
    
    Taurus3+ support is not tested
    '''
    def __init__(self,use_tau = False, tango_host = ''):
        self.log = Logger('ProxiesDict')
        self.log.setLogLevel('INFO')
        self.use_tau = TAU and use_tau
        self.tango_host = tango_host
        self.call__init__(CaselessDefaultDict,self.__default_factory__)
        
    def translate(self, dev):
        try:
            attr = get_attr_name(dev,False)
            if self.tango_host and ':' not in dev:
                dev = self.tango_host + '/' + dev            
            dev = get_dev_name(dev,full=True,fqdn=True).lower()
        except:
            dev = get_dev_name(dev,full=True,fqdn=False).lower()
        if attr:
            dev += '/'+attr
        return dev

    def __default_factory__(self,dev_name):
        '''
        Called by defaultdict_fromkey.__missing__ method
        If a key doesn't exists this method is called and 
        returns a proxy for a given device.
        If the proxy caused an exception (usually because device 
        doesn't exists) a None value is returned
        '''
        
        dev_name = self.translate(dev_name)
            
        if dev_name not in self.keys():
            self.log.debug( 'Getting a Proxy for %s'%dev_name)
            
            try:
                devklass,attrklass = (TAU.Device,TAU.Attribute) \
                    if self.use_tau else \
                    (PyTango.DeviceProxy,PyTango.AttributeProxy)
                klass = (devklass,attrklass)[get_attr_name(dev_name,False)]
                dev = klass(dev_name)
                
            except Exception,e:
                print('ProxiesDict: %s doesnt exist!'%dev_name)
                dev = None
        return dev
Beispiel #2
0
class ProxiesDict(CaselessDefaultDict,Object): 
    ''' Dictionary that stores PyTango.DeviceProxies
    It is like a normal dictionary but creates a new proxy each time 
        that the "get" method is called
    An earlier version is used in PyTangoArchiving.utils module
    This class must be substituted by Tau.Core.TauManager().getFactory()()
    '''
    def __init__(self,use_tau = False, tango_host = ''):
        self.log = Logger('ProxiesDict')
        self.log.setLogLevel('INFO')
        self.use_tau = TAU and use_tau
        self.tango_host = tango_host
        self.call__init__(CaselessDefaultDict,self.__default_factory__)

    def __default_factory__(self,dev_name):
        '''
        Called by defaultdict_fromkey.__missing__ method
        If a key doesn't exists this method is called and 
        returns a proxy for a given device.
        If the proxy caused an exception (usually because device 
        doesn't exists) a None value is returned
        '''
        
        if self.tango_host and ':' not in dev_name:
            dev_name = self.tango_host + '/' + dev_name
            
        if dev_name not in self.keys():
            self.log.debug( 'Getting a Proxy for %s'%dev_name)
            
            try:
                devklass,attrklass = (TAU.Device,TAU.Attribute) \
                    if self.use_tau else \
                    (PyTango.DeviceProxy,PyTango.AttributeProxy)
                dev = (attrklass if 
                    str(dev_name).count('/')==(4 if ':' in dev_name else 3) 
                    else devklass)(dev_name)
            except Exception,e:
                print('ProxiesDict: %s doesnt exist!'%dev_name)
                dev = None
        return dev
Beispiel #3
0
class ServersDict(CaselessDict, Object):
    ''' 
    Dictionary of TServer classes indexed by server/instance names and loaded using wildcard expressions.
    Provides Jive/Astor functionality to a list of servers and allows to select/start/stop them by host, class or devices
    Its purpose is to allow generic start/stop of lists of Tango DeviceServers.
    This methods of selection provide new ways of search apart of Jive-like selection.
       
    @attention Dict keys are lower case, to get the real server name each key returns a TServer object with a .name attribute
    
    @par Usage:
    <pre>
    from fandango import Astor
    astor = Astor()
    astor.load_by_name('snap*')
    astor.keys()
      ['snapmanager/1', 'snaparchiver/1', 'snapextractor/1']
    server = astor['snaparchiver/1']
    server.get_device_list()
        ['dserver/snaparchiver/1', 'archiving/snaparchiver/1']
    astor.states()
    server.get_all_states()
        dserver/snaparchiver/1: ON
        archiving/snaparchiver/1: ON
     astor.get_device_host('archiving/snaparchiver/1')
        palantir01
     astor.stop_servers('snaparchiver/1')
     astor.stop_all_servers()
     astor.start_servers('snaparchiver/1','palantir01',wait=1000)
     astor.set_server_level('snaparchiver/1','palantir01',4)

     #Setting the polling of a device:
     server = astor['PySignalSimulator/bl11']
     for dev_name in server.get_device_list():
         dev = server.get_device(dev_name)
         attrs = dev.get_attribute_list()
         [dev.poll_attribute(attr,3000) for attr in attrs] 
     </pre>
    '''
    def __init__(self,
                 pattern='',
                 klass='',
                 devs_list='',
                 servers_list='',
                 hosts='',
                 loadAll=False,
                 log='WARNING',
                 logger=None,
                 tango_host=''):
        ''' def __init__(self,pattern='', klass='',devs_list='',servers_list=''):
        The ServersDict can be initialized using any of the three argument lists or a wildcard for Database.get_server_list(pattern) 
        ServersDict('*') can be used to load all servers in database
        '''
        self.call__init__(CaselessDict, self)
        if logger is None:
            self.log = Logger('ServersDict')
            self.log.setLogLevel(log)
        else:
            self.log = logger
        self.log.debug('ServersDict(%s)' % ','.join(
            map(str, (pattern, klass, devs_list, servers_list, hosts, loadAll,
                      log, logger, tango_host))))

        ## proxies will keep a list of persistent device proxies
        self.proxies = ProxiesDict(tango_host=tango_host)
        ## db will keep a persistent link to PyTango database
        self.db = get_database() if not tango_host else get_database(
            *(tango_host.split(':')))
        self.server_names = self.keys
        self.servers = self.values

        if loadAll: self.load_all_servers()
        elif klass: self.load_by_class(klass)
        elif devs_list: self.load_from_devs_list(devs_list)
        elif servers_list:
            self.load_from_servers_list(servers_list)
            #elif pattern: self.load_from_servers_list(self.db.get_server_list(pattern))
        elif hosts:
            hosts = type(hosts) is str and (',' in hosts and hosts.split(',')
                                            or [hosts]) or hosts
            for h in hosts:
                self.load_by_host(h)
        elif pattern:
            self.load_by_name(pattern)
        #dict.__init__(self)

    ## @name Dict methods
    # @{

    def __arranged_key(self, key):
        return key if key.count('/') <= 1 else key.split('/', 1)[1]

    #def __getitem__(self,key): dicts.CaselessDict.__getitem__(self,self.__arranged_key(key))
    #def __setitem__(self,key,value): dicts.CaselessDict.__setitem__(self,self.__arranged_key(key),value)
    #def __delitem__(self,key): dicts.CaselessDict.__delitem__(self,self.__arranged_key(key))
    #def __contains__(self,key): dicts.CaselessDict.__contains__(self,self.__arranged_key(key))
    #def has_key(self,key): dicts.CaselessDict.has_key(self,self.__arranged_key(key))
    #def get(self,key,def_val=None): dicts.CaselessDict.get(self,self.__arranged_key(key),def_val)
    #def pop(self,key,def_val=None): dicts.CaselessDict.pop(self,self.__arranged_key(key),def_val)
    #def setdefault(self,key,def_val=None): dicts.CaselessDict.pop(self,self.__arranged_key(key),def_val)

    def __repr__(self):
        return self.get_report()

    def __str__(self):
        return self.get_report()

    ## @}

    ## @name Database access
    # @{

    def load_all_servers(self):
        """ It loads all device servers declared in Tango database """
        #classes = self.db.get_device_family('dserver/*')
        #for c in classes:
        #    self.load_by_exec(c)
        print self.db
        self.load_from_servers_list(self.db.get_server_list())

    def load_by_name(self, name):
        ''' Initializes the dict with all the servers matching a given name (usually the executable name or class). A list of names is also possible.'''
        if type(name) in (list, set):
            for pattern in name:
                self.load_by_name(pattern)
        else:
            if name.count('/') >= 2 and not name.startswith('dserver/'):
                return self.load_from_devs_list([name])
            else:
                server_name = name.replace('dserver/', '')
                self.log.info('loading by %s server_name' % server_name)
                family = server_name.split(
                    '/')[0] if '/' in server_name else server_name
                member = server_name.split(
                    '/')[1] if '/' in server_name else '*'
                servers_list = self.get_devs_from_db('dserver/%s/%s' %
                                                     (family, member))
                #servers_list = [s for s in self.db.get_server_list() if fun.matchCl('%s/%s'%(family,member),s)]
                if servers_list:
                    self.load_from_servers_list(
                        [d.replace('dserver/', '') for d in servers_list],
                        check=False)
                    self.log.info('%d servers loaded' % len(servers_list))
                    return len(servers_list)
                else:
                    self.log.warning('No server matches with %s (family=%s).' %
                                     (server_name, family))
                    return 0
        return self

    def load_by_class(self, klass):
        """ Initializes the ServersDict using all the devices from a given class """
        self.load_from_devs_list(get_class_devices(klass))

    def load_by_host(self, host):
        """ Initializes the dict with all the servers assigned to a given host. """
        servers = self.get_db_device().DbGetHostServerList(host)
        self.log.warning("%d servers assigned in DB to host %s: %s" %
                         (len(servers), host, servers))
        if servers: self.load_from_servers_list(servers)
        return self

    def load_from_devs_list(self, devs_list):
        ''' Initializes the dict using a list of devices; a query to the database is used to identify the server for each device.  '''
        if type(devs_list) is str: devs_list = devs_list.split(',')
        if type(devs_list) not in [list, set, tuple]: devs_list = [devs_list]
        servers_list = set()
        for d in devs_list:
            devs = self.get_devs_from_db(d) if '*' in d else [d]
            devs = [get_normal_name(d) for d in devs]
            [
                servers_list.add(self.get_device_server(dev)) for dev in devs
                if dev
            ]
        self.log.info('Loading %d servers matching %s devices' %
                      (len(servers_list), len(devs_list)))
        self.load_from_servers_list([s for s in servers_list if s])
        return self

    def load_from_servers_list(self, servers_list, check=True):
        """ Initializes the dictionary using a list of server_names like ['Exec/Instance'] """
        t0 = time.time()
        if type(servers_list) is str: servers_list = servers_list.split(',')
        if check: self.check_servers_names(servers_list)
        for s in servers_list:
            try:
                self.log.debug('loading from %s/%s server' %
                               (get_tango_host(self.db), s))
                ss = TServer(name=s, parent=self)
                ss.init_from_db(self.db)
                self[s] = ss
            except Exception, e:
                self.log.warning('exception loading %s server: %s' %
                                 (s, str(e)[:100] + '...'))
                print traceback.format_exc()
        self.log.debug('load_from_servers_list(%d) took %f seconds' %
                       (len(servers_list), time.time() - t0))
        return self
Beispiel #4
0
class ServersDict(CaselessDict,Object):
    ''' 
    Dictionary of TServer classes indexed by server/instance names and loaded using wildcard expressions.
    Provides Jive/Astor functionality to a list of servers and allows to select/start/stop them by host, class or devices
    Its purpose is to allow generic start/stop of lists of Tango DeviceServers.
    This methods of selection provide new ways of search apart of Jive-like selection.
       
    @attention Dict keys are lower case, to get the real server name each key returns a TServer object with a .name attribute
    
    @par Usage:
    <pre>
    from fandango import Astor
    astor = Astor()
    astor.load_by_name('snap*')
    astor.keys()
      ['snapmanager/1', 'snaparchiver/1', 'snapextractor/1']
    server = astor['snaparchiver/1']
    server.get_device_list()
        ['dserver/snaparchiver/1', 'archiving/snaparchiver/1']
    astor.states()
    server.get_all_states()
        dserver/snaparchiver/1: ON
        archiving/snaparchiver/1: ON
     astor.get_device_host('archiving/snaparchiver/1')
        palantir01
     astor.stop_servers('snaparchiver/1')
     astor.stop_all_servers()
     astor.start_servers('snaparchiver/1','palantir01',wait=1000)
     astor.set_server_level('snaparchiver/1','palantir01',4)

     #Setting the polling of a device:
     server = astor['PySignalSimulator/bl11']
     for dev_name in server.get_device_list():
         dev = server.get_device(dev_name)
         attrs = dev.get_attribute_list()
         [dev.poll_attribute(attr,3000) for attr in attrs] 
     </pre>
    '''
    def __init__(self,pattern='',klass='',devs_list='',servers_list='',hosts='',loadAll=False,log='WARNING',logger=None,tango_host=''):
        ''' def __init__(self,pattern='', klass='',devs_list='',servers_list=''):
        The ServersDict can be initialized using any of the three argument lists or a wildcard for Database.get_server_list(pattern) 
        ServersDict('*') can be used to load all servers in database
        '''
        self.call__init__(CaselessDict,self)
        if logger is None:
            self.log = Logger('ServersDict')
            self.log.setLogLevel(log)
        else: self.log=logger
        self.log.debug('ServersDict(%s)'%','.join(map(str,(pattern,klass,devs_list,servers_list,hosts,loadAll,log,logger,tango_host))))
        
        ## proxies will keep a list of persistent device proxies
        self.proxies = ProxiesDict()
        ## db will keep a persistent link to PyTango database
        self.db = get_database() if not tango_host else get_database(*(tango_host.split(':')))
        self.server_names = self.keys
        self.servers = self.values
                
        if loadAll: self.load_all_servers()
        elif klass: self.load_by_class(klass)
        elif devs_list: self.load_from_devs_list(devs_list)
        elif servers_list: self.load_from_servers_list(servers_list)
        #elif pattern: self.load_from_servers_list(self.db.get_server_list(pattern))
        elif hosts: 
            hosts = type(hosts) is str and (',' in hosts and hosts.split(',') or [hosts]) or hosts
            for h in hosts: self.load_by_host(h)
        elif pattern: self.load_by_name(pattern)
        #dict.__init__(self)
    
    ## @name Dict methods
    # @{
    
    def __arranged_key(self,key): return key if key.count('/')<=1 else key.split('/',1)[1]
    #def __getitem__(self,key): dicts.CaselessDict.__getitem__(self,self.__arranged_key(key))
    #def __setitem__(self,key,value): dicts.CaselessDict.__setitem__(self,self.__arranged_key(key),value)
    #def __delitem__(self,key): dicts.CaselessDict.__delitem__(self,self.__arranged_key(key))   
    #def __contains__(self,key): dicts.CaselessDict.__contains__(self,self.__arranged_key(key))
    #def has_key(self,key): dicts.CaselessDict.has_key(self,self.__arranged_key(key))
    #def get(self,key,def_val=None): dicts.CaselessDict.get(self,self.__arranged_key(key),def_val)
    #def pop(self,key,def_val=None): dicts.CaselessDict.pop(self,self.__arranged_key(key),def_val)
    #def setdefault(self,key,def_val=None): dicts.CaselessDict.pop(self,self.__arranged_key(key),def_val)   
    
    def __repr__(self): return self.get_report()
    def __str__(self): return self.get_report()
    
    ## @}
    
    ## @name Database access
    # @{
       
    def load_all_servers(self):
        """ It loads all device servers declared in Tango database """
        #classes = self.db.get_device_family('dserver/*')
        #for c in classes:
        #    self.load_by_exec(c)
        print self.db
        self.load_from_servers_list(self.db.get_server_list())
        
    def load_by_name(self,name):
        ''' Initializes the dict with all the servers matching a given name (usually the executable name or class). A list of names is also possible.'''
        if type(name) in (list,set):
            for pattern in name:
                self.load_by_name(pattern)
        else:
            if name.count('/')>=2 and not name.startswith('dserver/'):
                return self.load_from_devs_list([name])
            else:
                server_name = name.replace('dserver/','')
                self.log.info('loading by %s server_name'%server_name)
                family = server_name.split('/')[0] if '/' in server_name else server_name
                member = server_name.split('/')[1] if '/' in server_name else '*'
                servers_list = self.get_devs_from_db('dserver/%s/%s' % (family,member))
                #servers_list = [s for s in self.db.get_server_list() if fun.matchCl('%s/%s'%(family,member),s)]
                if servers_list:
                    self.load_from_servers_list([d.replace('dserver/','') for d in servers_list],check=False)
                    self.log.info('%d servers loaded'%len(servers_list))
                    return len(servers_list)
                else:
                    self.log.warning('No server matches with %s (family=%s).'%(server_name,family))
                    return 0
        return self
    
    def load_by_class(self,klass):
        """ Initializes the ServersDict using all the devices from a given class """
        self.load_from_devs_list(get_class_devices(klass))
        
    def load_by_host(self,host):
        """ Initializes the dict with all the servers assigned to a given host. """
        servers = self.get_db_device().DbGetHostServerList(host)
        self.log.warning("%d servers assigned in DB to host %s: %s" % (len(servers),host,servers))
        if servers: self.load_from_servers_list(servers)
        return self
    
    def load_from_devs_list(self,devs_list):
        ''' Initializes the dict using a list of devices; a query to the database is used to identify the server for each device.  '''
        if type(devs_list) is str: devs_list = devs_list.split(',')
        if type(devs_list) not in [list,set,tuple]: devs_list = [devs_list]
        servers_list=set()
        for d in devs_list:
            devs = self.get_devs_from_db(d) if '*' in d else [d] 
            [servers_list.add(self.get_device_server(dev)) for dev in devs if dev]
        self.log.info('Loading %d servers matching %s devices'%(len(servers_list),len(devs_list)))
        self.load_from_servers_list([s for s in servers_list if s])
        return self
    
    def load_from_servers_list(self,servers_list,check=True):
        """ Initializes the dictionary using a list of server_names like ['Exec/Instance'] """
        t0 = time.time()
        if type(servers_list) is str: servers_list = servers_list.split(',')
        if check: self.check_servers_names(servers_list)
        for s in servers_list:
            try:           
                self.log.debug('loading from %s/%s server'%(get_tango_host(self.db),s))
                ss=TServer(name=s,parent=self)
                ss.init_from_db(self.db)
                self[s] = ss
            except Exception,e:
                self.log.warning('exception loading %s server: %s' % (s,str(e)[:100]+'...'))
                print traceback.format_exc()
        self.log.debug('load_from_servers_list(%d) took %f seconds' % (len(servers_list),time.time()-t0))
        return self