| |
1 #!/usr/bin/python |
| |
2 |
| |
3 import dbus |
| |
4 import re |
| |
5 import sys |
| |
6 import time |
| |
7 import urllib |
| |
8 |
| |
9 obj = dbus.SessionBus().get_object("net.sf.gaim.GaimService", "/net/sf/gaim/GaimObject") |
| |
10 gaim = dbus.Interface(obj, "net.sf.gaim.GaimInterface") |
| |
11 |
| |
12 class CheckedObject: |
| |
13 def __init__(self, obj): |
| |
14 self.obj = obj |
| |
15 |
| |
16 def __getattr__(self, attr): |
| |
17 return CheckedAttribute(self, attr) |
| |
18 |
| |
19 class CheckedAttribute: |
| |
20 def __init__(self, cobj, attr): |
| |
21 self.cobj = cobj |
| |
22 self.attr = attr |
| |
23 |
| |
24 def __call__(self, *args): |
| |
25 result = self.cobj.obj.__getattr__(self.attr)(*args) |
| |
26 if result == 0: |
| |
27 raise "Error: " + self.attr + " " + str(args) + " returned " + str(result) |
| |
28 return result |
| |
29 |
| |
30 cgaim = CheckedObject(gaim) |
| |
31 |
| |
32 def extendlist(list, length, fill): |
| |
33 if len(list) < length: |
| |
34 return list + [fill] * (length - len(list)) |
| |
35 else: |
| |
36 return list |
| |
37 |
| |
38 def convert(value): |
| |
39 try: |
| |
40 return int(value) |
| |
41 except: |
| |
42 return value |
| |
43 |
| |
44 def findaccount(protocolname, accountname=""): |
| |
45 try: |
| |
46 # prefer connected accounts |
| |
47 account = cgaim.GaimAccountsFindConnected(accountname, protocolname) |
| |
48 return account |
| |
49 except: |
| |
50 # try to get any account and connect it |
| |
51 account = cgaim.GaimAccountsFindAny(accountname, protocolname) |
| |
52 gaim.GaimAccountSetStatusVargs(account, "online", 1) |
| |
53 gaim.GaimAccountConnect(account) |
| |
54 return account |
| |
55 |
| |
56 def goim(account, screenname, message=None): |
| |
57 # XXX: 1 == GAIM_CONV_TYPE_IM |
| |
58 conversation = cgaim.GaimConversationNew(1, account, screenname) |
| |
59 if message: |
| |
60 gaim.GaimConvSendConfirm(conversation, message) |
| |
61 |
| |
62 def gochat(account, params, message=None): |
| |
63 connection = cgaim.GaimAccountGetConnection(account) |
| |
64 gaim.ServJoinChat(connection, params) |
| |
65 |
| |
66 if message != None: |
| |
67 for i in range(20): |
| |
68 # XXX: 2 == GAIM_CONV_TYPE_CHAT |
| |
69 conversation = gaim.GaimFindConversationWithAccount(2, params.get("channel", params.get("room")), account) |
| |
70 if conversation: |
| |
71 gaim.GaimConvSendConfirm(conversation, message) |
| |
72 break |
| |
73 else: |
| |
74 time.sleep(0.5) |
| |
75 |
| |
76 def addbuddy(account, screenname, group="", alias=""): |
| |
77 cgaim.GaimBlistRequestAddBuddy(account, screenname, group, alias) |
| |
78 |
| |
79 |
| |
80 def aim(uri): |
| |
81 protocol = "prpl-oscar" |
| |
82 match = re.match(r"^(aim|icq):([^?]*)(\?(.*))", uri) |
| |
83 if not match: |
| |
84 print "Invalid aim URI: %s" % uri |
| |
85 return |
| |
86 |
| |
87 command = urllib.unquote_plus(match.group(2)) |
| |
88 paramstring = match.group(4) |
| |
89 params = {} |
| |
90 if paramstring: |
| |
91 for param in paramstring.split("&"): |
| |
92 key, value = extendlist(param.split("=", 1), 2, "") |
| |
93 params[key] = urllib.unquote_plus(value) |
| |
94 accountname = params.get("account", "") |
| |
95 screenname = params.get("screenname", "") |
| |
96 |
| |
97 account = findaccount(protocol, accountname) |
| |
98 |
| |
99 if command.lower() == "goim": |
| |
100 goim(account, screenname, params.get("message")) |
| |
101 elif command.lower() == "gochat": |
| |
102 gochat(account, params) |
| |
103 elif command.lower() == "addbuddy": |
| |
104 addbuddy(account, screenname, params.get("group", "")) |
| |
105 |
| |
106 def gg(uri): |
| |
107 protocol = "prpl-gg" |
| |
108 match = re.match(r"^gg:(.*)", uri) |
| |
109 if not match: |
| |
110 print "Invalid gg URI: %s" % uri |
| |
111 return |
| |
112 |
| |
113 screenname = urllib.unquote_plus(match.group(1)) |
| |
114 account = findaccount(protocol) |
| |
115 goim(account, screenname) |
| |
116 |
| |
117 def icq(uri): |
| |
118 aim(uri) |
| |
119 |
| |
120 def irc(uri): |
| |
121 protocol = "prpl-irc" |
| |
122 match = re.match(r"^irc:(//([^/]*)/)?([^?]*)(\?(.*))?", uri) |
| |
123 if not match: |
| |
124 print "Invalid irc URI: %s" % uri |
| |
125 return |
| |
126 |
| |
127 server = urllib.unquote_plus(match.group(2)) or "" |
| |
128 target = match.group(3) or "" |
| |
129 query = match.group(5) or "" |
| |
130 |
| |
131 modifiers = {} |
| |
132 if target: |
| |
133 for modifier in target.split(",")[1:]: |
| |
134 modifiers[modifier] = True |
| |
135 |
| |
136 isnick = modifiers.has_key("isnick") |
| |
137 |
| |
138 paramstring = match.group(5) |
| |
139 params = {} |
| |
140 if paramstring: |
| |
141 for param in paramstring.split("&"): |
| |
142 key, value = extendlist(param.split("=", 1), 2, "") |
| |
143 params[key] = urllib.unquote_plus(value) |
| |
144 |
| |
145 account = findaccount(protocol) |
| |
146 |
| |
147 if (target != ""): |
| |
148 if (isnick): |
| |
149 goim(account, urllib.unquote_plus(target.split(",")[0]), params.get("msg")) |
| |
150 else: |
| |
151 channel = urllib.unquote_plus(target.split(",")[0]) |
| |
152 if channel[0] != "#": |
| |
153 channel = "#" + channel |
| |
154 gochat(account, {"server": server, "channel": channel, "password": params.get("key", "")}, params.get("msg")) |
| |
155 |
| |
156 def msnim(uri): |
| |
157 protocol = "prpl-msn" |
| |
158 match = re.match(r"^msnim:([^?]*)(\?(.*))", uri) |
| |
159 if not match: |
| |
160 print "Invalid msnim URI: %s" % uri |
| |
161 return |
| |
162 |
| |
163 command = urllib.unquote_plus(match.group(1)) |
| |
164 paramstring = match.group(3) |
| |
165 params = {} |
| |
166 if paramstring: |
| |
167 for param in paramstring.split("&"): |
| |
168 key, value = extendlist(param.split("=", 1), 2, "") |
| |
169 params[key] = urllib.unquote_plus(value) |
| |
170 screenname = params.get("contact", "") |
| |
171 |
| |
172 account = findaccount(protocol) |
| |
173 |
| |
174 if command.lower() == "chat": |
| |
175 goim(account, screenname) |
| |
176 elif command.lower() == "add": |
| |
177 addbuddy(account, screenname) |
| |
178 |
| |
179 def sip(uri): |
| |
180 protocol = "prpl-simple" |
| |
181 match = re.match(r"^sip:(.*)", uri) |
| |
182 if not match: |
| |
183 print "Invalid sip URI: %s" % uri |
| |
184 return |
| |
185 |
| |
186 screenname = urllib.unquote_plus(match.group(1)) |
| |
187 account = findaccount(protocol) |
| |
188 goim(account, screenname) |
| |
189 |
| |
190 def xmpp(uri): |
| |
191 protocol = "prpl-jabber" |
| |
192 match = re.match(r"^xmpp:((//)?([^/?#]*))?(/?([^?#]*))(\?([^;#]*)(;([^#]*))?)?(#(.*))?", uri) |
| |
193 if not match: |
| |
194 print "Invalid xmpp URI: %s" % uri |
| |
195 return |
| |
196 |
| |
197 tmp = match.group(3) |
| |
198 if (tmp): |
| |
199 accountname = urllib.unquote_plus(tmp) |
| |
200 else: |
| |
201 accountname = "" |
| |
202 |
| |
203 screenname = urllib.unquote_plus(match.group(5)) |
| |
204 |
| |
205 tmp = match.group(7) |
| |
206 if (tmp): |
| |
207 command = urllib.unquote_plus(tmp) |
| |
208 else: |
| |
209 command = "" |
| |
210 |
| |
211 paramstring = match.group(9) |
| |
212 params = {} |
| |
213 if paramstring: |
| |
214 for param in paramstring.split(";"): |
| |
215 key, value = extendlist(param.split("=", 1), 2, "") |
| |
216 params[key] = urllib.unquote_plus(value) |
| |
217 |
| |
218 account = findaccount(protocol, accountname) |
| |
219 |
| |
220 if command.lower() == "message": |
| |
221 goim(account, screenname, params.get("body")) |
| |
222 elif command.lower() == "join": |
| |
223 room, server = screenname.split("@") |
| |
224 gochat(account, {"room": room, "server": server}) |
| |
225 elif command.lower() == "roster": |
| |
226 addbuddy(account, screenname, params.get("group", ""), params.get("name", "")) |
| |
227 else: |
| |
228 goim(account, screenname) |
| |
229 |
| |
230 def ymsgr(uri): |
| |
231 protocol = "prpl-yahoo" |
| |
232 match = re.match(r"^ymsgr:([^?]*)(\?([^&]*)(&(.*))?)", uri) |
| |
233 if not match: |
| |
234 print "Invalid ymsgr URI: %s" % uri |
| |
235 return |
| |
236 |
| |
237 command = urllib.unquote_plus(match.group(1)) |
| |
238 screenname = urllib.unquote_plus(match.group(3)) |
| |
239 paramstring = match.group(5) |
| |
240 params = {} |
| |
241 if paramstring: |
| |
242 for param in paramstring.split("&"): |
| |
243 key, value = extendlist(param.split("=", 1), 2, "") |
| |
244 params[key] = urllib.unquote_plus(value) |
| |
245 |
| |
246 account = findaccount(protocol) |
| |
247 |
| |
248 if command.lower() == "sendim": |
| |
249 goim(account, screenname, params.get("m")) |
| |
250 elif command.lower() == "chat": |
| |
251 gochat(account, {"room": screenname}) |
| |
252 elif command.lower() == "addfriend": |
| |
253 addbuddy(account, screenname) |
| |
254 |
| |
255 |
| |
256 def main(argv=sys.argv): |
| |
257 if len(argv) != 2: |
| |
258 print "Usage: %s URI" % argv[0] |
| |
259 print "Example: %s \"xmpp:romeo@montague.net?message\"" % argv[0] |
| |
260 return |
| |
261 |
| |
262 uri = argv[1] |
| |
263 type = uri.split(":")[0] |
| |
264 |
| |
265 if type == "aim": |
| |
266 aim(uri) |
| |
267 elif type == "gg": |
| |
268 gg(uri) |
| |
269 elif type == "icq": |
| |
270 icq(uri) |
| |
271 elif type == "irc": |
| |
272 irc(uri) |
| |
273 elif type == "msnim": |
| |
274 msnim(uri) |
| |
275 elif type == "sip": |
| |
276 sip(uri) |
| |
277 elif type == "xmpp": |
| |
278 xmpp(uri) |
| |
279 elif type == "ymsgr": |
| |
280 ymsgr(uri) |
| |
281 else: |
| |
282 print "Unkown protocol: %s" % type |
| |
283 |
| |
284 if __name__ == "__main__": |
| |
285 main() |