Index: configure.ac
===================================================================
RCS file: /cvs/gnome/rhythmbox/configure.ac,v
retrieving revision 1.255
diff -u -r1.255 configure.ac
--- configure.ac	11 Aug 2006 05:32:53 -0000	1.255
+++ configure.ac	2 Sep 2006 16:40:37 -0000
@@ -965,6 +965,8 @@
 plugins/pythonconsole/Makefile
 plugins/artdisplay/Makefile
 plugins/artdisplay/artdisplay/Makefile
+plugins/magnatune/Makefile
+plugins/magnatune/magnatune/Makefile
 plugins/generic-player/Makefile
 plugins/rb/Makefile
 bindings/Makefile
Index: data/art/Makefile.am
===================================================================
RCS file: /cvs/gnome/rhythmbox/data/art/Makefile.am,v
retrieving revision 1.24
diff -u -r1.24 Makefile.am
--- data/art/Makefile.am	5 Apr 2006 13:59:16 -0000	1.24
+++ data/art/Makefile.am	2 Sep 2006 16:40:38 -0000
@@ -7,7 +7,8 @@
 	   rhythmbox-no-star.png       \
 	   rhythmbox-podcast.png       \
 	   media-eject.png             \
-	   about-logo.png
+	   about-logo.png              \
+           magnatune_circle_small.png
 
 artdir = $(pkgdatadir)/art
 
Index: plugins/Makefile.am
===================================================================
RCS file: /cvs/gnome/rhythmbox/plugins/Makefile.am,v
retrieving revision 1.12
diff -u -r1.12 Makefile.am
--- plugins/Makefile.am	10 Aug 2006 15:12:24 -0000	1.12
+++ plugins/Makefile.am	2 Sep 2006 16:40:49 -0000
@@ -18,6 +18,7 @@
 	sample-python					\
 	artdisplay					\
 	lyrics						\
+	magnatune					\
 	rb
 endif
 
