hooks/notification.py
brancholdstable
changeset 7074 e4580e5f0703
parent 6760 2c1fc68ac258
child 7068 90ddf608fe2b
equal deleted inserted replaced
6749:48f468f33704 7074:e4580e5f0703
    20 """
    20 """
    21 __docformat__ = "restructuredtext en"
    21 __docformat__ = "restructuredtext en"
    22 
    22 
    23 from logilab.common.textutils import normalize_text
    23 from logilab.common.textutils import normalize_text
    24 
    24 
       
    25 from cubicweb import RegistryNotFound
    25 from cubicweb.selectors import is_instance
    26 from cubicweb.selectors import is_instance
    26 from cubicweb.server import hook
    27 from cubicweb.server import hook
    27 from cubicweb.sobjects.supervising import SupervisionMailOp
    28 from cubicweb.sobjects.supervising import SupervisionMailOp
    28 
    29 
    29 class RenderAndSendNotificationView(hook.Operation):
    30 class RenderAndSendNotificationView(hook.Operation):
    40 class NotificationHook(hook.Hook):
    41 class NotificationHook(hook.Hook):
    41     __abstract__ = True
    42     __abstract__ = True
    42     category = 'notification'
    43     category = 'notification'
    43 
    44 
    44     def select_view(self, vid, rset, row=0, col=0):
    45     def select_view(self, vid, rset, row=0, col=0):
    45         return self._cw.vreg['views'].select_or_none(vid, self._cw, rset=rset,
    46         try:
    46                                                      row=row, col=col)
    47             return self._cw.vreg['views'].select_or_none(vid, self._cw, rset=rset,
       
    48                                                          row=row, col=col)
       
    49         except RegistryNotFound: # can happen in some config
       
    50                                  # (e.g. repo only config with no
       
    51                                  # notification views registered by
       
    52                                  # the instance's cubes)
       
    53             return None
    47 
    54 
    48 
    55 
    49 class StatusChangeHook(NotificationHook):
    56 class StatusChangeHook(NotificationHook):
    50     """notify when a workflowable entity has its state modified"""
    57     """notify when a workflowable entity has its state modified"""
    51     __regid__ = 'notifystatuschange'
    58     __regid__ = 'notifystatuschange'
    67             comment = normalize_text(comment, 80)
    74             comment = normalize_text(comment, 80)
    68         RenderAndSendNotificationView(self._cw, view=view, viewargs={
    75         RenderAndSendNotificationView(self._cw, view=view, viewargs={
    69             'comment': comment, 'previous_state': entity.previous_state.name,
    76             'comment': comment, 'previous_state': entity.previous_state.name,
    70             'current_state': entity.new_state.name})
    77             'current_state': entity.new_state.name})
    71 
    78 
    72 
       
    73 class RelationChangeHook(NotificationHook):
    79 class RelationChangeHook(NotificationHook):
    74     __regid__ = 'notifyrelationchange'
    80     __regid__ = 'notifyrelationchange'
    75     events = ('before_add_relation', 'after_add_relation',
    81     events = ('before_add_relation', 'after_add_relation',
    76               'before_delete_relation', 'after_delete_relation')
    82               'before_delete_relation', 'after_delete_relation')
    77 
    83 
   123     def __call__(self):
   129     def __call__(self):
   124         session = self._cw
   130         session = self._cw
   125         if session.added_in_transaction(self.entity.eid):
   131         if session.added_in_transaction(self.entity.eid):
   126             return # entity is being created
   132             return # entity is being created
   127         # then compute changes
   133         # then compute changes
   128         attrs = [k for k in self.entity.edited_attributes
   134         attrs = [k for k in self.entity.cw_edited
   129                  if not k in self.skip_attrs]
   135                  if not k in self.skip_attrs]
   130         if not attrs:
   136         if not attrs:
   131             return
   137             return
   132         changes = session.transaction_data.setdefault('changes', {})
   138         changes = session.transaction_data.setdefault('changes', {})
   133         thisentitychanges = changes.setdefault(self.entity.eid, set())
   139         thisentitychanges = changes.setdefault(self.entity.eid, set())
   138             rqlrestr.append('X %s %s' % (attr, var))
   144             rqlrestr.append('X %s %s' % (attr, var))
   139         rql = 'Any %s WHERE %s' % (','.join(rqlsel), ','.join(rqlrestr))
   145         rql = 'Any %s WHERE %s' % (','.join(rqlsel), ','.join(rqlrestr))
   140         rset = session.execute(rql, {'x': self.entity.eid})
   146         rset = session.execute(rql, {'x': self.entity.eid})
   141         for i, attr in enumerate(attrs):
   147         for i, attr in enumerate(attrs):
   142             oldvalue = rset[0][i]
   148             oldvalue = rset[0][i]
   143             newvalue = self.entity[attr]
   149             newvalue = self.entity.cw_edited[attr]
   144             if oldvalue != newvalue:
   150             if oldvalue != newvalue:
   145                 thisentitychanges.add((attr, oldvalue, newvalue))
   151                 thisentitychanges.add((attr, oldvalue, newvalue))
   146         if thisentitychanges:
   152         if thisentitychanges:
   147             EntityUpdatedNotificationOp(session)
   153             EntityUpdatedNotificationOp(session)
   148 
   154 
   166         event = self.event.split('_', 1)[1]
   172         event = self.event.split('_', 1)[1]
   167         if event == 'update_entity':
   173         if event == 'update_entity':
   168             if self._cw.added_in_transaction(self.entity.eid):
   174             if self._cw.added_in_transaction(self.entity.eid):
   169                 return False
   175                 return False
   170             if self.entity.e_schema == 'CWUser':
   176             if self.entity.e_schema == 'CWUser':
   171                 if not (self.entity.edited_attributes - frozenset(('eid', 'modification_date',
   177                 if not (frozenset(self.entity.cw_edited)
   172                                                                    'last_login_time'))):
   178                         - frozenset(('eid', 'modification_date',
       
   179                                      'last_login_time'))):
   173                     # don't record last_login_time update which are done
   180                     # don't record last_login_time update which are done
   174                     # automatically at login time
   181                     # automatically at login time
   175                     return False
   182                     return False
   176         self._cw.transaction_data.setdefault('pendingchanges', []).append(
   183         self._cw.transaction_data.setdefault('pendingchanges', []).append(
   177             (event, self))
   184             (event, self))