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



(happy dance!)
Everything (basically) seems to be working now. The tracks have proper
metadata, they play fine (although the duration in the xml file doesn't
include the extra bit announcing the artist/album at the end of each
file, but nothing we can do about that), and nothing crashes :).

I noticed that if I look at a track's properties, when I close rhythmbox
I see this message (just once, no matter how many files' properties I
looked at, but it doesn't happen if I don't look at any):

sys:1: GtkWarning: gtk_tree_selection_count_selected_rows: assertion
`GTK_IS_TREE_SELECTION (selection)' failed
sys:1: Warning: invalid unclassed pointer in cast to `GObject'
sys:1: Warning: instance with invalid (NULL) class pointer
sys:1: Warning: g_signal_emit_valist: assertion `G_TYPE_CHECK_INSTANCE
(instance)' failed

It seems to be harmless, so I'm not too worried about it.

I think I'll file a bug about the async.open/read issue, unless anyone
has an idea as to what's going on with that.

I'll also get in touch with John at Magnatune and ask for a partner id
and get info on how the purchase API responds. I still need to figure
out a way to attach the album's sku string to an entry so that it can be
purchased.

I've attached a much cleaner-looking :) version of the code, with just
the playing bits. It still blocks the ui for about 2 minutes, but other
than that it works perfectly as far as I can tell.

Thank you everyone for your help and patience 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/
--

 	"What time is it?"
	"I don't know, it keeps changing."
import rhythmdb, rb
import gobject, gtk
from gettext import gettext as _

import xml.sax, xml.sax.handler
import datetime

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

class TrackListHandler(xml.sax.handler.ContentHandler):
	
	def __init__(self, db, entry_type):
		xml.sax.handler.ContentHandler.__init__(self)
		self._track = {} # temporary dictionary for track info
		self._db = db
		self._entry_type = entry_type
	
	def startElement(self, name, attrs):
		self._text = ""
	
	def endElement(self, name):
		if name == "Track":
			try:
				# add the track to the source
				entry = self._db.entry_new(self._entry_type, self._track['url'])
				date = datetime.date(int(self._track['launchdate'][0:4]), 1, 1).toordinal() # year is sometimes 0, so we use launchdate
				
				# set metadata
				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_DATE, date)
				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']))
				
				self._db.commit()
			except Exception,e: # This happens on duplicate uris being added
				print _("Couldn't add %s - %s") % (self._track['artist'], self._track['trackname']) # This should be printed to debug
				print e
			
			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")
		self.entry_type = rhythmdb.entry_register_type("MagnatuneEntryType")
		self.source = gobject.new (MagnatuneSource, shell=shell, name=_("Magnatune"), entry_type=self.entry_type)
		shell.register_entry_type_for_source(self.source, self.entry_type)
		
		icon = gtk.gdk.pixbuf_new_from_xpm_data(magnatune_logo_xpm) # Include a flashy Magnatune logo for the source
		self.source.set_property("icon", icon)
		shell.append_source(self.source, None) # Add the source to the list
		
		self.parser = xml.sax.make_parser()
		self.parser.setContentHandler(TrackListHandler(self.db, self.entry_type))
		self.parser.parse("http://magnatune.com/info/song_info.xml";)
	
	def deactivate(self, shell):
		self.db.entry_delete_by_type(self.entry_type)
		self.db.commit()
		self.source.delete_thyself()
		self.source = None

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

gobject.type_register(MagnatuneSource)

################################################
# Magnatune Logo. Seems to work well enough... #
################################################

# (converted from http://www.magnatune.com/favicon.ico)

magnatune_logo_xpm = [
"32 32 4 1",
" 	c None", #Original colours:
".	c None", #FFFFFF
"+	c #303030", #C0C0C0 
"@	c #000000", #808080
"................................",
"................................",
"................................",
"................................",
"................................",
"................................",
"............++@@@@++............",
"..........+@@@@@@@@@@+..........",
".........+@@@+....+@@@+.........",
"........+@@+...++...+@@+........",
".......+@@+....@@....+@@+.......",
".......@@+.....@@.....+@@.......",
"......+@@......@@......@@+......",
"      + +      @@      + +      ",
"......@@...@@..@@..@@...@@......",
"......@@...@@+.@@.+@@...@@......",
"......@@...@@+.@@.+@@...@@......",
"......@@...@@+.@@.+@@...@@......",
"      + +  @@+.@@.+@@  + +      ",
"......+@@..@@+.@@.+@@..@@+......",
".......@@+.@@+.@@.+@@.+@@.......",
".......+@@+.+..+...+.+@@+.......",
"........+@@+........+@@+........",
".........+@@@+....+@@@+.........",
"..........+@@@@@@@@@@+..........",
"............++@@@@++............",
"................................",
"................................",
"................................",
"................................",
"................................",
"................................"
]


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