Merge lp:~dobey/rhythmbox-ubuntuone/drop-store-ui into lp:rhythmbox-ubuntuone

Proposed by dobey
Status: Merged
Approved by: dobey
Approved revision: 123
Merged at revision: 122
Proposed branch: lp:~dobey/rhythmbox-ubuntuone/drop-store-ui
Merge into: lp:rhythmbox-ubuntuone
Diff against target: 359 lines (+44/-275)
2 files modified
ubuntuone/MusicStoreWidget.py (+0/-265)
ubuntuone/ubuntuone.py (+44/-10)
To merge this branch: bzr merge lp:~dobey/rhythmbox-ubuntuone/drop-store-ui
Reviewer Review Type Date Requested Status
Diego Sarmentero (community) Approve
Alejandro J. Cura (community) Approve
Review via email: mp+141811@code.launchpad.net

Commit message

Remove the UI and source for the music store
Switch to using DownloadFinished directly from syncdaemon

To post a comment you must log in.
Revision history for this message
Alejandro J. Cura (alecu) wrote :

Code looks good. +1

review: Approve
Revision history for this message
Diego Sarmentero (diegosarmentero) wrote :

+1

review: Approve

Preview Diff

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

Subscribers

People subscribed via source and target branches