[rhythmbox] magnatune: Use keyring to store account info



commit 89a48d0d63e0f14234c1d74d47ee97c9b5877211
Author: Adam Zimmerman <adamz src gnome org>
Date:   Tue Feb 16 15:10:36 2010 -0800

    magnatune: Use keyring to store account info

 data/rhythmbox.schemas                          |   22 -------
 plugins/magnatune/magnatune/MagnatuneSource.py  |   56 ++++++++++++-------
 plugins/magnatune/magnatune/TrackListHandler.py |   11 ++--
 plugins/magnatune/magnatune/__init__.py         |   70 +++++++++++++++++++----
 4 files changed, 101 insertions(+), 58 deletions(-)
---
diff --git a/data/rhythmbox.schemas b/data/rhythmbox.schemas
index 99eb1aa..fd2aa19 100644
--- a/data/rhythmbox.schemas
+++ b/data/rhythmbox.schemas
@@ -1188,28 +1188,6 @@
         </locale>
       </schema>
       <schema>
-        <key>/schemas/apps/rhythmbox/plugins/magnatune/username</key>
-        <applyto>/apps/rhythmbox/plugins/magnatune/username</applyto>
-        <owner>rhythmbox</owner>
-        <type>string</type>
-        <default></default>
-        <locale name="C">
-    <short>Magnatune account username.</short>
-    <long>Magnatune account username.</long>
-        </locale>
-      </schema>
-      <schema>
-        <key>/schemas/apps/rhythmbox/plugins/magnatune/password</key>
-        <applyto>/apps/rhythmbox/plugins/magnatune/password</applyto>
-        <owner>rhythmbox</owner>
-        <type>string</type>
-        <default></default>
-        <locale name="C">
-    <short>Magnatune account password.</short>
-    <long>Magnatune account password.</long>
-        </locale>
-      </schema>
-      <schema>
         <key>/schemas/apps/rhythmbox/plugins/daap/active</key>
         <applyto>/apps/rhythmbox/plugins/daap/active</applyto>
         <owner>rhythmbox</owner>
diff --git a/plugins/magnatune/magnatune/MagnatuneSource.py b/plugins/magnatune/magnatune/MagnatuneSource.py
index cd5dcb8..2aa3a92 100644
--- a/plugins/magnatune/magnatune/MagnatuneSource.py
+++ b/plugins/magnatune/magnatune/MagnatuneSource.py
@@ -33,6 +33,7 @@ import os
 import gobject, gio
 import gtk
 import gnome, gconf
+import gnomekeyring as keyring
 import xml
 import urllib
 import urlparse
@@ -210,7 +211,6 @@ class MagnatuneSource(rb.BrowserSource):
 				gtk.show_uri(screen, url, gtk.gdk.CURRENT_TIME)
 				urls.add(url)
 	
-	# This method isn't called at the moment. We'll need it later to add download accounts though...
 	def download_album(self):
 		try:
 			library_location = self.__client.get_list("/apps/rhythmbox/library_locations", gconf.VALUE_STRING)[0] # Just use the first library location
@@ -275,15 +275,23 @@ class MagnatuneSource(rb.BrowserSource):
 
 
 	def __load_catalogue(self):
+		def got_items(result, items):
+			account_type = self.__client.get_string(self.__plugin.gconf_keys['account_type'])
+			if result is not None and account_type != 'none':
+				rb.error_dialog(title = _("Couldn't get account details"),
+				                message = str(result))
+				return
+			username, password = items[0].secret.split('\n')
+			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, self.__catalogue_chunk_cb, parser)
+		
 		self.__notify_status_changed()
 		self.__has_loaded = True
 
-		parser = xml.sax.make_parser()
-		parser.setContentHandler(TrackListHandler(self.__db, self.__entry_type, self.__sku_dict, self.__home_dict, self.__art_dict, self.__plugin))
-		
-		self.__catalogue_loader = rb.ChunkLoader()
-		self.__catalogue_loader.get_url_chunks(magnatune_song_info, 64*1024, True, self.__catalogue_chunk_cb, parser)
-
+		keyring.find_items(keyring.ITEM_GENERIC_SECRET, {'rhythmbox-plugin': 'magnatune'}, got_items)
 
 
 	def __find_song_info(self, catalogue):
@@ -370,22 +378,30 @@ class MagnatuneSource(rb.BrowserSource):
 
 	#
 	# internal purchasing code
-	# not used at the moment, but it will be used again when we have download accounts...
 	#
 	def __auth_download(self, sku): # http://magnatune.com/info/api#purchase
