=== added directory 'plugins/ubuntuonemusicstore' === added file 'plugins/ubuntuonemusicstore/PLUGININFO' --- plugins/ubuntuonemusicstore/PLUGININFO 1970-01-01 00:00:00 +0000 +++ plugins/ubuntuonemusicstore/PLUGININFO 2010-04-02 10:16:40 +0000 @@ -0,0 +1,4 @@ +Version='0.0.1' +Authors=['Stuart Langridge stuart.langridge@canonical.com', 'Johannes Schwarz '] +Name=_('Ubuntu One Music Store') +Description=_('The Ubuntu One Music Store offers you to buy DRM free music.') === added file 'plugins/ubuntuonemusicstore/__init__.py' --- plugins/ubuntuonemusicstore/__init__.py 1970-01-01 00:00:00 +0000 +++ plugins/ubuntuonemusicstore/__init__.py 2010-04-29 12:54:09 +0000 @@ -0,0 +1,249 @@ +# Copyright (C) 2010 Stuart Langridge, Johannes Schwarz +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +import gtk, gobject, os, urllib, logging +import gst, gst.pbutils +import aptdaemon.client +from aptdaemon.enums import * +from aptdaemon.gtkwidgets import AptErrorDialog, AptProgressBar +import dbus.exceptions + +from ubuntuone.gtkwidgets import MusicStore + +from xl import event +from xl import trax +from xl import settings +from xl import playlist +from xl.nls import gettext as _ +from xlgui import guiutil, panel + +logger = logging.getLogger(__name__) + +UMUSICSTORE = None + +def enable(exaile): + if (exaile.loading): + event.add_callback(_enable, 'exaile_loaded') + else: + _enable(None, exaile, None) + +def _enable(eventname, exaile, nothing): + global UMUSICSTORE + UMUSICSTORE = MusicStorePlugin(exaile) + exaile.gui.add_panel(UMUSICSTORE, _('MusicStore')) + +def disable(exaile): + global UMUSICSTORE + exaile.gui.remove_panel(UMUSICSTORE) + UMUSICSTORE = None + +class MusicStorePlugin (gtk.VBox): + """The Ubuntu One Music Store.""" + __gsignals__ = { + "preview-mp3": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (str, str)), + "play-library": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (str, str)), + "download-finished": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (str,)), + "url-loaded": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (str,)), + } + + def __init__(self, exaile): + gtk.VBox.__init__(self) + self.exaile = exaile + self.playlist_handle = exaile.gui.main.get_selected_playlist().playlist + if (settings.get_option('plugin/ubuntuonemusicstore/check_mp3', True)): + self.test_can_play_mp3() + else: + self.add_music_store_widget() + + def add_music_store_widget(self): + """Display the music store widget in Exaile.""" + self.browser = MusicStore() + self.add(self.browser) + self.show_all() + self.browser.connect("preview-mp3", self.play_preview_mp3) + self.browser.connect("play-library", self.play_library) + self.browser.connect("download-finished", self.download_finished) + self.browser.connect("url-loaded", self.url_loaded) + + def url_loaded(self, widget, url): + """A URL is loaded in the plugin""" + logger.info("URL loaded: %s", url) + + def download_finished(self, widget, path): + """A file is finished downloading""" + track = trax.Track(path) + self.exaile.collection.add(track) + + def play_preview_mp3(self, widget, url, title): + """Play a passed mp3; signal handler for preview-mp3 signal.""" + track = trax.get_tracks_from_uri(url)[0] + track.set_tag_raw('title', title) + track.set_tag_raw('artist', _('Track Preview')) + track.set_tag_raw('album', 'Ubuntu One Music Store') + self.exaile.player.play(track) + + def play_library(self, widget, path): + """Switch to and start playing a song from the library""" + tracks = trax.get_tracks_from_uri(path) + new_pl = playlist.Playlist('Ubuntu One Music Store') + new_pl.add_tracks(tracks) + self.exaile.queue.play() + + def test_can_play_mp3(self): + """Can the user play mp3s? Start a GStreamer pipeline to check.""" + mp3pth = os.path.realpath(os.path.join( + os.path.split(__file__)[0], "empty.mp3")) + uri = "file://%s" % urllib.quote("%s" % mp3pth) + self.install_pipeline = gst.parse_launch( + 'uridecodebin uri=%s ! fakesink' % uri) + bus = self.install_pipeline.get_bus() + bus.add_signal_watch() + bus.connect("message::element", self._got_element_msg) + bus.connect("message::eos", self._got_end_of_stream) + self.install_pipeline.set_state(gst.STATE_PLAYING) + + def _got_element_msg(self, bus, msg): + """Handler for element messages from the check-mp3 pipeline. + GStreamer throws a "plugin-missing" element message if the + user does not have the right codecs to play a file.""" + plugin_missing = gst.pbutils.is_missing_plugin_message(msg) + if plugin_missing: + self.install_pipeline.set_state(gst.STATE_NULL) + self.install_mp3_playback() + + def _got_end_of_stream(self, bus, msg): + """Handler for end of stream from the check-mp3 pipeline. + If we reach the end of the stream, mp3 playback is enabled.""" + self.install_pipeline.set_state(gst.STATE_NULL) + if os.environ.has_key("U1INSTALLMP3ANYWAY"): + # override the decision not to install the package + self.install_mp3_playback() + else: + self.add_music_store_widget() + + def install_mp3_playback(self): + """Use aptdaemon to install the Fluendo mp3 playback codec package.""" + self.install_box = gtk.Alignment(xscale=0.0, yscale=0.0, xalign=0.5, + yalign=0.5) + self.install_vbox = gtk.VBox() + self.install_label_head = gtk.Label() + self.install_label_head.set_use_markup(True) + not_installed = _("MP3 plugins are not installed") + self.install_label_head.set_markup('' + '%s' % not_installed) + self.install_label_head.set_alignment(0.0, 0.5) + self.install_label_eula = gtk.Label() + # EULA text copied from /var/lib/dpkg/info/gstreamer0.10-fluendo-plugins-mp3-partner.templates + # The partner package shows the EULA itself on installations, but + # aptdaemon installations work like DEBIAN_FRONTEND=noninteractive + # so we show the EULA here. (This also avoids a popup window.) + # EULA text is not translatable; do not wrap it with gettext! + self.install_label_eula.set_markup( + "MPEG Layer-3 audio decoding technology notice\n" + "MPEG Layer-3 audio decoding technology licensed " + "from Fraunhofer IIS and Thomson\n" + "This product cannot be installed in product other than Personal " + "Computers sold for general purpose usage, and not for set-top " + "boxes, embedded PC, PC which are sold and customized for " + "mainly audio or multimedia playback and/or registration, " + "unless the seller has received a license by Fraunhofer IIS" + "and Thomson and pay the relevant royalties to them.") + self.install_label_eula.set_alignment(0.0, 0.5) + self.install_label_eula.set_size_request(400,200) + self.install_label_eula.set_line_wrap(True) + self.install_label_body = gtk.Label() + self.install_label_body.set_text(_('To listen to your purchased songs' + ', you need to install MP3 plugins. Click below to install them.')) + self.install_label_body.set_alignment(0.0, 0.5) + self.install_hbtn = gtk.HButtonBox() + self.install_hbtn.set_layout(gtk.BUTTONBOX_END) + self.install_button = gtk.Button(label=_("Install MP3 plugins")) + self.install_button.connect("clicked", self._start_mp3_install) + self.install_hbtn.add(self.install_button) + self.install_vbox.pack_start(self.install_label_head, expand=False) + self.install_vbox.pack_start(self.install_label_body, expand=False, + padding=12) + self.install_vbox.pack_start(self.install_hbtn, expand=False) + self.install_vbox.pack_start(self.install_label_eula, expand=False, + padding=12) + self.install_box.add(self.install_vbox) + self.install_box.show_all() + self.add(self.install_box) + self.show_all() + + def _start_mp3_install(self, btn): + """Add the 'partner' repository and update the package list from it.""" + self.ac = aptdaemon.client.AptClient() + try: + self.ac.add_repository("deb","http://archive.canonical.com/", "lucid", ["partner"]) + except dbus.exceptions.DBusException, e: + if e.get_dbus_name() == "org.freedesktop.PolicyKit.Error.NotAuthorized": + # user cancelled, so exit from here so they can press the button again + return + self.ac.update_cache(reply_handler=self._finish_updating_packages, + error_handler=self._on_error) + + def _finish_updating_packages(self, transaction): + """Now that partner is added, install our mp3 codec package.""" + self.update_progress = AptProgressBar(transaction) + self.update_progress.show() + self.install_label_head.set_text("") + self.install_label_body.set_text(_("Finding MP3 plugins")) + self.install_label_eula.hide() + self.install_hbtn.hide() + self.install_vbox.pack_start(self.update_progress, expand=False) + transaction.run(reply_handler=lambda: True, + error_handler=self._on_error) + self.ac.install_packages(["gstreamer0.10-fluendo-plugins-mp3-partner"], + reply_handler=self._run_transaction, + error_handler=self._on_error) + + def _run_transaction(self, transaction): + """Show progress of aptdaemon package installation.""" + self.update_progress.hide() + self.install_progress = AptProgressBar(transaction) + self.install_progress.show() + self.install_label_head.set_text("") + self.install_label_body.set_text("Installing MP3 plugins") + self.install_label_eula.hide() + self.install_hbtn.hide() + self.install_vbox.pack_start(self.install_progress, expand=False) + transaction.run(reply_handler=lambda: True, + error_handler=self._on_error) + transaction.connect("finished", self._finished) + + def _finished(self, trans, exit_code): + """Aptdaemon package installation finished; show music store.""" + if exit_code == 0 or exit_code == 2: # 0: success, 2: already installed + self.remove(self.install_box) + gst.update_registry() + settings.set_option('plugin/ubuntuonemusicstore/check_mp3', False) + self.add_music_store_widget() + else: + self._on_error("Could not find the " + "gstreamer0.10-fluendo-plugins-mp3-partner package.") + + def _on_error(self, error): + """Error handler for aptdaemon.""" + logger.error(error) + problem_installing = _("There was a problem installing, sorry") + self.install_label_head.set_markup('' + '%s' % problem_installing) + self.install_label_body.set_text(_('Check your internet connection and ' + 'try again.')) + if getattr(self, "install_progress"): + self.install_progress.hide() + self.install_hbtn.show() === added file 'plugins/ubuntuonemusicstore/empty.mp3' Binary files plugins/ubuntuonemusicstore/empty.mp3 1970-01-01 00:00:00 +0000 and plugins/ubuntuonemusicstore/empty.mp3 2010-03-24 19:37:16 +0000 differ