Merge lp:~dobey/rhythmbox-ubuntuone/libu1-mp3-install into lp:rhythmbox-ubuntuone

Proposed by dobey
Status: Merged
Approved by: dobey
Approved revision: 101
Merged at revision: 101
Proposed branch: lp:~dobey/rhythmbox-ubuntuone/libu1-mp3-install
Merge into: lp:rhythmbox-ubuntuone
Diff against target: 432 lines (+33/-226)
5 files modified
gst/__init__.py (+0/-14)
gst/pbutils.py (+0/-6)
rb.py (+3/-0)
umusicstore/MusicStoreWidget.py (+23/-200)
umusicstore/__init__.py (+7/-6)
To merge this branch: bzr merge lp:~dobey/rhythmbox-ubuntuone/libu1-mp3-install
Reviewer Review Type Date Requested Status
Eric Casteleijn (community) Approve
Roberto Alsina (community) Approve
Review via email: mp+56471@code.launchpad.net

Commit message

Update for new rhythmbox API changes
Remove MP3 codec installation bits as libu1 handles this now

To post a comment you must log in.
Revision history for this message
Roberto Alsina (ralsina) wrote :

+1

review: Approve
Revision history for this message
Eric Casteleijn (thisfred) wrote :

Looks good to me.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== removed directory 'gst'
2=== removed file 'gst/__init__.py'
3--- gst/__init__.py 2010-11-02 15:50:32 +0000
4+++ gst/__init__.py 1970-01-01 00:00:00 +0000
5@@ -1,14 +0,0 @@
6-"""Fake gst.py module for testing."""
7-
8-STATE_NULL = 0
9-STATE_PLAYING = 1
10-
11-
12-def parse_launch(*args, **kwargs):
13- """Fake parse_launch."""
14- return
15-
16-
17-def update_registry(*args, **kwargs):
18- """Fake update_registry."""
19- return
20
21=== removed file 'gst/pbutils.py'
22--- gst/pbutils.py 2010-11-02 15:50:32 +0000
23+++ gst/pbutils.py 1970-01-01 00:00:00 +0000
24@@ -1,6 +0,0 @@
25-"""Fake pbutils module for testing."""
26-
27-
28-def is_missing_plugin_message(*args, **kwargs):
29- """Fake is_missing_plugin_message."""
30- return
31
32=== modified file 'rb.py'
33--- rb.py 2010-11-02 15:50:32 +0000
34+++ rb.py 2011-04-05 21:38:26 +0000
35@@ -30,6 +30,9 @@
36 """Fake method."""
37 return
38
39+def rb_display_page_group_get_by_id(*args, **kwargs):
40+ """Fake method."""
41+ return
42
43 def rb_source_group_register(*args, **kwargs):
44 """Fake method."""
45
46=== modified file 'umusicstore/MusicStoreWidget.py'
47--- umusicstore/MusicStoreWidget.py 2010-12-16 14:40:36 +0000
48+++ umusicstore/MusicStoreWidget.py 2011-04-05 21:38:26 +0000
49@@ -23,16 +23,11 @@
50 import gtk
51 import gio
52
53-import aptdaemon.client
54-import dbus
55-import dbus.exceptions
56 import gconf
57 import gettext
58-import gst
59-import gst.pbutils
60 import os
61 # pylint: disable=F0401
62-import rb
63+import rb as RB
64 import rhythmdb
65 # pylint: enable=F0401
66 import stat
67@@ -40,13 +35,6 @@
68 import urlparse
69 import xdg.BaseDirectory
70
71-from aptdaemon import policykit1
72-try:
73- from aptdaemon.defer import inline_callbacks
74-except ImportError:
75- from defer import inline_callbacks
76-from aptdaemon.enums import EXIT_SUCCESS
77-from aptdaemon.gtkwidgets import AptProgressBar
78 from gettext import lgettext as _
79 from ubuntuone.gtkwidgets import MusicStore as U1MusicStore
80
81@@ -67,39 +55,39 @@
82 def __init__(self):
83 rhythmdb.EntryType.__init__(self, name='ubuntuone')
84
85- def can_sync_metadata(self, entry):
86+ def do_can_sync_metadata(self, entry):
87 """Not a real source, so we can't sync metadata."""
88 return False
89
90+ def do_sync_metadata(self, entry, changes):
91+ """Do nothing."""
92+ return
93+
94
95 class U1MusicStoreWidget(object):
96 """The Ubuntu One Music Store."""
97- def __init__(self, plugin, find_file):
98+ def __init__(self, plugin):
99 self.plugin = plugin
100- self.find_file = find_file
101+ self.entry_type = U1EntryType()
102
103 def activate(self, shell):
104 """Plugin startup."""
105 self.db = shell.get_property("db")
106- group = rb.rb_source_group_get_by_name("stores")
107- if not group:
108- group = rb.rb_source_group_register("stores",
109- "Stores",
110- rb.SOURCE_GROUP_CATEGORY_FIXED)
111+ group = RB.rb_display_page_group_get_by_id("stores")
112
113 icon = gtk.IconTheme().load_icon(
114 "ubuntuone", gtk.icon_size_lookup(gtk.ICON_SIZE_MENU)[0], 0)
115
116- self.entry_type = U1EntryType()
117 self.db.register_entry_type(self.entry_type)
118
119 self.source = gobject.new(U1Source,
120 shell=shell,
121 entry_type=self.entry_type,
122- source_group=group,
123- icon=icon,
124+ pixbuf=icon,
125 plugin=self.plugin)
126 shell.register_entry_type_for_source(self.source, self.entry_type)
127+ shell.append_display_page(self.source, group)
128+
129 self.shell = shell
130 self.source.connect("preview-mp3", self.play_preview_mp3)
131 self.source.connect("play-library", self.play_library)
132@@ -107,7 +95,6 @@
133 self.source.connect("url-loaded", self.url_loaded)
134
135 # Do these every time
136- shell.append_source(self.source, None) # Add the source to the list
137 self.add_u1_library()
138
139 def deactivate(self, shell):
140@@ -176,17 +163,16 @@
141 print "couldn't find entry", uri
142 return
143 libsrc = self.shell.props.library_source
144- artist_view, album_view = libsrc.get_property_views()[0:]
145+ artist_view, album_view = libsrc.get_property_views()[0:2]
146 song_view = libsrc.get_entry_view()
147 artist = self.shell.props.db.entry_get(entry, rhythmdb.PROP_ARTIST)
148 album = self.shell.props.db.entry_get(entry, rhythmdb.PROP_ALBUM)
149- self.shell.props.sourcelist.select(libsrc)
150+ self.shell.props.display_page_tree.select(libsrc)
151 artist_view.set_selection([artist])
152 album_view.set_selection([album])
153 song_view.scroll_to_entry(entry)
154 player = self.shell.get_player()
155 player.stop()
156- player.play()
157 player.play_entry(entry, libsrc)
158
159 def play_preview_mp3(self, source, url, title):
160@@ -284,11 +270,11 @@
161 gconf.VALUE_STRING, libraries)
162
163
164-class U1Source(rb.Source, gobject.GObject):
165+class U1Source(RB.Source, gobject.GObject):
166 """A Rhythmbox source widget for the U1 Music Store."""
167 # gproperties required so that rb.Source is instantiable
168 __gproperties__ = {
169- 'plugin': (rb.Plugin, 'plugin', 'plugin',
170+ 'plugin': (RB.Plugin, 'plugin', 'plugin',
171 gobject.PARAM_WRITABLE | gobject.PARAM_CONSTRUCT_ONLY),
172 }
173 # we have the preview-mp3 signal; we receive it from the widget, and
174@@ -306,18 +292,18 @@
175 }
176
177 def __init__(self):
178- rb.Source.__init__(self, name=_("Ubuntu One"))
179+ RB.Source.__init__(self, name=_("Ubuntu One"))
180 gobject.GObject.__init__(self)
181 self.browser = MUSIC_STORE_WIDGET
182 self.__activated = False
183+ self.add_music_store_widget()
184
185 def do_impl_activate(self):
186 """Source startup."""
187 if self.__activated:
188 return
189 self.__activated = True
190- self.test_can_play_mp3()
191- rb.Source.do_impl_activate(self)
192+ RB.Source.do_impl_activate(self)
193
194 def do_impl_want_uri(self, uri):
195 """I want to handle u1ms URLs"""
196@@ -332,179 +318,15 @@
197 uri_to_use = uri.replace("u1ms://", "http://")
198 print "Calling u1musicstore plugin with %s" % uri_to_use
199 shell = self.get_property("shell")
200- shell.props.sourcelist.select(self)
201+ shell.props.display_page_tree.select(self)
202 self.browser.load_store_link(uri_to_use)
203 return True
204
205- def test_can_play_mp3(self):
206- """Can the user play mp3s? Start a GStreamer pipeline to check."""
207- mp3pth = os.path.realpath(os.path.join(
208- os.path.split(__file__)[0], "empty.mp3"))
209- uri = "file://%s" % urllib.quote("%s" % mp3pth)
210- self.install_pipeline = gst.parse_launch(
211- 'uridecodebin uri=%s ! fakesink' % uri)
212- bus = self.install_pipeline.get_bus()
213- bus.add_signal_watch()
214- bus.connect("message::element", self._got_element_msg)
215- bus.connect("message::eos", self._got_end_of_stream)
216- self.install_pipeline.set_state(gst.STATE_PLAYING)
217-
218- def _got_element_msg(self, bus, msg):
219- """Handler for element messages from the check-mp3 pipeline.
220- GStreamer throws a "plugin-missing" element message if the
221- user does not have the right codecs to play a file."""
222- plugin_missing = gst.pbutils.is_missing_plugin_message(msg)
223- if plugin_missing:
224- self.install_pipeline.set_state(gst.STATE_NULL)
225- self.install_mp3_playback()
226-
227- def _got_end_of_stream(self, bus, msg):
228- """Handler for end of stream from the check-mp3 pipeline.
229- If we reach the end of the stream, mp3 playback is enabled."""
230- self.install_pipeline.set_state(gst.STATE_NULL)
231- if os.environ.get("U1INSTALLMP3ANYWAY", None) is not None:
232- # override the decision not to install the package
233- self.install_mp3_playback()
234- else:
235- self.add_music_store_widget()
236-
237- def install_mp3_playback(self):
238- """Use aptdaemon to install the Fluendo mp3 playback codec package."""
239- self.install_box = gtk.Alignment(xscale=0.0, yscale=0.0, xalign=0.5,
240- yalign=0.5)
241- self.install_vbox = gtk.VBox()
242- self.install_label_head = gtk.Label()
243- self.install_label_head.set_use_markup(True)
244- not_installed = _("MP3 plugins are not installed")
245- self.install_label_head.set_markup('<span weight="bold" size="larger">'
246- '%s</span>' % not_installed)
247- self.install_label_head.set_alignment(0.0, 0.5)
248- self.install_label_body = gtk.Label()
249- self.install_label_body.set_text(_('To listen to your purchased songs'
250- ', you need to install MP3 plugins. Click below to install them.'))
251- self.install_label_body.set_alignment(0.0, 0.5)
252- self.install_label_eula = gtk.Label()
253- # EULA text copied from
254- # gstreamer0.10-fluendo-plugins-mp3-partner.templates
255- # The partner package shows the EULA itself on installations, but
256- # aptdaemon installations work like DEBIAN_FRONTEND=noninteractive
257- # so we show the EULA here. (This also avoids a popup window.)
258- # EULA text is not translatable; do not wrap it with gettext!
259- self.install_label_eula.set_markup(
260- "<small>MPEG Layer-3 audio decoding technology notice\n"
261- "MPEG Layer-3 audio decoding technology licensed "
262- "from Fraunhofer IIS and Thomson\n"
263- "This product cannot be installed in product other than Personal "
264- "Computers sold for general purpose usage, and not for set-top "
265- "boxes, embedded PC, PC which are sold and customized for "
266- "mainly audio or multimedia playback and/or registration, "
267- "unless the seller has received a license by Fraunhofer IIS"
268- "and Thomson and pay the relevant royalties to them.</small>")
269- self.install_label_eula.set_alignment(0.0, 0.5)
270- self.install_label_eula.set_size_request(400, 200)
271- self.install_label_eula.set_line_wrap(True)
272- self.install_hbtn = gtk.HButtonBox()
273- self.install_hbtn.set_layout(gtk.BUTTONBOX_END)
274- self.install_button = gtk.Button(label=_("Install MP3 plugins"))
275- self.install_button.connect("clicked", self._start_mp3_install)
276- self.install_hbtn.add(self.install_button)
277- self.install_vbox.pack_start(self.install_label_head, expand=False)
278- self.install_vbox.pack_start(self.install_label_body, expand=False,
279- padding=12)
280- self.install_vbox.pack_start(self.install_hbtn, expand=False)
281- self.install_vbox.pack_start(self.install_label_eula, expand=False,
282- padding=12)
283- self.install_box.add(self.install_vbox)
284- self.install_box.show_all()
285- self.add(self.install_box)
286-
287- @inline_callbacks
288- def _authenticate_for_add_and_install(self):
289- """Authenticate with aptdaemon"""
290- bus = dbus.SystemBus()
291- name = bus.get_unique_name()
292- action = policykit1.PK_ACTION_INSTALL_PACKAGES_FROM_NEW_REPO
293- flags = policykit1.CHECK_AUTH_ALLOW_USER_INTERACTION
294- yield policykit1.check_authorization_by_name(name, action, flags=flags)
295-
296- @inline_callbacks
297- def _start_mp3_install(self, btn):
298- """Add the 'partner' repository and update the package list from it."""
299- self.ac = aptdaemon.client.AptClient()
300- try:
301- yield self._authenticate_for_add_and_install()
302- trans = yield self.ac.add_repository(
303- src_type="deb",
304- uri="http://archive.canonical.com/",
305- dist="maverick",
306- comps=["partner"],
307- comment="added by U1MusicStoreWidget",
308- sourcesfile=PARTNER_LIST)
309- yield trans.run(defer=True)
310- trans = yield self.ac.update_cache(sources_list=SOURCES_DIR
311- + PARTNER_LIST)
312- self.update_progress = AptProgressBar(trans)
313- self.update_progress.show()
314- self.install_label_head.set_text("")
315- self.install_label_body.set_text(_("Finding MP3 plugins"))
316- self.install_label_eula.hide()
317- self.install_hbtn.hide()
318- self.install_vbox.pack_start(self.update_progress, expand=False)
319- trans.connect("finished", self._package_update_finished)
320- yield trans.run(defer=True)
321- except Exception, e: # pylint: disable=W0703
322- self._on_error(e)
323-
324- @inline_callbacks
325- def _package_update_finished(self, transaction, exit_code):
326- """Packagelist update complete; kick off the install"""
327- self.update_progress.hide()
328- if exit_code != EXIT_SUCCESS:
329- self._on_error(transaction)
330- return
331- try:
332- trans = yield self.ac.install_packages([PLUGIN_PACKAGENAME])
333- self.install_progress = AptProgressBar(transaction)
334- self.install_progress.show()
335- self.install_label_head.set_text("")
336- self.install_label_body.set_text(_("Installing MP3 plugins"))
337- self.install_label_eula.hide()
338- self.install_hbtn.hide()
339- self.install_vbox.pack_start(self.install_progress, expand=False)
340- trans.connect("finished", self._package_install_finished)
341- yield trans.run(defer=True)
342- except Exception, e: # pylint: disable=W0703
343- self._on_error(e)
344-
345- def _package_install_finished(self, trans, exit_code):
346- """Aptdaemon package installation finished; show music store."""
347- if exit_code == EXIT_SUCCESS:
348- self.remove(self.install_box)
349- gst.update_registry()
350- self.add_music_store_widget()
351- else:
352- self._on_error(
353- "Could not find the %r package" % PLUGIN_PACKAGENAME)
354-
355- def _on_error(self, error):
356- """Error handler for aptdaemon."""
357- print error
358- problem_installing = _("There was a problem installing, sorry")
359- self.install_label_head.set_markup('<span weight="bold" size="larger">'
360- '%s</span>' % problem_installing)
361- self.install_label_body.set_text(_('Check your internet connection '
362- 'and try again.'))
363- for widget_name in ("install_progress", "update_progress"):
364- widget = getattr(self, widget_name, None)
365- if widget is not None:
366- widget.hide()
367- self.install_hbtn.show()
368-
369 def add_music_store_widget(self):
370 """Display the music store widget in Rhythmbox."""
371 self.add(self.browser)
372- self.show_all()
373- self.browser.set_no_show_all(True)
374+ self.browser.show()
375+ self.show()
376 self.browser.set_property("visible", True)
377 self.browser.connect("preview-mp3",
378 self.re_emit_preview)
379@@ -542,3 +364,4 @@
380 self.__plugin = value
381 else:
382 raise AttributeError('unknown property %s' % prop.name)
383+
384
385=== modified file 'umusicstore/__init__.py'
386--- umusicstore/__init__.py 2010-11-02 15:50:32 +0000
387+++ umusicstore/__init__.py 2011-04-05 21:38:26 +0000
388@@ -17,7 +17,7 @@
389 # Authored by Stuart Langridge <stuart.langridge@canonical.com>
390
391 import gconf
392-import rb
393+import rb as RB
394
395 from .MusicStoreWidget import U1MusicStoreWidget
396 from .U1MSLinks import U1MSLinkProvider
397@@ -26,15 +26,14 @@
398 "/apps/rhythmbox/plugins/umusicstore/first_time_flag"
399
400
401-class U1MusicStorePlugin (rb.Plugin):
402+class U1MusicStorePlugin (RB.Plugin):
403 """The Ubuntu One Music Store."""
404
405 def __init__(self):
406- rb.Plugin.__init__(self)
407+ RB.Plugin.__init__(self)
408
409 # The Music Store itself
410- self.music_store_widget = U1MusicStoreWidget(
411- plugin=self, find_file=self.find_file)
412+ self.music_store_widget = U1MusicStoreWidget(plugin=self)
413
414 # The Links button
415 self.music_store_links_provider = U1MSLinkProvider(
416@@ -48,10 +47,12 @@
417 # Select the source if it's the first time
418 conf_client = gconf.client_get_default()
419 if not conf_client.get_bool(U1_FIRST_TIME_FLAG_ENTRY):
420- shell.props.sourcelist.select(self.music_store_widget.source)
421+ shell.props.display_page_tree.select(
422+ self.music_store_widget.source)
423 conf_client.set_bool(U1_FIRST_TIME_FLAG_ENTRY, True)
424
425 def deactivate(self, shell):
426 """Plugin shutdown."""
427 self.music_store_widget.deactivate(shell)
428 self.music_store_links_provider.deactivate(shell)
429+
430
431=== removed file 'umusicstore/empty.mp3'
432Binary files umusicstore/empty.mp3 2010-02-02 19:30:32 +0000 and umusicstore/empty.mp3 1970-01-01 00:00:00 +0000 differ

Subscribers

People subscribed via source and target branches