Using Gajim with MPD
This is a simple example of what's possible with D-Bus and gajim-remote. This script reads the currently playing song out of MPD and updates the Gajim status message with gajim-remote when the song has changed.
Requirements:
- Gajim with D-Bus working (see GajimDBus)
- mpd and mpc (see http://www.musicpd.org)
Notes:
- As of 2005-11-09 this only works for me with the svn version of Gajim. Gajim 0.8.2 give a "Service not available" error when running gajim-remote
- gajim-remote currently (also 2005-11-09) doesn't offer an option to set just the status message without setting online/offline status. Hence the status is set to online whenever the song title changes.
- The script adds a music note (♫) in front of the current track. It might be that this Unicode character is not supported in all (Windows?) clients.
#!/bin/bash
function reset_status_message() {
gajim-remote change_status online ""
}
trap reset_status_message EXIT
while sleep 1
do
if [ "`mpc | wc -l`" == "1" ] ; then
CURRENT_TITLE=""
else
CURRENT_TITLE="`mpc --format \"[%name%: &[%artist% - ]%title%]|%name%|[%artist% - [%album% - ]]%title%|%shortfile%|\" | head -n 1`"
fi
if [ "$CURRENT_TITLE" != "$LAST_TITLE" ]
then
LAST_TITLE="$CURRENT_TITLE"
if [ -n "$CURRENT_TITLE" ]
then
echo `date +"%Y-%m-%d %H:%M:%S"` - \"$CURRENT_TITLE\"
gajim-remote change_status online "♫ $CURRENT_TITLE"
else
gajim-remote change_status online ""
fi
fi
done
This is the same script, but modified to only update when you are online.
#!/bin/bash
function reset_status_message() {
gajim-remote change_status online ""
}
trap reset_status_message EXIT
while sleep 1
do
if [ "`mpc | wc -l`" == "1" ] ; then
CURRENT_TITLE=""
else
CURRENT_TITLE="`mpc --format \"[%title%[ - %artist%][ #[%album%#]]]|[%file%]\" | head -n 1`"
fi
STATUS=`gajim-remote get_status`
if [[ "$CURRENT_TITLE" != "$LAST_TITLE" && $STATUS == "online" ]]
then
LAST_TITLE="$CURRENT_TITLE"
if [ -n "$CURRENT_TITLE" ]
then
echo `date +"%Y-%m-%d %H:%M:%S"` - \"$CURRENT_TITLE\"
gajim-remote change_status online "Listening to: $CURRENT_TITLE"
else
gajim-remote change_status online ""
fi
fi
done
And a third variant which uses less resources (running gajim-remote commands every second uses 22% of my Athlon64 3400Mhz cpu)
#!/bin/bash
#
# show the current playing song in gajim
function reset_status_message() {
gajim-remote change_status online ""
}
trap reset_status_message EXIT
while sleep 1
do
if [ "`mpc | wc -l`" == "1" ] ; then
CURRENT_TITLE=""
else
CURRENT_TITLE="`mpc --format \"[[%artist% - ]%title%]|[%file%]\" | sed '3,$d' | sed '2s,].*$,],' | awk 'BEGIN { FS = "\n"; RS = "" } { print $1, $NF }'`"
fi
if [ "$CURRENT_TITLE" != "$LAST_TITLE" ] ; then
STATUS=`gajim-remote get_status`
if [ $STATUS == "online" ] ; then
LAST_TITLE="$CURRENT_TITLE"
if [ -n "$CURRENT_TITLE" ] ; then
gajim-remote change_status online "♫ $CURRENT_TITLE"
else
gajim-remote change_status online ""
fi
fi
fi
done
Variant of script in Python (uses ~0% cpu on P4 :-)
#!/usr/bin/python
# -*- coding: utf-8 -*-
HOST = "" # localhost
PORT = 6600 # Port
global oldm,oldmus
oldm=oldmus=""
import socket,string,time,os
#Getting string with songname
def get(s):
artist=album=title=""
for i in s.split("\n"):
if i.startswith("Artist:"):
artist=i.replace("Artist: ","",1)
elif i.startswith("Album:"):
album=i.replace("Album: ","",1)
elif i.startswith("Title: "):
title=i.replace("Title: ","",1)
elif i.startswith("file: "):
file=i.replace("file: ","",1)
if artist==title=="":
return file
else:
return artist+": "+album+" - "+title
#Getting gajim status
def get_gajim():
f=os.popen("gajim-remote get_status")
return f.read().replace("\n","")
#Getting status-message
def getm_gajim():
f=os.popen("gajim-remote get_status_message")
return "\""+f.read().replace("\n","")+"\""
#Setting status
def set_gajim(s=""):
global oldm,oldmus
if s=="":
if oldmus!="":
o=getm_gajim()
if o!=oldmus:
oldm=o
s=oldm
oldmus=""
else:
return
else:
if s==oldmus:
return
else:
o=getm_gajim()
if o!=oldmus:
oldm=o
oldmus=s
print s
f=os.popen("gajim-remote change_status "+get_gajim()+" "+s)
#Playing status (play/pause/...)
def status(s):
for i in s.split("\n"):
if i.startswith("state:"):
return i.replace("state: ","",1)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
sock.recv(1024) #Zeroing...
try:
while 1:
sock.send("status\n")
if status(sock.recv(1024)) == "play":
sock.send("currentsong\n")
s="\"NP: "+get(sock.recv(1024))+"\""
set_gajim(s)
else:
set_gajim()
time.sleep(1)
except KeyboardInterrupt:
set_gajim()
sock.send("close")
sock.close()
print "-----------------------\nExiting..."
This script reads the currently playing song out of MPD and updates the Gajim Tune message when the song has changed:
#!/usr/bin/python
# -*- coding: utf-8 -*-
HOST = 'localhost'
PORT = 6600
import socket, time, dbus.service
from dbus.mainloop.glib import DBusGMainLoop
class mpdtune(dbus.service.Object):
def __init__(self):
dbus.service.Object.__init__(self, dbus.SessionBus(), '/Player')
@dbus.service.signal(dbus_interface = 'org.freedesktop.MediaPlayer')
def TrackChange(self, trackinfo):
print trackinfo
def get_status(data):
for line in data.split('\n'):
if line.startswith('state:'):
return line.replace('state: ', '', 1)
def get_data(data):
artist = album = title = ''
for line in data.split('\n'):
if line.startswith('Artist:'):
artist = line.replace('Artist: ', '', 1)
elif line.startswith('Album:'):
album = line.replace('Album: ', '', 1)
elif line.startswith('Title: '):
title = line.replace('Title: ', '', 1)
elif line.startswith('Name:'):
title = line.replace('Name: ', '', 1)
elif line.startswith('file: http'):
album = line.replace('file: ', '', 1)
return title, artist, album
def set_status(title = '', artist = '', album = ''):
global lasttune
if lasttune == title + ' - ' + artist + ' - ' + album:
return
lasttune = title + ' - ' + artist + ' - '+ album
tune.TrackChange(dbus.Dictionary({'title' : title, 'artist' : artist, 'album' : album}))
dbus.SessionBus(mainloop = DBusGMainLoop())
lasttune = ''
tune = mpdtune()
handle = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
handle.connect((HOST, PORT))
handle.recv(1024)
try:
while 1:
handle.send('status\n')
if get_status(handle.recv(1024)) == 'play':
handle.send('currentsong\n')
data = get_data(handle.recv(1024))
set_status(data[0], data[1], data[2])
else:
set_status()
time.sleep(3)
except KeyboardInterrupt:
set_status()
handle.send('close\n')
handle.close()
