Merge lp:~manishsinha/zeitgeist/fix-blacklist-api into lp:zeitgeist/0.1

Proposed by Seif Lotfy
Status: Rejected
Rejected by: Siegfried Gevatter
Proposed branch: lp:~manishsinha/zeitgeist/fix-blacklist-api
Merge into: lp:zeitgeist/0.1
Diff against target: 240 lines (+136/-27)
2 files modified
_zeitgeist/engine/extensions/blacklist.py (+112/-18)
test/blacklist-test.py (+24/-9)
To merge this branch: bzr merge lp:~manishsinha/zeitgeist/fix-blacklist-api
Reviewer Review Type Date Requested Status
Markus Korn Needs Information
Seif Lotfy Needs Fixing
Review via email: mp+45013@code.launchpad.net

Description of the change

Manish took the initiative to reimplemented the blacklist according to https://bugs.launchpad.net/zeitgeist/+bug/612344
All test cases work and I think we should start reviewing the code here (i know its not the purpose of a merge request).

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

line 15-19 in the patch is unnecessary it can be replaced at line 15 with
    ---
    self._blacklist = pickle.load(file(CONFIG_FILE))
    ---

line 52 in the patch can be removed and is not needed, since internally we do not need to make event dbus send-able unless we are sending them out.

line 82 in the patch can be removed and is not needed, since internally we do not need to make event dbus send-able unless we are sending them out.

Revision history for this message
Seif Lotfy (seif) wrote :

needs fixing

review: Needs Fixing
Revision history for this message
Markus Korn (thekorn) wrote :

I'm exited to see some progress on the blacklist API front, thanks Manish and Seif.
But, to be honest, I don't see which direction this API takes. First of all, in the bug Seif linked we discussed many different approaches, and for me it is not clear which one is implemented here.
And secondly, if I interpret Manish's comment at [0] as final decision (which is perfectly fine with me), I see that the implementation in this branch is completely different

* Changed-signal has signature a(E)s and not sa(E)
* GetTemplates is not returning a dictionary a{sa(E)} but a(sa(E))

Also, when getting a Changed Signal, how do I know what the content means? Is it an added or removed Blacklist?

And one last comment: IMHO pickle sucks, have you considered using JSON, as templates are perfect JSON objects.

[0] https://bugs.launchpad.net/zeitgeist/+bug/612344/comments/18

review: Needs Information
Revision history for this message
Seif Lotfy (seif) wrote :

> I'm exited to see some progress on the blacklist API front, thanks Manish and
> Seif.
> But, to be honest, I don't see which direction this API takes. First of all,
> in the bug Seif linked we discussed many different approaches, and for me it
> is not clear which one is implemented here.
> And secondly, if I interpret Manish's comment at [0] as final decision (which
> is perfectly fine with me), I see that the implementation in this branch is
> completely different
>
> * Changed-signal has signature a(E)s and not sa(E)
> * GetTemplates is not returning a dictionary a{sa(E)} but a(sa(E))

Yeah I noticed this while trying to build a UI tool for it. This needs to change, since its not what we agreed on and not what I had in mind.

>
> Also, when getting a Changed Signal, how do I know what the content means? Is
> it an added or removed Blacklist?

I think we need 2 signals in that case for both situations

>
> And one last comment: IMHO pickle sucks, have you considered using JSON, as
> templates are perfect JSON objects.

Thank you for bringing this topic up. I agree that JSON is the way to go for us not only here but for the datasource registry since it will allow us to do easier debugging.

>
> [0] https://bugs.launchpad.net/zeitgeist/+bug/612344/comments/18

It is a good momentum generator now so lets keep on this.

Revision history for this message
Manish Sinha (मनीष सिन्हा) (manishsinha) wrote :

> But, to be honest, I don't see which direction this API takes. First of all,
> in the bug Seif linked we discussed many different approaches, and for me it
> is not clear which one is implemented here.

This is the one Mikkel proposed.

