Merge lp:~dobey/rhythmbox-ubuntuone/update-4-2 into lp:rhythmbox-ubuntuone/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
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

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

Subscribers

People subscribed via source and target branches

to all changes: