#!/usr/bin/ruby # $Id: dbus-itunes.rb,v 1.4 2008/01/14 19:43:06 jcs Exp $ # # dbus-itunes.rb # in client mode on a mac, talk to itunes via applescript and forward track # info via udp to another machine running this in server mode which then # forwards the message to the d-bus notification service # # Copyright (c) 2008 joshua stein # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. The name of the author may not be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # where the server will bind and the client will send to UDP_SERVER = "192.168.1.25" UDP_PORT = 2500 # valid itunes icon png on the server ITUNES_ICON = "#{ENV['HOME']}/.itunes.png" mode = ARGV[0] case mode when "client" require "rubygems" require "socket" require "appscript" include Appscript when "server" require "dbus" require "socket" else puts "usage: #{File.basename(__FILE__)} " exit -1 end def notify(message, title = nil, timeout = -1) @notify.Notify( "iTunes", 0, (File.exists?(ITUNES_ICON) ? ITUNES_ICON: ""), (title.to_s == "" ? "" : title.to_s), message.to_s, [], {}, timeout ) end if mode == "server" session_bus = DBus::SessionBus.instance notify_bus = session_bus.service("org.freedesktop.Notifications") @notify = notify_bus.object("/org/freedesktop/Notifications") @notify.default_iface = "org.freedesktop.Notifications" @notify.introspect server = UDPSocket.new server.bind(UDP_SERVER, UDP_PORT) notify "#{File.basename(__FILE__)} server started on " + "#{UDP_SERVER}:#{UDP_PORT}", "iTunes" while true begin packet = server.recvfrom(1024) if packet[0].to_s != "" track, artist, album = packet[0].gsub(/&/, "&").gsub(//, ">").split("|") notify( "#{track}\n" + artist + (album.to_s == "" ? "" : "\n#{album}"), "iTunes", 3000 ) end rescue end end elsif mode == "client" socket = UDPSocket.open socket.connect(UDP_SERVER, UDP_PORT) socket.send "#{File.basename(__FILE__)} client started", 0 last_track = "" while true do t = app("iTunes").current_track if t.name.exists title = t.name.get title = "Unknown Track" if title.to_s == "" artist = t.artist.get artist = "Unknown Artist" if artist.to_s == "" album = t.album.get begin str = "#{title}|#{artist}|#{album}" if str != last_track socket.send str, 0 last_track = str end rescue => e puts "error: #{e}" end end sleep 1 end end