> And secondly, if I interpret Manish's comment at [0] as final decision (which
> is perfectly fine with me), I see that the implementation in this branch is
> completely different
>
> * Changed-signal has signature a(E)s and not sa(E)

Yeah. This is just a placement or parameters or dbus signature. Can be changed anytime.

> * GetTemplates is not returning a dictionary a{sa(E)} but a(sa(E))

Are you sure dictionary is a good way to go? I found the latter to be convenient.

>
> Also, when getting a Changed Signal, how do I know what the content means? Is
> it an added or removed Blacklist?

Same thought from my side. When I was implementing, I was wondering about this. Left this for discussion during the review as the change doesn't involve huge code overhaul.

> And one last comment: IMHO pickle sucks, have you considered using JSON, as
> templates are perfect JSON objects.

I just carry forwarded what already was there. Didn't change this part. Still, it wont be a huge change in the codebase.

Revision history for this message
Markus Korn (thekorn) wrote :

> It is a good momentum generator now so lets keep on this.

I hate your momentum generators, they make me thinking about problems like this in an endless loop ;)

Can someone please summarize for me why we want this string identifier 'blacklister' for the client setting a certain blacklist? And why is it not an identifier for the blacklist template itself?
In my understanding it's purely informational, so why do we group the templates internally by this string, instead we could just maintain templates internally as
   blacklists = set([(<template1>, "client1"), (<template2>, "client1"), (<template3>, "client2")])

Revision history for this message
Manish Sinha (मनीष सिन्हा) (manishsinha) wrote :

> line 15-19 in the patch is unnecessary it can be replaced at line 15 with
> ---
> self._blacklist = pickle.load(file(CONFIG_FILE))
> ---

Will check when I reach home

> line 52 in the patch can be removed and is not needed, since internally we do
> not need to make event dbus send-able unless we are sending them out.

Agree

> line 82 in the patch can be removed and is not needed, since internally we do
> not need to make event dbus send-able unless we are sending them out.

Agree

Revision history for this message
Manish Sinha (मनीष सिन्हा) (manishsinha) wrote :

> Can someone please summarize for me why we want this string identifier
> 'blacklister' for the client setting a certain blacklist?

Ask Mikkel. IIRC he proposed the idea.

> And why is it not an identifier for the blacklist template itself?

I think, since the blacklist template is an event itself which has an id, then that id can act as an identifier for the template.

> In my understanding it's purely informational, so why do we group the
> templates internally by this string, instead we could just maintain templates
> internally as
> blacklists = set([(<template1>, "client1"), (<template2>, "client1"),
> (<template3>, "client2")])

I still find having a dictionary a better idea. Keys are blacklister and the value contains the blacklist templates set by them.

Revision history for this message
Siegfried Gevatter (rainct) wrote :

A quick comment: How's the Changed signal supposed to work, ie. how do you know if the templates are being added or removed? Why not have two separated signals (TemplatesAdded, TemplatesRemoved)?

I also don't buy this "blacklister" stuff. What's the point of it?

Revision history for this message
Manish Sinha (मनीष सिन्हा) (manishsinha) wrote :

> A quick comment: How's the Changed signal supposed to work, ie. how do you
> know if the templates are being added or removed? Why not have two separated
> signals (TemplatesAdded, TemplatesRemoved)?

+1 for this idea.

> I also don't buy this "blacklister" stuff. What's the point of it?

Well, that is for knowing which application set the blacklist. Kamstrup proposed that idea

Unmerged revisions

1655. By Manish Sinha (मनीष सिन्हा)

Fixed unit tests and cleaned the blacklist extension

1654. By Manish Sinha (मनीष सिन्हा)

Rebase from trunk

1653. By Manish Sinha (मनीष सिन्हा)

Fix the logical error when comparing blacklist templates

1652. By Manish Sinha (मनीष सिन्हा)

Fixed blacklist-test.py's 2/4 tests - testClear and testBlacklistUingClientDBusInterface

