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

Proposed by Siegfried Gevatter
Status: Merged
Merged at revision: 1668
Proposed branch: lp:~zeitgeist/zeitgeist/bug695363
Merge into: lp:zeitgeist/0.1
Diff against target: 172 lines (+104/-13)
2 files modified
test/remote-test.py (+51/-10)
zeitgeist/client.py (+53/-3)
To merge this branch: bzr merge lp:~zeitgeist/zeitgeist/bug695363
Reviewer Review Type Date Requested Status
Mikkel Kamstrup Erlandsen Approve
Review via email: mp+48950@code.launchpad.net

Description of the change

Expose DataSourceRegistry's enabled status and callback in the Python API.

To post a comment you must log in.
Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) wrote :

 review needsfixing

> === modified file 'test/remote-test.py'
> +       def _create_mainloop(self):
> +               mainloop = gobject.MainLoop()
> +
> +               def cb_timeout():
> +                       mainloop.quit()
> +                       self.fail("Timed out -- operations not completed in reasonable time.")
> +
> +               # Add an arbitrary timeout so this test won't block if it fails
> +               gobject.timeout_add_seconds(30, cb_timeout)

I think 5s ought to be more than enough here? No-one will ever wait
30s for the timeout before they kill the proces anyway :-)

> === modified file 'zeitgeist/client.py'
> +       def set_data_source_enabled_callback(self, unique_id, enabled_callback):
> +               """
> +               This method may only be used after having registered the given unique_id
> +               with register_data_source before.
> +
> +               It registers a method to be called whenever the `enabled' status of
> +               the previously registered data-source changes.
> +
> +               Remember that on some systems the DataSourceRegistry extension may be
> +               disabled, in which case this method will have no effect.
> +               """
> +
> +               assert unique_id in self._data_sources, \
> +                       'set_data_source_enabled_callback() called before ' \
> +                       'register_data_source()'
> +
> +               assert callable(enabled_callback), \
> +                       'enabled_callback: expected a callable method'
> +
> +               self._data_sources[unique_id]['callback'] = enabled_callback

I don't think it's nice to assert in a library. You should throw
ValueError or TypeErrors instead I think.

review: Needs Fixing
lp:~zeitgeist/zeitgeist/bug695363 updated
1660. By Siegfried Gevatter