-		print "downloading album:", sku
-		url_dict = {
-			'id':	magnatune_partner_id,
-			'sku':	sku
-		}
-		url = "http://%s:%s download magnatune com/buy/membership_free_dl_xml?" % (self.__client.get_string(self.__plugin.gconf_keys['username']), self.__client.get_string(self.__plugin.gconf_keys['password']))
-		url = url + urllib.urlencode(url_dict)
-
-		l = rb.Loader()
-		l.get_url (url, self.__auth_data_cb, sku)
+		def got_items(result, items):
+			if result is not None:
+				rb.error_dialog(title = _("Couldn't get account details"),
+				                message = str(result))
+				return
+			
+			username, password = items[0].secret.split('\n')
+			print "downloading album: " + sku
+			url_dict = {
+				'id':	magnatune_partner_id,
+				'sku':	sku
+			}
+			url = "http://%s:%s download magnatune com/buy/membership_free_dl_xml?" % (username, password)
+			url = url + urllib.urlencode(url_dict)
+
+			l = rb.Loader()
+			l.get_url (url, self.__auth_data_cb, (sku, username, password))
+		
+		keyring.find_items(keyring.ITEM_GENERIC_SECRET, {'rhythmbox-plugin': 'magnatune'}, got_items)
 
 
-	def __auth_data_cb (self, data, sku):
+	def __auth_data_cb (self, data, (sku, username, password)):
 		buy_album_handler = BuyAlbumHandler(self.__client.get_string(self.__plugin.gconf_keys['format']))
 		auth_parser = xml.sax.make_parser()
 		auth_parser.setContentHandler(buy_album_handler)
@@ -402,7 +418,7 @@ class MagnatuneSource(rb.BrowserSource):
 
 			# process the URI: add authentication info, quote the filename component for some reason
 			parsed = urlparse.urlparse(buy_album_handler.url)
-			netloc = "%s:%s %s" % (self.__client.get_string(self.__plugin.gconf_keys['username']), self.__client.get_string(self.__plugin.gconf_keys['password']), parsed.hostname)
+			netloc = "%s:%s %s" % (username, password, parsed.hostname)
 
 			spath = os.path.split(urllib.url2pathname(parsed.path))
 			basename = spath[1]
diff --git a/plugins/magnatune/magnatune/TrackListHandler.py b/plugins/magnatune/magnatune/TrackListHandler.py
index 3294fb4..aa9681b 100644
--- a/plugins/magnatune/magnatune/TrackListHandler.py
+++ b/plugins/magnatune/magnatune/TrackListHandler.py
@@ -26,12 +26,13 @@
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
 
 import rhythmdb
+import gnomekeyring as keyring
 import xml.sax, xml.sax.handler
 import datetime, re, urllib
 
 class TrackListHandler(xml.sax.handler.ContentHandler):
 
-	def __init__(self, db, entry_type, sku_dict, home_dict, art_dict, plugin):
+	def __init__(self, db, entry_type, sku_dict, home_dict, art_dict, account_type, username, password):
 		xml.sax.handler.ContentHandler.__init__(self)
 		self.__db = db
 		self.__entry_type = entry_type
@@ -39,9 +40,9 @@ class TrackListHandler(xml.sax.handler.ContentHandler):
 		self.__home_dict = home_dict
 		self.__art_dict = art_dict
 		self.__track = {}
-		self.__plugin = plugin
-		self.__user = urllib.quote(self.__plugin.client.get_string(self.__plugin.gconf_keys['username']))
-		self.__pw = urllib.quote(self.__plugin.client.get_string(self.__plugin.gconf_keys['password']))
+		self.__account_type = account_type
+		self.__user = urllib.quote(username)
+		self.__pw = urllib.quote(password)
 		self.__URIre = re.compile(r'^http://[^.]+\.magnatune\.com/')
 		self.__nsre = re.compile(r'\.(mp3|ogg)$')
 
@@ -62,7 +63,7 @@ class TrackListHandler(xml.sax.handler.ContentHandler):
 				else:
 					trackurl = self.__track['url']
 				# use ad-free tracks if available
-				if self.__plugin.client.get_string(self.__plugin.gconf_keys['account_type']) != 'none':
+				if self.__account_type != 'none':
 					trackurl = self.fix_trackurl(trackurl)
 	
 				# add the track to the source
