Merge lp:~dobey/rhythmbox-ubuntuone/update-4-2 into lp:rhythmbox-ubuntuone/stable-4-2
- update-4-2
- Merge into stable-4-2
Proposed by
dobey
Status: | Merged |
---|---|
Approved by: | dobey |
Approved revision: | no longer in the source branch. |
Merged at revision: | 122 |
Proposed branch: | lp:~dobey/rhythmbox-ubuntuone/update-4-2 |
Merge into: | lp:rhythmbox-ubuntuone/stable-4-2 |
Diff against target: |
423 lines (+48/-291) 7 files modified
po/POTFILES.in (+0/-2) rhythmbox-ubuntuone.desktop.in (+0/-12) run-tests (+3/-0) setup.cfg (+1/-1) setup.py (+0/-1) ubuntuone/MusicStoreWidget.py (+0/-265) ubuntuone/ubuntuone.py (+44/-10) |
To merge this branch: | bzr merge lp:~dobey/rhythmbox-ubuntuone/update-4-2 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Roberto Alsina (community) | Approve | ||
Review via email: mp+142395@code.launchpad.net |
Commit message
[Rodney Dawes]
Update setup.py to remove MusicStoreWidget.py as well.
Update POTFILES.in
Remove the .desktop file as we don't need it any more
Run setup.py build and clean in the run-tests script for basic checks
Remove the UI and source for the music store
Switch to using DownloadFinished directly from syncdaemon
Description of the change
To post a comment you must log in.
Revision history for this message
Roberto Alsina (ralsina) : | # |
review:
Approve
- 122. By dobey
-
[r=dobey] [Rodney Dawes]
Update setup.py to remove MusicStoreWidget.py as well.
Update POTFILES.in
Remove the .desktop file as we don't need it any more
Run setup.py build and clean in the run-tests script for basic checks
Remove the UI and source for the music store
Switch to using DownloadFinished directly from syncdaemon
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'po/POTFILES.in' |
2 | --- po/POTFILES.in 2012-02-23 00:50:54 +0000 |
3 | +++ po/POTFILES.in 2013-01-08 20:17:25 +0000 |
4 | @@ -1,5 +1,3 @@ |
5 | -rhythmbox-ubuntuone.desktop.in |
6 | ubuntuone/ubuntuone.py |
7 | -ubuntuone/MusicStoreWidget.py |
8 | [type: gettext/ini]ubuntuone/ubuntuone.plugin.in |
9 | |
10 | |
11 | === removed file 'rhythmbox-ubuntuone.desktop.in' |
12 | --- rhythmbox-ubuntuone.desktop.in 2012-03-07 16:01:45 +0000 |
13 | +++ rhythmbox-ubuntuone.desktop.in 1970-01-01 00:00:00 +0000 |
14 | @@ -1,12 +0,0 @@ |
15 | -[Desktop Entry] |
16 | -Name=Ubuntu One Music Store |
17 | -_Comment=Purchase music on Ubuntu One in Rhythmbox |
18 | -Exec=rhythmbox %U |
19 | -Terminal=false |
20 | -Type=Application |
21 | -Icon=rhythmbox |
22 | -Categories=GNOME;GTK;AudioVideo; |
23 | -MimeType=x-scheme-handler/u1ms |
24 | -StartupNotify=true |
25 | -X-Ubuntu-Gettext-Domain=rhythmbox-ubuntuone |
26 | -NoDisplay=true |
27 | |
28 | === modified file 'run-tests' |
29 | --- run-tests 2012-08-24 19:36:25 +0000 |
30 | +++ run-tests 2013-01-08 20:17:25 +0000 |
31 | @@ -14,6 +14,7 @@ |
32 | # |
33 | # You should have received a copy of the GNU General Public License along |
34 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
35 | +./setup.py build |
36 | export PYTHONPATH=ubuntuone |
37 | USE_PYFLAKES=1 u1lint . |
38 | if [ -x `which pep8` ]; then |
39 | @@ -22,3 +23,5 @@ |
40 | echo "Please install the 'pep8' package." |
41 | fi |
42 | rm -rf _trial_temp |
43 | +./setup.py clean |
44 | + |
45 | |
46 | === modified file 'setup.cfg' |
47 | --- setup.cfg 2012-02-23 00:50:54 +0000 |
48 | +++ setup.cfg 2013-01-08 20:17:25 +0000 |
49 | @@ -1,2 +1,2 @@ |
50 | [build_i18n] |
51 | -desktop_files=[("lib/rhythmbox/plugins/ubuntuone", ("ubuntuone/ubuntuone.plugin.in",)), ("share/applications", ("rhythmbox-ubuntuone.desktop.in",))] |
52 | +desktop_files=[("lib/rhythmbox/plugins/ubuntuone", ("ubuntuone/ubuntuone.plugin.in",))] |
53 | |
54 | === modified file 'setup.py' |
55 | --- setup.py 2012-12-07 18:50:52 +0000 |
56 | +++ setup.py 2013-01-08 20:17:25 +0000 |
57 | @@ -15,6 +15,5 @@ |
58 | url='https://launchpad.net/rhythmbox-ubuntuone', |
59 | data_files=[('lib/rhythmbox/plugins/ubuntuone', |
60 | ['ubuntuone/ubuntuone.py', |
61 | - 'ubuntuone/MusicStoreWidget.py', |
62 | ])], |
63 | ) |
64 | |
65 | === removed file 'ubuntuone/MusicStoreWidget.py' |
66 | --- ubuntuone/MusicStoreWidget.py 2012-12-07 15:06:25 +0000 |
67 | +++ ubuntuone/MusicStoreWidget.py 1970-01-01 00:00:00 +0000 |
68 | @@ -1,265 +0,0 @@ |
69 | -# Copyright (C) 2009-2012 Canonical, Ltd. |
70 | -# |
71 | -# This library is free software; you can redistribute it and/or modify |
72 | -# it under the terms of the GNU Lesser General Public License |
73 | -# version 3.0 as published by the Free Software Foundation. |
74 | -# |
75 | -# This library is distributed in the hope that it will be useful, |
76 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
77 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
78 | -# GNU Lesser General Public License version 3.0 for more details. |
79 | -# |
80 | -# You should have received a copy of the GNU Lesser General Public |
81 | -# License along with this library. If not, see |
82 | -# <http://www.gnu.org/licenses/>. |
83 | -"""The Ubuntu One Rhythmbox plugin.""" |
84 | - |
85 | -from __future__ import print_function, unicode_literals |
86 | - |
87 | -import gettext |
88 | -import os |
89 | - |
90 | -# pylint: disable=E0611,F0401 |
91 | -from gi.repository import Gio, GObject, Gtk, RB |
92 | -from gi.repository.UbuntuOneUI import MusicStore as U1MusicStore |
93 | -# pylint: enable=E0611,F0401 |
94 | - |
95 | -from gettext import lgettext as _ |
96 | -parseurl = None |
97 | -try: |
98 | - import urllib.parse |
99 | - parseurl = urllib.parse.urlparse |
100 | -except ImportError: |
101 | - import urlparse |
102 | - parseurl = urlparse.urlparse |
103 | - |
104 | -gettext.bindtextdomain("rhythmbox-ubuntuone", "/usr/share/locale") |
105 | -gettext.textdomain("rhythmbox-ubuntuone") |
106 | - |
107 | -MUSIC_STORE_WIDGET = U1MusicStore() |
108 | -U1LIBRARYPATH = MUSIC_STORE_WIDGET.get_library_location() |
109 | - |
110 | - |
111 | -class U1EntryType(RB.RhythmDBEntryType): |
112 | - """Entry type for the Ubuntu One Music Store source.""" |
113 | - |
114 | - def __init__(self): |
115 | - RB.RhythmDBEntryType.__init__(self, name='ubuntuone') |
116 | - |
117 | - def do_can_sync_metadata(self, entry): |
118 | - """Not a real source, so we can't sync metadata.""" |
119 | - return False |
120 | - |
121 | - def do_sync_metadata(self, entry, changes): |
122 | - """Do nothing.""" |
123 | - return |
124 | - |
125 | - |
126 | -class U1MusicStoreWidget(object): |
127 | - """The Ubuntu One Music Store.""" |
128 | - def __init__(self, plugin): |
129 | - self.plugin = plugin |
130 | - self.db = None |
131 | - self.shell = None |
132 | - self.source = None |
133 | - self.entry_type = U1EntryType() |
134 | - |
135 | - def activate(self, shell): |
136 | - """Plugin startup.""" |
137 | - self.db = shell.get_property("db") |
138 | - group = RB.DisplayPageGroup.get_by_id("stores") |
139 | - |
140 | - icon = Gtk.IconTheme.get_default().load_icon( |
141 | - "ubuntuone", 24, 0) |
142 | - |
143 | - self.db.register_entry_type(self.entry_type) |
144 | - |
145 | - self.source = GObject.new(U1Source, |
146 | - shell=shell, |
147 | - entry_type=self.entry_type, |
148 | - pixbuf=icon, |
149 | - plugin=self.plugin) |
150 | - shell.register_entry_type_for_source(self.source, self.entry_type) |
151 | - shell.append_display_page(self.source, group) |
152 | - |
153 | - self.shell = shell |
154 | - self.source.connect("preview-mp3", self.play_preview_mp3) |
155 | - self.source.connect("play-library", self.play_library) |
156 | - self.source.connect("download-finished", self.download_finished) |
157 | - self.source.connect("url-loaded", self.url_loaded) |
158 | - |
159 | - self.source.props.query_model = RB.RhythmDBQueryModel.new_empty( |
160 | - self.db) |
161 | - |
162 | - def deactivate(self, shell): |
163 | - """Plugin shutdown.""" |
164 | - # remove source |
165 | - self.source.delete_thyself() |
166 | - # delete held references |
167 | - del self.db |
168 | - del self.source |
169 | - del self.shell |
170 | - |
171 | - def url_loaded(self, source, url): |
172 | - """A URL is loaded in the plugin""" |
173 | - if parseurl(url)[2] == "https": |
174 | - pass |
175 | - else: |
176 | - pass |
177 | - |
178 | - def _udf_path_to_library_uri(self, path): |
179 | - """Build a URI from the path for the song in the library.""" |
180 | - if path.startswith(U1LIBRARYPATH): |
181 | - library_path = path |
182 | - else: |
183 | - subpath = path |
184 | - if subpath.startswith("/"): |
185 | - subpath = subpath[1:] |
186 | - library_path = os.path.join(U1LIBRARYPATH, subpath) |
187 | - # convert path to URI. Don't use urllib for this; Python and |
188 | - # glib escape URLs differently. gio does it the glib way. |
189 | - return Gio.File.new_for_path(library_path).get_uri() |
190 | - |
191 | - def download_finished(self, source, path): |
192 | - """A file is finished downloading""" |
193 | - library_uri = self._udf_path_to_library_uri(path) |
194 | - # Import the URI |
195 | - if not self.db.entry_lookup_by_location(library_uri): |
196 | - self.db.add_uri(library_uri) |
197 | - |
198 | - def play_library(self, source, path): |
199 | - """Switch to and start playing a song from the library""" |
200 | - uri = self._udf_path_to_library_uri(path) |
201 | - entry = self.db.entry_lookup_by_location(uri) |
202 | - if not entry: |
203 | - print("couldn't find entry: %s" % uri) |
204 | - return |
205 | - libsrc = self.shell.props.library_source |
206 | - artist_view, album_view = libsrc.get_property_views()[0:2] |
207 | - song_view = libsrc.get_entry_view() |
208 | - artist = entry.get_string(RB.RhythmDBPropType.ARTIST) |
209 | - album = entry.get_string(RB.RhythmDBPropType.ALBUM) |
210 | - self.shell.props.display_page_tree.select(libsrc) |
211 | - artist_view.set_selection([artist]) |
212 | - album_view.set_selection([album]) |
213 | - song_view.scroll_to_entry(entry) |
214 | - player = self.shell.get_property('shell-player') |
215 | - player.stop() |
216 | - player.play_entry(entry, libsrc) |
217 | - |
218 | - def play_preview_mp3(self, source, url, title): |
219 | - """Play a passed mp3; signal handler for preview-mp3 signal.""" |
220 | - # create an entry, don't save it, and play it |
221 | - entry = RB.RhythmDBEntry.new(self.db, self.entry_type, url) |
222 | - self.db.entry_set(entry, RB.RhythmDBPropType.TITLE, title) |
223 | - player = self.shell.get_property('shell-player') |
224 | - player.stop() |
225 | - player.play_entry(entry, self.source) |
226 | - |
227 | - |
228 | -class U1Source(RB.Source): |
229 | - """A Rhythmbox source widget for the U1 Music Store.""" |
230 | - # gproperties required so that rb.Source is instantiable |
231 | - __gproperties__ = { |
232 | - str('plugin'): (GObject.GObject, str('plugin'), str('plugin'), |
233 | - GObject.PARAM_WRITABLE | GObject.PARAM_CONSTRUCT_ONLY), |
234 | - } |
235 | - # we have the preview-mp3 signal; we receive it from the widget, and |
236 | - # re-emit it so that the plugin gets it, because the plugin actually |
237 | - # plays the mp3 |
238 | - __gsignals__ = { |
239 | - str("preview-mp3"): (GObject.SIGNAL_RUN_FIRST, |
240 | - GObject.TYPE_NONE, (str, str)), |
241 | - str("play-library"): (GObject.SIGNAL_RUN_FIRST, |
242 | - GObject.TYPE_NONE, (str,)), |
243 | - str("download-finished"): (GObject.SIGNAL_RUN_FIRST, |
244 | - GObject.TYPE_NONE, (str,)), |
245 | - str("url-loaded"): (GObject.SIGNAL_RUN_FIRST, |
246 | - GObject.TYPE_NONE, (str,)), |
247 | - } |
248 | - |
249 | - def __init__(self): |
250 | - RB.Source.__init__(self, name=_("Ubuntu One")) |
251 | - self.browser = MUSIC_STORE_WIDGET |
252 | - self.__activated = False |
253 | - self.__plugin = None |
254 | - self.add_music_store_widget() |
255 | - |
256 | - def do_impl_activate(self): |
257 | - """Source startup.""" |
258 | - if self.__activated: |
259 | - return |
260 | - self.__activated = True |
261 | - RB.Source.do_impl_activate(self) |
262 | - |
263 | - def do_impl_want_uri(self, uri): |
264 | - """I want to handle u1ms URLs""" |
265 | - if uri.startswith("u1ms://"): |
266 | - return 100 |
267 | - return 0 |
268 | - |
269 | - def do_impl_add_uri(self, uri, title, genre, callback=None, |
270 | - callback_data=None, destroy_data=None): |
271 | - """Handle a u1ms URL""" |
272 | - if not uri.startswith("u1ms://"): |
273 | - return |
274 | - uri_to_use = uri.replace("u1ms://", "http://") |
275 | - # pylint: disable=E1101 |
276 | - shell = self.get_property("shell") |
277 | - shell.props.display_page_tree.select(self) |
278 | - self.browser.load_store_link(uri_to_use) |
279 | - if callback is not None: |
280 | - callback(callback_data) |
281 | - if destroy_data is not None: |
282 | - destroy_data(callback_data) |
283 | - |
284 | - def add_music_store_widget(self): |
285 | - """Display the music store widget in Rhythmbox.""" |
286 | - # pylint: disable=E1101 |
287 | - if self.browser.get_property('parent') is None: |
288 | - self.add(self.browser) |
289 | - else: |
290 | - self.browser.reparent(self) |
291 | - self.browser.show() |
292 | - self.show() |
293 | - self.browser.set_property("visible", True) |
294 | - self.browser.connect("preview-mp3", |
295 | - self.re_emit_preview) |
296 | - self.browser.connect("play-library", |
297 | - self.re_emit_playlibrary) |
298 | - self.browser.connect("download-finished", |
299 | - self.re_emit_downloadfinished) |
300 | - self.browser.connect("url-loaded", |
301 | - self.re_emit_urlloaded) |
302 | - |
303 | - def do_impl_can_pause(self): |
304 | - """Implementation can pause. |
305 | - If we don't handle this, Rhythmbox segfaults.""" |
306 | - return True # so we can pause, else we segfault |
307 | - |
308 | - def re_emit_preview(self, widget, url, title): |
309 | - """Handle the preview-mp3 signal and re-emit it.""" |
310 | - # pylint: disable=E1101 |
311 | - self.emit("preview-mp3", url, title) |
312 | - |
313 | - def re_emit_playlibrary(self, widget, path): |
314 | - """Handle the play-library signal and re-emit it.""" |
315 | - # pylint: disable=E1101 |
316 | - self.emit("play-library", path) |
317 | - |
318 | - def re_emit_downloadfinished(self, widget, path): |
319 | - """Handle the download-finished signal and re-emit it.""" |
320 | - # pylint: disable=E1101 |
321 | - self.emit("download-finished", path) |
322 | - |
323 | - def re_emit_urlloaded(self, widget, url): |
324 | - """Handle the url-loaded signal and re-emit it.""" |
325 | - # pylint: disable=E1101 |
326 | - self.emit("url-loaded", url) |
327 | - |
328 | - def do_set_property(self, prop, value): |
329 | - """Allow property settings to handle the plug-in call.""" |
330 | - if prop.name == 'plugin': |
331 | - self.__plugin = value |
332 | - else: |
333 | - raise AttributeError('unknown property %s' % prop.name) |
334 | |
335 | === modified file 'ubuntuone/ubuntuone.py' |
336 | --- ubuntuone/ubuntuone.py 2012-08-24 19:36:25 +0000 |
337 | +++ ubuntuone/ubuntuone.py 2013-01-08 20:17:25 +0000 |
338 | @@ -16,13 +16,14 @@ |
339 | |
340 | from __future__ import print_function, unicode_literals |
341 | |
342 | -# pylint: disable=E0611 |
343 | +import os |
344 | + |
345 | +from dbus import SessionBus, DBusException |
346 | +from dirspec.utils import user_home |
347 | from gi.repository import Gio, GObject, Peas |
348 | -# pylint: enable=E0611 |
349 | |
350 | -# pylint: disable=W0403 |
351 | -from MusicStoreWidget import U1MusicStoreWidget, U1LIBRARYPATH |
352 | -# pylint: enable=W0403 |
353 | +U1LIBRARYPATH = os.path.join(user_home, '.ubuntuone', |
354 | + 'Purchased from Ubuntu One') |
355 | |
356 | |
357 | class UbuntuOnePlugin (GObject.GObject, Peas.Activatable): |
358 | @@ -32,14 +33,19 @@ |
359 | |
360 | def __init__(self): |
361 | GObject.GObject.__init__(self) |
362 | + self.db = None |
363 | + |
364 | + # Connect to the session bus |
365 | + self._signal = None |
366 | + try: |
367 | + self._bus = SessionBus() |
368 | + except DBusException: |
369 | + return |
370 | |
371 | # RhythmDB settings so we can handle changes |
372 | self.rdbconf = Gio.Settings('org.gnome.rhythmbox.rhythmdb') |
373 | self.rdbconf.connect('changed::locations', self._locations_changed) |
374 | |
375 | - # The Music Store itself |
376 | - self.music_store_widget = U1MusicStoreWidget(plugin=self) |
377 | - |
378 | def _locations_changed(self, *args, **kwargs): |
379 | """Handle the locations setting being changed.""" |
380 | libraries = self.rdbconf.get_strv('locations') |
381 | @@ -57,12 +63,40 @@ |
382 | libraries.remove(unescaped_path) |
383 | self.rdbconf.set_strv('locations', libraries) |
384 | |
385 | + def download_finished(self, path, info): |
386 | + """A file is finished downloading""" |
387 | + if not path.startswith(U1LIBRARYPATH): |
388 | + return |
389 | + |
390 | + # convert path to URI. Don't use urllib for this; Python and |
391 | + # glib escape URLs differently. gio does it the glib way. |
392 | + library_uri = Gio.File.new_for_path(path).get_uri() |
393 | + |
394 | + # Import the URI |
395 | + if not self.db.entry_lookup_by_location(library_uri): |
396 | + self.db.add_uri(library_uri) |
397 | + |
398 | def do_activate(self): |
399 | """Plug-in startup.""" |
400 | # Add the Ubuntu One purchased music directory if not already added |
401 | self._locations_changed() |
402 | - self.music_store_widget.activate(self.object) |
403 | + # Get a reference to the db |
404 | + self.db = self.object.get_property('db') |
405 | + |
406 | + # Connect to the download finished from syncdaemon |
407 | + try: |
408 | + self._bus.add_signal_receiver(self.download_finished, |
409 | + signal_name='DownloadFinished') |
410 | + except DBusException: |
411 | + return |
412 | |
413 | def do_deactivate(self): |
414 | """Plug-in shutdown.""" |
415 | - self.music_store_widget.deactivate(self.object) |
416 | + del self.db |
417 | + |
418 | + # Disconnect the signal handler for downloads |
419 | + try: |
420 | + self.bus.remove_signal_handler(self.download_finished, |
421 | + signal_name='DownloadFinished') |
422 | + except DBusException: |
423 | + return |