In testSetOne even though blacklist is being set, it cannot be retreived.
testAplyBlacklist fails becuase testSetOne fails

1651. By Manish Sinha (मनीष सिन्हा)

Added RemoveTemplate and fixed all the names and functionality

1650. By Manish Sinha (मनीष सिन्हा)

Got the Blacklist extension working. It can query all blacklists, set blacklists and block events which match the blacklists

1649. By Manish Sinha (मनीष सिन्हा)

Commit to exhibit that bug 691167 bug is real

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '_zeitgeist/engine/extensions/blacklist.py'
--- _zeitgeist/engine/extensions/blacklist.py 2010-10-19 13:54:12 +0000
+++ _zeitgeist/engine/extensions/blacklist.py 2011-01-03 00:36:07 +0000
@@ -3,6 +3,7 @@
3# Zeitgeist3# Zeitgeist
4#4#
5# Copyright © 2009 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>5# Copyright © 2009 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>
6# Copyright © 2010 Manish Sinha <manishsinha@ubuntu.com>
6#7#
7# This program is free software: you can redistribute it and/or modify8# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Lesser General Public License as published by9# it under the terms of the GNU Lesser General Public License as published by
@@ -56,41 +57,105 @@
56 if os.path.exists(CONFIG_FILE):57 if os.path.exists(CONFIG_FILE):
57 try:58 try:
58 raw_blacklist = pickle.load(file(CONFIG_FILE))59 raw_blacklist = pickle.load(file(CONFIG_FILE))
59 self._blacklist = map(Event, raw_blacklist)60 self._blacklist = {}
61 for key in raw_blacklist:
62 self._blacklist[key] = map(Event, raw_blacklist[key])
60 log.debug("Loaded blacklist config from %s"63 log.debug("Loaded blacklist config from %s"
61 % CONFIG_FILE)64 % CONFIG_FILE)
62 except Exception, e:65 except Exception, e:
63 log.warn("Failed to load blacklist config file %s: %s"\66 log.warn("Failed to load blacklist config file %s: %s"\
64 % (CONFIG_FILE, e))67 % (CONFIG_FILE, e))
65 self._blacklist = []68 self._blacklist = {}
66 else:69 else:
67 log.debug("No existing blacklist config found")70 log.debug("No existing blacklist config found")
68 self._blacklist = []71 self._blacklist = {}
69 72
70 def pre_insert_event(self, event, sender):73 def pre_insert_event(self, event, sender):
71 for tmpl in self._blacklist:74 for tmpl in self._blacklist:
72 if event.matches_template(tmpl): return None75 for single_event in self._blacklist[tmpl]:
76 if event.matches_template(single_event): return None
73 return event77 return event
74 78
75 # PUBLIC79 # PUBLIC
76 def set_blacklist(self, event_templates):80 def set_blacklist(self, event_templates, blacklister):
77 self._blacklist = event_templates81 try:
78 map(Event._make_dbus_sendable, self._blacklist)82 event_list = self._blacklist[blacklister]
79 83 except KeyError:
84 event_list = []
85 self._blacklist[blacklister] = event_list
86
87 map(Event._make_dbus_sendable, event_templates)
88
89 # Create a list to hold non-duplicate events
90 new_templates = []
91 if len(event_list) > 0:
92 for candidate_temp in event_list:
93 for event in event_templates:
94 # If the event is already in the list
95 if event.matches_template(candidate_temp):
96 log.debug("Duplicate blacklist template found. Skipping")
97 continue
98 # The event is new, insert it to the blacklist`
99 new_templates.append(event)
100 else:
101 new_templates.extend(event_templates)
102
103 event_list.extend(new_templates)
104
105 # Create plain python objects and pickel it
106 self._create_plain_and_save()
107
108 return new_templates
109
110 def remove_blacklist(self, event_templates, blacklister):
111 try:
112 event_list = self._blacklist[blacklister]
113 except KeyError:
114 log.debug("No such blacklister exists")
115 return []
116
117 map(Event._make_dbus_sendable, event_templates)
118
119 # Create a list to hold the event templates which exist
120 candidate_template = []
121 for event in event_templates:
122 for template in event_list:
123 # If the event is in the list, add it to candidate list
124 if event.matches_template(template):
125 candidate_template.append(template)
126
127 # Remove all the candidate event templates
128 for tempel in candidate_template:
129 event_list.remove(tempel)
130
131 self._create_plain_and_save()
132
133 return candidate_template
134
135 def _create_plain_and_save(self):
136 blacklist_dict = {}
137 for b_actor in self._blacklist:
138 conv_event = map(Event.get_plain, self._blacklist[b_actor])
139 blacklist_dict[str(b_actor)] = conv_event
140
80 out = file(CONFIG_FILE, "w")141 out = file(CONFIG_FILE, "w")
81 pickle.dump(map(Event.get_plain, self._blacklist), out) 142 pickle.dump(blacklist_dict, out)
82 out.close()143 out.close()
83 log.debug("Blacklist updated: %s" % self._blacklist)144 log.debug("Blacklist updated: %s" % blacklist_dict)
84 145
85 # PUBLIC146 # PUBLIC
86 def get_blacklist(self):147 def get_blacklist(self):
87 return self._blacklist148 event_list = []
149 for blacklister in self._blacklist:
150 event_list.append([blacklister, self._blacklist[blacklister]])
151
152 return event_list
88 153
89 @dbus.service.method(BLACKLIST_DBUS_INTERFACE,154 @dbus.service.method(BLACKLIST_DBUS_INTERFACE,
90 in_signature="a("+constants.SIG_EVENT+")")155 in_signature="a("+constants.SIG_EVENT+")s")
91 def SetBlacklist(self, event_templates):156 def AddTemplates(self, event_templates, blacklister):
92 """157 """
93 Set the blacklist to :const:`event_templates`. Events158 Add a new blacklist template :const:`event_templates`. Events
94 matching any these templates will be blocked from insertion159 matching any these templates will be blocked from insertion
95 into the log. It is still possible to find and look up events160 into the log. It is still possible to find and look up events
96 matching the blacklist which was inserted before the blacklist161 matching the blacklist which was inserted before the blacklist
@@ -98,14 +163,17 @@
98 163
99 :param event_templates: A list of164 :param event_templates: A list of
100 :class:`Events <zeitgeist.datamodel.Event>`165 :class:`Events <zeitgeist.datamodel.Event>`
166 :param blacklister: The unique identifier of the
167 application setting the blacklist
101 """168 """
102 tmp = map(Event, event_templates)169 tmp = map(Event, event_templates)
103 self.set_blacklist(tmp)170 added_templates = self.set_blacklist(tmp, blacklister)
171 self.Changed(added_templates, blacklister)
104 172
105 @dbus.service.method(BLACKLIST_DBUS_INTERFACE,173 @dbus.service.method(BLACKLIST_DBUS_INTERFACE,
106 in_signature="",174 in_signature="",
107 out_signature="a("+constants.SIG_EVENT+")")175 out_signature="a(sa("+constants.SIG_EVENT+"))")
108 def GetBlacklist(self):176 def GetTemplates(self):
109 """177 """
110 Get the current blacklist templates.178 Get the current blacklist templates.
111 179
@@ -113,3 +181,29 @@
113 :class:`Events <zeitgeist.datamodel.Event>`181 :class:`Events <zeitgeist.datamodel.Event>`
114 """182 """
115 return self.get_blacklist()183 return self.get_blacklist()
184
185 @dbus.service.method(BLACKLIST_DBUS_INTERFACE,
186 in_signature="a("+constants.SIG_EVENT+")s")
187 def RemoveTemplates(self, event_templates, blacklister):
188 """
189 Remove the blacklist templates :const: `event_templates`.
190 The event templates specified would be removed for the
191 specific blacklister. When the removal of template is
192 successful, then event matching these templates can be
193 inserted.
194
195 :param event_templates: A list of
196 :class: `Events <zeitgeist.datamodel.Event>`
197 :param blacklister: The unique identiier of the
198 application setting the blacklist. The event
199 templates which are to be removed and searched
200 against this blacklister
201 """
202 tmp = map(Event, event_templates)
203 removed_templates = self.remove_blacklist(tmp, blacklister)
204 self.Changed(removed_templates, blacklister)
205
206 @dbus.service.signal(BLACKLIST_DBUS_INTERFACE,
207 signature="a("+constants.SIG_EVENT+")s")
208 def Changed(self, event_templates, blacklister):
209 pass
116210
=== modified file 'test/blacklist-test.py'
--- test/blacklist-test.py 2010-09-22 19:21:19 +0000
+++ test/blacklist-test.py 2011-01-03 00:36:07 +0000
@@ -29,18 +29,28 @@
29 self.blacklist = dbus.Interface(obj, "org.gnome.zeitgeist.Blacklist")29 self.blacklist = dbus.Interface(obj, "org.gnome.zeitgeist.Blacklist")
30 30
31 def testClear(self):31 def testClear(self):
32 self.blacklist.SetBlacklist([])32 blks = self.blacklist.GetTemplates()
33 empty = self.blacklist.GetBlacklist()33 for entry in blks:
34 blacklists = map(Event.get_plain, entry[1])
35 self.blacklist.RemoveTemplates(str(entry[0]), blacklists)
36 empty = self.blacklist.GetTemplates()
34 self.assertEquals(empty, [])37 self.assertEquals(empty, [])
35 38
36 def testSetOne(self):39 def testSetOne(self):
40 blacklister = "application://zeitgeist.unittest"
37 orig = Event.new_for_values(interpretation=Interpretation.ACCESS_EVENT,41 orig = Event.new_for_values(interpretation=Interpretation.ACCESS_EVENT,
38 subject_uri="http://nothingtoseehere.gov")42 subject_uri="http://nothingtoseehere.gov")
39 self.blacklist.SetBlacklist([orig])43 self.blacklist.AddTemplates([orig,], blacklister)
40 result = map(Event, self.blacklist.GetBlacklist())44 allblks = self.blacklist.GetTemplates()
41 45 blks = {}
42 self.assertEquals(len(result), 1)46 for blk in allblks:
43 result = result[0]47 blks[str(blk[0])] = map(Event.new_for_struct, blk[1])
48
49 self.assertEquals(len(blks.keys()), 1)
50 self.assertEquals(blks.has_key(blacklister), True)
51 blacklists = blks[blacklister]
52 self.assertEquals(len(blacklists), 1)
53 result = blacklists[0]
44 self.assertEquals(result.manifestation, "")54 self.assertEquals(result.manifestation, "")
45 self.assertEquals(result.interpretation, Interpretation.ACCESS_EVENT)55 self.assertEquals(result.interpretation, Interpretation.ACCESS_EVENT)
46 self.assertEquals(len(result.subjects), 1)56 self.assertEquals(len(result.subjects), 1)
@@ -73,9 +83,14 @@
73 del self.blacklist83 del self.blacklist
74 iface = ZeitgeistDBusInterface()84 iface = ZeitgeistDBusInterface()
75 blacklist = iface.get_extension("Blacklist", "blacklist")85 blacklist = iface.get_extension("Blacklist", "blacklist")
76 blacklist.SetBlacklist([])86
77 empty = blacklist.GetBlacklist()87 blks = blacklist.GetTemplates()
88 for entry in blks:
89 blacklists = map(Event.get_plain, entry[1])
90 blacklist.RemoveTemplates(str(entry[0]), blacklists)
91 empty = blacklist.GetTemplates()
78 self.assertEquals(empty, [])92 self.assertEquals(empty, [])
93
7994
80if __name__ == "__main__":95if __name__ == "__main__":
81 unittest.main()96 unittest.main()

Subscribers

People subscribed via source and target branches