sobjects/notification.py
branchtls-sprint
changeset 1477 b056a49c16dc
parent 1398 5fe84a5f7035
parent 1410 dc22b5461850
child 1723 30c3a713ab61
equal deleted inserted replaced
1476:f94b41709ce6 1477:b056a49c16dc
    37     """
    37     """
    38     id = 'recipients_finder'
    38     id = 'recipients_finder'
    39     __select__ = yes()
    39     __select__ = yes()
    40     user_rql = ('Any X,E,A WHERE X is CWUser, X in_state S, S name "activated",'
    40     user_rql = ('Any X,E,A WHERE X is CWUser, X in_state S, S name "activated",'
    41                 'X primary_email E, E address A')
    41                 'X primary_email E, E address A')
    42     
    42 
    43     def recipients(self):
    43     def recipients(self):
    44         mode = self.config['default-recipients-mode']
    44         mode = self.config['default-recipients-mode']
    45         if mode == 'users':
    45         if mode == 'users':
    46             # use unsafe execute else we may don't have the right to see users
    46             # use unsafe execute else we may don't have the right to see users
    47             # to notify...
    47             # to notify...
    53             dests = zip(self.config['default-dest-addrs'], repeat(lang))
    53             dests = zip(self.config['default-dest-addrs'], repeat(lang))
    54         else: # mode == 'none'
    54         else: # mode == 'none'
    55             dests = []
    55             dests = []
    56         return dests
    56         return dests
    57 
    57 
    58     
    58 
    59 # hooks #######################################################################
    59 # hooks #######################################################################
    60 
    60 
    61 class RenderAndSendNotificationView(PreCommitOperation):
    61 class RenderAndSendNotificationView(PreCommitOperation):
    62     """delay rendering of notification view until precommit"""
    62     """delay rendering of notification view until precommit"""
    63     def precommit_event(self):
    63     def precommit_event(self):
    64         if self.view.rset[0][0] in self.session.query_data('pendingeids', ()):
    64         if self.view.rset[0][0] in self.session.query_data('pendingeids', ()):
    65             return # entity added and deleted in the same transaction
    65             return # entity added and deleted in the same transaction
    66         self.view.render_and_send(**getattr(self, 'viewargs', {}))
    66         self.view.render_and_send(**getattr(self, 'viewargs', {}))
    67         
    67 
    68 class StatusChangeHook(Hook):
    68 class StatusChangeHook(Hook):
    69     """notify when a workflowable entity has its state modified"""
    69     """notify when a workflowable entity has its state modified"""
    70     events = ('after_add_entity',)
    70     events = ('after_add_entity',)
    71     accepts = ('TrInfo',)
    71     accepts = ('TrInfo',)
    72     
    72 
    73     def call(self, session, entity):
    73     def call(self, session, entity):
    74         if not entity.from_state: # not a transition
    74         if not entity.from_state: # not a transition
    75             return
    75             return
    76         rset = entity.related('wf_info_for')
    76         rset = entity.related('wf_info_for')
    77         try:
    77         try:
   131     * set id and accepts attributes to match desired events and entity types
   131     * set id and accepts attributes to match desired events and entity types
   132     * set a content attribute to define the content of the email (unless you
   132     * set a content attribute to define the content of the email (unless you
   133       override call)
   133       override call)
   134     """
   134     """
   135     msgid_timestamp = True
   135     msgid_timestamp = True
   136     
   136 
   137     def recipients(self):
   137     def recipients(self):
   138         finder = self.vreg.select_component('recipients_finder', self.req, self.rset)
   138         finder = self.vreg.select_component('recipients_finder', self.req, self.rset)
   139         return finder.recipients()
   139         return finder.recipients()
   140         
   140 
   141     def subject(self):
   141     def subject(self):
   142         entity = self.entity(0, 0)
   142         entity = self.entity(0, 0)
   143         subject = self.req._(self.message)
   143         subject = self.req._(self.message)
   144         etype = entity.dc_type()
   144         etype = entity.dc_type()
   145         eid = entity.eid
   145         eid = entity.eid
   148 
   148 
   149     def user_login(self):
   149     def user_login(self):
   150         # req is actually a session (we are on the server side), and we have to
   150         # req is actually a session (we are on the server side), and we have to
   151         # prevent nested internal session
   151         # prevent nested internal session
   152         return self.req.actual_session().user.login
   152         return self.req.actual_session().user.login
   153     
   153 
   154     def context(self, **kwargs):
   154     def context(self, **kwargs):
   155         entity = self.entity(0, 0)
   155         entity = self.entity(0, 0)
   156         for key, val in kwargs.iteritems():
   156         for key, val in kwargs.iteritems():
   157             if val and isinstance(val, unicode) and val.strip():
   157             if val and isinstance(val, unicode) and val.strip():
   158                kwargs[key] = self.req._(val)
   158                kwargs[key] = self.req._(val)
   160                        'eid': entity.eid,
   160                        'eid': entity.eid,
   161                        'etype': entity.dc_type(),
   161                        'etype': entity.dc_type(),
   162                        'url': entity.absolute_url(),
   162                        'url': entity.absolute_url(),
   163                        'title': entity.dc_long_title(),})
   163                        'title': entity.dc_long_title(),})
   164         return kwargs
   164         return kwargs
   165     
   165 
   166     def cell_call(self, row, col=0, **kwargs):
   166     def cell_call(self, row, col=0, **kwargs):
   167         self.w(self.req._(self.content) % self.context(**kwargs))
   167         self.w(self.req._(self.content) % self.context(**kwargs))
   168 
   168 
   169     def construct_message_id(self, eid):
   169     def construct_message_id(self, eid):
   170         return construct_message_id(self.config.appid, eid, self.msgid_timestamp)
   170         return construct_message_id(self.config.appid, eid, self.msgid_timestamp)
   235     except:
   235     except:
   236         return None
   236         return None
   237     if appid != fromappid or host != gethostname():
   237     if appid != fromappid or host != gethostname():
   238         return None
   238         return None
   239     return values
   239     return values
   240     
   240 
   241 
   241 
   242 class StatusChangeMixIn(object):
   242 class StatusChangeMixIn(object):
   243     id = 'notif_status_change'
   243     id = 'notif_status_change'
   244     msgid_timestamp = True
   244     msgid_timestamp = True
   245     message = _('status changed')
   245     message = _('status changed')
   261 
   261 
   262 # XXX should be based on dc_title/dc_description, no?
   262 # XXX should be based on dc_title/dc_description, no?
   263 
   263 
   264 class ContentAddedView(NotificationView):
   264 class ContentAddedView(NotificationView):
   265     __abstract__ = True
   265     __abstract__ = True
   266     id = 'notif_after_add_entity' 
   266     id = 'notif_after_add_entity'
   267     msgid_timestamp = False
   267     msgid_timestamp = False
   268     message = _('new')
   268     message = _('new')
   269     content = """
   269     content = """
   270 %(title)s
   270 %(title)s
   271 
   271 
   272 %(content)s
   272 %(content)s
   273 
   273 
   274 url: %(url)s
   274 url: %(url)s
   275 """
   275 """
   276     
   276 
   277     def context(self, **kwargs):
   277     def context(self, **kwargs):
   278         entity = self.entity(0, 0)
   278         entity = self.entity(0, 0)
   279         content = entity.printable_value(self.content_attr, format='text/plain')
   279         content = entity.printable_value(self.content_attr, format='text/plain')
   280         if content:
   280         if content:
   281             contentformat = getattr(entity, self.content_attr + '_format', 'text/rest')
   281             contentformat = getattr(entity, self.content_attr + '_format', 'text/rest')
   282             content = normalize_text(content, 80, rest=contentformat=='text/rest')
   282             content = normalize_text(content, 80, rest=contentformat=='text/rest')
   283         return super(ContentAddedView, self).context(content=content, **kwargs)
   283         return super(ContentAddedView, self).context(content=content, **kwargs)
   284     
   284 
   285     def subject(self):
   285     def subject(self):
   286         entity = self.entity(0, 0)
   286         entity = self.entity(0, 0)
   287         return  u'%s #%s (%s)' % (self.req.__('New %s' % entity.e_schema),
   287         return  u'%s #%s (%s)' % (self.req.__('New %s' % entity.e_schema),
   288                                   entity.eid, self.user_login())
   288                                   entity.eid, self.user_login())
   289 
   289 
   290 NormalizedTextView = class_renamed('NormalizedTextView', ContentAddedView)
   290 NormalizedTextView = class_renamed('NormalizedTextView', ContentAddedView)
   291 
       
   292 class CardAddedView(ContentAddedView):
       
   293     """get notified from new cards"""
       
   294     __select__ = implements('Card')
       
   295     content_attr = 'synopsis'
       
   296     
       
   297