[rhythmbox] magnatune: use gnome-keyring via g-i, other fixes (bug #661957)
- From: Jonathan Matthew <jmatthew src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rhythmbox] magnatune: use gnome-keyring via g-i, other fixes (bug #661957)
- Date: Sun, 5 Feb 2012 09:58:48 +0000 (UTC)
commit 53563b040c7e0ad86d5e079a5e6aa7ff2f8666e5
Author: Jonathan Matthew <jonathan d14n org>
Date: Sun Feb 5 19:28:11 2012 +1000
magnatune: use gnome-keyring via g-i, other fixes (bug #661957)
The plugin now works well enough to be enabled again. Some things
probably still don't work.
plugins/magnatune/MagnatuneSource.py | 123 ++++++++++++++++------------------
plugins/magnatune/Makefile.am | 14 ++--
plugins/magnatune/magnatune.py | 95 +++++++++++++-------------
3 files changed, 111 insertions(+), 121 deletions(-)
---
diff --git a/plugins/magnatune/MagnatuneSource.py b/plugins/magnatune/MagnatuneSource.py
index d269bbe..b1a9920 100644
--- a/plugins/magnatune/MagnatuneSource.py
+++ b/plugins/magnatune/MagnatuneSource.py
@@ -31,12 +31,10 @@ import urllib
import urlparse
import threading
import zipfile
-import gnomekeyring as keyring
import rb
from gi.repository import RB
-from gi.repository import GObject, Gtk, Gio
-# XXX use GnomeKeyring when introspection is available
+from gi.repository import GObject, Gtk, Gdk, Gio, GnomeKeyring
from TrackListHandler import TrackListHandler
from BuyAlbumHandler import BuyAlbumHandler, MagnatunePurchaseError
@@ -47,7 +45,7 @@ gettext.install('rhythmbox', RB.locale_dir())
magnatune_partner_id = "rhythmbox"
# URIs
-magnatune_song_info_uri = Gio.file_new_for_uri("http://magnatune.com/info/song_info_xml.zip")
+magnatune_song_info_uri = "http://magnatune.com/info/song_info_xml.zip"
magnatune_buy_album_uri = "https://magnatune.com/buy/choose?"
magnatune_api_download_uri = "http://%s:%s download magnatune com/buy/membership_free_dl_xml?"
@@ -87,7 +85,7 @@ class MagnatuneSource(RB.BrowserSource):
self.__downloads = {} # keeps track of download progress for each file
self.__cancellables = {} # keeps track of Gio.Cancellable objects so we can abort album downloads
- self.__art_store = RB.ExtDB("album-art")
+ self.__art_store = RB.ExtDB(name="album-art")
#
# RBSource methods
@@ -115,11 +113,6 @@ class MagnatuneSource(RB.BrowserSource):
qm = self.props.query_model
return (qm.compute_status_normal("%d song", "%d songs"), None, 2.0)
- def do_get_ui_actions(self):
- return ["MagnatuneDownloadAlbum",
- "MagnatuneArtistInfo",
- "MagnatuneCancelDownload"]
-
def do_selected(self):
if not self.__activated:
shell = self.props.shell
@@ -144,10 +137,10 @@ class MagnatuneSource(RB.BrowserSource):
def do_impl_can_delete(self):
return False
- def do_impl_pack_paned(self, paned):
+ def do_pack_content(self, content):
self.__paned_box = Gtk.VBox(homogeneous=False, spacing=5)
self.pack_start(self.__paned_box, True, True, 0)
- self.__paned_box.pack_start(paned, True, True, 0)
+ self.__paned_box.pack_start(content, True, True, 0)
def do_delete_thyself(self):
@@ -179,7 +172,7 @@ class MagnatuneSource(RB.BrowserSource):
urls = set([])
for tr in tracks:
- sku = self.__sku_dict[self.__db.entry_get_string(tr, RB.RhythmDBPropType.LOCATION)]
+ sku = self.__sku_dict[tr.get_string(RB.RhythmDBPropType.LOCATION)]
url = self.__home_dict[sku]
if url not in urls:
Gtk.show_uri(screen, url, Gdk.CURRENT_TIME)
@@ -191,14 +184,14 @@ class MagnatuneSource(RB.BrowserSource):
urls = set([])
for tr in tracks:
- sku = self.__sku_dict[self.__db.entry_get_string(tr, RB.RhythmDBPropType.LOCATION)]
+ sku = self.__sku_dict[tr.get_string(RB.RhythmDBPropType.LOCATION)]
url = magnatune_buy_album_uri + urllib.urlencode({ 'sku': sku, 'ref': magnatune_partner_id })
if url not in urls:
Gtk.show_uri(screen, url, Gdk.CURRENT_TIME)
urls.add(url)
def download_album(self):
- if selt.__settings['account_type'] != 'download':
+ if selt.__settings['account-type'] != 'download':
# The user doesn't have a download account, so redirect them to the purchase page.
self.purchase_redirect()
return
@@ -216,7 +209,7 @@ class MagnatuneSource(RB.BrowserSource):
skus = []
for track in tracks:
- sku = self.__sku_dict[self.__db.entry_get_string(track, RB.RhythmDBPropType.LOCATION)]
+ sku = self.__sku_dict[track.get_string(RB.RhythmDBPropType.LOCATION)]
if sku in skus:
continue
skus.append(sku)
@@ -241,19 +234,17 @@ class MagnatuneSource(RB.BrowserSource):
return info.filename;
return None
- def download_progress(complete, total):
+ def download_progress(copy, complete, total, self):
self.__load_progress = (complete, total)
self.__notify_status_changed()
- def download_finished(uri, result):
- try:
- success = uri.copy_finish(result)
- except:
- success = False
-
+ def download_finished(copy, success, self):
if not success:
+ print "catalog download failed"
+ print copy.get_error()
return
+ print "catalog download successful"
# done downloading, unzip to real location
catalog_zip = zipfile.ZipFile(magnatune_song_info_temp)
catalog = open(magnatune_song_info, 'w')
@@ -266,7 +257,8 @@ class MagnatuneSource(RB.BrowserSource):
catalog.close()
catalog_zip.close()
- dest.delete()
+ df = Gio.file_new_for_path(magnatune_song_info_temp)
+ df.delete(None)
self.__updating = False
self.__catalogue_loader = None
self.__notify_status_changed()
@@ -276,46 +268,23 @@ class MagnatuneSource(RB.BrowserSource):
self.__updating = True
- dest = Gio.file_new_for_path(magnatune_song_info_temp)
- self.__catalogue_loader = Gio.Cancellable()
try:
- # For some reason, Gio.FileCopyFlags.OVERWRITE doesn't work for copy_async
- dest.delete()
+ df = Gio.file_new_for_path(magnatune_song_info_temp)
+ df.delete(None)
except:
pass
- magnatune_song_info_uri.copy_async(dest,
- download_finished,
- progress_callback=download_progress,
- flags=Gio.FileCopyFlags.OVERWRITE,
- cancellable=self.__catalogue_loader)
+ self.__catalog_loader = RB.AsyncCopy()
+ self.__catalog_loader.set_progress(download_progress, self)
+ self.__catalog_loader.start(magnatune_song_info_uri, magnatune_song_info_temp, download_finished, self)
def load_catalogue():
- def got_items(result, items):
- account_type = self.__settings['account_type']
- username = ""
- password = ""
- if account_type == 'none':
- pass
- elif result is not None or len(items) == 0:
- RB.error_dialog(title = _("Couldn't get account details"),
- message = str(result))
- return
- else:
- try:
- username, password = items[0].secret.split('\n')
- except ValueError: # Couldn't parse secret, possibly because it's empty
- pass
- parser = xml.sax.make_parser()
- parser.setContentHandler(TrackListHandler(self.__db, self.__entry_type, self.__sku_dict, self.__home_dict, self.__art_dict, account_type, username, password))
-
- self.__catalogue_loader = rb.ChunkLoader()
- self.__catalogue_loader.get_url_chunks(magnatune_song_info, 64*1024, True, catalogue_chunk_cb, parser)
- def catalogue_chunk_cb(result, total, parser):
- if not result or isinstance(result, Exception):
- if result:
+ def catalogue_chunk_cb(loader, data, total, parser):
+ if data is None:
+ error = loader.get_error()
+ if error:
# report error somehow?
- print "error loading catalogue: %s" % result
+ print "error loading catalogue: %s" % error
try:
parser.close()
@@ -329,7 +298,7 @@ class MagnatuneSource(RB.BrowserSource):
# restart in-progress downloads
# (doesn't really belong here)
- for f in magnatune_in_progress_dir.enumerate_children('standard::name'):
+ for f in magnatune_in_progress_dir.enumerate_children('standard::name', Gio.FileQueryInfoFlags.NONE, None):
name = f.get_name()
if not name.startswith("in_progress_"):
continue
@@ -338,18 +307,19 @@ class MagnatuneSource(RB.BrowserSource):
self.__download_album(Gio.file_new_for_uri(uri), name[12:])
else:
# hack around some weird chars that show up in the catalogue for some reason
- result = result.replace("\x19", "'")
- result = result.replace("\x13", "-")
+ data = str(data.str)
+ data = data.replace("\x19", "'")
+ data = data.replace("\x13", "-")
# argh.
- result = result.replace("Rock & Roll", "Rock & Roll")
+ data = data.replace("Rock & Roll", "Rock & Roll")
try:
- parser.feed(result)
+ parser.feed(data)
except xml.sax.SAXParseException, e:
print "error parsing catalogue: %s" % e
- load_size['size'] += len(result)
+ load_size['size'] += len(data)
self.__load_progress = (load_size['size'], total)
self.__notify_status_changed()
@@ -361,11 +331,34 @@ class MagnatuneSource(RB.BrowserSource):
self.__notify_status_changed()
load_size = {'size': 0}
- keyring.find_items(keyring.ITEM_GENERIC_SECRET, {'rhythmbox-plugin': 'magnatune'}, got_items)
+ account_type = self.__settings['account-type']
+ username = ""
+ password = ""
+
+ if account_type != 'none':
+ attributes = GnomeKeyring.attribute_list_new()
+ GnomeKeyring.attribute_list_append_string(attributes, "rhythmbox-plugin", "magnatune")
+ (result, items) = GnomeKeyring.find_items_sync(GnomeKeyring.ItemType.GENERIC_SECRET, attributes)
+ if result is not GnomeKeyring.Result.OK or len(items) == 0:
+ RB.error_dialog(title = _("Couldn't get account details"),
+ message = GnomeKeyring.result_to_message(result))
+ account_type = 'none'
+ else:
+ try:
+ username, password = items[0].get_secret().split('\n')
+ except ValueError: # Couldn't parse secret, possibly because it's empty
+ account_type = 'none'
+
+ parser = xml.sax.make_parser()
+ parser.setContentHandler(TrackListHandler(self.__db, self.__entry_type, self.__sku_dict, self.__home_dict, self.__art_dict, account_type, username, password))
+
+ self.__catalogue_loader = RB.ChunkLoader()
+ self.__catalogue_loader.set_callback(catalogue_chunk_cb, parser)
+ self.__catalogue_loader.start(magnatune_song_info, 64*1024)
self.__catalogue_check = rb.UpdateCheck()
- self.__catalogue_check.check_for_update(magnatune_song_info, magnatune_song_info_uri.get_uri(), update_cb)
+ self.__catalogue_check.check_for_update(magnatune_song_info, magnatune_song_info_uri, update_cb)
def __show_loading_screen(self, show):
diff --git a/plugins/magnatune/Makefile.am b/plugins/magnatune/Makefile.am
index effb8bd..1fa6861 100644
--- a/plugins/magnatune/Makefile.am
+++ b/plugins/magnatune/Makefile.am
@@ -1,22 +1,20 @@
# Magnatune Store Python Plugin
-# this plugin is disabled until we can access gnome-keyring
-
plugindir = $(PLUGINDIR)/magnatune
plugindatadir = $(PLUGINDATADIR)/magnatune
-noinst_PYTHON = \
+plugin_PYTHON = \
MagnatuneSource.py \
BuyAlbumHandler.py \
TrackListHandler.py \
magnatune.py
-# %.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
-# plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
+%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+plugin_DATA = $(plugin_in_files:.plugin.in=.plugin)
plugin_in_files = magnatune.plugin.in
gtkbuilderdir = $(plugindatadir)
-noinst_DATA = \
+gtkbuilder_DATA = \
magnatune-loading.ui \
magnatune-prefs.ui \
magnatune_logo_color_small.png \
@@ -26,8 +24,8 @@ themedir = $(pkgdatadir)/icons/hicolor
size = 24x24
context = places
icondir = $(themedir)/$(size)/$(context)
-noinst_DATA += icons/hicolor/$(size)/$(context)/magnatune.png
+icon_DATA = icons/hicolor/$(size)/$(context)/magnatune.png
-EXTRA_DIST = $(plugin_in_files) $(gtkbuilder_DATA) $(icon_DATA) $(noinst_DATA)
+EXTRA_DIST = $(plugin_in_files) $(gtkbuilder_DATA) $(icon_DATA)
CLEANFILES = $(plugin_DATA)
DISTCLEANFILES = $(plugin_DATA)
diff --git a/plugins/magnatune/magnatune.py b/plugins/magnatune/magnatune.py
index a10d4e7..d0cc371 100644
--- a/plugins/magnatune/magnatune.py
+++ b/plugins/magnatune/magnatune.py
@@ -31,12 +31,10 @@ import sys, os.path
import xml
import datetime
import string
-import gnomekeyring as keyring
import rb
from gi.repository import RB
-from gi.repository import GObject, Gtk, Gio, Peas, PeasGtk
-# XXX use GnomeKeyring when available
+from gi.repository import GObject, Gtk, Gio, Peas, PeasGtk, GnomeKeyring
from MagnatuneSource import MagnatuneSource
@@ -57,6 +55,11 @@ popup_ui = """
<separator/>
<menuitem name="PropertiesLibraryPopup" action="MusicProperties"/>
</popup>
+ <toolbar name="MagnatuneToolBar">
+ <toolitem name="MagnatuneDownloadAlbumToolbar" action="MagnatuneDownloadAlbum"/>
+ <toolitem name="MagnatuneArtistInfoToolbar" action="MagnatuneArtistInfo"/>
+ <toolitem name="MagnatuneCancelDownloadToolbar" action="MagnatuneCancelDownload"/>
+ </toolbar>
</ui>
"""
@@ -102,7 +105,8 @@ class Magnatune(GObject.GObject, Peas.Activatable):
pixbuf=icon,
plugin=self,
settings=settings.get_child("source"),
- name=_("Magnatune"))
+ name=_("Magnatune"),
+ toolbar_path="/MagnatuneToolBar")
shell.register_entry_type_for_source(self.source, self.entry_type)
shell.append_display_page(self.source, group)
@@ -168,41 +172,6 @@ class MagnatuneConfig(GObject.GObject, PeasGtk.Configurable):
'item': None
}
- def got_items(result, items):
- def created_item(result, id):
- if result is None: # Item successfully created
- keyring_data['id'] = id
- keyring.item_get_info(None, id, got_item)
- else:
- print "Couldn't create keyring item: " + str(result)
- fill_account_details()
- dialog.present()
- def got_item(result, item):
- if result is None: # Item retrieved successfully
- keyring_data['item'] = item
- else:
- print "Couldn't retrieve keyring item: " + str(result)
- fill_account_details()
- dialog.present()
-
-
- if result is None and len(items) != 0: # Got list of search results
- keyring_data['id'] = items[0].item_id
- keyring.item_get_info(None, keyring_data['id'], got_item)
- elif result == keyring.NoMatchError or len(items) == 0: # No items were found, so we'll create one
- keyring.item_create(None,
- keyring.ITEM_GENERIC_SECRET,
- "Rhythmbox: Magnatune account information",
- {'rhythmbox-plugin': 'magnatune'},
- "", # Empty secret for now
- True,
- created_item)
- else: # Some other error occurred
- print "Couldn't access keyring: " + str(result)
- fill_account_details()
- dialog.present()
-
-
def fill_account_details():
account_type = self.settings['account_type']
builder.get_object("no_account_radio").set_active(account_type == "none")
@@ -253,16 +222,16 @@ class MagnatuneConfig(GObject.GObject, PeasGtk.Configurable):
builder.get_object("account_changed_label").show()
def close_button_pressed(x, y):
- try:
- if keyring_data['id'] and keyring_data['item']:
- # The async version is not in the python bindings, grr...
- keyring.item_set_info_sync(None, keyring_data['id'], keyring_data['item'])
- else:
+ if keyring_data['id'] and keyring_data['item']:
+ result = GnomeKeyring.item_set_info_sync(None,
+ keyring_data['id'],
+ keyring_data['item'])
+ if result != GnomeKeyring.Result.OK:
RB.error_dialog(title = _("Couldn't store account information"),
- message = _("There was a problem accessing the keyring. Check the debug output for more information."))
- except Exception, e:
+ message = GnomeKeyring.result_to_message(result))
+ else:
RB.error_dialog(title = _("Couldn't store account information"),
- message = str(e))
+ message = _("There was a problem accessing the keyring. Check the debug output for more information."))
dialog.hide()
def format_selection_changed(self, button):
@@ -289,5 +258,35 @@ class MagnatuneConfig(GObject.GObject, PeasGtk.Configurable):
builder.connect_signals(self.configure_callback_dic)
dialog.connect("response", close_button_pressed)
- keyring.find_items(keyring.ITEM_GENERIC_SECRET, {'rhythmbox-plugin': 'magnatune'}, got_items)
+ attributes = GnomeKeyring.attribute_list_new()
+ GnomeKeyring.attribute_list_append_string(attributes, "rhythmbox-plugin", "magnatune")
+ (result, items) = GnomeKeyring.find_items_sync(GnomeKeyring.ItemType.GENERIC_SECRET, attributes)
+ if result == GnomeKeyring.Result.OK and len(items) != 0:
+ keyring_data['id'] = items[0].item_id
+ (result, item) = GnomeKeyring.item_get_info_sync(None, keyring_data['id'])
+ if result == GnomeKeyring.Result.OK:
+ keyring_data['item'] = item
+ else:
+ print "Couldn't get keyring item: " + GnomeKeyring.result_to_message(result)
+
+ elif result == GnomeKeyring.Result.NO_MATCH or len(items) == 0:
+ # no item found, so create a new one
+ result = GnomeKeyring.item_create_sync(None,
+ GnomeKeyring.ItemType.GENERIC_SECRET,
+ "Rhythmbox: Magnatune account information",
+ attributes,
+ "", # Empty secret for now
+ True)
+ if result == GnomeKeyring.Result.OK:
+ keyring_data['id'] = id
+ (result, item) = GnomeKeyring.item_get_info_sync(None, id)
+ if result == GnomeKeyring.Result.OK:
+ keyring_data['item'] = item
+ else:
+ print "Couldn't create keyring item: " + GnomeKeyring.result_to_message(result)
+ else:
+ print "Couldn't access keyring: " + str(result)
+
+ fill_account_details()
+ dialog.present()
return dialog
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]