diff --git a/plugins/magnatune/magnatune/__init__.py b/plugins/magnatune/magnatune/__init__.py
index f7eb5cf..4f84d56 100644
--- a/plugins/magnatune/magnatune/__init__.py
+++ b/plugins/magnatune/magnatune/__init__.py
@@ -29,6 +29,7 @@ import rhythmdb, rb
 import gobject
 import gtk
 import gconf, gnome
+import gnomekeyring as keyring
 
 import urllib
 import zipfile
@@ -67,9 +68,7 @@ class Magnatune(rb.Plugin):
 		'pay': "/apps/rhythmbox/plugins/magnatune/pay",
 		'ccauthtoken': "/apps/rhythmbox/plugins/magnatune/ccauthtoken",
 		'continue': "/apps/rhythmbox/plugins/magnatune/continue",
-		'account_type': "/apps/rhythmbox/plugins/magnatune/account_type",
-		'username': "/apps/rhythmbox/plugins/magnatune/username",
-		'password': "/apps/rhythmbox/plugins/magnatune/password"
+		'account_type': "/apps/rhythmbox/plugins/magnatune/account_type"
 	}
 
 
@@ -158,6 +157,42 @@ class Magnatune(rb.Plugin):
 		self.source.playing_entry_changed (entry)
 	
 	def create_configure_dialog(self, dialog=None):
+		keyring_data = {}
+		
+		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:
+					rb.error_dialog(title = _("Couldn't create keyring item"),
+					                message = str(result))
+			def got_item(result, item):
+				if result is None: # Item retrieved successfully
+					keyring_data['item'] = item
+					fill_account_details()
+					dialog.present()
+				else:
+					rb.error_dialog(title = _("Couldn't access keyring"),
+					                message = str(result))
+			
+			
+			if result is None: # 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: # 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
+				rb.error_dialog(title = _("Couldn't access keyring"),
+				                message = str(result))
+		
+		
 		if dialog == None:
 			def fill_account_details():
 				account_type = self.client.get_string(self.gconf_keys['account_type'])
@@ -165,8 +200,9 @@ class Magnatune(rb.Plugin):
 				builder.get_object("stream_account_radio").set_active(account_type == "stream")
 				builder.get_object("download_account_radio").set_active(account_type == "download")
 				
-				builder.get_object("username_entry").set_text(self.client.get_string(self.gconf_keys['username']))
-				builder.get_object("password_entry").set_text(self.client.get_string(self.gconf_keys['password']))
+				username, password = keyring_data['item'].get_secret().split('\n')
+				builder.get_object("username_entry").set_text(username)
+				builder.get_object("password_entry").set_text(password)
 				
 				has_account = account_type != "none"
 				builder.get_object("username_entry").set_sensitive(has_account)
@@ -194,9 +230,21 @@ class Magnatune(rb.Plugin):
 					builder.get_object("account_changed_label").show()
 			
 			def account_details_changed(entry):
-				self.client.set_string(self.gconf_keys['username'], builder.get_object("username_entry").get_text())
-				self.client.set_string(self.gconf_keys['password'], builder.get_object("password_entry").get_text())
+				username = builder.get_object("username_entry").get_text()
+				password = builder.get_object("password_entry").get_text()
+				keyring_data['item'].set_secret('\n'.join((username, password)))
+				
 				builder.get_object("account_changed_label").show()
+			
+			def close_button_pressed(x, y):
+				# The async version is not in the python bindings, grr...
+				try:
+					keyring.item_set_info_sync(None, keyring_data['id'], keyring_data['item'])
+				except Exception, e:
+					rb.error_dialog(title = _("Couldn't store account information"),
+					                message = str(e))
+				dialog.hide()
+				
 
 			self.configure_callback_dic = {
 				"rb_magnatune_audio_combobox_changed_cb" : lambda w: self.client.set_string(self.gconf_keys['format'], self.format_list[w.get_active()]),
@@ -213,10 +261,10 @@ class Magnatune(rb.Plugin):
 			dialog = builder.get_object('preferences_dialog')
 			
 			builder.get_object("audio_combobox").set_active(self.format_list.index(self.client.get_string(self.gconf_keys['format'])))
-			fill_account_details()
 			
 			builder.connect_signals(self.configure_callback_dic)
-			dialog.connect("response", lambda x,y: dialog.hide())
-
-		dialog.present()
+			dialog.connect("response", close_button_pressed)
+		
+		keyring.find_items(keyring.ITEM_GENERIC_SECRET, {'rhythmbox-plugin': 'magnatune'}, got_items)
 		return dialog
+



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]