--- /dev/null	2006-05-30 18:15:07.000000000 -0700
+++ plugins/magnatune/magnatune-download.glade	2006-08-16 21:13:55.000000000 -0700
@@ -0,0 +1,116 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkWindow" id="download_window">
+  <property name="title" translatable="yes">Download Progress</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_CENTER</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+  <signal name="delete_event" handler="on_download_window_delete_event" last_modification_time="Wed, 28 Jun 2006 18:52:32 GMT"/>
+
+  <child>
+    <widget class="GtkVBox" id="vbox1">
+      <property name="border_width">12</property>
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">8</property>
+
+      <child>
+	<widget class="GtkLabel" id="info_label">
+	  <property name="visible">True</property>
+	  <property name="label" translatable="yes">An email has been sent with download information in case
+you need to re-download this album in the future.</property>
+	  <property name="use_underline">False</property>
+	  <property name="use_markup">True</property>
+	  <property name="justify">GTK_JUSTIFY_LEFT</property>
+	  <property name="wrap">False</property>
+	  <property name="selectable">False</property>
+	  <property name="xalign">0.5</property>
+	  <property name="yalign">0.5</property>
+	  <property name="xpad">0</property>
+	  <property name="ypad">0</property>
+	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	  <property name="width_chars">-1</property>
+	  <property name="single_line_mode">False</property>
+	  <property name="angle">0</property>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">False</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkProgressBar" id="download_pbar">
+	  <property name="visible">True</property>
+	  <property name="orientation">GTK_PROGRESS_LEFT_TO_RIGHT</property>
+	  <property name="fraction">0</property>
+	  <property name="pulse_step">0.10000000149</property>
+	  <property name="text"></property>
+	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">False</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHSeparator" id="hseparator1">
+	  <property name="visible">True</property>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">False</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHBox" id="hbox1">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkButton" id="cancel_button">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-cancel</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <signal name="clicked" handler="rb_magnatune_cancel_button_clicked_cb" last_modification_time="Wed, 28 Jun 2006 18:41:24 GMT"/>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	      <property name="pack_type">GTK_PACK_END</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">False</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
--- /dev/null	2006-05-30 18:15:07.000000000 -0700
+++ plugins/magnatune/magnatune-loading.glade	2006-08-26 11:48:34.000000000 -0700
@@ -0,0 +1,122 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkWindow" id="window1">
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">window1</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+
+  <child>
+    <widget class="GtkVBox" id="magnatune_loading_vbox">
+      <property name="border_width">12</property>
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">6</property>
+
+      <child>
+	<widget class="GtkImage" id="image1">
+	  <property name="visible">True</property>
+	  <property name="pixbuf">magnatune_logo_color_small.png</property>
+	  <property name="xalign">0.5</property>
+	  <property name="yalign">0.5</property>
+	  <property name="xpad">0</property>
+	  <property name="ypad">0</property>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkLabel" id="label1">
+	  <property name="visible">True</property>
+	  <property name="label" translatable="yes">&lt;b&gt;Magnatune online music store&lt;/b&gt;</property>
+	  <property name="use_underline">False</property>
+	  <property name="use_markup">True</property>
+	  <property name="justify">GTK_JUSTIFY_CENTER</property>
+	  <property name="wrap">False</property>
+	  <property name="selectable">False</property>
+	  <property name="xalign">0.5</property>
+	  <property name="yalign">0.5</property>
+	  <property name="xpad">0</property>
+	  <property name="ypad">0</property>
+	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	  <property name="width_chars">-1</property>
+	  <property name="single_line_mode">False</property>
+	  <property name="angle">0</property>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkLabel" id="label2">
+	  <property name="visible">True</property>
+	  <property name="can_focus">True</property>
+	  <property name="label" translatable="yes">Magnatune is an online record label that is not evil. Some of their key attributes are:
+
+    * Free listening of all songs
+    * All albums and artists hand-picked
+    * Very simple user interface, quick to play music
+    * Radio stations and &quot;genre mix&quot; playlists allow background listening - can do work while listening to our music
+    * No need to &quot;register&quot; to listen or buy
+    * Smaller selection means easier to find good music
+    * Wide variety of genres, can fit any mood
+    * Our genres are hard to find in record stores and not on radio (though do appear on college radio)
+    * Downloads and CDs are both available (no other site on the internet sells both)
+    * Perfect quality downloads (CD copy) are available when you download (not inferior quality sound)
+    * No copy protection on the music (DRM) which allows playing music on any device (unlike iTunes/MSN/etc)
+    * Extensive biographical info about each musician, and artist photo -- feel a strong connection to the artist
+    * Full color, high quality cover art PDF available for most albums - easy to print
+    * Variable pricing scheme means you can pay as little as $5 for an album if you choose
+    * 50% of payment goes to artist (makes buyer feel good: they're helping the world)
+    * Not venture-capital backed big business
+    * Not part of the &quot;evil&quot; major label machine - for those that hate the music biz and want to help topple it
+    * Founder/owner runs it -- support a small business
+    * Low pressure environment - nothing flashing, no audio ads while listening to albums
+    * Music selection is unique to Magnatune, unlike most on-line stores that have more-or-less the same (gigantic) selection
+
+You can find more information at http://www.magnatune.com/</property>
+	  <property name="use_underline">False</property>
+	  <property name="use_markup">False</property>
+	  <property name="justify">GTK_JUSTIFY_LEFT</property>
+	  <property name="wrap">False</property>
+	  <property name="selectable">True</property>
+	  <property name="xalign">0</property>
+	  <property name="yalign">0.5</property>
+	  <property name="xpad">0</property>
+	  <property name="ypad">0</property>
+	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	  <property name="width_chars">-1</property>
+	  <property name="single_line_mode">False</property>
+	  <property name="angle">0</property>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
--- /dev/null	2006-05-30 18:15:07.000000000 -0700
+++ plugins/magnatune/magnatune-prefs.glade	2006-08-26 11:57:34.000000000 -0700
@@ -0,0 +1,759 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+<requires lib="gnome"/>
+
+<widget class="GtkDialog" id="preferences_dialog">
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">Magnatune Preferences</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+  <property name="has_separator">True</property>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox1">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="dialog-action_area1">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="closebutton1">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-close</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-7</property>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkVBox" id="magnatune_vbox">
+	  <property name="border_width">5</property>
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">18</property>
+
+	  <child>
+	    <widget class="GtkImage" id="image1">
+	      <property name="visible">True</property>
+	      <property name="pixbuf">magnatune_logo_color_small.png</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkVBox" id="vbox2">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<widget class="GtkLabel" id="magnatune_label">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Magnatune Information</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkHBox" id="hbox14">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">0</property>
+
+		  <child>
+		    <widget class="GtkLabel" id="label20">
+		      <property name="visible">True</property>
+		      <property name="label"></property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">8</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkVBox" id="vbox13">
+		      <property name="visible">True</property>
+		      <property name="homogeneous">False</property>
+		      <property name="spacing">6</property>
+
+		      <child>
+			<widget class="GtkTable" id="table1">
+			  <property name="visible">True</property>
+			  <property name="n_rows">4</property>
+			  <property name="n_columns">2</property>
+			  <property name="homogeneous">False</property>
+			  <property name="row_spacing">6</property>
+			  <property name="column_spacing">12</property>
+
+			  <child>
+			    <widget class="GtkLabel" id="username_label">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">_Name:</property>
+			      <property name="use_underline">True</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			      <property name="mnemonic_widget">name_entry</property>
+			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			      <property name="width_chars">-1</property>
+			      <property name="single_line_mode">False</property>
+			      <property name="angle">0</property>
+			    </widget>
+			    <packing>
+			      <property name="left_attach">0</property>
+			      <property name="right_attach">1</property>
+			      <property name="top_attach">0</property>
+			      <property name="bottom_attach">1</property>
+			      <property name="x_options">fill</property>
+			      <property name="y_options"></property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkEntry" id="name_entry">
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="editable">True</property>
+			      <property name="visibility">True</property>
+			      <property name="max_length">0</property>
+			      <property name="text" translatable="yes"></property>
+			      <property name="has_frame">True</property>
+			      <property name="invisible_char">*</property>
+			      <property name="activates_default">False</property>
+			      <signal name="changed" handler="rb_magnatune_name_entry_changed_cb" last_modification_time="Mon, 26 Jun 2006 19:58:32 GMT"/>
+			    </widget>
+			    <packing>
+			      <property name="left_attach">1</property>
+			      <property name="right_attach">2</property>
+			      <property name="top_attach">0</property>
+			      <property name="bottom_attach">1</property>
+			      <property name="y_options"></property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkEntry" id="email_entry">
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="editable">True</property>
+			      <property name="visibility">True</property>
+			      <property name="max_length">0</property>
+			      <property name="text" translatable="yes"></property>
+			      <property name="has_frame">True</property>
+			      <property name="invisible_char">*</property>
+			      <property name="activates_default">False</property>
+			      <signal name="changed" handler="rb_magnatune_email_entry_changed_cb" last_modification_time="Mon, 26 Jun 2006 19:58:51 GMT"/>
+			    </widget>
+			    <packing>
+			      <property name="left_attach">1</property>
+			      <property name="right_attach">2</property>
+			      <property name="top_attach">1</property>
+			      <property name="bottom_attach">2</property>
+			      <property name="y_options"></property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkLabel" id="password_label">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">_Email:</property>
+			      <property name="use_underline">True</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			      <property name="mnemonic_widget">email_entry</property>
+			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			      <property name="width_chars">-1</property>
+			      <property name="single_line_mode">False</property>
+			      <property name="angle">0</property>
+			    </widget>
+			    <packing>
+			      <property name="left_attach">0</property>
+			      <property name="right_attach">1</property>
+			      <property name="top_attach">1</property>
+			      <property name="bottom_attach">2</property>
+			      <property name="x_options">fill</property>
+			      <property name="y_options"></property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkLabel" id="cc_label">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">C_redit Card:</property>
+			      <property name="use_underline">True</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			      <property name="mnemonic_widget">cc_entry</property>
+			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			      <property name="width_chars">-1</property>
+			      <property name="single_line_mode">False</property>
+			      <property name="angle">0</property>
+			    </widget>
+			    <packing>
+			      <property name="left_attach">0</property>
+			      <property name="right_attach">1</property>
+			      <property name="top_attach">2</property>
+			      <property name="bottom_attach">3</property>
+			      <property name="x_options">fill</property>
+			      <property name="y_options"></property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkEntry" id="cc_entry">
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="editable">True</property>
+			      <property name="visibility">True</property>
+			      <property name="max_length">0</property>
+			      <property name="text" translatable="yes"></property>
+			      <property name="has_frame">True</property>
+			      <property name="invisible_char">●</property>
+			      <property name="activates_default">False</property>
+			      <signal name="changed" handler="rb_magnatune_cc_entry_changed_cb" last_modification_time="Mon, 26 Jun 2006 19:55:57 GMT"/>
+			    </widget>
+			    <packing>
+			      <property name="left_attach">1</property>
+			      <property name="right_attach">2</property>
+			      <property name="top_attach">2</property>
+			      <property name="bottom_attach">3</property>
+			      <property name="y_options"></property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkHBox" id="hbox20">
+			      <property name="visible">True</property>
+			      <property name="homogeneous">False</property>
+			      <property name="spacing">0</property>
+
+			      <child>
+				<widget class="GtkLabel" id="mm_label">
+				  <property name="visible">True</property>
+				  <property name="label" translatable="yes">_Month:</property>
+				  <property name="use_underline">True</property>
+				  <property name="use_markup">False</property>
+				  <property name="justify">GTK_JUSTIFY_LEFT</property>
+				  <property name="wrap">False</property>
+				  <property name="selectable">False</property>
+				  <property name="xalign">0.5</property>
+				  <property name="yalign">0.5</property>
+				  <property name="xpad">8</property>
+				  <property name="ypad">0</property>
+				  <property name="mnemonic_widget">mm_entry</property>
+				  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+				  <property name="width_chars">-1</property>
+				  <property name="single_line_mode">False</property>
+				  <property name="angle">0</property>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">False</property>
+				  <property name="fill">False</property>
+				</packing>
+			      </child>
+
+			      <child>
+				<widget class="GtkComboBox" id="mm_entry">
+				  <property name="visible">True</property>
+				  <property name="items" translatable="yes">01
+02
+03
+04
+05
+06
+07
+08
+09
+10
+11
+12</property>
+				  <property name="add_tearoffs">False</property>
+				  <property name="focus_on_click">True</property>
+				  <signal name="changed" handler="rb_magnatune_mm_entry_changed_cb" last_modification_time="Sat, 26 Aug 2006 18:57:16 GMT"/>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">False</property>
+				  <property name="fill">True</property>
+				</packing>
+			      </child>
+
+			      <child>
+				<widget class="GtkLabel" id="yy_label">
+				  <property name="visible">True</property>
+				  <property name="label" translatable="yes">_Year:</property>
+				  <property name="use_underline">True</property>
+				  <property name="use_markup">False</property>
+				  <property name="justify">GTK_JUSTIFY_LEFT</property>
+				  <property name="wrap">False</property>
+				  <property name="selectable">False</property>
+				  <property name="xalign">0.5</property>
+				  <property name="yalign">0.5</property>
+				  <property name="xpad">8</property>
+				  <property name="ypad">0</property>
+				  <property name="mnemonic_widget">yy_entry</property>
+				  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+				  <property name="width_chars">-1</property>
+				  <property name="single_line_mode">False</property>
+				  <property name="angle">0</property>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">False</property>
+				  <property name="fill">False</property>
+				</packing>
+			      </child>
+
+			      <child>
+				<widget class="GtkEntry" id="yy_entry">
+				  <property name="visible">True</property>
+				  <property name="can_focus">True</property>
+				  <property name="editable">True</property>
+				  <property name="visibility">True</property>
+				  <property name="max_length">2</property>
+				  <property name="text" translatable="yes"></property>
+				  <property name="has_frame">True</property>
+				  <property name="invisible_char">●</property>
+				  <property name="activates_default">False</property>
+				  <signal name="changed" handler="rb_magnatune_yy_entry_changed_cb" last_modification_time="Sat, 26 Aug 2006 18:56:35 GMT"/>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">True</property>
+				  <property name="fill">True</property>
+				</packing>
+			      </child>
+			    </widget>
+			    <packing>
+			      <property name="left_attach">1</property>
+			      <property name="right_attach">2</property>
+			      <property name="top_attach">3</property>
+			      <property name="bottom_attach">4</property>
+			      <property name="x_options">fill</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkLabel" id="exp_label">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">Expiry:</property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			      <property name="width_chars">-1</property>
+			      <property name="single_line_mode">False</property>
+			      <property name="angle">0</property>
+			    </widget>
+			    <packing>
+			      <property name="left_attach">0</property>
+			      <property name="right_attach">1</property>
+			      <property name="top_attach">3</property>
+			      <property name="bottom_attach">4</property>
+			      <property name="x_options">fill</property>
+			      <property name="y_options"></property>
+			    </packing>
+			  </child>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkHBox" id="hbox22">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">0</property>
+
+	      <child>
+		<widget class="GtkLabel" id="pay_label">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Default _amount to pay:</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">8</property>
+		  <property name="ypad">0</property>
+		  <property name="mnemonic_widget">pay_combobox</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkComboBox" id="pay_combobox">
+		  <property name="visible">True</property>
+		  <property name="items" translatable="yes">$5
+$6
+$7
+$8 (typical)
+$9
+$10 (better than average)
+$11
+$12 (generous)
+$13
+$14
+$15 (VERY generous!)
+$16
+$17
+$18 (We love you!)</property>
+		  <property name="add_tearoffs">False</property>
+		  <property name="focus_on_click">True</property>
+		  <signal name="changed" handler="rb_magnatune_pay_combobox_changed_cb" last_modification_time="Mon, 26 Jun 2006 20:12:55 GMT"/>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label56">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">(US Dollars)</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">8</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkHBox" id="hbox21">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">0</property>
+
+	      <child>
+		<widget class="GtkLabel" id="audio_label">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Preferred audio _format:</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">8</property>
+		  <property name="ypad">0</property>
+		  <property name="mnemonic_widget">audio_combobox</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkComboBox" id="audio_combobox">
+		  <property name="visible">True</property>
+		  <property name="items" translatable="yes">Ogg Vorbis
+FLAC
+WAV
+VBR MP3
+128K MP3</property>
+		  <property name="add_tearoffs">False</property>
+		  <property name="focus_on_click">True</property>
+		  <signal name="changed" handler="rb_magnatune_audio_combobox_changed_cb" last_modification_time="Mon, 26 Jun 2006 20:06:22 GMT"/>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkVBox" id="vbox14">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">0</property>
+
+	      <child>
+		<widget class="GtkHBox" id="hbox15">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">0</property>
+
+		  <child>
+		    <widget class="GtkLabel" id="label21">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Find out about Magnatune at </property>
+		      <property name="use_underline">True</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="mnemonic_widget">magnatune_link</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GnomeHRef" id="magnatune_link">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="url">http://www.magnatune.com/</property>
+		      <property name="text" translatable="yes">http://www.magnatune.com/</property>
+		      <property name="focus_on_click">True</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkHBox" id="hbox17">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">0</property>
+
+		  <child>
+		    <widget class="GtkLabel" id="label27">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Redownload purchased music at </property>
+		      <property name="use_underline">True</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="mnemonic_widget">redownload_link</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GnomeHRef" id="redownload_link">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="url">http://www.magnatune.com/info/redownload</property>
+		      <property name="text" translatable="yes">http://www.magnatune.com/info/redownload</property>
+		      <property name="focus_on_click">True</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
--- /dev/null	2006-05-30 18:15:07.000000000 -0700
+++ plugins/magnatune/magnatune-purchase.glade	2006-08-26 13:54:00.000000000 -0700
@@ -0,0 +1,336 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkDialog" id="purchase_dialog">
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">Purchase Magnatune Tracks</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+  <property name="has_separator">True</property>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox1">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="dialog-action_area1">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="button1">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-cancel</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-6</property>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="button2">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-3</property>
+
+	      <child>
+		<widget class="GtkAlignment" id="alignment1">
+		  <property name="visible">True</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xscale">0</property>
+		  <property name="yscale">0</property>
+		  <property name="top_padding">0</property>
+		  <property name="bottom_padding">0</property>
+		  <property name="left_padding">0</property>
+		  <property name="right_padding">0</property>
+
+		  <child>
+		    <widget class="GtkHBox" id="hbox1">
+		      <property name="visible">True</property>
+		      <property name="homogeneous">False</property>
+		      <property name="spacing">2</property>
+
+		      <child>
+			<widget class="GtkImage" id="image2">
+			  <property name="visible">True</property>
+			  <property name="stock">gtk-apply</property>
+			  <property name="icon_size">4</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label3">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">_Purchase</property>
+			  <property name="use_underline">True</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+		    </widget>
+		  </child>
+		</widget>
+	      </child>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkTable" id="table1">
+	  <property name="border_width">12</property>
+	  <property name="visible">True</property>
+	  <property name="n_rows">3</property>
+	  <property name="n_columns">3</property>
+	  <property name="homogeneous">False</property>
+	  <property name="row_spacing">0</property>
+	  <property name="column_spacing">0</property>
+
+	  <child>
+	    <widget class="GtkLabel" id="audio_label">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">Audio _format:</property>
+	      <property name="use_underline">True</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">8</property>
+	      <property name="ypad">0</property>
+	      <property name="mnemonic_widget">audio_combobox</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="left_attach">1</property>
+	      <property name="right_attach">2</property>
+	      <property name="top_attach">2</property>
+	      <property name="bottom_attach">3</property>
+	      <property name="x_options">fill</property>
+	      <property name="y_options"></property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkComboBox" id="audio_combobox">
+	      <property name="visible">True</property>
+	      <property name="items" translatable="yes">Ogg Vorbis
+FLAC
+WAV
+VBR MP3
+128K MP3</property>
+	      <property name="add_tearoffs">False</property>
+	      <property name="focus_on_click">True</property>
+	    </widget>
+	    <packing>
+	      <property name="left_attach">2</property>
+	      <property name="right_attach">3</property>
+	      <property name="top_attach">2</property>
+	      <property name="bottom_attach">3</property>
+	      <property name="x_options">fill</property>
+	      <property name="y_options">fill</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkComboBox" id="pay_combobox">
+	      <property name="visible">True</property>
+	      <property name="items" translatable="yes">$5
+$6
+$7
+$8 (typical)
+$9
+$10 (better than average)
+$11
+$12 (generous)
+$13
+$14
+$15 (VERY generous!)
+$16
+$17
+$18 (We love you!)</property>
+	      <property name="add_tearoffs">False</property>
+	      <property name="focus_on_click">True</property>
+	    </widget>
+	    <packing>
+	      <property name="left_attach">2</property>
+	      <property name="right_attach">3</property>
+	      <property name="top_attach">1</property>
+	      <property name="bottom_attach">2</property>
+	      <property name="x_options">fill</property>
+	      <property name="y_options">fill</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkLabel" id="pay_label">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">_Amount to pay:</property>
+	      <property name="use_underline">True</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">8</property>
+	      <property name="ypad">0</property>
+	      <property name="mnemonic_widget">pay_combobox</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="left_attach">1</property>
+	      <property name="right_attach">2</property>
+	      <property name="top_attach">1</property>
+	      <property name="bottom_attach">2</property>
+	      <property name="x_options">fill</property>
+	      <property name="y_options"></property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkLabel" id="info_label">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label"></property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">True</property>
+	      <property name="selectable">True</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">8</property>
+	      <property name="ypad">8</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="left_attach">1</property>
+	      <property name="right_attach">3</property>
+	      <property name="top_attach">0</property>
+	      <property name="bottom_attach">1</property>
+	      <property name="x_options">fill</property>
+	      <property name="y_options"></property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkLabel" id="label2">
+	      <property name="visible">True</property>
+	      <property name="label"></property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="left_attach">0</property>
+	      <property name="right_attach">1</property>
+	      <property name="top_attach">1</property>
+	      <property name="bottom_attach">3</property>
+	      <property name="x_options">fill</property>
+	      <property name="y_options"></property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkImage" id="image1">
+	      <property name="visible">True</property>
+	      <property name="icon_size">6</property>
+	      <property name="icon_name">gtk-dialog-question</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	    </widget>
+	    <packing>
+	      <property name="left_attach">0</property>
+	      <property name="right_attach">1</property>
+	      <property name="top_attach">0</property>
+	      <property name="bottom_attach">1</property>
+	      <property name="x_options">fill</property>
+	      <property name="y_options">fill</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
--- /dev/null	2006-05-30 18:15:07.000000000 -0700
+++ plugins/magnatune/magnatune.rb-plugin.desktop.in	2006-08-26 12:24:15.000000000 -0700
@@ -0,0 +1,9 @@
+[RB Plugin]
+Loader=python
+Module=magnatune
+IAge=1
+_Name=Magnatune Store
+_Description=Adds support to Rhythmbox for playing and purchasing from the Magnatune online music store
+Authors=Adam Zimmerman, James Livingston
+Copyright=(C) 2006 Adam Zimmerman
+Website=http://www.rhythmbox.org/
--- /dev/null	2006-05-30 18:15:07.000000000 -0700
+++ plugins/magnatune/Makefile.am	2006-09-02 09:39:34.000000000 -0700
@@ -0,0 +1,24 @@
+# Magnatune Store Python Plugin
+
+SUBDIRS = magnatune
+
+plugindir = $(PLUGINDIR)
+
+%.rb-plugin: %.rb-plugin.desktop.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:.rb-plugin.desktop.in=.rb-plugin)
+
+
+plugin_in_files = magnatune.rb-plugin.desktop.in
+
+glade_DATA =	\
+		magnatune-download.glade		\
+		magnatune-loading.glade			\
+		magnatune-purchase.glade		\
+		magnatune-prefs.glade                   \
+                magnatune_logo_color_small.png
+
+gladedir = $(pkgdatadir)/glade
+EXTRA_DIST = $(plugin_in_files) $(glade_DATA)
+CLEANFILES = $(plugin_DATA)
+DISTCLEANFILES = $(plugin_DATA)
+
--- /dev/null	2006-05-30 18:15:07.000000000 -0700
+++ plugins/magnatune/magnatune/BuyAlbumHandler.py	2006-08-16 21:13:55.000000000 -0700
@@ -0,0 +1,35 @@
+import gnomevfs
+import xml.sax, xml.sax.handler
+
+class BuyAlbumHandler(xml.sax.handler.ContentHandler): # Class to download the track, etc.
+	
+	format_map =	{
+			'ogg'		:	'URL_OGGZIP',
+			'flac'		:	'URL_FLACZIP',
+			'wav'		:	'URL_WAVZIP',
+			'mp3-cbr'	:	'URL_128KMP3ZIP',
+			'mp3-vbr'	:	'URL_VBRZIP'
+			}
+	
+	def __init__(self, format):
+		xml.sax.handler.ContentHandler.__init__(self)
+		self._format_tag = self.format_map[format] # format of audio to download
+	
+	def startElement(self, name, attrs):
+		self._text = ""
+	
+	def endElement(self, name):
+		if name == "ERROR": # Something went wrong. Display error message to user.
+			raise MagnatunePurchaseError(self._text)
+		elif name == "DL_USERNAME":
+			self.username = self._text
+		elif name == "DL_PASSWORD":
+			self.password = self._text
+		elif name == self._format_tag:
+			self.url = self._text
+	
+	def characters(self, content):
+		self._text = self._text + content
+
+class MagnatunePurchaseError(Exception):
+	pass
--- /dev/null	2006-05-30 18:15:07.000000000 -0700
+++ plugins/magnatune/magnatune/__init__.py	2006-08-26 12:03:10.000000000 -0700
@@ -0,0 +1,134 @@
+import rhythmdb, rb
+import gobject
+import gtk, gtk.glade
+import gconf, gnomevfs, gnome
+
+import urllib
+import zipfile
+import sys, os.path
+import xml
+
+from MagnatuneSource import MagnatuneSource
+
+
+popup_ui = """
+<ui>
+  <popup name="MagnatuneSourceViewPopup">
+    <menuitem name="AddToQueueLibraryPopup" action="AddToQueue"/>
+    <menuitem name="MagnatunePurchaseAlbum" action="MagnatunePurchase"/>
+    <menuitem name="MagnatuneArtistInfo" action="MagnatuneArtistInfo"/>
+    <separator/>
+    <menuitem name="BrowseGenreLibraryPopup" action="BrowserSrcChooseGenre"/>
+    <menuitem name="BrowseArtistLibraryPopup" action="BrowserSrcChooseArtist"/>
+    <menuitem name="BrowseAlbumLibraryPopup" action="BrowserSrcChooseAlbum"/>
+    <separator/>
+    <menuitem name="PropertiesLibraryPopup" action="MusicProperties"/>
+  </popup>
+</ui>
+"""
+
+
+class Magnatune(rb.Plugin):
+	client = gconf.client_get_default()
+
+	format_list = ['ogg', 'flac', 'wav', 'mp3-vbr', 'mp3-cbr']
+
+	gconf_keys = {
+		'format': "/apps/rhythmbox/plugins/magnatune/format",
+		'pay': "/apps/rhythmbox/plugins/magnatune/pay",
+		'ccnumber': "/apps/rhythmbox/plugins/magnatune/cc_number",
+		'ccyear': "/apps/rhythmbox/plugins/magnatune/cc_year",
+		'ccmonth': "/apps/rhythmbox/plugins/magnatune/cc_month",
+		'ccname': "/apps/rhythmbox/plugins/magnatune/name",
+		'email': "/apps/rhythmbox/plugins/magnatune/email"
+	}
+
+
+	#
+	# Core methods
+	#
+	
+	def __init__(self):
+		rb.Plugin.__init__(self)
+		
+	def activate(self, shell):
+		self.shell = shell # so buy_track can update the progress bar
+		self.db = shell.get_property("db")
+
+		self.entry_type = self.db.entry_register_type("MagnatuneEntryType")
+		# allow changes which don't do anything
+		self.entry_type.can_sync_metadata = True
+		self.entry_type.sync_metadata = None
+
+		self.source = gobject.new (MagnatuneSource, shell=shell, entry_type=self.entry_type, plugin=self)
+		shell.register_entry_type_for_source(self.source, self.entry_type)
+		shell.append_source(self.source, None) # Add the source to the list
+		
+		manager = shell.get_player().get_property('ui-manager')
+		action = gtk.Action('MagnatunePurchase', _('Purchase Album'),
+				_("Purchase this album from Magnatune"),
+				'gnome-mime-audio')
+		action.connect('activate', lambda a: self.shell.get_property("selected-source").purchase_tracks())
+		self.action_group = gtk.ActionGroup('MagnatunePluginActions')
+		self.action_group.add_action(action)
+		action = gtk.Action('MagnatuneArtistInfo', _('Artist Information'),
+				_("Get information about this artist"),
+				'gnome-mime-audio')
+		action.connect('activate', lambda a: self.shell.get_property("selected-source").display_artist_info())
+		self.action_group.add_action(action)
+		manager.insert_action_group(self.action_group, 0)
+		self.ui_id = manager.add_ui_from_string(popup_ui)
+		manager.ensure_update()
+	
+	def deactivate(self, shell):
+		manager = shell.get_player().get_property('ui-manager')
+		manager.remove_ui (self.ui_id)
+		manager.remove_action_group(self.action_group)
+		self.action_group = None
+
+		self.db.entry_delete_by_type(self.entry_type)
+		self.db.commit()
+		self.db = None
+		self.entry_type = None
+		self.source.delete_thyself()
+		self.source = None
+		self.shell = None
+	
+	def create_configure_dialog(self, dialog=None):
+		if dialog == None:
+			self.configure_callback_dic = {
+				"rb_magnatune_name_entry_changed_cb" : lambda w: self.client.set_string(self.gconf_keys['ccname'], w.get_text()),
+				"rb_magnatune_email_entry_changed_cb" : lambda w: self.client.set_string(self.gconf_keys['email'], w.get_text()),
+				"rb_magnatune_cc_entry_changed_cb" : lambda w: self.client.set_string(self.gconf_keys['ccnumber'], w.get_text()),
+				"rb_magnatune_yy_entry_changed_cb" : lambda w: self.client.set_string(self.gconf_keys['ccyear'], w.get_text()),
+				"rb_magnatune_mm_entry_changed_cb" : lambda w: self.client.set_string(self.gconf_keys['ccmonth'], w.get_active_text()),
+				"rb_magnatune_pay_combobox_changed_cb" : lambda w: self.client.set_int(self.gconf_keys['pay'], w.get_active() + 5),
+				"rb_magnatune_audio_combobox_changed_cb" : lambda w: self.client.set_string(self.gconf_keys['format'], self.format_list[w.get_active()])
+			}
+
+			gladexml = gtk.glade.XML(self.find_file("magnatune-prefs.glade"))
+			gladexml.signal_autoconnect(self.configure_callback_dic)
+
+			# FIXME this bit should be in glade too
+			dialog = gladexml.get_widget('preferences_dialog')
+			dialog.connect("response", lambda w, r: w.hide())
+			
+			if self.client.get_string(self.gconf_keys['ccname']) == None: # check to make sure fields exist
+				self.client.set_string(self.gconf_keys['ccname'], "")
+				self.client.set_string(self.gconf_keys['email'], "")
+				self.client.set_string(self.gconf_keys['ccnumber'], "")
+				self.client.set_string(self.gconf_keys['ccyear'], "")
+				self.client.set_string(self.gconf_keys['ccmonth'], "")
+				self.client.set_int(self.gconf_keys['pay'], 3)
+				self.client.set_string(self.gconf_keys['format'], "")
+
+			gladexml.get_widget("name_entry").set_text(self.client.get_string(self.gconf_keys['ccname']))
+			gladexml.get_widget("email_entry").set_text(self.client.get_string(self.gconf_keys['email']))
+			gladexml.get_widget("cc_entry").set_text(self.client.get_string(self.gconf_keys['ccnumber']))
+			gladexml.get_widget("yy_entry").set_text(self.client.get_string(self.gconf_keys['ccyear']))
+			gladexml.get_widget("mm_entry").set_active(int(self.client.get_string(self.gconf_keys['ccmonth'])) - 1)
+			gladexml.get_widget("pay_combobox").set_active(self.client.get_int(self.gconf_keys['pay']) - 5)
+			gladexml.get_widget("audio_combobox").set_active(self.format_list.index(self.client.get_string(self.gconf_keys['format'])))
+
+		dialog.present()
+		return dialog
--- /dev/null	2006-05-30 18:15:07.000000000 -0700
+++ plugins/magnatune/magnatune/MagnatuneSource.py	2006-08-29 22:06:01.000000000 -0700
@@ -0,0 +1,527 @@
+import rb, rhythmdb
+from TrackListHandler import TrackListHandler
+from BuyAlbumHandler import BuyAlbumHandler, MagnatunePurchaseError
+
+import gobject
+import gtk.glade
+import gnomevfs, gnome, gconf
+import xml
+import urllib, zipfile
+
+magnatune_partner_id = "zimmerman"
+
+# URIs
+magnatune_dir = gnome.user_dir_get() + "rhythmbox/magnatune/"
+magnatune_song_info_uri = gnomevfs.URI("http://magnatune.com/info/song_info.xml")
+local_song_info_uri = gnomevfs.URI(magnatune_dir + "song_info.xml")
+local_song_info_temp_uri = gnomevfs.URI(magnatune_dir + "song_info.xml.tmp")
+
+
+class MagnatuneSource(rb.BrowserSource):
+	__gproperties__ = {
+		'plugin': (rb.Plugin, 'plugin', 'plugin', gobject.PARAM_WRITABLE|gobject.PARAM_CONSTRUCT_ONLY),
+	}
+
+	__client = gconf.client_get_default()
+	
+	
+	def __init__(self):
+		circle_file_name = rb.Plugin.find_file(rb.Plugin(), "magnatune_circle_small.png") # bit of a hack, since self.__plugin isn't defined here
+		icon = gtk.gdk.pixbuf_new_from_file(circle_file_name)
+		rb.BrowserSource.__init__(self, name=_("Magnatune"), icon=icon)
+
+		# track data
+		self.__sku_dict = {}
+		self.__home_dict = {}
+
+		# catalogue stuff
+		self.__activated = False
+		self.__notify_id = 0
+		self.__update_id = 0
+		self.__xfer_handle = None
+		self.__info_screen = None
+		self.__updating = True
+		self.__has_loaded = False
+		self.__load_handle = None
+		self.__load_current_size = 0
+		self.__load_total_size = 1
+		
+		self.__downloads = {} # keeps track of amount downloaded for each file
+		self.__downloading = False # keeps track of whether we are currently downloading an album
+		self.purchase_filesize = 0 # total amount of bytes to download
+		self.progress_dialog = None
+		
+	def do_set_property(self, property, value):
+		if property.name == 'plugin':
+			self.__plugin = value
+		else:
+			raise AttributeError, 'unknown property %s' % property.name
+
+
+	#
+	# RBSource methods
+	#
+
+	def do_impl_show_entry_popup(self):
+		self.show_source_popup ("/MagnatuneSourceViewPopup")
+
+	def do_impl_get_status(self):
+		if self.__updating:
+			if self.__load_total_size > 0:
+				progress = min (float(self.__load_current_size) / self.__load_total_size, 1.0)
+			else:
+				progress = 0.0
+			return (_("Loading Magnatune catalogue"), None, progress)
+		else:
+			# FIXME: how do you actually do this?
+			#return rb.BrowserSource.do_impl_get_status (self)
+			return ("", None, 0.0)
+
+	def do_impl_activate(self):
+		if not self.__activated:
+			shell = self.get_property('shell')
+			self.__db = shell.get_property('db')
+			self.__entry_type = self.get_property('entry-type')
+
+			self.__activated = True
+			self.__show_loading_screen (True)
+			self.__load_catalogue()
+
+			# start our catalogue updates
+			self.__update_id = gobject.timeout_add(6 * 60 * 60 * 1000, self.__update_catalogue)
+			self.__update_catalogue()
+			
+			if self.__client.get_string("/apps/rhythmbox/plugins/magnatune/sorting") == None:
+				self.__client.set_string("/apps/rhythmbox/plugins/magnatune/sorting", "Artist,ascending")
+				self.get_entry_view().set_sorting_type("Artist,ascending")
+			else:
+				self.get_entry_view().set_sorting_type(self.__client.get_string("/apps/rhythmbox/plugins/magnatune/sorting"))
+
+		rb.BrowserSource.do_impl_activate (self)
+
+	def do_impl_delete_thyself(self):
+		if self.__update_id != 0:
+			gobject.source_remove (self.__update_id)
+			self.__update_id = 0
+
+		if self.__notify_id != 0:
+			gobject.source_remove (self.__notify_id)
+			self.__notify_id = 0
+
+		if self.__xfer_handle is not None:
+			self.__xfer_handle.close(lambda handle, exc: None) #FIXME: report it?
+			self.__xfer_handle = None
+		
+		self.__client.set_string("/apps/rhythmbox/plugins/magnatune/sorting", self.get_entry_view().get_sorting_type())
+		
+		if self.__downloading:
+			in_progress = create_if_needed(gnomevfs.URI(magnatune_dir + "downloads_in_progress"), gnomevfs.OPEN_WRITE)
+			for uri in self.__downloads.keys():
+				in_progress.write(str(uri) + "\n")
+			in_progress.close()
+
+		rb.BrowserSource.do_impl_delete_thyself (self)
+
+
+	#
+	# methods for use by plugin and UI
+	#
+
+
+	def display_artist_info(self):
+		tracks = self.get_entry_view().get_selected_entries()
+		urls = set([])
+
+		for tr in tracks:
+			url = self.__home_dict[self.__db.entry_get(tr, rhythmdb.PROP_LOCATION)]
+			if url not in urls:
+				gnomevfs.url_show(url)
+				urls.add(url)
+
+	def purchase_tracks(self):
+		tracks = self.get_entry_view().get_selected_entries()
+		skus = []
+
+		for track in tracks:
+			sku = self.__sku_dict[self.__db.entry_get(track, rhythmdb.PROP_LOCATION)]
+			if sku in skus:
+				continue
+			skus.append(sku)
+			artist = self.__db.entry_get(track, rhythmdb.PROP_ARTIST)
+			album = self.__db.entry_get(track, rhythmdb.PROP_ALBUM)	
+
+			gladexml = gtk.glade.XML(self.__plugin.find_file("magnatune-purchase.glade"))
+			pay_combo = gladexml.get_widget("pay_combobox")
+			format_combo = gladexml.get_widget("audio_combobox")
+			text_label = gladexml.get_widget("info_label")
+
+			pay_combo.set_active(self.__client.get_int(self.__plugin.gconf_keys['pay']) - 5)
+			format_combo.set_active(self.__plugin.format_list.index(self.__client.get_string(self.__plugin.gconf_keys['format'])))
+			text_label.set_text(_("Would you like to purchase the album '%s' by '%s'.") % (album, artist))
+
+			window = gladexml.get_widget("purchase_dialog")
+			if window.run() == gtk.RESPONSE_ACCEPT:
+				self.__purchase_album (sku, pay_combo.get_active() + 5, self.__plugin.format_list[format_combo.get_active()])
+
+			window.destroy()
+
+	#
+	# internal catalogue downloading and loading
+	#
+	def __load_catalogue_read_cb (self, handle, data, exc_type, bytes_requested, parser):
+		if exc_type:
+			if issubclass (exc_type, gnomevfs.EOFError):
+				# successfully loaded
+				gtk.gdk.threads_enter()
+				self.__show_loading_screen (False)
+				if gnomevfs.exists(gnomevfs.URI(magnatune_dir + "downloads_in_progress")):
+					in_progress = gnomevfs.read_entire_file(magnatune_dir + "downloads_in_progress")
+					for uri in in_progress.split("\n"):
+						if uri == '':
+							continue
+						self.__download_album(gnomevfs.URI(uri))
+					gnomevfs.unlink(gnomevfs.URI(magnatune_dir + "downloads_in_progress"))
+				gtk.gdk.threads_leave()
+			else:
+				# error reading file
+				raise exc_type
+			
+			parser.close()
+			handle.close(lambda handle, exc: None) # FIXME: report it?
+			self.__load_handle = None
+			self.__updating = False
+			self.__notify_status_changed()
+ 		else:
+
+			parser.feed(data)
+			handle.read(64 * 1024, self.__load_catalogue_read_cb, parser)
+
+		self.__notify_status_changed()
+
+	def __load_catalogue_open_cb (self, handle, exc_type):
+		if exc_type:
+			self.__load_handle = None
+			self.__notify_status_changed()
+			
+			if gnomevfs.exists(local_song_info_uri):
+				raise exc_type
+			else:
+				return
+
+		parser = xml.sax.make_parser()
+		parser.setContentHandler(TrackListHandler(self.__db, self.__entry_type, self.__sku_dict, self.__home_dict))
+		handle.read (64 * 1024, self.__load_catalogue_read_cb, parser)
+
+	def __load_catalogue(self):
+		self.__notify_status_changed()
+		self.__load_handle = gnomevfs.async.open (local_song_info_uri, self.__load_catalogue_open_cb)
+
+
+	def __download_update_cb (self, _reserved, info, moving):
+		if info.phase == gnomevfs.XFER_PHASE_COMPLETED:
+			if moving:
+				# done moving, load catalogue
+				self.__updating = False
+				self.__load_catalogue()
+			else:
+				# done downloading, move to real location
+				create_if_needed(local_song_info_uri, gnomevfs.OPEN_WRITE).close() # OPEN_NONE throws an exception
+				gnomevfs.async.xfer (source_uri_list = [local_song_info_temp_uri],
+						     target_uri_list = [local_song_info_uri],
+						     xfer_options = gnomevfs.XFER_REMOVESOURCE,
+						     error_mode = gnomevfs.XFER_ERROR_MODE_ABORT,
+						     overwrite_mode = gnomevfs.XFER_OVERWRITE_MODE_REPLACE,
+						     progress_update_callback = self.__download_update_cb,
+						     update_callback_data = True,
+						     progress_sync_callback = None,
+						     sync_callback_data = None)
+		else:
+			#print info
+			pass
+
+		return 1
+
+	def __download_progress_cb (self, info, data):
+		#if info.status == gnomevfs.XFER_PROGRESS_STATUS_OK:
+		if True:
+			self.__load_current_size = info.bytes_copied
+			self.__load_total_size = info.bytes_total
+			self.__notify_status_changed()
+		else:
+			print info
+		return 1
+
+	def __download_catalogue(self):
+		self.__updating = True
+		create_if_needed(local_song_info_temp_uri, gnomevfs.OPEN_WRITE).close()
+		self.__xfer_handle = gnomevfs.async.xfer (source_uri_list = [magnatune_song_info_uri],
+							  target_uri_list = [local_song_info_temp_uri],
+							  xfer_options = gnomevfs.XFER_FOLLOW_LINKS_RECURSIVE,
+							  error_mode = gnomevfs.XFER_ERROR_MODE_ABORT,
+							  overwrite_mode = gnomevfs.XFER_OVERWRITE_MODE_REPLACE,
+							  progress_update_callback = self.__download_update_cb,
+							  update_callback_data = False,
+							  progress_sync_callback = self.__download_progress_cb,
+							  sync_callback_data = None)
+
+	def __update_catalogue(self):
+		def info_cb (handle, results):
+			(remote_uri, remote_exc, remote_info) = results[0]
+			(local_uri, local_exc, local_info) = results[1]
+
+			if remote_exc:
+				# error locating remote file
+				print "error locating remote catalogue", remote_exc
+			elif local_exc:
+				if issubclass (local_exc, gnomevfs.NotFoundError):
+					# we haven't got it yet
+					print "no local copy of catalogue"
+					self.__download_catalogue()
+				else:
+					# error locating local file
+					print "error locating local catalogue", local_exc
+					self.__download_catalogue()
+			else:
+				try:
+					if remote_info.mtime > local_info.mtime:
+						# newer version available
+						self.__download_catalogue()
+					else:
+						# up to date
+						pass
+				except ValueError, e:
+					# couldn't get the mtimes. download?
+					print "error checking times", e
+					self.__download_catalogue()
+			return
+
+		gnomevfs.async.get_file_info ((magnatune_song_info_uri, local_song_info_uri), info_cb)
+
+	def __show_loading_screen(self, show):
+		if self.__info_screen is None:
+			# load the glade stuff
+			gladexml = gtk.glade.XML(self.__plugin.find_file("magnatune-loading.glade"), root="magnatune_loading_vbox")
+			self.__info_screen = gladexml.get_widget("magnatune_loading_vbox")
+			self.pack_start(self.__info_screen)
+			self.get_entry_view().set_no_show_all (True)
+			self.__info_screen.set_no_show_all (True)
+
+		self.__info_screen.set_property("visible", show)
+		self.get_entry_view().set_property("visible", not show)
+
+	def __notify_status_changed(self):
+		def change_idle_cb():
+			self.notify_status_changed()
+			self.__notify_id = 0
+			return False
+
+		if self.__notify_id == 0:
+			self.__notify_id = gobject.idle_add(change_idle_cb)
+
+
+	#
+	# internal purchasing code
+	#
+	def __purchase_album(self, sku, pay, format):
+		ccnumber = self.__client.get_string(self.__plugin.gconf_keys['ccnumber'])
+		ccyear = self.__client.get_string(self.__plugin.gconf_keys['ccyear'])
+		ccmonth = self.__client.get_string(self.__plugin.gconf_keys['ccmonth'])
+		name = self.__client.get_string(self.__plugin.gconf_keys['ccname'])
+		email = self.__client.get_string(self.__plugin.gconf_keys['email'])
+
+		print "purchasing tracks:", sku, pay, format, ccnumber, ccyear, ccmonth, name, email
+
+		### FIXME: all code below here needs reviewing
+		try:
+			self.__buy_track(sku, pay, format, name, email, ccnumber, ccyear, ccmonth)
+		except MagnatunePurchaseError, e:
+			error_dlg = gtk.Dialog(title="Error", flags=gtk.DIALOG_DESTROY_WITH_PARENT, buttons=(gtk.STOCK_OK, gtk.RESPONSE_OK))
+			label = gtk.Label(_("An error occurred while trying to purchase the album.\nThe Magnatune server returned:\n%s") % str(e))
+			error_dlg.vbox.pack_start(label)
+			label.set_selectable(True)
+			label.show()
+			error_dlg.connect("response", lambda w, r: w.destroy())
+			error_dlg.show()
+
+	def __buy_track(self, sku, pay, format, name, email, ccnumber, ccyear, ccmonth): # http://magnatune.com/info/api#purchase
+		url = "https://magnatune.com/buy/buy_dl_cc_xml?"
+		url = url + urllib.urlencode({
+						'id':	magnatune_partner_id,
+						'sku':	sku,
+						'amount': pay,
+						'cc':	ccnumber,
+						'yy':	ccyear,
+						'mm':	ccmonth,
+						'name': name,
+						'email':email
+					})
+
+		self.__buy_album_handler = BuyAlbumHandler(format) # so we can get the url and auth info
+		self.__auth_parser = xml.sax.make_parser()
+		self.__auth_parser.setContentHandler(self.__buy_album_handler)
+		
+		self.__wait_dlg = gtk.Dialog(title="Authorizing Purchase", flags=gtk.DIALOG_NO_SEPARATOR|gtk.DIALOG_DESTROY_WITH_PARENT)
+		lbl = gtk.Label("Authorizing purchase with the Magnatune server. Please wait...")
+		self.__wait_dlg.vbox.pack_start(lbl)
+		lbl.show()
+		self.__wait_dlg.show()
+		gnomevfs.async.open(gnomevfs.URI(url), self.__auth_open_cb)
+	
+	def __auth_open_cb(self, handle, exc_type):
+		if exc_type:
+			raise exc_type
+		
+		handle.read(64 * 1024, self.__auth_read_cb)
+		
+	
+	def __auth_read_cb (self, handle, data, exc_type, bytes_requested):
+		data = data.replace("<br>", "") # get rid of any stray <br> tags that will mess up the parser
+		if exc_type:
+			if issubclass (exc_type, gnomevfs.EOFError):
+				# successfully loaded
+				gtk.gdk.threads_enter()
+				audio_dl_uri = gnomevfs.URI(self.__buy_album_handler.url)
+				audio_dl_uri = gnomevfs.URI(self.__buy_album_handler.url[0:self.__buy_album_handler.url.rfind("/") + 1] + urllib.quote(audio_dl_uri.short_name))
+				audio_dl_uri.user_name = str(self.__buy_album_handler.username) # URI objects don't like unicode strings
+				audio_dl_uri.password = str(self.__buy_album_handler.password)
+				
+				self.__download_album(audio_dl_uri)
+				self.__wait_dlg.destroy()
+				gtk.gdk.threads_leave()
+			else:
+				# error reading file
+				raise exc_type
+			
+			self.__auth_parser.close()
+			handle.close(lambda handle, exc: None) # FIXME: report it?
+			
+ 		else:
+
+			self.__auth_parser.feed(data)
+			handle.read(64 * 1024, self.__auth_read_cb)
+	
+	def __download_album(self, audio_dl_uri):
+			library_location = self.__client.get_list("/apps/rhythmbox/library_locations", gconf.VALUE_STRING)[0] # Just use the first library location
+			to_file_uri = gnomevfs.URI(library_location + "/" + audio_dl_uri.short_name)
+			
+			self.__downloading = True
+			self.__init_progress_info(audio_dl_uri)
+			create_if_needed(to_file_uri, gnomevfs.OPEN_WRITE).close()
+			gnomevfs.async.xfer (source_uri_list = [audio_dl_uri],
+							target_uri_list = [to_file_uri],
+							xfer_options = gnomevfs.XFER_FOLLOW_LINKS_RECURSIVE,
+							error_mode = gnomevfs.XFER_ERROR_MODE_ABORT,
+							overwrite_mode = gnomevfs.XFER_OVERWRITE_MODE_REPLACE,
+							progress_update_callback = self.__purchase_download_update_cb,
+							update_callback_data = (to_file_uri, library_location, audio_dl_uri),
+							progress_sync_callback = self.__purchase_download_progress_cb,
+							sync_callback_data = (to_file_uri, audio_dl_uri))
+	
+	def __init_progress_info(self, audio_dl_uri):
+		def cancelled_cb (*args):
+			self.cancelled = True
+		
+		callbacks = {"rb_magnatune_cancel_button_clicked_cb": cancelled_cb,
+				"on_download_window_delete_event":	cancelled_cb
+				}
+
+		self.purchase_filesize += gnomevfs.get_file_info(audio_dl_uri).size
+		
+		if self.progress_dialog == None:
+			self.purchase_downloaded = 0
+			self.progress_dialog = gtk.glade.XML(self.__plugin.find_file("magnatune-download.glade"))
+			self.progress_dialog.signal_autoconnect(callbacks)
+			self.cancelled = False
+			self.progress_dialog.get_widget("download_window").show()
+	
+	def __purchase_download_update_cb(self, _reserved, info, data):
+		gtk.gdk.threads_enter()
+		if (info.phase == gnomevfs.XFER_PHASE_COMPLETED) and (not self.cancelled):
+			to_file_uri = data[0]
+			library_location = data[1]
+			audio_dl_uri = data[2]
+			
+			self.purchase_filesize -= gnomevfs.get_file_info(audio_dl_uri).size
+			del self.__downloads[str(audio_dl_uri)]
+			album = zipfile.ZipFile(to_file_uri.path)
+			for track in album.namelist():
+				track_uri = gnomevfs.URI(library_location + "/" + track)
+				out = create_if_needed(track_uri, gnomevfs.OPEN_WRITE)
+				out.write(album.read(track))
+				out.close()
+			album.close()
+			gnomevfs.unlink(to_file_uri)
+			if self.purchase_filesize == 0:
+				self.__downloading = False
+				self.__destroy_progress_window()
+			self.__db.add_uri("file://" + urllib.quote(track_uri.dirname))
+		gtk.gdk.threads_leave()
+		return 1
+	
+	def __purchase_download_progress_cb(self, info, data):
+		to_file_uri = data[0]
+		audio_dl_uri = data[1]
+		gtk.gdk.threads_enter()
+		
+		if self.cancelled:
+			try:
+				del self.__downloads[str(audio_dl_uri)]
+				self.purchase_filesize -= gnomevfs.get_file_info(audio_dl_uri).size
+				if self.purchase_filesize == 0:
+					self.__downloading = False
+					self.__destroy_progress_window()
+				gnomevfs.unlink(to_file_uri)
+			except KeyError: # for some reason, this gets called more than once, even though we return 0
+				pass
+			gtk.gdk.threads_leave()
+			return 0
+		
+		self.__downloads[str(audio_dl_uri)] = info.bytes_copied
+		purchase_downloaded = 0
+		for i in self.__downloads.values():
+			purchase_downloaded += i
+		purchase_fraction = purchase_downloaded / float(self.purchase_filesize)
+		self.__update_progress_bar(purchase_fraction)
+		gtk.gdk.threads_leave()
+		return 1
+	
+	def __update_progress_bar(self, purchase_fraction):
+		self.progress_dialog.get_widget("download_pbar").set_fraction(purchase_fraction)
+		self.progress_dialog.get_widget("download_pbar").set_text(str(int(purchase_fraction * 100)) + "%")
+		return False
+	
+	def __destroy_progress_window(self):
+		self.progress_dialog.get_widget("download_window").destroy()
+		self.progress_dialog = None
+		return False
+
+
+gobject.type_register(MagnatuneSource)
+
+
+def create_if_needed(uri, mode):
+	if not gnomevfs.exists(uri):
+		for directory in URIIterator(uri):
+			if not gnomevfs.exists(directory):
+				gnomevfs.make_directory(directory, 0755)
+		out = gnomevfs.create(uri, open_mode=mode)
+	else:
+		out = gnomevfs.open(uri, open_mode=mode)
+	return out
+
+
+
+class URIIterator:
+	def __init__(self, uri):
+		self.uri_list = uri.dirname.split("/")[1:] # dirname starts with /
+		self.counter = 0
+	def __iter__(self):
+		return self
+	def next(self):
+		if self.counter == len(self.uri_list) + 1:
+			raise StopIteration
+		value = "file://"
+		for i in range(self.counter):
+			value += "/" + self.uri_list[i]
+		self.counter += 1
+		return gnomevfs.URI(value)
--- /dev/null	2006-05-30 18:15:07.000000000 -0700
+++ plugins/magnatune/magnatune/Makefile.am	2006-08-16 21:13:55.000000000 -0700
@@ -0,0 +1,8 @@
+# Magnatune Store Python Plugin
+
+plugindir = $(PLUGINDIR)/magnatune
+plugin_PYTHON =                       \
+       MagnatuneSource.py             \
+       BuyAlbumHandler.py             \
+       TrackListHandler.py            \
+       __init__.py
--- /dev/null	2006-05-30 18:15:07.000000000 -0700
+++ plugins/magnatune/magnatune/TrackListHandler.py	2006-08-16 21:13:55.000000000 -0700
@@ -0,0 +1,49 @@
+import rhythmdb
+import xml.sax, xml.sax.handler
+import datetime
+
+class TrackListHandler(xml.sax.handler.ContentHandler):
+	
+	def __init__(self, db, entry_type, sku_dict, home_dict):
+		xml.sax.handler.ContentHandler.__init__(self)
+		self.__db = db
+		self.__entry_type = entry_type
+		self.__sku_dict = sku_dict
+		self.__home_dict = home_dict
+		self.__track = {}
+	
+	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_lookup_by_location (self.__track['url'])
+				if entry == None:
+					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
+				
+				self.__db.set(entry, rhythmdb.PROP_ARTIST, self.__track['artist'])
+				self.__db.set(entry, rhythmdb.PROP_ALBUM, self.__track['albumname'])
+				self.__db.set(entry, rhythmdb.PROP_TITLE, self.__track['trackname'])
+				self.__db.set(entry, rhythmdb.PROP_TRACK_NUMBER, int(self.__track['tracknum']))
+				self.__db.set(entry, rhythmdb.PROP_DATE, date)
+				self.__db.set(entry, rhythmdb.PROP_GENRE, self.__track['mp3genre'])
+				self.__db.set(entry, rhythmdb.PROP_DURATION, int(self.__track['seconds']))
+				self.__sku_dict[self.__track['url']] = self.__track['albumsku']
+				self.__home_dict[self.__track['url']] = self.__track['home']
+				
+				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']), 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
