Merge lp:~zeitgeist/zeitgeist/hooks into lp:zeitgeist/0.1

Proposed by Markus Korn
Status: Merged
Merged at revision: 1532
Proposed branch: lp:~zeitgeist/zeitgeist/hooks
Merge into: lp:zeitgeist/0.1
Diff against target: 285 lines (+119/-31)
5 files modified
_zeitgeist/engine/extension.py (+61/-18)
_zeitgeist/engine/extensions/blacklist.py (+1/-1)
_zeitgeist/engine/extensions/datasource_registry.py (+1/-1)
_zeitgeist/engine/main.py (+6/-2)
test/engine-extension-test.py (+50/-9)
To merge this branch: bzr merge lp:~zeitgeist/zeitgeist/hooks
Reviewer Review Type Date Requested Status
Siegfried Gevatter Approve
Seif Lotfy Approve
Review via email: mp+31522@code.launchpad.net

Commit message

Fixed the "hook renaming"/"add missing hooks"-bug

Renaming of existing hooks (API change!):
* insert_event_hook() -> pre_insert_event()
* get_event_hook() -> get_event()
* delete_events_hook() -> post_delete_events()

Added additional hooks:
* added post_insert_event()
* added pre_delete_events()

changes to the tests:
* added tests for all hooks

Description of the change

Fixed the "hook renaming"/"add missing hooks"-bug

Renaming of existing hooks (API change!):
* insert_event_hook() -> pre_insert_event()
* get_event_hook() -> get_event()
* delete_events_hook() -> post_delete_events()

Added additional hooks:
* added post_insert_event()
* added pre_delete_events()

changes to the tests:
* added tests for all hooks

To post a comment you must log in.
Revision history for this message
Seif Lotfy (seif) wrote :

simple and straight forward... tests work here

Revision history for this message
Seif Lotfy (seif) :
review: Approve
Revision history for this message
Siegfried Gevatter (rainct) wrote :

