Re: [Rhythmbox-devel] Magnatune catalog/purchasing plugin



OK, I'm almost there! There are still a couple issues though.

On Thu, 2006-15-06 at 20:41 +1000, Jonathan Matthew wrote:
> Sources display entries using an RBEntryView instance (or rb.EntryView
> in python).  The RBEntryView is a tree view backed by a
> RhythmDBQueryModel, which is a GtkTreeModel that contains a set of
> entries matching particular criteria.  So, an entry is shown in any
> source for which it matches the query.
> 

I've made all the changes you suggested, and my source now shows up in
the list. But when I click on it, I just see a blank grey box. Do I need
to create my own EntryView? I can't see where the ipod source does it,
but that could just be my weak (i.e., nonexistent) C skillz :P

Also, duplicate URIs cause rhythmdb to give a warning. This happens a
few times in song_info.xml, but it also happens for every track after
the plugin is unloaded and then loaded again.

Finally, loading the plugin blocks the UI for about 2 minutes while the
tracks are being parsed. I tried (as you can see from the code) putting
the call to xml.sax.parse into a Thread object, but when I tried that
the method didn't run at all (the source showed up, but the "Adding
artist - title" string never got printed). Is there something else I can
do so my code doesn't block the UI?

Thanks for all the help so far.

--
Adam Zimmerman <adam_zimmerman sfu ca>

CREATIVITY  - http://mirrors.creativecommons.org/movingimages/Building_on_the_Past.mpg
ALWAYS      - http://www.musiccreators.ca/
BUILDS      - http://www.ubuntu.com/
ON THE PAST - http://www.theopencd.org/
--

 If I have trouble installing Linux, something is wrong. Very wrong.
		-- Linus Torvalds
import rhythmdb, rb
import gobject, gtk
from gettext import gettext as _

import xml.sax, xml.sax.handler
import urllib
from threading import Thread

magnatune_partner_id = "rhythmbox" # this needs to be set up with magnatune


################################################
# Class to add Magnatune catalog to the source #
################################################

class TrackListHandler(xml.sax.handler.ContentHandler):
	
	def __init__(self, source, db, entry_type):
		xml.sax.handler.ContentHandler.__init__(self)
		self._track = {} # temporary dictionary for track info
		self._source = source
		self._db = db
		self._entry_type = entry_type
	
	def startElement(self, name, attrs):
		self._text = ""
	
	def endElement(self, name):
		if name == "Track":
			
			try:
				print "Adding: %s - %s" % (self._track['artist'], self._track['trackname'])
				# add the track to the source
				entry = self._db.entry_new(self._entry_type, self._track['url'])
				
				self._db.entry_set_uninserted(entry, rhythmdb.PROP_ARTIST, self._track['artist'])
				self._db.entry_set_uninserted(entry, rhythmdb.PROP_ALBUM, self._track['albumname'])
				self._db.entry_set_uninserted(entry, rhythmdb.PROP_TITLE, self._track['trackname'])
				self._db.entry_set_uninserted(entry, rhythmdb.PROP_TRACK_NUMBER, int(self._track['tracknum']))
				self._db.entry_set_uninserted(entry, rhythmdb.PROP_YEAR, int(self._track['year']))
				self._db.entry_set_uninserted(entry, rhythmdb.PROP_GENRE, self._track['mp3genre'])
				self._db.entry_set_uninserted(entry, rhythmdb.PROP_DURATION, int(self._track['seconds']))
				# somehow associate the sku with the track as well, so we can buy it.
				
				self._db.commit()
				# temporary, until we can properly make proper query models in python
				model = self._source.get_property("query-model")
				model.add_entry(entry, -1)
			except: # This happens on duplicate uris being added
				print "Couldn't add track."
				pass # for now
			
			self._track = {}
		elif name == "AllSongs":
			pass # end of the file
		else:
			self._track[name] = self._text
	
	def characters(self, content):
		self._text = self._text + content


################################################
# Main Magnatune Plugin Class                  #
################################################

class Magnatune(rb.Plugin):

	def __init__(self):
		rb.Plugin.__init__(self)
		
	def activate(self, shell):
		self.db = shell.get_property("db")
		# disabled for now, as db.query_parse doesn't exist
		#query = db.query_parse(rhythmdb.QUERY_PROP_EQUALS, rhythmdb.PROP_TYPE, self.entry_type)
		#model = db.query_model_new(query)
		model = self.db.query_model_new_empty()
		self.entry_type = rhythmdb.rhythmdb_entry_register_type("MagnatuneEntryType")
		self.source = gobject.new (MagnatuneSource, shell=shell, name=_("Magnatune"), query_model=model)
		shell.register_entry_type_for_source(self.source, self.entry_type)
		
		#icon = blabla
		#self.source.set_property("icon", icon)
		shell.append_source(self.source, None) # Add the source to the list
		
		xml.sax.parse("http://magnatune.com/info/song_info.xml";, TrackListHandler(self.source, self.db, self.entry_type)) # Add the tracks to the source
		
		# doesn't work
		#parse_thread = ParseThread(self.source, self.db, self.entry_type)
		#parse_thread.start()
	
	def deactivate(self, shell):
		self.source.delete_thyself()
		self.source = None
	
#	def create_configure_dialog(self):
#		return None # return a gtk dialog with configure options

class ParseThread(Thread):
	def __init__(self, source, db, entry_type):
		Thread.__init__(self)
		self.source = source
		self.db = db
		self.entry_type = entry_type
	def run(self):
		xml.sax.parse("http://magnatune.com/info/song_info.xml";, TrackListHandler(self.source, self.db, self.entry_type)) # Add the tracks to the source

class MagnatuneSource(rb.Source):
	def __init__(self):
		rb.Source.__init__(self)

gobject.type_register(MagnatuneSource)


################################################
# Purchasing code. Do this later               #
################################################

class BuyAlbumHandler(xml.sax.handler.ContentHandler): # Class to download the track, etc.
	
	def __init__(self):
		xml.sax.handler.ContentHandler.__init__(self)
	
	def startElement(self, name, attrs):
		self._text = ""
	
	def endElement(self, name): # need to figure out the format of what gets returned, there's no documentation on the site.
		pass
	
	def characters(self, content):
		self._text = self._text + content

def buy_track(track, amount, cc, name, email): # http://magnatune.com/info/api#purchase
	url = "https://magnatune.com/buy/buy_dl_cc_xml?";
	url = url + urllib.urlencode({
					'id':	magnatune_partner_id,
					'sku':	track['albumsku'],
					'amount': amount,
					'cc':	cc['number'],
					'yy':	cc['year'],
					'mm':	cc['month'],
					'name': name,
					'email':email
				})
	xml.sax.parse(url, BuyAlbumHandler())
	
	url = "" # get download url
	# transfer the track to the library with track-transfer
[RB Plugin]
Loader=python
Module=magnatune
IAge=1
Name=Magnatune support
Description=Adds support to Rhythmbox for playing the Magnatune catalog
Authors=Adam Zimmerman
Copyright=(C) 2006 Adam Zimmerman
Website=http://www.rhythmbox.org


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