server/hooksmanager.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 12 Nov 2009 13:53:26 +0100
branchstable
changeset 3829 9674d62a54f9
parent 3689 deb13e88e037
child 3720 5376aaadd16b
child 4212 ab6573088b4a
permissions -rw-r--r--
close #474415 by using 'is' instead of comparison which explicitly fails on entity classes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     1
"""Hooks management
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     2
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     3
Hooks are called before / after any individual update of entities / relations
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     4
in the repository.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     5
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     6
Here is the prototype of the different hooks:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     7
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     8
* filtered on the entity's type:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     9
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    10
  before_add_entity    (session, entity)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    11
  after_add_entity     (session, entity)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    12
  before_update_entity (session, entity)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    13
  after_update_entity  (session, entity)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    14
  before_delete_entity (session, eid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    15
  after_delete_entity  (session, eid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    16
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    17
* filtered on the relation's type:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    18
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
  before_add_relation    (session, fromeid, rtype, toeid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
  after_add_relation     (session, fromeid, rtype, toeid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    21
  before_delete_relation (session, fromeid, rtype, toeid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    22
  after_delete_relation  (session, fromeid, rtype, toeid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    23
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    24
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    25
:organization: Logilab
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1802
diff changeset
    26
:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    27
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1802
diff changeset
    28
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    29
"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    30
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    31
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 730
diff changeset
    32
ENTITIES_HOOKS = ('before_add_entity',    'after_add_entity',
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    33
                  'before_update_entity', 'after_update_entity',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    34
                  'before_delete_entity', 'after_delete_entity')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
RELATIONS_HOOKS = ('before_add_relation',   'after_add_relation' ,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    36
                   'before_delete_relation','after_delete_relation')
2493
9806571ea790 major refactoring of database dump/restore:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2492
diff changeset
    37
SYSTEM_HOOKS = ('server_backup', 'server_restore',
9806571ea790 major refactoring of database dump/restore:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2492
diff changeset
    38
                'server_startup', 'server_shutdown',
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    39
                'session_open', 'session_close')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    40
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    41
ALL_HOOKS = frozenset(ENTITIES_HOOKS + RELATIONS_HOOKS + SYSTEM_HOOKS)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    42
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    43
class HooksManager(object):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    44
    """handle hooks registration and calls
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    45
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
    verification_hooks_activated = True
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 730
diff changeset
    47
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    48
    def __init__(self, schema):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    49
        self.set_schema(schema)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    50
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    51
    def set_schema(self, schema):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    52
        self._hooks = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
        self.schema = schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
        self._init_hooks(schema)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 730
diff changeset
    55
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    56
    def register_hooks(self, hooks):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
        """register a dictionary of hooks :
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 730
diff changeset
    58
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
             {'event': {'entity or relation type': [callbacks list]}}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    61
        for event, subevents in hooks.items():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    62
            for subevent, callbacks in subevents.items():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
                for callback in callbacks:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    64
                    self.register_hook(callback, event, subevent)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 730
diff changeset
    65
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    66
    def register_hook(self, function, event, etype=''):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    67
        """register a function to call when <event> occurs
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 730
diff changeset
    68
2579
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
    69
        <etype> is an entity/relation type or an empty string.
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
    70
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
    71
        If etype is the empty string, the function will be called at each event,
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
    72
        else the function will be called only when event occurs on an entity or
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
    73
        relation of the given type.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    74
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
        assert event in ALL_HOOKS, '%r NOT IN %r' % (event, ALL_HOOKS)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    76
        assert (not event in SYSTEM_HOOKS or not etype), (event, etype)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    77
        etype = etype or ''
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    78
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    79
            self._hooks[event][etype].append(function)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    80
            self.debug('registered hook %s on %s (%s)', event, etype or 'any',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    81
                       function.func_name)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 730
diff changeset
    82
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    83
        except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    84
            self.error('can\'t register hook %s on %s (%s)',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    85
                       event, etype or 'any', function.func_name)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 730
diff changeset
    86
