101 |
101 |
102 |
102 |
103 class EntityUpdateHook(NotificationHook): |
103 class EntityUpdateHook(NotificationHook): |
104 __regid__ = 'notifentityupdated' |
104 __regid__ = 'notifentityupdated' |
105 __abstract__ = True # do not register by default |
105 __abstract__ = True # do not register by default |
106 |
106 __select__ = NotificationHook.__select__ & hook.from_dbapi_query() |
107 events = ('before_update_entity',) |
107 events = ('before_update_entity',) |
108 skip_attrs = set() |
108 skip_attrs = set() |
109 |
109 |
110 def __call__(self): |
110 def __call__(self): |
111 session = self._cw |
111 session = self._cw |
112 if self.entity.eid in session.transaction_data.get('neweids', ()): |
112 if self.entity.eid in session.transaction_data.get('neweids', ()): |
113 return # entity is being created |
113 return # entity is being created |
114 if session.is_super_session: |
|
115 return # ignore changes triggered by hooks |
|
116 # then compute changes |
114 # then compute changes |
117 changes = session.transaction_data.setdefault('changes', {}) |
115 changes = session.transaction_data.setdefault('changes', {}) |
118 thisentitychanges = changes.setdefault(self.entity.eid, set()) |
116 thisentitychanges = changes.setdefault(self.entity.eid, set()) |
119 attrs = [k for k in self.entity.edited_attributes if not k in self.skip_attrs] |
117 attrs = [k for k in self.entity.edited_attributes if not k in self.skip_attrs] |
120 if not attrs: |
118 if not attrs: |
123 for i, attr in enumerate(attrs): |
121 for i, attr in enumerate(attrs): |
124 var = chr(65+i) |
122 var = chr(65+i) |
125 rqlsel.append(var) |
123 rqlsel.append(var) |
126 rqlrestr.append('X %s %s' % (attr, var)) |
124 rqlrestr.append('X %s %s' % (attr, var)) |
127 rql = 'Any %s WHERE %s' % (','.join(rqlsel), ','.join(rqlrestr)) |
125 rql = 'Any %s WHERE %s' % (','.join(rqlsel), ','.join(rqlrestr)) |
128 rset = session.unsafe_execute(rql, {'x': self.entity.eid}, 'x') |
126 rset = session.execute(rql, {'x': self.entity.eid}, 'x') |
129 for i, attr in enumerate(attrs): |
127 for i, attr in enumerate(attrs): |
130 oldvalue = rset[0][i] |
128 oldvalue = rset[0][i] |
131 newvalue = self.entity[attr] |
129 newvalue = self.entity[attr] |
132 if oldvalue != newvalue: |
130 if oldvalue != newvalue: |
133 thisentitychanges.add((attr, oldvalue, newvalue)) |
131 thisentitychanges.add((attr, oldvalue, newvalue)) |
137 |
135 |
138 # supervising ################################################################## |
136 # supervising ################################################################## |
139 |
137 |
140 class SomethingChangedHook(NotificationHook): |
138 class SomethingChangedHook(NotificationHook): |
141 __regid__ = 'supervising' |
139 __regid__ = 'supervising' |
|
140 __select__ = NotificationHook.__select__ & hook.from_dbapi_query() |
142 events = ('before_add_relation', 'before_delete_relation', |
141 events = ('before_add_relation', 'before_delete_relation', |
143 'after_add_entity', 'before_update_entity') |
142 'after_add_entity', 'before_update_entity') |
144 |
143 |
145 def __call__(self): |
144 def __call__(self): |
146 # XXX use proper selectors |
|
147 if self._cw.is_super_session or self._cw.repo.config.repairing: |
|
148 return # ignore changes triggered by hooks or maintainance shell |
|
149 dest = self._cw.vreg.config['supervising-addrs'] |
145 dest = self._cw.vreg.config['supervising-addrs'] |
150 if not dest: # no supervisors, don't do this for nothing... |
146 if not dest: # no supervisors, don't do this for nothing... |
151 return |
147 return |
152 if self._call(): |
148 if self._call(): |
153 SupervisionMailOp(self._cw) |
149 SupervisionMailOp(self._cw) |