Index: rhythmbox/README
===================================================================
--- rhythmbox/README	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
+++ rhythmbox/README	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
@@ -0,0 +1,23 @@
+This is a plugin for the Rhythmbox music player, which enables
+Gutenbach users to easily queue music.
+
+Plugin written by Nimrod Gileadi, copyright 2010.
+
+Questions or comments should be directed at gutenbach@mit.edu
+
+INSTALLATION:
+
+1) Move the folder 'pikamp3' and its contents to
+~/.gnome2/rhythmbox/plugins/.  You will have to edit __init.py__,
+replacing "printername" and "hostname" with the desired values (e.g.,
+"sipbmp3" and "zsr.mit.edu").
+
+2) Open rhythmbox, and navigate the 'Edit' menu.  Select 'Plugins'.
+
+3) Check the box next to 'gutenbach'.
+
+4) To queue a song/songs, highlight them, and right click and select
+'Send to gutenbach'.
+
+TODO:
+- turn this into a debian package to auto generate the config file
Index: rhythmbox/__init__.py
===================================================================
--- rhythmbox/__init__.py	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
+++ rhythmbox/__init__.py	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
@@ -0,0 +1,69 @@
+"""
+This module implements a Rhythmbox plugin that sends selected track to a
+printer queue. It's meant to be used with gutenbach, a music spooling printer
+server.
+
+The plugin uses lpr to send the files to gutenbach.
+"""
+import gtk
+import rb
+import subprocess
+import urllib
+import urlparse
+
+# UI Change is an extra item added to right-click menu when clicking on tracks
+popup_ui = """
+<ui> 
+  <popup name="BrowserSourceViewPopup"> 
+    <menuitem name="Gutenbach" action="SendToGutenbach"/>
+  </popup>
+</ui>
+"""
+class GutenbachPlugin(rb.Plugin):
+    def __init__(self):
+        rb.Plugin.__init__(self)
+
+    def activate(self, shell):
+        """Adds a new item to the right-click menu which allows
+        sending music files to the gutenbach server.
+        """
+        self.shell = shell
+        # Create action for sending a track to gutenbach
+        action = gtk.Action('SendToGutenbach', _('Send to gutenbach'),
+                _("Queue selected tracks to the gutenbach server."),
+                "")
+        action.connect('activate', self.gutenbach_action, shell)
+        action_group = gtk.ActionGroup('GutenbachActionGroup')
+        action_group.add_action(action)
+        manager = shell.get_ui_manager()
+        manager.insert_action_group(action_group)
+        manager.add_ui_from_string(popup_ui)
+
+        # Default configuration options
+        self.printer = "printername"
+        self.printer_host = "hostname"
+
+    def deactivate(self, shell):
+        del self.shell
+
+    def gutenbach_action(self, action, shell):
+        """An action called when the user clicks the right-click menu item
+        to send a track to gutenbach.
+        This function calls an instance of lpr for each file to be added.
+        """
+        source = shell.get_property("selected-source")
+        # For each track currently selected in the song browser
+        for entry in source.get_entry_view().get_selected_entries():
+            # Only play files that are stored on the user's computer
+            uri = entry.get_playback_uri()
+            p = urlparse.urlparse(urllib.unquote(uri))
+            if p.scheme == "file":
+                path = p.path
+                if self.printer_host:
+                    printer = '@'.join([self.printer, self.printer_host])
+                else:
+                    printer = self.printer
+                command = 'lpr -P %s "%s"' % (printer, path)
+                print "About to run command '%s'" % command
+                subprocess.Popen(command, shell=True)
+
Index: rhythmbox/gutenbach-prefs.ui
===================================================================
--- rhythmbox/gutenbach-prefs.ui	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
+++ rhythmbox/gutenbach-prefs.ui	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
@@ -0,0 +1,115 @@
+<?xml version="1.0"?>
+<interface>
+  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-naming-policy project-wide -->
+  <object class="GtkDialog" id="gutenbach-prefs">
+    <property name="border_width">5</property>
+    <property name="title" translatable="yes">gutenbach Configuration</property>
+    <property name="type_hint">dialog</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <object class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
+        <child>
+          <object class="GtkVBox" id="vbox1">
+            <property name="visible">True</property>
+            <property name="orientation">vertical</property>
+            <child>
+              <object class="GtkVBox" id="vbox2">
+                <property name="visible">True</property>
+                <property name="orientation">vertical</property>
+                <child>
+                  <object class="GtkLabel" id="printer_label">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">Printer name:</property>
+                  </object>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkEntry" id="printer_entry">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="invisible_char">&#x25CF;</property>
+                    <property name="text" translatable="yes">pikamp3</property>
+                  </object>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkVBox" id="vbox3">
+                <property name="visible">True</property>
+                <property name="orientation">vertical</property>
+                <child>
+                  <object class="GtkLabel" id="host_label">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">Printer host:</property>
+                  </object>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkEntry" id="host_entry">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="invisible_char">&#x25CF;</property>
+                  </object>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <object class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="OK">
+                <property name="label" translatable="yes">OK</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="0">OK</action-widget>
+    </action-widgets>
+  </object>
+</interface>
Index: rhythmbox/gutenbach.rb-plugin
===================================================================
--- rhythmbox/gutenbach.rb-plugin	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
+++ rhythmbox/gutenbach.rb-plugin	(revision 30beeab008c68e1e024ed39a16b17a5d50ed07a3)
@@ -0,0 +1,7 @@
+[RB Plugin]
+Loader=python
+Module=gutenbach
+IAge=1
+Name=gutenbach
+Description="Print" tunes to the gutenbach server
+Authors=Nimrod Gileadi <nimrodg@mit.edu>
