hooks/notification.py
author Pierre-Yves David <pierre-yves.david@logilab.fr>
Wed, 07 Mar 2012 16:16:44 +0100
branchstable
changeset 8300 87c72dccf7b9
parent 8227 884405bf3621
child 8236 cc70da744f43
permissions -rw-r--r--
[storage/bfss] ensure bfss never remove a cw_edited item (closes #2236287) When the <old value> == <new value> (not really and update but can happen), the value was popped but never restored. The cw_edited attribut had wrong content for a small time lapse.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7068
90ddf608fe2b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6760
diff changeset
     1
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4993
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4993
diff changeset
     3
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4993
diff changeset
     4
# This file is part of CubicWeb.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4993
diff changeset
     5
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4993
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4993
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4993
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4993
diff changeset
     9
# any later version.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4993
diff changeset
    10
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4993
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4993
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4993
diff changeset
    14
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4993
diff changeset
    15
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4993
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4993
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
7068
90ddf608fe2b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6760
diff changeset
    18
"""some hooks to handle notification on entity's changes"""
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    19
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    20
__docformat__ = "restructuredtext en"
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    21
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    22
from logilab.common.textutils import normalize_text
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    23
6760
2c1fc68ac258 handle the fact that there might be no views registered in some configurations (#1382716)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6466
diff changeset
    24
from cubicweb import RegistryNotFound
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5693
diff changeset
    25
from cubicweb.selectors import is_instance
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    26
from cubicweb.server import hook
3427
78dfef45ee48 [notification] add missing import, fix dummy AttributeError in RenderAndSendNotificationView
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3422
diff changeset
    27
from cubicweb.sobjects.supervising import SupervisionMailOp
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    28
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    29
class RenderAndSendNotificationView(hook.Operation):
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    30
    """delay rendering of notification view until precommit"""
7879
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
    31
    view = None # make pylint happy
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
    32
8227
884405bf3621 [email notifications] send notification at post-commit time (closes #2119248)
Alexandre Richardson <alexandre.richardson@logilab.fr>
parents: 7879
diff changeset
    33
    def postcommit_event(self):
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    34
        view = self.view
3418
7b49fa7e942d [api] use _cw, cw_row, cw_col, cw_rset etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3376
diff changeset
    35
        if view.cw_rset is not None and not view.cw_rset:
3072
6fb42c53f6df backport 3.5 branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3023
diff changeset
    36
            return # entity added and deleted in the same transaction (cache effect)
3422
089c4b71ac16 [hooks] fix dummy NameError in RenderAndSendNotification
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3418
diff changeset
    37
        if view.cw_rset and self.session.deleted_in_transaction(view.cw_rset[view.cw_row or 0][view.cw_col or 0]):
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    38
            return # entity added and deleted in the same transaction
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    39
        self.view.render_and_send(**getattr(self, 'viewargs', {}))
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    40
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    41
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    42
class NotificationHook(hook.Hook):
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    43
    __abstract__ = True
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    44
    category = 'notification'
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    45
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    46
    def select_view(self, vid, rset, row=0, col=0):
6760
2c1fc68ac258 handle the fact that there might be no views registered in some configurations (#1382716)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6466
diff changeset
    47
        try:
2c1fc68ac258 handle the fact that there might be no views registered in some configurations (#1382716)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6466
diff changeset
    48
            return self._cw.vreg['views'].select_or_none(vid, self._cw, rset=rset,
2c1fc68ac258 handle the fact that there might be no views registered in some configurations (#1382716)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6466
diff changeset
    49
                                                         row=row, col=col)
2c1fc68ac258 handle the fact that there might be no views registered in some configurations (#1382716)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6466
diff changeset
    50
        except RegistryNotFound: # can happen in some config
2c1fc68ac258 handle the fact that there might be no views registered in some configurations (#1382716)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6466
diff changeset
    51
                                 # (e.g. repo only config with no
2c1fc68ac258 handle the fact that there might be no views registered in some configurations (#1382716)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6466
diff changeset
    52
                                 # notification views registered by
2c1fc68ac258 handle the fact that there might be no views registered in some configurations (#1382716)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6466
diff changeset
    53
                                 # the instance's cubes)
2c1fc68ac258 handle the fact that there might be no views registered in some configurations (#1382716)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6466
diff changeset
    54
            return None
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    55
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    56
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    57
class StatusChangeHook(NotificationHook):
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    58
    """notify when a workflowable entity has its state modified"""
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3163
diff changeset
    59
    __regid__ = 'notifystatuschange'
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5693
diff changeset
    60
    __select__ = NotificationHook.__select__ & is_instance('TrInfo')
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    61
    events = ('after_add_entity',)
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    62
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    63
    def __call__(self):
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    64
        entity = self.entity
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    65
        if not entity.from_state: # not a transition
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    66
            return
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    67
        rset = entity.related('wf_info_for')
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    68
        view = self.select_view('notif_status_change', rset=rset, row=0)
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    69
        if view is None:
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    70
            return
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    71
        comment = entity.printable_value('comment', format='text/plain')
3023
7864fee8b4ec backport 3.5 step 1, remaining wf changes in hooks to merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2900
diff changeset
    72
        # XXX don't try to wrap rest until we've a proper transformation (see
7864fee8b4ec backport 3.5 step 1, remaining wf changes in hooks to merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2900
diff changeset
    73
        # #103822)
7864fee8b4ec backport 3.5 step 1, remaining wf changes in hooks to merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2900
diff changeset
    74
        if comment and entity.comment_format != 'text/rest':
7864fee8b4ec backport 3.5 step 1, remaining wf changes in hooks to merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2900
diff changeset
    75
            comment = normalize_text(comment, 80)
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2841
diff changeset
    76
        RenderAndSendNotificationView(self._cw, view=view, viewargs={
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    77
            'comment': comment, 'previous_state': entity.previous_state.name,
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    78
            'current_state': entity.new_state.name})
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    79
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    80
class RelationChangeHook(NotificationHook):
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3163
diff changeset
    81
    __regid__ = 'notifyrelationchange'
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    82
    events = ('before_add_relation', 'after_add_relation',
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    83
              'before_delete_relation', 'after_delete_relation')
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    84
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    85
    def __call__(self):
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    86
        """if a notification view is defined for the event, send notification
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    87
        email defined by the view
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    88
        """
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2841
diff changeset
    89
        rset = self._cw.eid_rset(self.eidfrom)
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    90
        view = self.select_view('notif_%s_%s' % (self.event,  self.rtype),
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    91
                                rset=rset, row=0)
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    92
        if view is None:
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    93
            return
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2841
diff changeset
    94
        RenderAndSendNotificationView(self._cw, view=view)
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    95
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    96
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    97
class EntityChangeHook(NotificationHook):
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    98
    """if a notification view is defined for the event, send notification
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    99
    email defined by the view
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   100
    """
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3163
diff changeset
   101
    __regid__ = 'notifyentitychange'
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   102
    events = ('after_add_entity', 'after_update_entity')
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   103
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   104
    def __call__(self):
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   105
        rset = self.entity.as_rset()
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   106
        view = self.select_view('notif_%s' % self.event, rset=rset, row=0)
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   107
        if view is None:
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   108
            return
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2841
diff changeset
   109
        RenderAndSendNotificationView(self._cw, view=view)
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   110
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   111
3536
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   112
class EntityUpdatedNotificationOp(hook.SingleLastOperation):
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   113
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   114
    def precommit_event(self):
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   115
        session = self.session
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   116
        for eid in session.transaction_data['changes']:
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   117
            view = session.vreg['views'].select('notif_entity_updated', session,
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   118
                                                rset=session.eid_rset(eid),
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   119
                                                row=0)
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   120
            RenderAndSendNotificationView(session, view=view)
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   121
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   122
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   123
class EntityUpdateHook(NotificationHook):
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   124
    __regid__ = 'notifentityupdated'
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   125
    __abstract__ = True # do not register by default
4835
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   126
    __select__ = NotificationHook.__select__ & hook.from_dbapi_query()
3536
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   127
    events = ('before_update_entity',)
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   128
    skip_attrs = set()
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   129
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   130
    def __call__(self):
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   131
        session = self._cw
4843
5f7363416765 fix hooks control method name + other litle cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   132
        if session.added_in_transaction(self.entity.eid):
3536
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   133
            return # entity is being created
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   134
        # then compute changes
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   135
        attrs = [k for k in self.entity.cw_edited
4843
5f7363416765 fix hooks control method name + other litle cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   136
                 if not k in self.skip_attrs]
3536
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   137
        if not attrs:
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   138
            return
4993
c9229f185690 [notification] don't create 'changes' in transaction data until actually needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4843
diff changeset
   139
        changes = session.transaction_data.setdefault('changes', {})
c9229f185690 [notification] don't create 'changes' in transaction data until actually needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4843
diff changeset
   140
        thisentitychanges = changes.setdefault(self.entity.eid, set())
3536
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   141
        rqlsel, rqlrestr = [], ['X eid %(x)s']
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   142
        for i, attr in enumerate(attrs):
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   143
            var = chr(65+i)
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   144
            rqlsel.append(var)
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   145
            rqlrestr.append('X %s %s' % (attr, var))
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   146
        rql = 'Any %s WHERE %s' % (','.join(rqlsel), ','.join(rqlrestr))
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4993
diff changeset
   147
        rset = session.execute(rql, {'x': self.entity.eid})
3536
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   148
        for i, attr in enumerate(attrs):
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   149
            oldvalue = rset[0][i]
6466
43d71dd8a8ec cleanup and 3.10 updates
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   150
            newvalue = self.entity.cw_edited[attr]
3536
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   151
            if oldvalue != newvalue:
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   152
                thisentitychanges.add((attr, oldvalue, newvalue))
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   153
        if thisentitychanges:
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   154
            EntityUpdatedNotificationOp(session)
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   155
f6c9a5df80fb backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3427
diff changeset
   156
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   157
# supervising ##################################################################
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   158
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   159
class SomethingChangedHook(NotificationHook):
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3163
diff changeset
   160
    __regid__ = 'supervising'
4835
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   161
    __select__ = NotificationHook.__select__ & hook.from_dbapi_query()
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   162
    events = ('before_add_relation', 'before_delete_relation',
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   163
              'after_add_entity', 'before_update_entity')
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   164
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   165
    def __call__(self):
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2841
diff changeset
   166
        dest = self._cw.vreg.config['supervising-addrs']
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   167
        if not dest: # no supervisors, don't do this for nothing...
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   168
            return
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   169
        if self._call():
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2841
diff changeset
   170
            SupervisionMailOp(self._cw)
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   171
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   172
    def _call(self):
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   173
        event = self.event.split('_', 1)[1]
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   174
        if event == 'update_entity':
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2841
diff changeset
   175
            if self._cw.added_in_transaction(self.entity.eid):
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   176
                return False
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   177
            if self.entity.e_schema == 'CWUser':
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   178
                if not (frozenset(self.entity.cw_edited)
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   179
                        - frozenset(('eid', 'modification_date',
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   180
                                     'last_login_time'))):
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   181
                    # don't record last_login_time update which are done
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   182
                    # automatically at login time
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   183
                    return False
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2841
diff changeset
   184
        self._cw.transaction_data.setdefault('pendingchanges', []).append(
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   185
            (event, self))
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   186
        return True
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   187
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   188
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   189
class EntityDeleteHook(SomethingChangedHook):
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3163
diff changeset
   190
    __regid__ = 'supervisingentitydel'
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   191
    events = ('before_delete_entity',)
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   192
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   193
    def _call(self):
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   194
        try:
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   195
            title = self.entity.dc_title()
7815
2a164a9cf81c [exceptions] stop catching any exception in various places (closes #1942716)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7068
diff changeset
   196
        except Exception:
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   197
            # may raise an error during deletion process, for instance due to
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   198
            # missing required relation
5693
8af6623f3d4e [pylint] fix detected name errors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   199
            title = '#%s' % self.entity.eid
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2841
diff changeset
   200
        self._cw.transaction_data.setdefault('pendingchanges', []).append(
5693
8af6623f3d4e [pylint] fix detected name errors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   201
            ('delete_entity', (self.entity.eid, self.entity.__regid__, title)))
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   202
        return True