sobjects/notification.py
changeset 2841 107ba1c45227
parent 2818 326375561412
child 2880 bfc8e1831290
equal deleted inserted replaced
2840:06daf13195d4 2841:107ba1c45227
     1 """some hooks and views to handle notification on entity's changes
     1 """some views to handle notification on data changes
     2 
     2 
     3 :organization: Logilab
     3 :organization: Logilab
     4 :copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
     4 :copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
     5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
     5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
     6 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
     6 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
    16 except ImportError:
    16 except ImportError:
    17     def gethostname(): # gae
    17     def gethostname(): # gae
    18         return 'XXX'
    18         return 'XXX'
    19 
    19 
    20 from logilab.common.textutils import normalize_text
    20 from logilab.common.textutils import normalize_text
    21 from logilab.common.deprecation import class_renamed
    21 
    22 
    22 from cubicweb.selectors import yes
    23 from cubicweb import RegistryException
       
    24 from cubicweb.selectors import implements, yes
       
    25 from cubicweb.view import EntityView, Component
    23 from cubicweb.view import EntityView, Component
    26 from cubicweb.common.mail import format_mail
    24 from cubicweb.common.mail import format_mail
    27 
    25 
    28 from cubicweb.server.pool import PreCommitOperation
       
    29 from cubicweb.server.hookhelper import SendMailOp
    26 from cubicweb.server.hookhelper import SendMailOp
    30 from cubicweb.server.hooksmanager import Hook
       
    31 
    27 
    32 
    28 
    33 class RecipientsFinder(Component):
    29 class RecipientsFinder(Component):
    34     """this component is responsible to find recipients of a notification
    30     """this component is responsible to find recipients of a notification
    35 
    31 
    53             lang = self.vreg.property_value('ui.language')
    49             lang = self.vreg.property_value('ui.language')
    54             dests = zip(self.req.vreg.config['default-dest-addrs'], repeat(lang))
    50             dests = zip(self.req.vreg.config['default-dest-addrs'], repeat(lang))
    55         else: # mode == 'none'
    51         else: # mode == 'none'
    56             dests = []
    52             dests = []
    57         return dests
    53         return dests
    58 
       
    59 
       
    60 # hooks #######################################################################
       
    61 
       
    62 class RenderAndSendNotificationView(PreCommitOperation):
       
    63     """delay rendering of notification view until precommit"""
       
    64     def precommit_event(self):
       
    65         if self.view.rset and self.view.rset[0][0] in self.session.transaction_data.get('pendingeids', ()):
       
    66             return # entity added and deleted in the same transaction
       
    67         self.view.render_and_send(**getattr(self, 'viewargs', {}))
       
    68 
       
    69 class StatusChangeHook(Hook):
       
    70     """notify when a workflowable entity has its state modified"""
       
    71     events = ('after_add_entity',)
       
    72     accepts = ('TrInfo',)
       
    73 
       
    74     def call(self, session, entity):
       
    75         if not entity.from_state: # not a transition
       
    76             return
       
    77         rset = entity.related('wf_info_for')
       
    78         try:
       
    79             view = session.vreg['views'].select('notif_status_change', session,
       
    80                                                 rset=rset, row=0)
       
    81         except RegistryException:
       
    82             return
       
    83         comment = entity.printable_value('comment', format='text/plain')
       
    84         if comment:
       
    85             comment = normalize_text(comment, 80,
       
    86                                      rest=entity.comment_format=='text/rest')
       
    87         RenderAndSendNotificationView(session, view=view, viewargs={
       
    88             'comment': comment, 'previous_state': entity.previous_state.name,
       
    89             'current_state': entity.new_state.name})
       
    90 
       
    91 
       
    92 class RelationChangeHook(Hook):
       
    93     events = ('before_add_relation', 'after_add_relation',
       
    94               'before_delete_relation', 'after_delete_relation')
       
    95     accepts = ('Any',)
       
    96     def call(self, session, fromeid, rtype, toeid):
       
    97         """if a notification view is defined for the event, send notification
       
    98         email defined by the view
       
    99         """
       
   100         rset = session.eid_rset(fromeid)
       
   101         vid = 'notif_%s_%s' % (self.event,  rtype)
       
   102         try:
       
   103             view = session.vreg['views'].select(vid, session, rset=rset, row=0)
       
   104         except RegistryException:
       
   105             return
       
   106         RenderAndSendNotificationView(session, view=view)
       
   107 
       
   108 
       
   109 class EntityChangeHook(Hook):
       
   110     events = ('after_add_entity',
       
   111               'after_update_entity')
       
   112     accepts = ('Any',)
       
   113     def call(self, session, entity):
       
   114         """if a notification view is defined for the event, send notification
       
   115         email defined by the view
       
   116         """
       
   117         rset = entity.as_rset()
       
   118         vid = 'notif_%s' % self.event
       
   119         try:
       
   120             view = session.vreg['views'].select(vid, session, rset=rset, row=0)
       
   121         except RegistryException:
       
   122             return
       
   123         RenderAndSendNotificationView(session, view=view)
       
   124 
    54 
   125 
    55 
   126 # abstract or deactivated notification views and mixin ########################
    56 # abstract or deactivated notification views and mixin ########################
   127 
    57 
   128 class NotificationView(EntityView):
    58 class NotificationView(EntityView):
   294     def subject(self):
   224     def subject(self):
   295         entity = self.rset.get_entity(self.row or 0, self.col or 0)
   225         entity = self.rset.get_entity(self.row or 0, self.col or 0)
   296         return  u'%s #%s (%s)' % (self.req.__('New %s' % entity.e_schema),
   226         return  u'%s #%s (%s)' % (self.req.__('New %s' % entity.e_schema),
   297                                   entity.eid, self.user_login())
   227                                   entity.eid, self.user_login())
   298 
   228 
       
   229 from logilab.common.deprecation import class_renamed, class_moved
   299 NormalizedTextView = class_renamed('NormalizedTextView', ContentAddedView)
   230 NormalizedTextView = class_renamed('NormalizedTextView', ContentAddedView)
       
   231 from cubicweb.hooks.notification import RenderAndSendNotificationView
       
   232 RenderAndSendNotificationView = class_moved(RenderAndSendNotificationView)