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
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
34 """ Override this function in derived slices to colorize your job/task/... list"""
35 return self._colour_normal
36
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
69
70
71
72
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):
179
181 return j.id in self.objects
182
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
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
202 "Number of objects in the registry"
203 return len(self.objects)
204
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
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
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
267 from Ganga.Utility.ColourText import ANSIMarkup, NoMarkup, Foreground, Background, Effects
268 if interactive:
269 markup = ANSIMarkup()
270 else:
271 markup = NoMarkup()
272
273
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
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
319