pyLiMaSound

When life gives you lemons, make lemonade. This small application is my first real need to use the python language, and that makes me excited. Furthermore Ubuntu and Debian, in the desktop varieties, appear to come standard with PyGTK (your mileage may vary).

My main issue was that I needed to remotely adjust my OS X workstation’s sound, and I figured a control would be easier than opening a shell and running a script. Basically this will give you a small gtk.VScale widget (a vertical slider widget used to select a value from a range) in a resizable window. When everything is all setup I also run it using AllTray so that it can be docked into the system tray.

pylimasound-001.jpg
pylimasound-002.jpg

When a value is selected using the widget it passes the value off to rsh, which in turn sends the command to a remote workstation (the command I have prefilled into the script works on OS X’s main volume):

rsh -l remote_username mac_workstation.fqdn 
"osascript -e 'set Volume 4.6'"

The following, in the intended deployment requires password-less key based ssh connections between the workstation intended to remotely adjust the sound (any platform that supports PyGTK) and the Macintosh workstation:

#!/usr/bin/env python
#pyLiMaSound.py
 
import os
import gtk
import pygtk
 
pygtk.require("2.0")
 
user="remote_username"
host="mac_workstation.fqdn"
 
def scale_set_default_values(scale):
    scale.set_update_policy(gtk.UPDATE_DELAYED)
    scale.set_digits(1)
    scale.set_value_pos(gtk.POS_BOTTOM)
    scale.set_draw_value(True)
 
class pyLiMaSound:
    def delete_event(self, widget, event, data=None):
        print "delete event occurred"
        return False
 
    def destroy(self, widget, data=None):
        print "destroy signal occurred"
        gtk.main_quit()
 
    def rsh_vol_cmd(self, data):
        payload = "rsh -l " + user + " " + host 
            + " "osascript -e 'set Volume " + 
            str(data.value) + "'""
	print payload
        os.system(payload);
 
    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_default_size(50, 200)
        self.window.connect("delete_event", self.delete_event)
        self.window.connect("destroy", self.destroy)
        self.window.set_border_width(10)
 
        adj1 = gtk.Adjustment(0.0, 0.0, 10.1, 0.1, 0.1, 0.1)
	adj1.connect("value_changed", self.rsh_vol_cmd)
 
        self.vscale = gtk.VScale(adj1)
        scale_set_default_values(self.vscale)
        self.window.add(self.vscale)
        self.vscale.show()
        self.window.show()
 
    def main(self):
        gtk.main()
 
if __name__ == "__main__":
    control = pyLiMaSound()
    control.main()

Autoresponders – a loop

This past week I encountered an interesting situation between two web applications I work with regularly. The first is the goldfish autoresponder for postfix. The second is RT: Request Tracker.

The situation went something like this:

  • I had a ticket in RT that I wanted to resolve.
  • I set the form to cc the comment to a group of users who were interested in the details of the resolution.
  • I applied the ticket in RT.
  • RT cc’ed the users about the resolution.
  • One of the users had an autoresponder setup using goldfish, so it emailed back to RT about the user’s absence.
  • RT opened a ticket with the content of the email from the autoresponder, faithfully attaching the subject explaining the user’s absence.
  • RT then responded to the user’s email account about the new ticket’s creation.
  • Again goldfish autoresponds to a message from RT, creating a loop.

Every five minutes a new ticket was being created in RT because of goldfish’s configuration and cron job being set to run that often. I caught the cycle happening when the incoming queue of tickets had three or four created with their subjects typical of those created by an autoresponder.