Changeset 9510 for main/waeup.kofa/trunk/src/waeup/kofa
- Timestamp:
- 2 Nov 2012, 13:39:31 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
main/waeup.kofa/trunk/src/waeup/kofa/reports.py
r9344 r9510 21 21 import zc.async.interfaces 22 22 from persistent.list import PersistentList 23 from zope.component import getUtility, getUtilitiesFor 23 from zope import schema 24 from zope.component import getUtility, getUtilitiesFor, queryUtility 24 25 from zope.component.hooks import setSite 25 26 from zope.interface import implementer … … 27 28 from waeup.kofa.async import AsyncJob 28 29 from waeup.kofa.interfaces import ( 29 IJobManager, JOB_STATUS_MAP,) 30 IJobManager, JOB_STATUS_MAP, IKofaPluggable, IKofaObject) 31 from waeup.kofa.interfaces import MessageFactory as _ 30 32 from waeup.kofa.utils.helpers import now 31 33 … … 33 35 """A report. 34 36 """ 37 args = Attribute("""The args passed to constructor""") 38 39 kwargs = Attribute("""The keywords passed to constructor""") 40 35 41 creation_dt = Attribute( 36 42 """Datetime when a report was created. The datetime should """ … … 42 48 """ 43 49 44 class IReportGenerator(I nterface):50 class IReportGenerator(IKofaObject): 45 51 """A report generator. 46 52 """ 47 def generate(site): 53 title = Attribute("""Human readable description of report type.""") 54 def generate(site, args=[], kw={}): 48 55 """Generate a report. 49 """ 50 return Report() 56 57 `args` and `kw` are the parameters needed to create a specific 58 report (if any). 59 """ 51 60 52 61 class IReportJob(zc.async.interfaces.IJob): 53 def __init__(site, exporter_name): 54 pass 62 63 finished = schema.Bool( 64 title = u'`True` if the job finished.`', 65 default = False, 66 ) 67 68 failed = schema.Bool( 69 title = u"`True` iff the job finished and didn't provide a report.", 70 default = None, 71 ) 72 73 description = schema.TextLine( 74 title = u"""Textual representation of arguments and keywords.""", 75 default = u"", 76 ) 77 78 def __init__(site, generator_name): 79 """Create a report job via generator.""" 55 80 56 81 class IReportJobContainer(Interface): … … 113 138 """ 114 139 140 class IReportsContainer(grok.interfaces.IContainer, IReportJobContainer, 141 IKofaObject): 142 """A grok container that holds report jobs. 143 """ 144 145 class manageReportsPermission(grok.Permission): 146 """A permission to manage reports. 147 """ 148 grok.name('waeup.manageReports') 149 115 150 def get_generators(): 116 151 """Get available report generators. … … 128 163 creation_dt = None 129 164 130 def __init__(self): 165 def __init__(self, args=[], kwargs={}): 166 self.args = args 167 self.kwargs = kwargs 131 168 self.creation_dt = now() 132 169 133 170 def create_pdf(self): 134 raise NotImplemented 171 raise NotImplementedError() 135 172 136 173 @implementer(IReportGenerator) 137 174 class ReportGenerator(object): 138 def generate(self, site): 175 176 title = _("Unnamed Report") 177 def generate(self, site, args=[], kw={}): 139 178 result = Report() 140 179 return result … … 179 218 """ 180 219 def __init__(self, site, generator_name, args=[], kw={}): 220 self._generator_name = generator_name 181 221 super(AsyncReportJob, self).__init__( 182 report_job, site, generator_name, *args, **kw) 222 report_job, site, generator_name, args=args, kw=kw) 223 224 @property 225 def finished(self): 226 """A job is marked `finished` if it is completed. 227 228 Please note: a finished report job does not neccessarily 229 provide an IReport result. See meth:`failed`. 230 """ 231 return self.status == zc.async.interfaces.COMPLETED 232 233 @property 234 def failed(self): 235 """A report job is marked failed iff it is finished and the 236 result does not provide IReport. 237 238 While a job is unfinished, the `failed` status is ``None``. 239 240 Failed jobs normally provide a `traceback` to examine reasons. 241 """ 242 if not self.finished: 243 return None 244 if not IReport.providedBy(self.result): 245 return True 246 return False 247 248 @property 249 def description(self): 250 """A description gives a representation of the report to generate. 251 252 The description contains the name of the report generator 253 (trying to fetch the `name` attribute of the requested report 254 generator) and the arguments and keywords passed in. 255 256 Please note that this method is expensive! 257 """ 258 args = self.kwargs.get('args', []) 259 kw = self.kwargs.get('kw', dict()) 260 args = ', '.join(["%r" % x for x in args]) 261 kw = ', '.join(['%s=%r' % (key, val) for key, val in kw.items()]) 262 if len(args) and len(kw): 263 str_repr = args + ', ' + kw 264 else: 265 str_repr = args + kw 266 str_repr = '(' + str_repr + ')' 267 try: 268 generator = queryUtility( 269 IReportGenerator, name=self._generator_name) 270 name = generator.name 271 except: 272 name = _('Invalid Report Generator') 273 return name + ' ' + str_repr 274 183 275 184 276 @implementer(IReportJobContainer) … … 212 304 # Make sure that the persisted list is stored in ZODB 213 305 self.running_report_jobs = PersistentList(self.running_report_jobs) 214 self.running_report_jobs.append((job_id, generator_name, user_id) )306 self.running_report_jobs.append((job_id, generator_name, user_id),) 215 307 return job_id 216 308 … … 253 345 for entry in entries: 254 346 job = manager.get(entry[0]) 255 if job is None:256 continue257 347 status, status_translated = JOB_STATUS_MAP[job.status] 258 348 generator = getUtility(IReportGenerator, name=entry[1]) … … 287 377 return entry 288 378 return None 379 380 @implementer(IReportsContainer) 381 class ReportsContainer(grok.Container, ReportJobContainer): 382 """A container for reports. 383 """ 384 385 @implementer(IKofaPluggable) 386 class ReportsContainerPlugin(grok.GlobalUtility): 387 """A plugin that updates sites to contain a reports container. 388 """ 389 390 grok.name('reports') 391 392 deprecated_attributes = [] 393 394 def setup(self, site, name, logger): 395 """Add a reports container for `site`. 396 397 If there is such an object already, we install a fresh one. 398 """ 399 if site.get('reports', None) is not None: 400 del site['reports'] 401 logger.info('Removed reports container for site "%s"' % name) 402 return self.update(site, name, logger) 403 404 def update(self, site, name, logger): 405 """Install a reports container in `site`. 406 407 If one exists already, do nothing. 408 """ 409 if site.get('reports', None) is not None: 410 return 411 site['reports'] = ReportsContainer() 412 logger.info('Added reports container for site "%s"' % name) 413 return
Note: See TracChangeset for help on using the changeset viewer.