#! /usr/bin/env python
# -*- coding: iso-8859-15 -*-
#
# Copyright (C) 2007 Adam Wolk "Mulander" <netprobe@gmail.com>
# Copyright (C) 2007, 2008 Mikael Berthe "McKael" <mikael@lilotux.net>
#
# This script is provided under the terms of the GNU General Public License,
# see the file COPYING in the root mcabber source directory.
#
import sys, getopt
import os
import pynotify
CONFFILE = "mcevent.cfg"
# Default option values
opt = {
'use_notify': 0,
'use_voice': 0,
'use_sound': 1,
'short_nick': 1,
'unread_file': '',
'snd_cmd_msg_in': '/usr/bin/play -V0 -v3 sound.wav',
}
NOTIFY_TIMEOUT=4000
contact_map = { }
# Nickname used for the notification
contact_custom_msg = { }
# Message used for the notification
online_alerts = { }
# 0: disabled 1: normal notification 2: permanent notify box
voicemap = { }
# Specify the name pronounced by espeak
blacklist = { }
# No notification for these JIDs
CMD_ESPEAK="/usr/bin/espeak"
def init_notify():
import locale
global encoding
global NOTIFY_LOADED
pynotify.init('mcnotify')
encoding = (locale.getdefaultlocale())[1]
NOTIFY_LOADED = True
def read_conf_from_file():
import ConfigParser
config = ConfigParser.ConfigParser()
config.read(CONFFILE)
contact_map.clear()
contact_custom_msg.clear()
online_alerts.clear()
voicemap.clear()
blacklist.clear()
if config.has_option("Notifications", "notify"):
opt['use_notify'] = int(config.get("Notifications", "notify"))
if config.has_option("Notifications", "voice"):
opt['use_voice'] = int(config.get("Notifications", "voice"))
if config.has_option("Notifications", "sound"):
opt['use_sound'] = int(config.get("Notifications", "sound"))
if config.has_option("Notifications", "short_nick"):
opt['short_nick'] = int(config.get("Notifications", "short_nick"))
if config.has_option("Notifications", "unread_file"):
opt['unread_file'] = config.get("Notifications", "unread_file")
if config.has_option("Notifications", "snd_cmd_msg_in"):
opt['snd_cmd_msg_in'] = config.get("Notifications", "snd_cmd_msg_in")
if config.has_section("Contacts"):
for id in config.options("Contacts"):
contact_map[id] = config.get("Contacts", id)
if config.has_section("Contact_Customized_Messages"):
for id in config.options("Contact_Customized_Messages"):
contact_custom_msg[id] = config.get("Contact_Customized_Messages", id)
if config.has_section("Alerts"):
for id in config.options("Alerts"):
online_alerts[id] = int(config.get("Alerts", id))
if config.has_section("Voicemap"):
for id in config.options("Voicemap"):
voicemap[id] = config.get("Voicemap", id)
if config.has_section("Blacklist"):
for id in config.options("Blacklist"):
blacklist[id] = int(config.get("Blacklist", id))
if opt['use_notify'] and not NOTIFY_LOADED:
init_notify()
def say(buddy, text):
import subprocess
p = subprocess.Popen(CMD_ESPEAK, stdin=subprocess.PIPE, close_fds=True)
child_stdin = p.stdin
child_stdin.write(buddy + " " + text)
child_stdin.close()
def notify(buddy, msg, timeout):
msgbox = pynotify.Notification(unicode(buddy, encoding),
unicode(msg, encoding))
msgbox.set_timeout(timeout)
msgbox.set_urgency(pynotify.URGENCY_LOW)
msgbox.show()
def get_nick(jid):
if jid in contact_map:
buddy = contact_map[jid]
else:
buddy = jid
if opt['short_nick'] and '@' in buddy:
buddy = buddy[0:buddy.index('@')]
return buddy
def is_blacklisted(jid):
if jid in blacklist and blacklist[jid]:
return True
return False
def process_line(args):
argn = len(args)
if argn < 2:
print "Ignoring invalid event line."
return
elif argn == 2:
event,arg1 = args[0:2]
arg2 = None
filename = None
elif argn == 3:
event,arg1,arg2 = args[0:3]
filename = None
else:
# For now we simply ignore the file name
event,arg1,arg2 = args[0:3]
filename = None
if event == 'MSG' and arg1 == 'IN':
import os
jid = arg2
if not jid:
print "Ignoring invalid MSG event line."
return
buddy = get_nick(jid)
if jid in contact_custom_msg:
msg = contact_custom_msg[jid]
elif 'default' in contact_custom_msg:
msg = contact_custom_msg['default']
else:
msg = 'sent you a message.'
if not is_blacklisted(jid):
textmsg = None
if filename and os.path.exists(filename):
f = file(filename)
textmsg = f.read()
if opt['use_notify']:
if not textmsg:
textmsg = msg
notify(buddy, textmsg, NOTIFY_TIMEOUT)
if opt['use_sound']:
os.system(opt['snd_cmd_msg_in'] + '> /dev/null 2>&1')
if opt['use_voice'] and not is_blacklisted(jid):
if jid in voicemap:
buddy = voicemap[jid]
say(buddy, msg)
if filename and os.path.exists(filename):
os.remove(filename)
elif event == 'STATUS':
jid = arg2
if arg1 == 'O' and jid in online_alerts:
import os
type = online_alerts[jid]
if type > 0:
if opt['use_sound']:
os.system(opt['snd_cmd_msg_in'] + '> /dev/null 2>&1')
buddy = get_nick(jid)
if opt['use_notify']:
if type == 1:
timeout = NOTIFY_TIMEOUT
else:
timeout = pynotify.EXPIRES_NEVER
notify(buddy, "is online", timeout)
if filename and os.path.exists(filename):
os.remove(filename)
if opt['use_voice']:
if jid in voicemap:
buddy = voicemap[jid]
say(buddy, "is online now.")
elif event == 'UNREAD':
# arg1 is the number of unread buffers
if opt['unread_file'] != '':
fileHandle = open(opt['unread_file'], 'w')
fileHandle.write(arg1)
fileHandle.close()
##### MAIN #####
try:
opts, args = getopt.getopt(sys.argv[1:], "c:", ["help", "output="])
except getopt.GetoptError, err:
print str(err)
sys.exit(2)
for o, a in opts:
if o == "-c":
CONFFILE = a
try:
last_conf_read = os.stat(CONFFILE).st_ctime
except OSError:
sys.stderr.write("Cannot read config file!\n")
sys.exit(3)
NOTIFY_LOADED = False
read_conf_from_file()
# read stdin line by line
while 1:
try:
line = sys.stdin.readline()
except KeyboardInterrupt:
print "\nInterrupted!"
exit(0)
if not line:
break
last_conf_change = os.stat(CONFFILE).st_ctime
if last_conf_change > last_conf_read:
read_conf_from_file()
last_conf_read = last_conf_change
lineargs = line.split()
process_line(lineargs)
if NOTIFY_LOADED:
pynotify.uninit()
sys.exit(0)
# vim:set et sts=4 sw=4: