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

Proposed by Seif Lotfy
Status: Merged
Merged at revision: not available
Proposed branch: lp:~zeitgeist/zeitgeist/mostusedwith
Merge into: lp:zeitgeist/0.1
Diff against target: 292 lines (+67/-41)
7 files modified
_zeitgeist/engine/main.py (+23/-18)
_zeitgeist/engine/remote.py (+9/-3)
test/data/apriori_events.js (+1/-1)
test/engine-test.py (+18/-10)
test/remote-test.py (+2/-2)
zeitgeist/client.py (+12/-5)
zeitgeist/datamodel.py (+2/-2)
To merge this branch: bzr merge lp:~zeitgeist/zeitgeist/mostusedwith
Reviewer Review Type Date Requested Status
Zeitgeist Framework Team Pending
Review via email: mp+20154@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Seif Lotfy (seif) wrote :

This branch fixes https://bugs.edge.launchpad.net/zeitgeist/+bug/498878
Please take stabs at it

lp:~zeitgeist/zeitgeist/mostusedwith updated
1347. By Seif Lotfy

fixed test case

1348. By Seif Lotfy

removed second query

1349. By Seif Lotfy

merge and fix issues

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '_zeitgeist/engine/main.py'
2--- _zeitgeist/engine/main.py 2010-02-16 19:36:42 +0000
3+++ _zeitgeist/engine/main.py 2010-02-25 18:14:12 +0000
4@@ -28,7 +28,7 @@
5 import logging
6
7 from zeitgeist.datamodel import Event as OrigEvent, StorageState, TimeRange, \
8- ResultType, get_timestamp_for_now
9+ ResultType, get_timestamp_for_now, Interpretation
10 from _zeitgeist.engine.datamodel import Event, Subject
11 from _zeitgeist.engine.extension import ExtensionsCollection, load_class
12 from _zeitgeist.engine import constants
13@@ -258,7 +258,7 @@
14 return self._find_events(1, *args)
15
16 def find_related_uris(self, timerange, event_templates, result_event_templates,
17- result_storage_state):
18+ result_storage_state, num_results, result_type):
19 """
20 Return a list of subject URIs commonly used together with events
21 matching the given template, considering data from within the indicated
22@@ -273,13 +273,14 @@
23
24 #templates = event_templates + result_event_templates
25
26- events = self.find_events( timerange, result_event_templates,
27+ events = self.find_events(timerange, result_event_templates,
28 result_storage_state, 0, 1)
29
30 subject_uris = []
31 for event in event_templates:
32- if not event.subjects[0].uri in subject_uris:
33- subject_uris.append(event.subjects[0].uri)
34+ if len(event.subjects) > 0:
35+ if not event.subjects[0].uri in subject_uris:
36+ subject_uris.append(event.subjects[0].uri)
37
38 def create_buckets(events):
39 """
40@@ -293,37 +294,41 @@
41 buckets.append({})
42 buckets[len(buckets)-1][event.subjects[0].uri] = event
43 return buckets
44+
45 buckets = create_buckets(events)
46
47 keys_counter = {}
48- keys_subjects = {}
49- min_support = 0
50
51 for bucket in buckets:
52 counter = 0
53 for event in event_templates:
54 if bucket.has_key(event.subjects[0].uri):
55 counter += 1
56+ break
57 if counter > 0:
58 for key in bucket.keys():
59 if not key in subject_uris:
60 if not keys_counter.has_key(key):
61 keys_counter[key] = 0
62 keys_counter[key] += 1
63- min_support += 1
64- keys_subjects[key] = bucket[key]
65-
66-
67- min_support = min_support / len(keys_counter.keys())
68
69 sets = [[v, k] for k, v in keys_counter.iteritems()]
70 sets.sort()
71-
72- results = []
73- for r in sets:
74- if r[0] >= min_support:
75- results.append(r[1])
76- return results
77+ sets.reverse()
78+
79+ if result_type == 0:
80+ return map(lambda result: result[1], sets[:num_results])
81+ elif result_type == 1:
82+ events = []
83+ for r in sets:
84+ event = Event()
85+ subject = Subject()
86+ subject.uri = r[1]
87+ event.set_subjects([subject])
88+ events.append(event)
89+ events = self.find_events(timerange, events, result_storage_state, num_results, 2)
90+ return map(lambda event: event.subjects[0].uri, events)
91+ raise NotImplementedError, "Unsupported ResultType."
92
93 def insert_events(self, events, sender=None):
94 t = time.time()
95
96=== modified file '_zeitgeist/engine/remote.py'
97--- _zeitgeist/engine/remote.py 2010-01-27 15:08:51 +0000
98+++ _zeitgeist/engine/remote.py 2010-02-25 18:14:12 +0000
99@@ -4,6 +4,7 @@
100 #
101 # Copyright © 2009-2010 Siegfried-Angel Gevatter Pujals <rainct@ubuntu.com>
102 # Copyright © 2009 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
103+# Copyright © 2010 Seif Lotfy <seif@lotfy.com>
104 #
105 # This program is free software: you can redistribute it and/or modify
106 # it under the terms of the GNU Lesser General Public License as published by
107@@ -86,10 +87,10 @@
108 sender=sender))
109
110 @dbus.service.method(constants.DBUS_INTERFACE,
111- in_signature="(xx)a("+constants.SIG_EVENT+")a("+constants.SIG_EVENT+")u",
112+ in_signature="(xx)a("+constants.SIG_EVENT+")a("+constants.SIG_EVENT+")uuu",
113 out_signature="as")
114 def FindRelatedUris(self, time_range, event_templates,
115- result_event_templates, storage_state):
116+ result_event_templates, storage_state, num_events, result_type):
117 """Warning: This API is EXPERIMENTAL and is not fully supported yet.
118
119 Get a list of URIs of subjects which frequently occur together
120@@ -122,11 +123,16 @@
121 available. The list of possible values is enumerated in the
122 :class:`StorageState <zeitgeist.datamodel.StorageState>` class
123 :type storage_state: unsigned 32 bit integer, DBus signature :const:`u`
124+ :param num_events: maximal amount of returned events
125+ :type num_events: unsigned integer
126+ :param result_type: unsigned integer 0 for relevancy 1 for recency
127+ :type order: unsigned integer
128 :returns: A list of URIs matching the described criteria
129 :rtype: An array of strings, DBus signature :const:`as`.
130 """
131+ event_templates = map(Event, event_templates)
132 return _engine.find_related_uris(time_range, event_templates,
133- result_event_templates, storage_state)
134+ result_event_templates, storage_state, num_events, result_type)
135
136 @dbus.service.method(constants.DBUS_INTERFACE,
137 in_signature="(xx)a("+constants.SIG_EVENT+")uuu",
138
139=== modified file 'test/data/apriori_events.js'
140--- test/data/apriori_events.js 2010-02-07 03:44:19 +0000
141+++ test/data/apriori_events.js 2010-02-25 18:14:12 +0000
142@@ -390,4 +390,4 @@
143 }
144 ]
145 }
146-]
147+]
148\ No newline at end of file
149
150=== modified file 'test/engine-test.py'
151--- test/engine-test.py 2010-02-10 02:17:34 +0000
152+++ test/engine-test.py 2010-02-25 18:14:12 +0000
153@@ -490,28 +490,36 @@
154 TimeRange.always(), [], StorageState.Any, 0, ResultType.LeastRecentActor)
155 self.assertEquals([e[0][1] for e in events], ["100", "101", "105"])
156
157- def testRelatedForEvents(self):
158- import_events("test/data/apriori_events.js", self.engine)
159- result = self.engine.find_related_uris(
160- TimeRange.always(), [Event.new_for_values(subject_uri = "i2")], [],
161- StorageState.Any)
162+ def testRelatedForEventsSortRelevancy(self):
163+ import_events("test/data/apriori_events.js", self.engine)
164+ result = self.engine.find_related_uris(
165+ TimeRange.always(), [Event.new_for_values(subject_uri = "i2")], [],
166+ StorageState.Any, 2, 0)
167+ self.assertEquals(result, ["i1", "i3"])
168+
169+ def testRelatedForEventsSortRecency(self):
170+ import_events("test/data/apriori_events.js", self.engine)
171+ result = self.engine.find_related_uris(
172+ TimeRange.always(), [Event.new_for_values(subject_uri = "i2")], [],
173+ StorageState.Any, 2, 1)
174 self.assertEquals(result, ["i3", "i1"])
175
176 def testRelatedForMultipleEvents(self):
177 import_events("test/data/apriori_events.js", self.engine)
178 result = self.engine.find_related_uris(
179 TimeRange.always(), [Event.new_for_values(subject_uri = "i1"),
180- Event.new_for_values(subject_uri = "i4")],
181- [], StorageState.Any),
182- self.assertEquals(result, (["i3", "i2"],))
183+ Event.new_for_values(subject_uri = "i4")], [],
184+ StorageState.Any, 2, 0),
185+ self.assertEquals(result, (["i2", "i3"],))
186
187 def testRelatedForEventsWithManifestation(self):
188 import_events("test/data/apriori_events.js", self.engine)
189 result = self.engine.find_related_uris(TimeRange.always(),
190 [Event.new_for_values(subject_uri = "i4")],
191 [Event.new_for_values(subject_manifestation="stfu:File")],
192- StorageState.Any)
193- self.assertEquals(result, ["i3", "i5", "i1"])
194+ StorageState.Any,
195+ 10, 0)
196+ self.assertEquals(result, ["i1", "i5", "i3"])
197
198 if __name__ == "__main__":
199 unittest.main()
200
201=== modified file 'test/remote-test.py'
202--- test/remote-test.py 2010-02-16 09:43:31 +0000
203+++ test/remote-test.py 2010-02-25 18:14:12 +0000
204@@ -224,9 +224,9 @@
205
206 def callback(uris):
207 mainloop.quit()
208- self.assertEquals(uris, ["i3", "i2", "i1", "i5"])
209+ self.assertEquals(uris, ["i2", "i1", "i5", "i3"])
210
211- result = self.client.find_related_uris_for_uris(["i4"], callback)
212+ result = self.client.find_related_uris_for_uris(["i4"], callback, num_events=4, result_type=0)
213 mainloop.run()
214
215 def testFindEventsForValues(self):
216
217=== modified file 'zeitgeist/client.py'
218--- zeitgeist/client.py 2010-02-16 09:43:31 +0000
219+++ zeitgeist/client.py 2010-02-25 18:14:12 +0000
220@@ -670,8 +670,8 @@
221 error_handler=self._safe_error_handler(error_handler))
222
223 def find_related_uris_for_events(self, event_templates, uris_reply_handler,
224- time_range = None, result_event_templates=[],
225- storage_state=StorageState.Any, error_handler=None):
226+ error_handler=None, time_range = None, result_event_templates=[],
227+ storage_state=StorageState.Any, num_events=10, result_type=0):
228 """
229 Warning: This API is EXPERIMENTAL and is not fully supported yet.
230
231@@ -690,6 +690,10 @@
232 as subjects of events matching these templates
233 :param storage_state: The returned URIs must have this
234 :class:`storage state <zeitgeist.datamodel.StorageState>`
235+ :param num_events: number of related uris you want to have returned
236+ :param result_type: sorting of the results by
237+ 0 for relevancy
238+ 1 for recency
239 :param error_handler: An optional callback in case of errors.
240 Must take a single argument being the error raised by the
241 server. The default behaviour in case of errors is to call
242@@ -704,15 +708,16 @@
243 time_range = TimeRange.always()
244
245 self._iface.FindRelatedUris(time_range, event_templates,
246- result_event_templates, storage_state,
247+ result_event_templates, storage_state, num_events, result_type,
248 reply_handler=self._safe_reply_handler(uris_reply_handler),
249 error_handler=self._safe_error_handler(error_handler,
250 uris_reply_handler,
251- []))
252+ [])
253+ )
254
255 def find_related_uris_for_uris(self, subject_uris, uris_reply_handler,
256 time_range=None, result_event_templates=[],
257- storage_state=StorageState.Any, error_handler=None):
258+ storage_state=StorageState.Any, num_events=10, result_type=0, error_handler=None):
259 """
260 Warning: This API is EXPERIMENTAL and is not fully supported yet.
261
262@@ -728,6 +733,8 @@
263 time_range=time_range,
264 result_event_templates=result_event_templates,
265 storage_state=storage_state,
266+ num_events = num_events,
267+ result_type = result_type,
268 error_handler=error_handler)
269
270 def install_monitor (self, time_range, event_templates,
271
272=== modified file 'zeitgeist/datamodel.py'
273--- zeitgeist/datamodel.py 2010-01-30 13:35:22 +0000
274+++ zeitgeist/datamodel.py 2010-02-25 18:14:12 +0000
275@@ -4,7 +4,7 @@
276 #
277 # Copyright © 2009 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
278 # Copyright © 2009 Markus Korn <thekorn@gmx.de>
279-# Copyright © 2009 Seif Lotfy <seif@lotfy.com>
280+# Copyright © 2009-2010 Seif Lotfy <seif@lotfy.com>
281 # Copyright © 2009-2010 Siegfried-Angel Gevatter Pujals <rainct@ubuntu.com>
282 #
283 # This program is free software: you can redistribute it and/or modify
284@@ -532,7 +532,7 @@
285 "ordered ascendently by the popularity of the actor"))
286 MostRecentActor = enum_factory(("The last event of each different actor"))
287 LeastRecentActor = enum_factory(("The first event of each different actor"))
288-
289+
290 class Subject(list):
291 """
292 Represents a subject of an :class:`Event`. This class is both used to

Subscribers

People subscribed via source and target branches