[Rhythmbox-devel] Magnatune catalog/purchasing plugin

Hi everyone,

After reading this[1] entry in the blog of Magnatune's founder, I
figured I'd try to write a plugin for rhythmbox that did the same thing
as an exercise. So, after a while, I realized that I have basically no
idea how rhythmbox works, and the plugins I'm looking at for help
(mostly generic-player, since it adds a source) are written in C, which
I don't know.

So I've got a couple of questions about python plugins/rhythmbox in
general. I'd appreciate any help anyone could give me.

- How do I add songs to my source? generic-player seems to get its own
rhythmdb instance or something, and then call db.add_uri on the song
(directory in that case). I tried this in the python console, and
succeeded in adding a song to the library, so it seems right, just that
I need a separate db (or do I?).

- Is there a way to associate other data with an entry (such as the
album sku)? add_uri only takes the uri of the file as an argument.

- Is there a way to manually set the metadata for a track, so rhythmbox
doesn't have to hit every mp3 file on magnatune?

And some other questions related to purchasing (I'm going to try to get
playback working first, so these are lower priority):

- I'm not quite sure how to allow the user to set options (such as email
address, credit card info, etc.). Ideally I'd like to give the user the
option of entering cc info every time (default) or saving it.

- How do I add a context-menu action to an entry ("Buy this album")?

- Can I use track-transfer to transfer a bought file from its download
location into the library? Or do I have to use gnomevfs.xfer_uri?

That's all I can think of at the moment. Thanks in advance for any help!


[1] http://blogs.magnatune.com/buckman/2006/06/embedded_purcha.html

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/

 "...very few phenomena can pull someone out of Deep Hack Mode, with two
noted exceptions: being struck by lightning, or worse, your *computer*
being struck by lightning."
(By Matt Welsh)
import rhythmdb, rb
import gobject, gtk
from gettext import gettext as _

import xml.sax, xml.sax.handler
import urllib

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

class TrackListHandler(xml.sax.handler.ContentHandler): # Class to add Magnatune catalog to the source
	def __init__(self, source, db):
		self._track = {} # temporary dictionary for track info
		self._source = source # is this needed?
		self._db = db
	def startElement(self, name, attrs):
		self._text = ""
	def endElement(self, name):
		if name == "Track":
			# add the track to the source
			self._db.add_uri(self._track['url']) # this might be wrong, it seems to be what generic-player does
			# somehow associate the sku with the track as well. Also file metadata if possible.
			self._track = {}
		elif name == "AllSongs":
			pass # end of the file
			self._track[name] = self._text
	def characters(self, content):
		self._text = self._text + content

class BuyAlbumHandler(xml.sax.handler.ContentHandler): # Class to download the track, etc.
	def __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.
	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,
	xml.sax.parse(url, BuyAlbumHandler())
	url = "" # get download url
	# transfer the track to the library with track-transfer

class Magnatune(rb.Plugin):

	def __init__(self):
	def activate(self, shell):
		db = shell.get_property("db") # need to get the proper db for the source we create (or make one ourselves?)
		model = db.query_model_new_empty()
		self.source = gobject.new (MagnatuneSource, shell=shell, name=_("Magnatune"), query_model=model)
		#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, db)) # Add the tracks to the source
	def deactivate(self, shell):
		self.source = None

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


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