There's a comment which needs to be uploaded:
+ def **pre**_delete_events(self, ids, sender):
+ """
+ Hook applied before events are deleted from the log.
+
+ :param ids: A list of event ids for the events **that has been deleted**
+ :param sender: The unique DBus name for the client triggering the delete
+ :returns: The filtered list of event ids which should be deleted

Other than that, looks good. Thanks for working on this.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '_zeitgeist/engine/extension.py'
2--- _zeitgeist/engine/extension.py 2010-07-01 08:04:55 +0000
3+++ _zeitgeist/engine/extension.py 2010-08-02 10:23:57 +0000
4@@ -49,7 +49,7 @@
5 def __init__(self, engine):
6 self.engine = weakref.proxy(engine)
7
8- def insert_event_hook(self, event, sender):
9+ def pre_insert_event(self, event, sender):
10 """
11 Hook applied to all events before they are inserted into the
12 log. The returned event is progressively passed through all
13@@ -69,7 +69,27 @@
14 """
15 return event
16
17- def get_event_hook(self, event, sender):
18+ def post_insert_event(self, event, sender):
19+ """
20+ Hook applied to all events after they are inserted into the
21+ log. The returned event is progressively passed through all
22+ extensions before the final result is inserted.
23+
24+ To block an event completely simply return :const:`None`.
25+ The event may also be modified or completely substituted for
26+ another event.
27+
28+ The default implementation of this method simply returns the
29+ event as is.
30+
31+ :param event: An :class:`Event <zeitgeist.datamodel.Event>`
32+ instance
33+ :param sender: The D-Bus bus name of the client
34+ :returns: Nothing
35+ """
36+ pass
37+
38+ def get_event(self, event, sender):
39 """
40 Hook applied to all events before they are returned to a client.
41 The event returned from this method is progressively passed
42@@ -84,22 +104,32 @@
43 event as is.
44
45 :param event: An :class:`Event <zeitgeist.datamodel.Event>`
46- instance
47+ instance or :const:`None`
48 :param sender: The D-Bus bus name of the client
49 :returns: The filtered event instance as the client
50 should see it
51 """
52 return event
53
54- def delete_events_hook(self, ids, sender):
55+ def post_delete_events(self, ids, sender):
56 """
57- Hook applied after events has been deleted from the log.
58+ Hook applied after events have been deleted from the log.
59
60 :param ids: A list of event ids for the events that has been deleted
61 :param sender: The unique DBus name for the client triggering the delete
62 :returns: Nothing
63 """
64 pass
65+
66+ def pre_delete_events(self, ids, sender):
67+ """
68+ Hook applied before events are deleted from the log.
69+
70+ :param ids: A list of event ids for the events that has been deleted
71+ :param sender: The unique DBus name for the client triggering the delete
72+ :returns: The filtered list of event ids which should be deleted
73+ """
74+ return ids
75
76
77 def get_extensions():
78@@ -233,7 +263,7 @@
79
80 # FIXME: We need a stable iteration order
81 for ext in self.__extensions.itervalues():
82- event = ext.get_event_hook(event, sender)
83+ event = ext.get_event(event, sender)
84 if event is None:
85 # The event has been blocked by
86 # the extension pretend it's
87@@ -241,23 +271,36 @@
88 continue
89 return event
90
91- def apply_delete_hooks(self, ids, sender):
92- # Apply extension filters if we have an event
93-
94- # FIXME: We need a stable iteration order
95- for ext in self.__extensions.itervalues():
96- event = ext.delete_events_hook(ids, sender)
97-
98-
99- def apply_insert_hooks(self, event, sender):
100- # FIXME: We need a stable iteration order
101- for ext in self.__extensions.itervalues():
102- event = ext.insert_event_hook(event, sender)
103+ def apply_post_delete(self, ids, sender):
104+ # Apply extension filters if we have an event
105+
106+ # FIXME: We need a stable iteration order
107+ for ext in self.__extensions.itervalues():
108+ event = ext.post_delete_events(ids, sender)
109+
110+ def apply_pre_delete(self, ids, sender):
111+ # Apply extension filters if we have an event
112+
113+ # FIXME: We need a stable iteration order
114+ for ext in self.__extensions.itervalues():
115+ ids = ext.pre_delete_events(ids, sender)
116+
117+ return ids
118+
119+ def apply_pre_insert(self, event, sender):
120+ # FIXME: We need a stable iteration order
121+ for ext in self.__extensions.itervalues():
122+ event = ext.pre_insert_event(event, sender)
123 if event is None:
124 # The event has been blocked by the extension
125 return None
126 return event
127
128+ def apply_post_insert(self, event, sender):
129+ # FIXME: We need a stable iteration order
130+ for ext in self.__extensions.itervalues():
131+ event = ext.post_insert_event(event, sender)
132+
133 def __len__(self):
134 return len(self.__extensions)
135
136
137=== modified file '_zeitgeist/engine/extensions/blacklist.py'
138--- _zeitgeist/engine/extensions/blacklist.py 2010-01-21 15:31:07 +0000
139+++ _zeitgeist/engine/extensions/blacklist.py 2010-08-02 10:23:57 +0000
140@@ -68,7 +68,7 @@
141 log.debug("No existing blacklist config found")
142 self._blacklist = []
143
144- def insert_event_hook(self, event, sender):
145+ def pre_insert_event(self, event, sender):
146 for tmpl in self._blacklist:
147 if event.matches_template(tmpl): return None
148 return event
149
150=== modified file '_zeitgeist/engine/extensions/datasource_registry.py'
151--- _zeitgeist/engine/extensions/datasource_registry.py 2010-07-22 22:59:25 +0000
152+++ _zeitgeist/engine/extensions/datasource_registry.py 2010-08-02 10:23:57 +0000
153@@ -104,7 +104,7 @@
154 if datasource[DataSource.UniqueId] == unique_id:
155 return datasource
156
157- def insert_event_hook(self, event, sender):
158+ def pre_insert_event(self, event, sender):
159 for (unique_id, bus_names) in self._running.iteritems():
160 if sender in bus_names:
161 datasource = self._get_data_source(unique_id)
162
163=== modified file '_zeitgeist/engine/main.py'
164--- _zeitgeist/engine/main.py 2010-07-28 20:10:07 +0000
165+++ _zeitgeist/engine/main.py 2010-08-02 10:23:57 +0000
166@@ -511,7 +511,7 @@
167
168 id = self.next_event_id()
169 event[0][Event.Id] = id
170- event = self.extensions.apply_insert_hooks(event, sender)
171+ event = self.extensions.apply_pre_insert(event, sender)
172 if event is None:
173 raise AssertionError("Inserting of event was blocked by an extension")
174 elif not issubclass(type(event), OrigEvent):
175@@ -569,6 +569,9 @@
176 self._mimetype[subject.mimetype],
177 subject.text,
178 subject.storage))
179+
180+ self.extensions.apply_post_insert(event, sender)
181+
182 except sqlite3.IntegrityError:
183 # The event was already registered.
184 # Rollback _last_event_id and return the ID of the original event
185@@ -606,6 +609,7 @@
186 return ""
187
188 def delete_events (self, ids, sender=None):
189+ ids = self.extensions.apply_pre_delete(ids, sender)
190 # Extract min and max timestamps for deleted events
191 self._cursor.execute("""
192 SELECT MIN(timestamp), MAX(timestamp)
193@@ -622,7 +626,7 @@
194 self._cursor.connection.commit()
195 log.debug("Deleted %s" % map(int, ids))
196
197- self.extensions.apply_delete_hooks(ids, sender)
198+ self.extensions.apply_post_delete(ids, sender)
199
200 return timestamps
201 else:
202
203=== modified file 'test/engine-extension-test.py'
204--- test/engine-extension-test.py 2010-07-22 09:29:31 +0000
205+++ test/engine-extension-test.py 2010-08-02 10:23:57 +0000
206@@ -68,14 +68,26 @@
207
208 class BlockAllInsertExtension(Extension):
209 PUBLIC_METHODS = []
210-
211- def insert_event_hook(self, event, sender):
212+ insert_count = 0
213+ do_insert = True
214+
215+ @classmethod
216+ def pre_insert_event(cls, event, sender):
217+ if cls.do_insert:
218+ cls.do_insert = False
219+ return event
220 return None
221
222+ @classmethod
223+ def post_insert_event(cls, event, sender):
224+ cls.insert_count += 1
225+
226 self.engine.extensions.load(BlockAllInsertExtension)
227 ids = import_events("test/data/five_events.js", self.engine)
228- # all inserts where blocked, so each id is 0 to indicate this
229- self.assertEquals(filter(None, ids), [])
230+
231+ # all but the first one events are blocked
232+ self.assertEquals(filter(None, ids), [1])
233+ self.assertEquals(BlockAllInsertExtension.insert_count, 1)
234
235 def testDeleteHook(self):
236
237@@ -84,14 +96,43 @@
238 del_ids = []
239
240 @classmethod
241- def delete_events_hook(self, del_ids, sender):
242- self.del_ids = del_ids
243+ def pre_delete_events(cls, ids, sender):
244+ return ids[:1]
245+
246+ @classmethod
247+ def post_delete_events(cls, del_ids, sender):
248+ cls.del_ids = del_ids
249
250 self.engine.extensions.load(DeleteAllInsertExtension)
251 ids = import_events("test/data/five_events.js", self.engine)
252- # all inserts where blocked, so each id is 0 to indicate this
253- self.engine.delete_events([ids[1]])
254- self.assertEquals(DeleteAllInsertExtension.del_ids, [ids[1]])
255+
256+ # we try to delete the first two events, but the engine will
257+ # block the deletion of the seconds one
258+ self.engine.delete_events(ids[:2])
259+ self.assertEquals(DeleteAllInsertExtension.del_ids, ids[:1])
260+
261+ def testGetHook(self):
262+
263+ class BlockGetExtension(Extension):
264+ PUBLIC_METHODS = []
265+
266+ @classmethod
267+ def get_event(self, event, sender):
268+ if event is not None and int(event.timestamp) > 130:
269+ return None
270+ return event
271+
272+ self.engine.extensions.load(BlockGetExtension)
273+ ids = import_events("test/data/five_events.js", self.engine)
274+
275+ # request all events, but only the first event object
276+ # will be returned, the other events are blocked by the extension
277+ # and presented as `None`
278+ events = self.engine.get_events(ids)
279+ self.assertEqual(len(filter(lambda x: x is not None, events)), 1)
280+
281+
282+
283
284 if __name__ == "__main__":
285 unittest.main()

Subscribers

People subscribed via source and target branches