Merge lp:~lottanzb/lottanzb/inhibit-suspending-plugin into lp:lottanzb/0.5
- inhibit-suspending-plugin
- Merge into 0.5
Status: | Merged |
---|---|
Merged at revision: | 937 |
Proposed branch: | lp:~lottanzb/lottanzb/inhibit-suspending-plugin |
Merge into: | lp:lottanzb/0.5 |
Diff against target: |
322 lines (+283/-1) 4 files modified
NEWS (+8/-0) README (+4/-0) lottanzb/plugins/__init__.py (+1/-1) lottanzb/plugins/inhibit_suspending/__init__.py (+270/-0) |
To merge this branch: | bzr merge lp:~lottanzb/lottanzb/inhibit-suspending-plugin |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Severin H | Approve | ||
Marcel de Vries (community) | Approve | ||
Review via email: mp+17793@code.launchpad.net |
Commit message
Description of the change
Severin H (severinh) wrote : | # |
Severin H (severinh) wrote : | # |
I seem to have found a bug in gnome-session, preventing the plug-in from working properly on Ubuntu 9.10 and 10.04: https:/
There is a work-around, but I'd rather wait until things have been cleared up.
Severin H (severinh) wrote : | # |
Looks like this merge is currently blocked. The bug mentioned above has been confirmed and triaged. It looks like it's currently not possible to inhibit suspending on Karmic and Lucid machines. Too bad!
Severin H (severinh) wrote : | # |
The bug mentioned above has been fixed upstream. Do you (Sander and Marcel) still think that this plug-in would still be a valuable addition to LottaNZB even though it won't work on Ubuntu 9.10? It works fine on Ubuntu 9.04 and 10.04.
Severin H (severinh) : | # |
Marcel de Vries (carresmd-deactivatedaccount) wrote : | # |
As you block gnome-power-manager versions below 2.29.2, I couldn't test this as Fedora 12 still uses 2.28.2. However looking at the code, it's fine by me. Once I have set up a Fedora rawhide VM I'll give my definitive review. I'll approve for now, as I'm in a good mood ^^.
Severin H (severinh) wrote : | # |
Well, it will most probably not work in the Fedora rawhide VM either, simply because gnome-power-manager 2.29.2 hasn't been released yet. ^^ The fix should be part of the GNOME 2.30 Beta to be released in two days.
What do you think about putting this off to LottaNZB 0.5.4 (if it will be released at all)? I just don't feel comfortable releasing a plug-in that won't work for >75% of our users.
Marcel de Vries (carresmd-deactivatedaccount) wrote : | # |
It's probably best to put it off to 0.5.4. If I think about it, I see the bug reports floating in like 'Hey, this plugin isn't working...'.
Severin H (severinh) wrote : | # |
Now that Ubuntu 10.04 has been released, releasing LottaNZB 0.5.4 with this plug-in seems to be more reasonable. Besides this plug-in, some other minor bugs have been fixed and lots of translations were added and updated.
Preview Diff
1 | === modified file 'NEWS' |
2 | --- NEWS 2010-05-11 14:47:56 +0000 |
3 | +++ NEWS 2010-05-12 20:51:29 +0000 |
4 | @@ -1,6 +1,14 @@ |
5 | LottaNZB 0.5.4 - Development |
6 | ============================ |
7 | |
8 | +- New "Inhibit suspending" plug-in. When enabled, it prevents the computer from |
9 | + being suspended if there hasn't been any input for a certain amount of time, |
10 | + but there are still active LottaNZB downloads. This allows you to keep the |
11 | + computer powered on when you go to bed and let it suspend itself when all |
12 | + downloads are complete. |
13 | + Please note that this plug-in doesn't work on all systems. Most importantly, |
14 | + Ubuntu 9.10 isn't supported, while Ubuntu 9.04 and 10.04 are. The reason for |
15 | + this is bug #510907 in gnome-power-manager 2.28. |
16 | - Fix crash of LottaNZB at startup occuring when HellaNZB uses unrar-free to |
17 | extract downloaded archives. (LP: #577105, thanks to Jim in Chicago for |
18 | reporting this) |
19 | |
20 | === modified file 'README' |
21 | --- README 2010-02-15 21:32:25 +0000 |
22 | +++ README 2010-05-12 20:51:29 +0000 |
23 | @@ -48,6 +48,10 @@ |
24 | |
25 | - python-gnome2 (the gnomevfs module) |
26 | |
27 | +For the 'Inhibit suspending' plug-in: |
28 | + |
29 | +- gnome-power-manager >= 2.29.2 or gnome-power-manager <= 2.24.4 |
30 | + |
31 | The package names may vary depending on your distribution. |
32 | |
33 | Build LottaNZB |
34 | |
35 | === modified file 'lottanzb/plugins/__init__.py' |
36 | --- lottanzb/plugins/__init__.py 2010-01-20 22:46:40 +0000 |
37 | +++ lottanzb/plugins/__init__.py 2010-05-12 20:51:29 +0000 |
38 | @@ -150,7 +150,7 @@ |
39 | plug-in cannot be enabled. |
40 | """ |
41 | |
42 | - if key == "enabled" and value and not self.enabled: |
43 | + if key == "enabled" and value: |
44 | try: |
45 | if self.locked: |
46 | # The plug-in is locked and can therefore not be enabled |
47 | |
48 | === added directory 'lottanzb/plugins/inhibit_suspending' |
49 | === added file 'lottanzb/plugins/inhibit_suspending/__init__.py' |
50 | --- lottanzb/plugins/inhibit_suspending/__init__.py 1970-01-01 00:00:00 +0000 |
51 | +++ lottanzb/plugins/inhibit_suspending/__init__.py 2010-05-12 20:51:29 +0000 |
52 | @@ -0,0 +1,270 @@ |
53 | +# Copyright (C) 2008-2010 LottaNZB Development Team |
54 | +# |
55 | +# This program is free software; you can redistribute it and/or modify |
56 | +# it under the terms of the GNU General Public License as published by |
57 | +# the Free Software Foundation; version 3. |
58 | +# |
59 | +# This program is distributed in the hope that it will be useful, |
60 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
61 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
62 | +# GNU General Public License for more details. |
63 | +# |
64 | +# You should have received a copy of the GNU General Public License |
65 | +# along with this program; if not, write to the Free Software |
66 | +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. |
67 | + |
68 | +import re |
69 | + |
70 | +import logging |
71 | +log = logging.getLogger(__name__) |
72 | + |
73 | +try: |
74 | + import dbus |
75 | +except ImportError: |
76 | + dbus = None |
77 | + |
78 | +from subprocess import Popen, PIPE |
79 | +from distutils.version import StrictVersion |
80 | + |
81 | +from lottanzb.plugins import PluginBase, PluginEnablingError |
82 | +from lottanzb.util import _ |
83 | +from lottanzb.modes import standalone |
84 | + |
85 | +class Plugin(PluginBase): |
86 | + title = _("Inhibit suspending") |
87 | + description = _("Prevents the computer from being suspended while " |
88 | + "downloading.") |
89 | + author = _("LottaNZB Development Team") |
90 | + requires_modes = [standalone.Mode] |
91 | + |
92 | + def __init__(self, app, config): |
93 | + # Holds an `InhibitionProvider` if it's possible to instantiate one. |
94 | + self._provider = None |
95 | + |
96 | + PluginBase.__init__(self, app, config) |
97 | + |
98 | + self.connect_when_enabled(self.app.backend, "updated", |
99 | + self.on_backend_updated) |
100 | + |
101 | + def import_dependencies(self): |
102 | + """ |
103 | + Make sure that the D-Bus module is available on the user's machine. |
104 | + |
105 | + Try to set up an `InhibitionProvider` that provides the methods to |
106 | + inhibit or uninhibit suspending. |
107 | + """ |
108 | + |
109 | + global dbus |
110 | + |
111 | + if not dbus: |
112 | + import dbus |
113 | + |
114 | + # A provider should only be set up once, but this method may be called |
115 | + # several times. |
116 | + if self._provider is None: |
117 | + self._setup_provider() |
118 | + |
119 | + def _setup_provider(self): |
120 | + inhibition_providers_classes = ( |
121 | + GnomeSessionInhibitionProvider, |
122 | + HALInhibitionProvider |
123 | + ) |
124 | + |
125 | + for inhibition_providers_class in inhibition_providers_classes: |
126 | + try: |
127 | + provider = inhibition_providers_class("lottanzb") |
128 | + except InhibitionProviderError, error: |
129 | + # Try the next provider class. |
130 | + pass |
131 | + else: |
132 | + self._provider = provider |
133 | + |
134 | + if self._provider is None: |
135 | + # Bad luck. |
136 | + raise PluginEnablingError(self, _("Your desktop environment " |
137 | + "isn't supported by the plug-in.")) |
138 | + |
139 | + def refresh(self): |
140 | + """ |
141 | + Inhibit suspending if the plug-in is enabled and there are active |
142 | + downloads or an active post-processing operation. Allows suspending |
143 | + otherwise. |
144 | + """ |
145 | + |
146 | + if self._provider is not None: |
147 | + if self.enabled: |
148 | + downloads = self.app.backend.downloads |
149 | + inhibit = bool(downloads.get_processing() \ |
150 | + or (downloads.get_active_download() \ |
151 | + and not self.app.backend.paused)) |
152 | + |
153 | + if inhibit: |
154 | + self.inhibit() |
155 | + else: |
156 | + self.uninhibit() |
157 | + else: |
158 | + self.uninhibit() |
159 | + |
160 | + def on_backend_updated(self, backend): |
161 | + """ |
162 | + Check if suspending needs to be inhibited/uninhibited whenever the |
163 | + download list is updated. |
164 | + """ |
165 | + |
166 | + self.refresh() |
167 | + |
168 | + def inhibit(self): |
169 | + """Try to prevent the computer from being suspended.""" |
170 | + |
171 | + if not self._provider.is_inhibited(): |
172 | + reason = _("Download activity") |
173 | + |
174 | + try: |
175 | + self._provider.inhibit(reason) |
176 | + except InhibitionProviderError, error: |
177 | + log.warning(_("Could not disallow suspending: %s") % str(error)) |
178 | + else: |
179 | + log.info(_("Disallowing suspending.")) |
180 | + |
181 | + def uninhibit(self): |
182 | + """Allow the computer to be suspended.""" |
183 | + |
184 | + if self._provider.is_inhibited(): |
185 | + try: |
186 | + self._provider.uninhibit() |
187 | + except InhibitionProviderError, error: |
188 | + log.warning(_("Could not reallow suspending: %s") % \ |
189 | + str(error)) |
190 | + else: |
191 | + log.info(_("Allowing suspending.")) |
192 | + |
193 | + |
194 | +class InhibitionProvider: |
195 | + def __init__(self, application): |
196 | + self.application = application |
197 | + |
198 | + def inhibit(self, reason=""): |
199 | + raise NotImplementedError |
200 | + |
201 | + def uninhibit(self): |
202 | + raise NotImplementedError |
203 | + |
204 | + def is_inhibited(self): |
205 | + raise NotImplementedError |
206 | + |
207 | + def tear_down(self): |
208 | + pass |
209 | + |
210 | + |
211 | +class HALInhibitionProvider(InhibitionProvider): |
212 | + def __init__(self, application): |
213 | + InhibitionProvider.__init__(self, application) |
214 | + |
215 | + try: |
216 | + session_bus = dbus.SessionBus() |
217 | + interface_name = "org.freedesktop.PowerManagement.Inhibit" |
218 | + proxy = session_bus.get_object( |
219 | + "org.freedesktop.PowerManagement", |
220 | + "/org/freedesktop/PowerManagement/Inhibit" |
221 | + ) |
222 | + |
223 | + self._interface = dbus.Interface(proxy, interface_name) |
224 | + self._cookie = None |
225 | + except dbus.exceptions.DBusException, error: |
226 | + raise InhibitionProviderError() |
227 | + |
228 | + def inhibit(self, reason=""): |
229 | + """Try to prevent the computer from being suspended.""" |
230 | + |
231 | + try: |
232 | + self._cookie = self._interface.Inhibit(self.application, reason) |
233 | + except dbus.exceptions.DBusException, error: |
234 | + raise InhibitionProviderError(error.message) |
235 | + |
236 | + def uninhibit(self): |
237 | + """Allow the computer to be suspended.""" |
238 | + |
239 | + try: |
240 | + self._interface.UnInhibit(self._cookie) |
241 | + except dbus.exceptions.DBusException, error: |
242 | + raise InhibitionProviderError(error.message) |
243 | + finally: |
244 | + self._cookie = None |
245 | + |
246 | + def is_inhibited(self): |
247 | + return bool(self._cookie is not None) |
248 | + |
249 | + |
250 | +class GnomeSessionInhibitionProvider(InhibitionProvider): |
251 | + VERSION_PATTERN = re.compile("\d[\d\.]*") |
252 | + |
253 | + # The GNOME Power Manager didn't actually use the SessionManager D-Bus API |
254 | + # to check if there are any suspending inhibitors until version 2.29.2. |
255 | + # Thus, this `InhibitionProvider` will not work on systems like Ubuntu 9.10 |
256 | + # that use the GNOME 2.28 or older. |
257 | + # See https://bugzilla.gnome.org/show_bug.cgi?id=607748 |
258 | + MIN_GPM_VERSION = StrictVersion("2.29.2") |
259 | + |
260 | + def __init__(self, application): |
261 | + InhibitionProvider.__init__(self, application) |
262 | + |
263 | + try: |
264 | + process = Popen(["gnome-power-manager", "--version"], stdout=PIPE) |
265 | + process.wait() |
266 | + except OSError, error: |
267 | + raise InhibitionProviderError(str(error)) |
268 | + else: |
269 | + match = self.VERSION_PATTERN.search(process.stdout.read()) |
270 | + |
271 | + # Don't raise an `InhibitionProviderError` if the version output |
272 | + # doesn't have the expected format, so that potential future changes |
273 | + # to the GNOME Power Manager don't erroneously fail the check. |
274 | + if match and StrictVersion(match.group()) < self.MIN_GPM_VERSION: |
275 | + raise InhibitionProviderError() |
276 | + |
277 | + try: |
278 | + session_bus = dbus.SessionBus() |
279 | + interface_name = "org.gnome.SessionManager" |
280 | + proxy = session_bus.get_object( |
281 | + "org.gnome.SessionManager", |
282 | + "/org/gnome/SessionManager" |
283 | + ) |
284 | + |
285 | + self._interface = dbus.Interface(proxy, interface_name) |
286 | + self._client_id = self._interface.RegisterClient(self.application, |
287 | + self.application) |
288 | + self._cookie = None |
289 | + except dbus.exceptions.DBusException, error: |
290 | + raise InhibitionProviderError(error.message) |
291 | + |
292 | + def inhibit(self, reason=""): |
293 | + """Try to prevent the computer from being suspended.""" |
294 | + |
295 | + try: |
296 | + self._cookie = self._interface.Inhibit(self.application, 0, reason, |
297 | + 0x4) |
298 | + except dbus.exceptions.DBusException, error: |
299 | + raise InhibitionProviderError(error.message) |
300 | + |
301 | + def uninhibit(self): |
302 | + """Allow the computer to be suspended.""" |
303 | + |
304 | + try: |
305 | + self._interface.Uninhibit(self._cookie) |
306 | + except dbus.exceptions.DBusException, error: |
307 | + raise InhibitionProviderError(error.message) |
308 | + finally: |
309 | + self._cookie = None |
310 | + |
311 | + def tear_down(self): |
312 | + try: |
313 | + self._interface.UnregisterClient(self._client_id) |
314 | + except dbus.exceptions.DBusException, error: |
315 | + raise InhibitionProviderError(error.message) |
316 | + |
317 | + def is_inhibited(self): |
318 | + return bool(self._cookie is not None) |
319 | + |
320 | + |
321 | +class InhibitionProviderError(Exception): |
322 | + pass |
While all D-Bus operations seem to be properly done, I haven't actually tested the plug-in yet (by not doing any input for a few minutes while downloading). Also, the plug-in will need to be tested on Ubuntu 9.04 (or similar) as a different (older) power management API is used there.
So this merge proposal is mainly meant to be a call to testers. ;-)