2579
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
    87
    def unregister_hook(self, function_or_cls, event=None, etype=''):
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
    88
        """unregister a function to call when <event> occurs, or a Hook subclass.
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
    89
        In the later case, event/type information are extracted from the given
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
    90
        class.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    91
        """
2579
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
    92
        if isinstance(function_or_cls, type) and issubclass(function_or_cls, Hook):
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
    93
            for event, ertype in function_or_cls.register_to():
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
    94
                for hook in self._hooks[event][ertype]:
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
    95
                    if getattr(hook, 'im_self', None).__class__ is function_or_cls:
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
    96
                        self._hooks[event][ertype].remove(hook)
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
    97
                        self.info('unregister hook %s on %s (%s)', event, etype,
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
    98
                                  function_or_cls.__name__)
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
    99
                        break
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
   100
                else:
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
   101
                    self.warning("can't unregister hook %s on %s (%s), not found",
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
   102
                                 event, etype, function_or_cls.__name__)
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
   103
        else:
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
   104
            assert event in ALL_HOOKS, event
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
   105
            etype = etype or ''
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
   106
            self.info('unregister hook %s on %s (%s)', event, etype,
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
   107
                      function_or_cls.func_name)
e69b2342bd8b [hooksmanager] nicer unregister_hook implementation, allowing to give a Hook subclass as argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2493
diff changeset
   108
            self._hooks[event][etype].remove(function_or_cls)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   109
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   110
    def call_hooks(self, __event, __type='', *args, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   111
        """call hook matching event and optional type"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   112
        if __type:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   113
            self.info('calling hooks for event %s (%s)', __event, __type)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   114
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   115
            self.info('calling hooks for event %s', __event)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   116
        # call generic hooks first
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   117
        for hook in self._hooks[__event]['']:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
            #print '[generic]', hook.__name__
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   119
            hook(*args, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   120
        if __type:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   121
            for hook in self._hooks[__event][__type]:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   122
                #print '[%s]'%__type, hook.__name__
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   123
                hook(*args, **kwargs)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 730
diff changeset
   124
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   125
    def _init_hooks(self, schema):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   126
        """initialize the hooks map"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   127
        for hook_event in ENTITIES_HOOKS:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   128
            self._hooks[hook_event] = {'': []}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   129
            for etype in schema.entities():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   130
                self._hooks[hook_event][etype] = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   131
        for hook_event in RELATIONS_HOOKS:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   132
            self._hooks[hook_event] = {'': []}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   133
            for r_type in schema.relations():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   134
                self._hooks[hook_event][r_type] = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   135
        for hook_event in SYSTEM_HOOKS:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   136
            self._hooks[hook_event] = {'': []}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   137
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   138
    def register_system_hooks(self, config):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   139
        """register system hooks according to the configuration"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   140
        self.info('register core hooks')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   141
        from cubicweb.server.hooks import _register_metadata_hooks, _register_wf_hooks
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   142
        _register_metadata_hooks(self)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   143
        self.info('register workflow hooks')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   144
        _register_wf_hooks(self)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   145
        if config.core_hooks:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   146
            from cubicweb.server.hooks import _register_core_hooks
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   147
            _register_core_hooks(self)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   148
        if config.schema_hooks:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   149
            from cubicweb.server.schemahooks import _register_schema_hooks
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   150
            self.info('register schema hooks')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   151
            _register_schema_hooks(self)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   152
        if config.usergroup_hooks:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   153
            from cubicweb.server.hooks import _register_usergroup_hooks
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   154
            from cubicweb.server.hooks import _register_eproperty_hooks
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   155
            self.info('register user/group hooks')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   156
            _register_usergroup_hooks(self)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   157
            _register_eproperty_hooks(self)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   158
        if config.security_hooks:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   159
            from cubicweb.server.securityhooks import register_security_hooks
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   160
            self.info('register security hooks')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   161
            register_security_hooks(self)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   162
        if not self.verification_hooks_activated:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
            self.deactivate_verification_hooks()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   164
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   165
    def deactivate_verification_hooks(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   166
        from cubicweb.server.hooks import (cardinalitycheck_after_add_entity,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   167
                                        cardinalitycheck_before_del_relation,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   168
                                        cstrcheck_after_add_relation,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   169
                                        uniquecstrcheck_before_modification)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   170
        self.warning('deactivating verification hooks')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   171
        self.verification_hooks_activated = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   172
        self.unregister_hook(cardinalitycheck_after_add_entity, 'after_add_entity', '')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   173
        self.unregister_hook(cardinalitycheck_before_del_relation, 'before_delete_relation', '')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   174
        self.unregister_hook(cstrcheck_after_add_relation, 'after_add_relation', '')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   175
        self.unregister_hook(uniquecstrcheck_before_modification, 'before_add_entity', '')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   176
        self.unregister_hook(uniquecstrcheck_before_modification, 'before_update_entity', '')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   177
#         self.unregister_hook(tidy_html_fields('before_add_entity'), 'before_add_entity', '')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   178
#         self.unregister_hook(tidy_html_fields('before_update_entity'), 'before_update_entity', '')
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 730
diff changeset
   179
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   180
    def reactivate_verification_hooks(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   181
        from cubicweb.server.hooks import (cardinalitycheck_after_add_entity,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   182
                                        cardinalitycheck_before_del_relation,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   183
                                        cstrcheck_after_add_relation,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   184
                                        uniquecstrcheck_before_modification)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   185
        self.warning('reactivating verification hooks')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   186
        self.verification_hooks_activated = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   187
        self.register_hook(cardinalitycheck_after_add_entity, 'after_add_entity', '')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   188
        self.register_hook(cardinalitycheck_before_del_relation, 'before_delete_relation', '')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   189
        self.register_hook(cstrcheck_after_add_relation, 'after_add_relation', '')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   190
        self.register_hook(uniquecstrcheck_before_modification, 'before_add_entity', '')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   191
        self.register_hook(uniquecstrcheck_before_modification, 'before_update_entity', '')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   192
#         self.register_hook(tidy_html_fields('before_add_entity'), 'before_add_entity', '')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   193
#         self.register_hook(tidy_html_fields('before_update_entity'), 'before_update_entity', '')
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 730
diff changeset
   194
692
800592b8d39b replace deprecated cubicweb.common.selectors by its new module path (cubicweb.selectors)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 672
diff changeset
   195
from cubicweb.selectors import yes
722
50a99184cf47 update some imports
sylvain.thenault@logilab.fr
parents: 719
diff changeset
   196
from cubicweb.appobject import AppObject
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   197
712
ce49e3885453 remove autoselectors metaclass, __select__ is built during registration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 692
diff changeset
   198
class autoid(type):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   199
    """metaclass to create an unique 'id' attribute on the class using it"""
712
ce49e3885453 remove autoselectors metaclass, __select__ is built during registration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 692
diff changeset
   200
    # XXX is this metaclass really necessary ?
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   201
    def __new__(mcs, name, bases, classdict):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   202
        cls = super(autoid, mcs).__new__(mcs, name, bases, classdict)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   203
        cls.id = str(id(cls))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   204
        return cls
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   205
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   206
class Hook(AppObject):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   207
    __metaclass__ = autoid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   208
    __registry__ = 'hooks'
730
9062cdc140a9 __select__ migration
sylvain.thenault@logilab.fr
parents: 722
diff changeset
   209
    __select__ = yes()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   210
    # set this in derivated classes
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   211
    events = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   212
    accepts = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   213
    enabled = True
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 730
diff changeset
   214
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   215
    def __init__(self, event=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   216
        super(Hook, self).__init__()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   217
        self.event = event
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 730
diff changeset
   218
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   219
    @classmethod
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   220
    def registered(cls, vreg):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   221
        super(Hook, cls).registered(vreg)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   222
        return cls()
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 730
diff changeset
   223
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   224
    @classmethod
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   225
    def register_to(cls):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   226
        if not cls.enabled:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   227
            cls.warning('%s hook has been disabled', cls)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   228
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   229
        done = set()
2350
209a816a5fb4 added some assertion on expected hooks class attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   230
        assert isinstance(cls.events, (tuple, list)), \
209a816a5fb4 added some assertion on expected hooks class attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   231
               '%s: events is expected to be a tuple, not %s' % (
209a816a5fb4 added some assertion on expected hooks class attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   232
            cls, type(cls.events))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   233
        for event in cls.events:
2492
c51be1cf8317 should check for every system hooks, not only server_startup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2452
diff changeset
   234
            if event in SYSTEM_HOOKS:
2350
209a816a5fb4 added some assertion on expected hooks class attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   235
                assert not cls.accepts or cls.accepts == ('Any',), \
2492
c51be1cf8317 should check for every system hooks, not only server_startup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2452
diff changeset
   236
                       '%s doesnt make sense on %s' % (cls.accepts, event)
2350
209a816a5fb4 added some assertion on expected hooks class attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   237
                cls.accepts = ('Any',)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   238
            for ertype in cls.accepts:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   239
                if (event, ertype) in done:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   240
                    continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   241
                yield event, ertype
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   242
                done.add((event, ertype))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   243
                try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   244
                    eschema = cls.schema.eschema(ertype)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   245
                except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   246
                    # relation schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   247
                    pass
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   248
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   249
                    for eetype in eschema.specialized_by():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   250
                        if (event, eetype) in done:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   251
                            continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   252
                        yield event, str(eetype)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   253
                        done.add((event, eetype))
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 730
diff changeset
   254
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   255
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   256
    def make_callback(self, event):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   257
        if len(self.events) == 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   258
            return self.call
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   259
        return self.__class__(event=event).call
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   260
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   261
    def call(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   262
        raise NotImplementedError
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 730
diff changeset
   263
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   264
class SystemHook(Hook):
2452
868e0c75a57d fix SystemHook declaration, accepts=('',) doesn't mean anything
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2350
diff changeset
   265
    accepts = ()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   266
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   267
from logging import getLogger
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   268
from cubicweb import set_log_methods
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   269
set_log_methods(HooksManager, getLogger('cubicweb.hooksmanager'))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   270
set_log_methods(Hook, getLogger('cubicweb.hooks'))
2918
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   271
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   272
# base classes for relation propagation ########################################
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   273
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   274
from cubicweb.server.pool import PreCommitOperation
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   275
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   276
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   277
class PropagateSubjectRelationHook(Hook):
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   278
    """propagate permissions and nosy list when new entity are added"""
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   279
    events = ('after_add_relation',)
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   280
    # to set in concrete class
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   281
    rtype = None
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   282
    subject_relations = None
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   283
    object_relations = None
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   284
    accepts = None # subject_relations + object_relations
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   285
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   286
    def call(self, session, fromeid, rtype, toeid):
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   287
        for eid in (fromeid, toeid):
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   288
            etype = session.describe(eid)[0]
3689
deb13e88e037 follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3088
diff changeset
   289
            if self.rtype not in self.schema.eschema(etype).subjrels:
2918
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   290
                return
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   291
        if rtype in self.subject_relations:
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   292
            meid, seid = fromeid, toeid
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   293
        else:
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   294
            assert rtype in self.object_relations
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   295
            meid, seid = toeid, fromeid
3088
854a30d8c092 do not delay sync queries to an operation, it may cause pb (nosy list propagation for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2918
diff changeset
   296
        session.unsafe_execute(
854a30d8c092 do not delay sync queries to an operation, it may cause pb (nosy list propagation for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2918
diff changeset
   297
            'SET E %s P WHERE X %s P, X eid %%(x)s, E eid %%(e)s, NOT E %s P'\
854a30d8c092 do not delay sync queries to an operation, it may cause pb (nosy list propagation for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2918
diff changeset
   298
            % (self.rtype, self.rtype, self.rtype),
854a30d8c092 do not delay sync queries to an operation, it may cause pb (nosy list propagation for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2918
diff changeset
   299
            {'x': meid, 'e': seid}, ('x', 'e'))
2918
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   300
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   301
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   302
class PropagateSubjectRelationAddHook(Hook):
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   303
    """propagate on existing entities when a permission or nosy list is added"""
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   304
    events = ('after_add_relation',)
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   305
    # to set in concrete class
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   306
    rtype = None
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   307
    subject_relations = None
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   308
    object_relations = None
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   309
    accepts = None # (self.rtype,)
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   310
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   311
    def call(self, session, fromeid, rtype, toeid):
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   312
        eschema = self.schema.eschema(session.describe(fromeid)[0])
3088
854a30d8c092 do not delay sync queries to an operation, it may cause pb (nosy list propagation for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2918
diff changeset
   313
        execute = session.unsafe_execute
2918
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   314
        for rel in self.subject_relations:
3689
deb13e88e037 follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3088
diff changeset
   315
            if rel in eschema.subjrels:
3088
854a30d8c092 do not delay sync queries to an operation, it may cause pb (nosy list propagation for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2918
diff changeset
   316
                execute('SET R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
854a30d8c092 do not delay sync queries to an operation, it may cause pb (nosy list propagation for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2918
diff changeset
   317
                        'X %s R, NOT R %s P' % (rtype, rel, rtype),
854a30d8c092 do not delay sync queries to an operation, it may cause pb (nosy list propagation for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2918
diff changeset
   318
                        {'x': fromeid, 'p': toeid}, 'x')
2918
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   319
        for rel in self.object_relations:
3689
deb13e88e037 follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3088
diff changeset
   320
            if rel in eschema.objrels:
3088
854a30d8c092 do not delay sync queries to an operation, it may cause pb (nosy list propagation for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2918
diff changeset
   321
                execute('SET R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
854a30d8c092 do not delay sync queries to an operation, it may cause pb (nosy list propagation for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2918
diff changeset
   322
                        'R %s X, NOT R %s P' % (rtype, rel, rtype),
854a30d8c092 do not delay sync queries to an operation, it may cause pb (nosy list propagation for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2918
diff changeset
   323
                        {'x': fromeid, 'p': toeid}, 'x')
2918
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   324
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   325
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   326
class PropagateSubjectRelationDelHook(Hook):
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   327
    """propagate on existing entities when a permission is deleted"""
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   328
    events = ('after_delete_relation',)
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   329
    # to set in concrete class
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   330
    rtype = None
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   331
    subject_relations = None
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   332
    object_relations = None
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   333
    accepts = None # (self.rtype,)
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   334
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   335
    def call(self, session, fromeid, rtype, toeid):
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   336
        eschema = self.schema.eschema(session.describe(fromeid)[0])
3088
854a30d8c092 do not delay sync queries to an operation, it may cause pb (nosy list propagation for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2918
diff changeset
   337
        execute = session.unsafe_execute
2918
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   338
        for rel in self.subject_relations:
3689
deb13e88e037 follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3088
diff changeset
   339
            if rel in eschema.subjrels:
3088
854a30d8c092 do not delay sync queries to an operation, it may cause pb (nosy list propagation for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2918
diff changeset
   340
                execute('DELETE R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
854a30d8c092 do not delay sync queries to an operation, it may cause pb (nosy list propagation for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2918
diff changeset
   341
                        'X %s R' % (rtype, rel),
854a30d8c092 do not delay sync queries to an operation, it may cause pb (nosy list propagation for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2918
diff changeset
   342
                        {'x': fromeid, 'p': toeid}, 'x')
2918
452b4c9ee61d work in progress: backport some generic relation propagation hooks from tracker
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2579
diff changeset
   343
        for rel in self.object_relations:
3689
deb13e88e037 follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3088
diff changeset
   344
            if rel in eschema.objrels:
3088
854a30d8c092 do not delay sync queries to an operation, it may cause pb (nosy list propagation for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2918
diff changeset
   345
                execute('DELETE R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
854a30d8c092 do not delay sync queries to an operation, it may cause pb (nosy list propagation for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2918
diff changeset
   346
                        'R %s X' % (rtype, rel),
854a30d8c092 do not delay sync queries to an operation, it may cause pb (nosy list propagation for instance)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2918
diff changeset
   347
                        {'x': fromeid, 'p': toeid}, 'x')