|
1 #! /usr/bin/env python |
|
2 # -*- coding: iso-8859-15 -*- |
|
3 # |
|
4 # Copyright (C) 2007 Adam Wolk "Mulander" <netprobe@gmail.com> |
|
5 # Copyright (C) 2007, 2008 Mikael Berthe "McKael" <mikael@lilotux.net> |
|
6 # |
|
7 # This script is provided under the terms of the GNU General Public License, |
|
8 # see the file COPYING in the root mcabber source directory. |
|
9 # |
|
10 |
|
11 import sys |
|
12 import pynotify |
|
13 |
|
14 CONFFILE = "mcevent.cfg" |
|
15 |
|
16 # Default option values |
|
17 opt = { |
|
18 'use_notify': 0, |
|
19 'use_voice': 0, |
|
20 'use_sound': 1, |
|
21 'short_nick': 1, |
|
22 } |
|
23 |
|
24 NOTIFY_TIMEOUT=4000 |
|
25 |
|
26 contact_map = { } |
|
27 # Nickname used for the notification |
|
28 |
|
29 online_alerts = { } |
|
30 # 0: disabled 1: normal notification 2: permanent notify box |
|
31 |
|
32 voicemap = { } |
|
33 # Specify the name pronounced by espeak |
|
34 |
|
35 blacklist = { } |
|
36 # No notification for these JIDs |
|
37 |
|
38 CMD_MSG_IN="/usr/bin/play -V0 -v3 sound.wav" |
|
39 CMD_ESPEAK="/usr/bin/espeak" |
|
40 |
|
41 def init_notify(): |
|
42 import locale |
|
43 global encoding |
|
44 global NOTIFY_LOADED |
|
45 pynotify.init('mcnotify') |
|
46 encoding = (locale.getdefaultlocale())[1] |
|
47 NOTIFY_LOADED = True |
|
48 |
|
49 def read_conf_from_file(): |
|
50 import ConfigParser |
|
51 |
|
52 config = ConfigParser.ConfigParser() |
|
53 config.read(CONFFILE) |
|
54 |
|
55 contact_map.clear() |
|
56 online_alerts.clear() |
|
57 voicemap.clear() |
|
58 blacklist.clear() |
|
59 |
|
60 if config.has_option("Notifications", "notify"): |
|
61 opt['use_notify'] = int(config.get("Notifications", "notify")) |
|
62 if config.has_option("Notifications", "voice"): |
|
63 opt['use_voice'] = int(config.get("Notifications", "voice")) |
|
64 if config.has_option("Notifications", "sound"): |
|
65 opt['use_sound'] = int(config.get("Notifications", "sound")) |
|
66 if config.has_option("Notifications", "short_nick"): |
|
67 opt['short_nick'] = int(config.get("Notifications", "short_nick")) |
|
68 |
|
69 for id in config.options("Contacts"): |
|
70 contact_map[id] = config.get("Contacts", id) |
|
71 |
|
72 for id in config.options("Alerts"): |
|
73 online_alerts[id] = int(config.get("Alerts", id)) |
|
74 |
|
75 for id in config.options("Voicemap"): |
|
76 voicemap[id] = config.get("Voicemap", id) |
|
77 |
|
78 for id in config.options("Blacklist"): |
|
79 blacklist[id] = int(config.get("Blacklist", id)) |
|
80 |
|
81 if opt['use_notify'] and not NOTIFY_LOADED: |
|
82 init_notify() |
|
83 |
|
84 def say(buddy, text): |
|
85 import subprocess |
|
86 p = subprocess.Popen(CMD_ESPEAK, stdin=subprocess.PIPE, close_fds=True) |
|
87 child_stdin = p.stdin |
|
88 child_stdin.write(buddy + " " + text) |
|
89 child_stdin.close() |
|
90 |
|
91 def notify(buddy, msg, timeout): |
|
92 msgbox = pynotify.Notification(unicode(buddy, encoding), |
|
93 unicode(msg, encoding)) |
|
94 msgbox.set_timeout(timeout) |
|
95 msgbox.set_urgency(pynotify.URGENCY_LOW) |
|
96 msgbox.show() |
|
97 |
|
98 def get_nick(jid): |
|
99 if jid in contact_map: |
|
100 buddy = contact_map[jid] |
|
101 else: |
|
102 buddy = jid |
|
103 |
|
104 if opt['short_nick'] and '@' in buddy: |
|
105 buddy = buddy[0:buddy.index('@')] |
|
106 return buddy |
|
107 |
|
108 def is_blacklisted(jid): |
|
109 if jid in blacklist and blacklist[jid]: |
|
110 return True |
|
111 return False |
|
112 |
|
113 def process_line(args): |
|
114 argn = len(args) |
|
115 |
|
116 if argn < 2: |
|
117 print "Ignoring invalid event line." |
|
118 return |
|
119 elif argn == 2: |
|
120 event,arg1 = args[0:2] |
|
121 arg2 = None |
|
122 filename = None |
|
123 elif argn == 3: |
|
124 event,arg1,arg2 = args[0:3] |
|
125 filename = None |
|
126 else: |
|
127 # For now we simply ignore the file name |
|
128 event,arg1,arg2 = args[0:3] |
|
129 filename = None |
|
130 |
|
131 if event == 'MSG' and arg1 == 'IN': |
|
132 import os |
|
133 |
|
134 jid = arg2 |
|
135 buddy = get_nick(jid) |
|
136 msg = 'sent you a message.' |
|
137 |
|
138 if not is_blacklisted(jid): |
|
139 textmsg = None |
|
140 |
|
141 if filename and os.path.exists(filename): |
|
142 f = file(filename) |
|
143 textmsg = f.read() |
|
144 |
|
145 if opt['use_notify']: |
|
146 if not textmsg: |
|
147 textmsg = msg |
|
148 notify(buddy, textmsg, NOTIFY_TIMEOUT) |
|
149 |
|
150 if opt['use_sound']: |
|
151 os.system(CMD_MSG_IN + '> /dev/null 2>&1') |
|
152 |
|
153 if opt['use_voice'] and not is_blacklisted(jid): |
|
154 if jid in voicemap: |
|
155 buddy = voicemap[jid] |
|
156 say(buddy, msg) |
|
157 |
|
158 if filename and os.path.exists(filename): |
|
159 os.remove(filename) |
|
160 |
|
161 elif event == 'STATUS': |
|
162 jid = arg2 |
|
163 if arg1 == 'O' and jid in online_alerts: |
|
164 import os |
|
165 |
|
166 type = online_alerts[jid] |
|
167 if type > 0: |
|
168 if opt['use_sound']: |
|
169 os.system(CMD_MSG_IN + '> /dev/null 2>&1') |
|
170 |
|
171 buddy = get_nick(jid) |
|
172 |
|
173 if opt['use_notify']: |
|
174 if type == 1: |
|
175 timeout = NOTIFY_TIMEOUT |
|
176 else: |
|
177 timeout = pynotify.EXPIRES_NEVER |
|
178 notify(buddy, "is online", timeout) |
|
179 |
|
180 if filename and os.path.exists(filename): |
|
181 os.remove(filename) |
|
182 |
|
183 if opt['use_voice']: |
|
184 if jid in voicemap: |
|
185 buddy = voicemap[jid] |
|
186 say(buddy, "is online now.") |
|
187 |
|
188 elif event == 'UNREAD': |
|
189 # arg1 is the number of unread buffers |
|
190 fileHandle = open('/tmp/event.unread', 'w') |
|
191 fileHandle.write(arg1) |
|
192 fileHandle.close() |
|
193 |
|
194 |
|
195 ##### MAIN ##### |
|
196 |
|
197 NOTIFY_LOADED = False |
|
198 |
|
199 # read stdin line by line |
|
200 while 1: |
|
201 try: |
|
202 line = sys.stdin.readline() |
|
203 except KeyboardInterrupt: |
|
204 print "\nInterrupted!" |
|
205 exit(0) |
|
206 if not line: |
|
207 break |
|
208 |
|
209 read_conf_from_file() |
|
210 lineargs = line.split() |
|
211 process_line(lineargs) |
|
212 |
|
213 if NOTIFY_LOADED: |
|
214 pynotify.uninit() |
|
215 |
|
216 # vim:set et sts=4 sw=4 fileencoding=iso-8859-15: |