3 # |
3 # |
4 # Copyright (C) 2007 Adam Wolk "Mulander" <netprobe@gmail.com> |
4 # Copyright (C) 2007 Adam Wolk "Mulander" <netprobe@gmail.com> |
5 # Copyright (C) 2007, 2008 Mikael Berthe "McKael" <mikael@lilotux.net> |
5 # Copyright (C) 2007, 2008 Mikael Berthe "McKael" <mikael@lilotux.net> |
6 # |
6 # |
7 # This script is provided under the terms of the GNU General Public License, |
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. |
8 # see the file COPYING in this directory. |
9 # |
9 # |
|
10 """ |
|
11 This script reads mcabber event lines from the standard input |
|
12 and creates events accordingly. Examples: |
|
13 STATUS O user2@domain.org |
|
14 MSG IN user@domain.org |
|
15 UNREAD 1 |
|
16 """ |
10 |
17 |
11 import sys, getopt |
18 import sys, getopt |
12 import os |
19 import os |
13 import pynotify |
20 import pynotify |
14 |
21 |
15 CONFFILE = "mcevent.cfg" |
22 CONFFILE = "mcevent.cfg" |
16 |
23 |
17 # Default option values |
24 # Default option values |
18 opt = { |
25 OPT = { |
19 'use_notify': 0, |
26 'use_notify': 0, |
20 'use_voice': 0, |
27 'use_voice': 0, |
21 'use_sound': 1, |
28 'use_sound': 1, |
22 'short_nick': 1, |
29 'short_nick': 1, |
23 'unread_file': '', |
30 'unread_file': '', |
24 'snd_cmd_msg_in': '/usr/bin/play -V0 -v3 sound.wav', |
31 'snd_cmd_msg_in': '/usr/bin/play -V0 -v3 sound.wav', |
25 } |
32 } |
26 |
33 |
27 NOTIFY_TIMEOUT = 4000 |
34 NOTIFY_TIMEOUT = 4000 |
28 |
35 |
29 contact_map = { } |
36 CONTACT_MAP = { } |
30 # Nickname used for the notification |
37 # Nickname used for the notification |
31 |
38 |
32 contact_custom_msg = { } |
39 CONTACT_CUSTOM_MSG = { } |
33 # Message used for the notification |
40 # Message used for the notification |
34 |
41 |
35 online_alerts = { } |
42 ONLINE_ALERTS = { } |
36 # 0: disabled 1: normal notification 2: permanent notify box |
43 # 0: disabled 1: normal notification 2: permanent notify box |
37 |
44 |
38 voicemap = { } |
45 VOICEMAP = { } |
39 # Specify the name pronounced by espeak |
46 # Specify the name pronounced by espeak |
40 |
47 |
41 blacklist = { } |
48 BLACKLIST = { } |
42 # No notification for these JIDs |
49 # No notification for these JIDs |
43 |
50 |
44 CMD_ESPEAK = "/usr/bin/espeak" |
51 CMD_ESPEAK = "/usr/bin/espeak" |
45 |
52 |
46 ENCODING = '' |
53 ENCODING = '' |
47 |
54 |
48 def init_notify(): |
55 def init_notify(): |
|
56 """ |
|
57 Initialize the pynotify subsystem. |
|
58 """ |
49 import locale |
59 import locale |
50 global ENCODING, NOTIFY_LOADED |
60 global ENCODING, NOTIFY_LOADED |
51 pynotify.init('mcnotify') |
61 pynotify.init('mcnotify') |
52 ENCODING = (locale.getdefaultlocale())[1] |
62 ENCODING = (locale.getdefaultlocale())[1] |
53 NOTIFY_LOADED = True |
63 NOTIFY_LOADED = True |
54 |
64 |
55 def read_conf_from_file(): |
65 def read_conf_from_file(): |
|
66 """ |
|
67 Read the configuration file. |
|
68 """ |
56 import ConfigParser |
69 import ConfigParser |
57 |
70 |
58 config = ConfigParser.ConfigParser() |
71 config = ConfigParser.ConfigParser() |
59 config.read(CONFFILE) |
72 config.read(CONFFILE) |
60 |
73 |
61 contact_map.clear() |
74 CONTACT_MAP.clear() |
62 contact_custom_msg.clear() |
75 CONTACT_CUSTOM_MSG.clear() |
63 online_alerts.clear() |
76 ONLINE_ALERTS.clear() |
64 voicemap.clear() |
77 VOICEMAP.clear() |
65 blacklist.clear() |
78 BLACKLIST.clear() |
66 |
79 |
67 if config.has_option("Notifications", "notify"): |
80 if config.has_option("Notifications", "notify"): |
68 opt['use_notify'] = int(config.get("Notifications", "notify")) |
81 OPT['use_notify'] = int(config.get("Notifications", "notify")) |
69 if config.has_option("Notifications", "voice"): |
82 if config.has_option("Notifications", "voice"): |
70 opt['use_voice'] = int(config.get("Notifications", "voice")) |
83 OPT['use_voice'] = int(config.get("Notifications", "voice")) |
71 if config.has_option("Notifications", "sound"): |
84 if config.has_option("Notifications", "sound"): |
72 opt['use_sound'] = int(config.get("Notifications", "sound")) |
85 OPT['use_sound'] = int(config.get("Notifications", "sound")) |
73 if config.has_option("Notifications", "short_nick"): |
86 if config.has_option("Notifications", "short_nick"): |
74 opt['short_nick'] = int(config.get("Notifications", "short_nick")) |
87 OPT['short_nick'] = int(config.get("Notifications", "short_nick")) |
75 if config.has_option("Notifications", "unread_file"): |
88 if config.has_option("Notifications", "unread_file"): |
76 opt['unread_file'] = config.get("Notifications", "unread_file") |
89 OPT['unread_file'] = config.get("Notifications", "unread_file") |
77 if config.has_option("Notifications", "snd_cmd_msg_in"): |
90 if config.has_option("Notifications", "snd_cmd_msg_in"): |
78 opt['snd_cmd_msg_in'] = config.get("Notifications", "snd_cmd_msg_in") |
91 OPT['snd_cmd_msg_in'] = config.get("Notifications", "snd_cmd_msg_in") |
79 |
92 |
80 if config.has_section("Contacts"): |
93 if config.has_section("Contacts"): |
81 for cid in config.options("Contacts"): |
94 for cid in config.options("Contacts"): |
82 contact_map[cid] = config.get("Contacts", cid) |
95 CONTACT_MAP[cid] = config.get("Contacts", cid) |
83 |
96 |
84 if config.has_section("Contact_Customized_Messages"): |
97 if config.has_section("Contact_Customized_Messages"): |
85 for cid in config.options("Contact_Customized_Messages"): |
98 for cid in config.options("Contact_Customized_Messages"): |
86 contact_custom_msg[cid] = config.get("Contact_Customized_Messages", |
99 CONTACT_CUSTOM_MSG[cid] = config.get("Contact_Customized_Messages", |
87 cid) |
100 cid) |
88 |
101 |
89 if config.has_section("Alerts"): |
102 if config.has_section("Alerts"): |
90 for cid in config.options("Alerts"): |
103 for cid in config.options("Alerts"): |
91 online_alerts[cid] = int(config.get("Alerts", cid)) |
104 ONLINE_ALERTS[cid] = int(config.get("Alerts", cid)) |
92 |
105 |
93 if config.has_section("Voicemap"): |
106 if config.has_section("Voicemap"): |
94 for cid in config.options("Voicemap"): |
107 for cid in config.options("Voicemap"): |
95 voicemap[cid] = config.get("Voicemap", cid) |
108 VOICEMAP[cid] = config.get("Voicemap", cid) |
96 |
109 |
97 if config.has_section("Blacklist"): |
110 if config.has_section("Blacklist"): |
98 for cid in config.options("Blacklist"): |
111 for cid in config.options("Blacklist"): |
99 blacklist[cid] = int(config.get("Blacklist", cid)) |
112 BLACKLIST[cid] = int(config.get("Blacklist", cid)) |
100 |
113 |
101 if opt['use_notify'] and not NOTIFY_LOADED: |
114 if OPT['use_notify'] and not NOTIFY_LOADED: |
102 init_notify() |
115 init_notify() |
103 |
116 |
104 def say(buddy, text): |
117 def say(buddy, text): |
|
118 """ |
|
119 Create a subprocess and run a speech synthesizer. |
|
120 """ |
105 import subprocess |
121 import subprocess |
106 p = subprocess.Popen(CMD_ESPEAK, stdin=subprocess.PIPE, close_fds=True) |
122 p = subprocess.Popen(CMD_ESPEAK, stdin=subprocess.PIPE, close_fds=True) |
107 child_stdin = p.stdin |
123 child_stdin = p.stdin |
108 child_stdin.write(buddy + " " + text) |
124 child_stdin.write(buddy + " " + text) |
109 child_stdin.close() |
125 child_stdin.close() |
110 |
126 |
111 def notify(buddy, msg, timeout): |
127 def notify(buddy, msg, timeout): |
|
128 """ |
|
129 Create a pynotify popup. |
|
130 """ |
112 msgbox = pynotify.Notification(unicode(buddy, ENCODING), |
131 msgbox = pynotify.Notification(unicode(buddy, ENCODING), |
113 unicode(msg, ENCODING)) |
132 unicode(msg, ENCODING)) |
114 msgbox.set_timeout(timeout) |
133 msgbox.set_timeout(timeout) |
115 msgbox.set_urgency(pynotify.URGENCY_LOW) |
134 msgbox.set_urgency(pynotify.URGENCY_LOW) |
116 msgbox.show() |
135 msgbox.show() |
117 |
136 |
118 def get_nick(jid): |
137 def get_nick(jid): |
119 if jid in contact_map: |
138 """ |
120 buddy = contact_map[jid] |
139 Return the nick of the given contact (JID). |
|
140 """ |
|
141 if jid in CONTACT_MAP: |
|
142 buddy = CONTACT_MAP[jid] |
121 else: |
143 else: |
122 buddy = jid |
144 buddy = jid |
123 |
145 |
124 if opt['short_nick'] and '@' in buddy: |
146 if OPT['short_nick'] and '@' in buddy: |
125 buddy = buddy[0:buddy.index('@')] |
147 buddy = buddy[0:buddy.index('@')] |
126 return buddy |
148 return buddy |
127 |
149 |
128 def is_blacklisted(jid): |
150 def is_blacklisted(jid): |
129 if jid in blacklist and blacklist[jid]: |
151 """ |
|
152 Return True if the given contcat (JID) is blacklisted. |
|
153 """ |
|
154 if jid in BLACKLIST and BLACKLIST[jid]: |
130 return True |
155 return True |
131 return False |
156 return False |
132 |
157 |
133 def process_line(args): |
158 def process_line(args): |
|
159 """ |
|
160 Parse the provided line and run events. |
|
161 """ |
134 argn = len(args) |
162 argn = len(args) |
135 |
163 |
136 if argn < 2: |
164 if argn < 2: |
137 print "Ignoring invalid event line." |
165 print "Ignoring invalid event line." |
138 return |
166 return |
153 if not jid: |
181 if not jid: |
154 print "Ignoring invalid MSG event line." |
182 print "Ignoring invalid MSG event line." |
155 return |
183 return |
156 |
184 |
157 buddy = get_nick(jid) |
185 buddy = get_nick(jid) |
158 if jid in contact_custom_msg: |
186 if jid in CONTACT_CUSTOM_MSG: |
159 msg = contact_custom_msg[jid] |
187 msg = CONTACT_CUSTOM_MSG[jid] |
160 elif 'default' in contact_custom_msg: |
188 elif 'default' in CONTACT_CUSTOM_MSG: |
161 msg = contact_custom_msg['default'] |
189 msg = CONTACT_CUSTOM_MSG['default'] |
162 else: |
190 else: |
163 msg = 'sent you a message.' |
191 msg = 'sent you a message.' |
164 |
192 |
165 if not is_blacklisted(jid): |
193 if not is_blacklisted(jid): |
166 textmsg = None |
194 textmsg = None |
167 |
195 |
168 if filename and os.path.exists(filename): |
196 if filename and os.path.exists(filename): |
169 f = file(filename) |
197 fileh = file(filename) |
170 textmsg = f.read() |
198 textmsg = fileh.read() |
171 |
199 |
172 if opt['use_notify']: |
200 if OPT['use_notify']: |
173 if not textmsg: |
201 if not textmsg: |
174 textmsg = msg |
202 textmsg = msg |
175 notify(buddy, textmsg, NOTIFY_TIMEOUT) |
203 notify(buddy, textmsg, NOTIFY_TIMEOUT) |
176 |
204 |
177 if opt['use_sound']: |
205 if OPT['use_sound']: |
178 os.system(opt['snd_cmd_msg_in'] + '> /dev/null 2>&1') |
206 os.system(OPT['snd_cmd_msg_in'] + '> /dev/null 2>&1') |
179 |
207 |
180 if opt['use_voice'] and not is_blacklisted(jid): |
208 if OPT['use_voice'] and not is_blacklisted(jid): |
181 if jid in voicemap: |
209 if jid in VOICEMAP: |
182 buddy = voicemap[jid] |
210 buddy = VOICEMAP[jid] |
183 say(buddy, msg) |
211 say(buddy, msg) |
184 |
212 |
185 if filename and os.path.exists(filename): |
213 if filename and os.path.exists(filename): |
186 os.remove(filename) |
214 os.remove(filename) |
187 |
215 |
188 elif event == 'STATUS': |
216 elif event == 'STATUS': |
189 jid = arg2 |
217 jid = arg2 |
190 if arg1 == 'O' and jid in online_alerts: |
218 if arg1 == 'O' and jid in ONLINE_ALERTS: |
191 alert_type = online_alerts[jid] |
219 alert_type = ONLINE_ALERTS[jid] |
192 if alert_type > 0: |
220 if alert_type > 0: |
193 if opt['use_sound']: |
221 if OPT['use_sound']: |
194 os.system(opt['snd_cmd_msg_in'] + '> /dev/null 2>&1') |
222 os.system(OPT['snd_cmd_msg_in'] + '> /dev/null 2>&1') |
195 |
223 |
196 buddy = get_nick(jid) |
224 buddy = get_nick(jid) |
197 |
225 |
198 if opt['use_notify']: |
226 if OPT['use_notify']: |
199 if alert_type == 1: |
227 if alert_type == 1: |
200 timeout = NOTIFY_TIMEOUT |
228 timeout = NOTIFY_TIMEOUT |
201 else: |
229 else: |
202 timeout = pynotify.EXPIRES_NEVER |
230 timeout = pynotify.EXPIRES_NEVER |
203 notify(buddy, "is online", timeout) |
231 notify(buddy, "is online", timeout) |
204 |
232 |
205 if filename and os.path.exists(filename): |
233 if filename and os.path.exists(filename): |
206 os.remove(filename) |
234 os.remove(filename) |
207 |
235 |
208 if opt['use_voice']: |
236 if OPT['use_voice']: |
209 if jid in voicemap: |
237 if jid in VOICEMAP: |
210 buddy = voicemap[jid] |
238 buddy = VOICEMAP[jid] |
211 say(buddy, "is online now.") |
239 say(buddy, "is online now.") |
212 |
240 |
213 elif event == 'UNREAD': |
241 elif event == 'UNREAD': |
214 # arg1 is the number of unread buffers |
242 # arg1 is the number of unread buffers |
215 if opt['unread_file'] != '': |
243 if OPT['unread_file'] != '': |
216 fileHandle = open(opt['unread_file'], 'w') |
244 fileh = open(OPT['unread_file'], 'w') |
217 fileHandle.write(arg1) |
245 fileh.write(arg1) |
218 fileHandle.close() |
246 fileh.close() |
219 |
247 |
220 |
248 |
221 ##### MAIN ##### |
249 ##### MAIN ##### |
222 |
250 |
223 try: |
251 try: |