entities/adapters.py
changeset 5722 61d6a4caa963
parent 5720 f0e521487903
child 5768 1e73a466aa69
equal deleted inserted replaced
5720:f0e521487903 5722:61d6a4caa963
    27 from logilab.mtconverter import TransformError
    27 from logilab.mtconverter import TransformError
    28 from logilab.common.decorators import cached
    28 from logilab.common.decorators import cached
    29 
    29 
    30 from cubicweb.view import EntityAdapter, implements_adapter_compat
    30 from cubicweb.view import EntityAdapter, implements_adapter_compat
    31 from cubicweb.selectors import implements, relation_possible
    31 from cubicweb.selectors import implements, relation_possible
    32 from cubicweb.interfaces import IDownloadable, ITree
    32 from cubicweb.interfaces import IDownloadable, ITree, IProgress, IMileStone
    33 
    33 
    34 
    34 
    35 class IEmailableAdapter(EntityAdapter):
    35 class IEmailableAdapter(EntityAdapter):
    36     __regid__ = 'IEmailable'
    36     __regid__ = 'IEmailable'
    37     __select__ = relation_possible('primary_email') | relation_possible('use_email')
    37     __select__ = relation_possible('primary_email') | relation_possible('use_email')
   325             except AttributeError:
   325             except AttributeError:
   326                 break
   326                 break
   327         path.reverse()
   327         path.reverse()
   328         return path
   328         return path
   329 
   329 
       
   330 
       
   331 class IProgressAdapter(EntityAdapter):
       
   332     """something that has a cost, a state and a progression.
       
   333 
       
   334     You should at least override progress_info an in_progress methods on concret
       
   335     implementations.
       
   336     """
       
   337     __regid__ = 'IProgress'
       
   338     __select__ = implements(IProgress) # XXX for bw compat, should be abstract
       
   339 
       
   340     @property
       
   341     @implements_adapter_compat('IProgress')
       
   342     def cost(self):
       
   343         """the total cost"""
       
   344         return self.progress_info()['estimated']
       
   345 
       
   346     @property
       
   347     @implements_adapter_compat('IProgress')
       
   348     def revised_cost(self):
       
   349         return self.progress_info().get('estimatedcorrected', self.cost)
       
   350 
       
   351     @property
       
   352     @implements_adapter_compat('IProgress')
       
   353     def done(self):
       
   354         """what is already done"""
       
   355         return self.progress_info()['done']
       
   356 
       
   357     @property
       
   358     @implements_adapter_compat('IProgress')
       
   359     def todo(self):
       
   360         """what remains to be done"""
       
   361         return self.progress_info()['todo']
       
   362 
       
   363     @implements_adapter_compat('IProgress')
       
   364     def progress_info(self):
       
   365         """returns a dictionary describing progress/estimated cost of the
       
   366         version.
       
   367 
       
   368         - mandatory keys are (''estimated', 'done', 'todo')
       
   369 
       
   370         - optional keys are ('notestimated', 'notestimatedcorrected',
       
   371           'estimatedcorrected')
       
   372 
       
   373         'noestimated' and 'notestimatedcorrected' should default to 0
       
   374         'estimatedcorrected' should default to 'estimated'
       
   375         """
       
   376         raise NotImplementedError
       
   377 
       
   378     @implements_adapter_compat('IProgress')
       
   379     def finished(self):
       
   380         """returns True if status is finished"""
       
   381         return not self.in_progress()
       
   382 
       
   383     @implements_adapter_compat('IProgress')
       
   384     def in_progress(self):
       
   385         """returns True if status is not finished"""
       
   386         raise NotImplementedError
       
   387 
       
   388     @implements_adapter_compat('IProgress')
       
   389     def progress(self):
       
   390         """returns the % progress of the task item"""
       
   391         try:
       
   392             return 100. * self.done / self.revised_cost
       
   393         except ZeroDivisionError:
       
   394             # total cost is 0 : if everything was estimated, task is completed
       
   395             if self.progress_info().get('notestimated'):
       
   396                 return 0.
       
   397             return 100
       
   398 
       
   399     @implements_adapter_compat('IProgress')
       
   400     def progress_class(self):
       
   401         return ''
       
   402 
       
   403 
       
   404 class IMileStoneAdapter(IProgressAdapter):
       
   405     __regid__ = 'IMileStone'
       
   406     __select__ = implements(IMileStone) # XXX for bw compat, should be abstract
       
   407 
       
   408     parent_type = None # specify main task's type
       
   409 
       
   410     @implements_adapter_compat('IMileStone')
       
   411     def get_main_task(self):
       
   412         """returns the main ITask entity"""
       
   413         raise NotImplementedError
       
   414 
       
   415     @implements_adapter_compat('IMileStone')
       
   416     def initial_prevision_date(self):
       
   417         """returns the initial expected end of the milestone"""
       
   418         raise NotImplementedError
       
   419 
       
   420     @implements_adapter_compat('IMileStone')
       
   421     def eta_date(self):
       
   422         """returns expected date of completion based on what remains
       
   423         to be done
       
   424         """
       
   425         raise NotImplementedError
       
   426 
       
   427     @implements_adapter_compat('IMileStone')
       
   428     def completion_date(self):
       
   429         """returns date on which the subtask has been completed"""
       
   430         raise NotImplementedError
       
   431 
       
   432     @implements_adapter_compat('IMileStone')
       
   433     def contractors(self):
       
   434         """returns the list of persons supposed to work on this task"""
       
   435         raise NotImplementedError