Little changes.

Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'test/remote-test.py'
2--- test/remote-test.py 2010-12-29 15:31:26 +0000
3+++ test/remote-test.py 2011-02-09 10:00:27 +0000
4@@ -447,6 +447,9 @@
5 self.assertEquals(len(datasources), 1)
6 self._assertDataSourceEquals(datasources[0], self._ds2)
7
8+ def testRegisterDataSourceWithCallback(self):
9+ self.client.register_data_source(*self._ds1, enabled_callback=lambda x: True)
10+
11 def testRegisterDataSources(self):
12 # Insert two data-sources
13 self.client._registry.RegisterDataSource(*self._ds1)
14@@ -485,8 +488,21 @@
15 ds = list(self.client._registry.GetDataSources())[0]
16 self.assertEquals(ds[DataSource.Enabled], True)
17
18+ def _create_mainloop(self):
19+ mainloop = gobject.MainLoop()
20+
21+ def cb_timeout():
22+ mainloop.quit()
23+ self.fail("Timed out -- operations not completed in reasonable time.")
24+
25+ # Add an arbitrary timeout so this test won't block if it fails
26+ gobject.timeout_add_seconds(10, cb_timeout)
27+
28+ return mainloop
29+
30 def testDataSourceSignals(self):
31- mainloop = gobject.MainLoop()
32+ mainloop = self._create_mainloop()
33+
34 global hit
35 hit = 0
36
37@@ -514,10 +530,6 @@
38 # self.assertEquals(hit, 3)
39 # mainloop.quit()
40
41- def cb_timeout():
42- mainloop.quit()
43- self.fail("Timed out -- operations not completed in 1 minute.")
44-
45 # Connect to signals
46 self.client._registry.connect('DataSourceRegistered', cb_registered)
47 self.client._registry.connect('DataSourceEnabled', cb_enabled)
48@@ -526,11 +538,40 @@
49 # Register data-source, disable it, enable it again
50 gobject.idle_add(self.testSetDataSourceEnabled)
51
52- # Add an arbitrary timeout so this test won't block if it fails
53- gobject.timeout_add_seconds(30, cb_timeout)
54-
55- mainloop.run()
56-
57+ mainloop.run()
58+
59+ def testRegisterDataSourceEnabledCallbackOnRegister(self):
60+ mainloop = self._create_mainloop()
61+
62+ def callback(enabled):
63+ mainloop.quit()
64+ self.client.register_data_source(*self._ds1, enabled_callback=callback)
65+
66+ mainloop.run()
67+
68+ def testRegisterDataSourceEnabledCallbackOnChange(self):
69+ mainloop = self._create_mainloop()
70+ global hit
71+ hit = 0
72+
73+ # Register a callback
74+ def callback(enabled):
75+ global hit
76+ if hit == 0:
77+ # Register callback
78+ hit = 1
79+ elif hit == 1:
80+ # Disable callback
81+ mainloop.quit()
82+ else:
83+ self.fail("Unexpected number of signals: %d." % hit)
84+ self.client.register_data_source(*self._ds1)
85+ self.client.set_data_source_enabled_callback(self._ds1[0], callback)
86+
87+ # Disable the data-source
88+ self.client._registry.SetDataSourceEnabled(self._ds1[0], False)
89+
90+ mainloop.run()
91
92 class ZeitgeistRemotePropertiesTest(testutils.RemoteTestCase):
93
94
95=== modified file 'zeitgeist/client.py'
96--- zeitgeist/client.py 2011-02-08 13:26:37 +0000
97+++ zeitgeist/client.py 2011-02-09 10:00:27 +0000
98@@ -900,7 +900,12 @@
99 error_handler=error_handler)
100 self._installed_monitors.remove(monitor)
101
102- def register_data_source(self, unique_id, name, description, event_templates):
103+ # Data-source related class variables
104+ _data_sources = {}
105+ _data_sources_callback_installed = False
106+
107+ def register_data_source(self, unique_id, name, description,
108+ event_templates, enabled_callback=None):
109 """
110 Register a data-source as currently running. If the data-source was
111 already in the database, its metadata (name, description and
112@@ -917,13 +922,58 @@
113 :param description: data-source description (may be translated)
114 :param event_templates: list of
115 :class:`Event <zeitgeist.datamodel.Event>` templates.
116+ :param enabled_callback: method to call as response with the `enabled'
117+ status of the data-source, and after that every time said status
118+ is toggled. See set_data_source_enabled_callback() for more
119+ information.
120 """
121- # TODO: Make it possible to access the return value!
122+
123+ self._data_sources[unique_id] = {'enabled': None, 'callback': None}
124+
125+ if enabled_callback is not None:
126+ self.set_data_source_enabled_callback(unique_id, enabled_callback)
127+
128+ def _data_source_enabled_cb(unique_id, enabled):
129+ if unique_id not in self._data_sources:
130+ return
131+ self._data_sources[unique_id]['enabled'] = enabled
132+ callback = self._data_sources[unique_id]['callback']
133+ if callback is not None:
134+ callback(enabled)
135+
136+ def _data_source_register_cb(enabled):
137+ _data_source_enabled_cb(unique_id, enabled)
138+
139+ if not self._data_sources_callback_installed:
140+ self._registry.connect('DataSourceEnabled', _data_source_enabled_cb)
141+ self._data_sources_callback_installed = True
142+
143 self._registry.RegisterDataSource(unique_id, name, description,
144 event_templates,
145- reply_handler=self._void_reply_handler,
146+ reply_handler=_data_source_register_cb,
147 error_handler=self._void_reply_handler) # Errors are ignored
148
149+ def set_data_source_enabled_callback(self, unique_id, enabled_callback):
150+ """
151+ This method may only be used after having registered the given unique_id
152+ with register_data_source before.
153+
154+ It registers a method to be called whenever the `enabled' status of
155+ the previously registered data-source changes.
156+
157+ Remember that on some systems the DataSourceRegistry extension may be
158+ disabled, in which case this method will have no effect.
159+ """
160+
161+ if unique_id not in self._data_sources:
162+ raise ValueError, 'set_data_source_enabled_callback() called before ' \
163+ 'register_data_source()'
164+
165+ if not callable(enabled_callback):
166+ raise TypeError, 'enabled_callback: expected a callable method'
167+
168+ self._data_sources[unique_id]['callback'] = enabled_callback
169+
170 def _check_list_or_tuple(self, collection):
171 """
172 Raise a ValueError unless 'collection' is a list or tuple