Package Ganga :: Package GPIDev :: Package Lib :: Package Registry :: Module RegistrySlice
[hide private]
[frames] | no frames]

Source Code for Module Ganga.GPIDev.Lib.Registry.RegistrySlice

  1  import sys 
  2   
  3  import Ganga.Utility.logging 
  4  logger = Ganga.Utility.logging.getLogger() 
  5   
  6  from Ganga.Core import GangaException 
  7  from Ganga.Core.GangaRepository.Registry import Registry, RegistryKeyError, RegistryIndexError, RegistryAccessError 
  8   
  9  from Ganga.Utility.external.ordereddict import oDict 
 10   
 11  import Ganga.Utility.Config 
 12  config = Ganga.Utility.Config.makeConfig('Display','control the printing style of the different registries ("jobs","box","tasks"...)') 
 13   
14 -class RegistrySlice(object):
15 - def __init__(self,name,display_prefix):
16 self.objects = oDict() 17 self.name = name 18 self._display_columns = config[display_prefix+'_columns'] 19 self._display_columns_show_empty = config[display_prefix+"_columns_show_empty"] 20 self._display_columns_width = config[display_prefix+"_columns_width"] 21 self._display_columns_functions = {} 22 try: 23 cfs = config[display_prefix+'_columns_functions'] 24 for c in cfs: 25 self._display_columns_functions[c] = eval(cfs[c]) 26 except Exception,x: 27 logger.error("Error on evaluating display column functions from config file: %s: %s"% (x.__class__.__name__,x)) 28 29 from Ganga.Utility.ColourText import Effects 30 self._colour_normal = Effects().normal 31 self._proxyClass = None
32
33 - def _getColour(self,obj):
34 """ Override this function in derived slices to colorize your job/task/... list""" 35 return self._colour_normal
36
37 - def do_collective_operation(self,keep_going,method,*args,**kwds):
38 """ 39 """ 40 if not type(keep_going) is bool: 41 raise GangaException("The variable 'keep_going' must be a boolean. Probably you wanted to do %s(%s).%s()" % (self.name,keep_going,method)) 42 result = [] 43 for id,obj in self.objects.iteritems(): 44 try: 45 if type(method) is str: 46 doc = method 47 result.append(getattr(obj,method)(*args,**kwds)) 48 else: 49 try: 50 doc = method.__doc__ 51 except AttributeError: 52 doc = str(method) 53 result.append(method(obj,*args,**kwds)) 54 except GangaException,x: 55 if not keep_going: raise 56 except Exception,x: 57 logger.exception('%s %s %s: %s %s',doc,self.name,id,x.__class__.__name__,str(x)) 58 if not keep_going: raise 59 return result
60
61 - def ids(self,minid=None,maxid=None):
62 "Get the list of job ids. 'minid' and 'maxid' specify optional (inclusive) slice range." 63 if maxid is None: 64 maxid = sys.maxint 65 if minid is None: 66 minid = 0 67 return [k for k in self.objects.keys() if minid <= k <= maxid]
68 #ids = [] 69 #def callback(j): 70 # ids.append(j.id) 71 #self.do_select(callback,minid,maxid) 72 #return ids 73
74 - def clean(self,confirm=False,force=False):
75 """Cleans the repository only if this slice represents the repository 76 Returns True on success and False on failure""" 77 if not hasattr(self.objects,"clean"): 78 logger.error("'clean' only works on whole registries, e.g. 'jobs.clean()'. Use remove() to delete job slices") 79 return False 80 if not confirm: 81 logger.warning("You are about to irreversibly delete the WHOLE '%s' registry, without properly cleaning up individual jobs." % (self.objects.name)) 82 if force: 83 logger.warning("You will also cause any other Ganga sessions accessing this repository to shut down their operations") 84 logger.warning("If you just want to remove all jobs, type '%s.remove()'. If you really want to do this, type '%s.clean(confirm=True,force=True)" % (self.objects.name,self.objects.name)) 85 else: 86 logger.warning("If you just want to remove all jobs, type '%s.remove()'. If you really want to do this, type '%s.clean(confirm=True)" % (self.objects.name,self.objects.name)) 87 return False 88 return self.objects.clean(force)
89
90 - def select(self,minid=None,maxid=None,**attrs):
91 import repr 92 r = repr.Repr() 93 attrs_str = "".join([',%s=%s'%(a,r.repr(attrs[a])) for a in attrs]) 94 slice = self.__class__("%s.select(minid=%s,maxid=%s%s)"%(self.name,r.repr(minid),r.repr(maxid),attrs_str)) 95 def append(id,obj): 96 slice.objects[id] = obj
97 self.do_select(append,minid,maxid,**attrs) 98 return slice
99
100 - def do_select(self,callback,minid=None,maxid=None,**attrs):
101 """Get the slice of jobs. 'minid' and 'maxid' specify optional (inclusive) slice range. 102 The returned slice object has the job registry interface but it is not connected to 103 persistent storage. 104 """ 105 import sys 106 107 def select_by_list(id): 108 return id in ids
109 110 def select_by_range(id): 111 return minid <= id <= maxid 112 113 def is_container(c): 114 try: 115 0 in c 116 except: return False 117 else: return True 118 119 ids = None 120 121 if is_container(minid): 122 ids = minid 123 select = select_by_list 124 else: 125 if minid is None: minid = 0 126 if maxid is None: maxid = sys.maxint 127 select = select_by_range 128 129 for id, obj in self.objects.iteritems(): 130 if select(id): 131 selected=True 132 for a in attrs: 133 try: 134 item = obj._schema.getItem(a) 135 except KeyError: 136 from Ganga.GPIDev.Base import GangaAttributeError 137 raise GangaAttributeError('undefined select attribute: %s'%str(a)) 138 else: 139 attrvalue = attrs[a] 140 141 if item.isA('ComponentItem'): 142 from Ganga.GPIDev.Base.Filters import allComponentFilters 143 144 cfilter = allComponentFilters[item['category']] 145 filtered_value = cfilter(attrs[a],item) 146 if not filtered_value is None: 147 attrvalue = filtered_value._name 148 else: 149 attrvalue = attrvalue._name 150 151 if not getattr(obj,a)._name == attrvalue: 152 selected = False 153 break 154 else: 155 if getattr(obj,a) != attrvalue: 156 selected = False 157 break 158 if selected: 159 callback(id,obj) 160 161
162 - def copy(self,keep_going):
163 slice = self.__class__("copy of %s" % self.name) 164 for id,obj in self.objects.iteritems(): 165 #obj = _unwrap(obj) 166 copy = obj.clone() 167 # If the copied object is not automatically registered, 168 # try to register it in the old objects registry 169 new_id = copy._getRegistryID() 170 if new_id is None: 171 reg = obj._getRegistry() 172 if reg is None: 173 new_id = id 174 else: 175 reg._add(copy) 176 new_id = copy._getRegistryID() 177 slice.objects[new_id] = copy 178 return slice
179
180 - def __contains__(self,j):
181 return j.id in self.objects
182
183 - def __call__(self,id):
184 """ Retrieve an object by id. 185 """ 186 try: 187 return self.objects[id] 188 except KeyError: 189 raise RegistryKeyError('Object id=%d not found'%id)
190
191 - def __iter__(self):
192 "Iterator for the objects. " 193 class Iterator: 194 def __init__(self,reg): 195 self.it = reg.objects.values().__iter__()
196 def __iter__(self): return self 197 def next(self): 198 return self.it.next() 199 return Iterator(self) 200
201 - def __len__(self):
202 "Number of objects in the registry" 203 return len(self.objects)
204
205 - def __getitem__(self,x):
206 """Retrieve the job object from the registry: registry[x]. 207 If 'x' is a job id (int) then a single job object is returned or IndexError. 208 If 'x' is a name (string) then a unique same name is returned, otherwise []. 209 If 'x' is a job object then it is returned if it belongs to the registry, otherwise None. 210 If 'x' is not of any of the types above, raise TypeError. 211 or by name. If retrieved by name then the job must be unique, otherwise the RegistryKeyError is raised. 212 If the input is incorrect, RegistryAccessError is raised. 213 """ 214 if type(x) == int: 215 try: 216 return self.objects.values()[x] 217 except IndexError: 218 raise RegistryIndexError('list index out of range') 219 220 if type(x) == str: 221 ids = [] 222 for j in self.objects.values(): 223 if j.name == x: 224 ids.append(j.id) 225 if len(ids) > 1: 226 raise RegistryKeyError('object "%s" not unique'%x) 227 if len(ids) == 0: 228 raise RegistryKeyError('object "%s" not found'%x) 229 return self.objects[ids[0]] 230 231 raise RegistryAccessError('Expected int or string (job name).')
232
233 - def __getslice__(self,i1,i2):
234 import sys 235 236 if i2 == sys.maxint: 237 endrange = '' 238 else: 239 endrange = str(i2) 240 241 slice = self.__class__("%s[%d:%s]"%(self.name,i1,endrange)) 242 s = self.objects.items()[i1:i2] 243 for id,obj in s: 244 slice.objects[id] = obj 245 return slice
246
247 - def _get_display_value(self,obj,item):
248 def getatr(obj,members): 249 val = getattr(obj,members[0]) 250 if len(members)>1: 251 return getatr(val,members[1:]) 252 else: 253 return val
254 try: 255 try: 256 f = self._display_columns_functions[item] 257 val = self._display_columns_functions[item](obj) 258 except KeyError: 259 val = getatr(obj,item.split('.')) 260 if not val and not item in self._display_columns_show_empty: 261 val = "" 262 except AttributeError: 263 val = "" 264 return str(val) 265
266 - def _display(self,interactive=0):
267 from Ganga.Utility.ColourText import ANSIMarkup, NoMarkup, Foreground, Background, Effects 268 if interactive: 269 markup = ANSIMarkup() 270 else: 271 markup = NoMarkup() 272 273 # default column width 274 default_width = 10 275 276 cnt = len(self) 277 ds = "Registry Slice: %s (%d objects)\n" % (self.name,cnt) 278 279 format = "#" 280 flist = [] 281 for d in self._display_columns: 282 width = self._display_columns_width.get(d,default_width) 283 flist.append("%"+str(width)+"s ") 284 #format += "%"+str(width)+"s " 285 format = "|".join(flist) 286 format += "\n" 287 288 if cnt > 0: 289 ds += "--------------\n" 290 ds += format % self._display_columns 291 ds += "-"*len(format % tuple([""]*len(self._display_columns))) + "\n" 292 293 for obj in self.objects.values(): 294 colour = self._getColour(obj) 295 296 vals = [] 297 for item in self._display_columns: 298 width = self._display_columns_width.get(item,default_width) 299 if obj._data is None and hasattr(obj,"_index_cache") and not obj._index_cache is None: 300 try: 301 if item == "fqid": 302 vals.append(str(obj._index_cache["display:"+item])) 303 else: 304 vals.append(str(obj._index_cache["display:"+item])[0:width]) 305 continue 306 except KeyError: 307 pass 308 if item == "fqid": 309 vals.append(self._get_display_value(obj,item)) 310 else: 311 vals.append(self._get_display_value(obj,item)[0:width]) 312 ds += markup(format % tuple(vals), colour) 313 return ds
314 315 __str__ = _display 316
317 - def _id(self):
318 return id(self)
319