9 bus
= dbus
.SessionBus()
12 obj
= bus
.get_object("im.pidgin.purple.PurpleService",
13 "/im/pidgin/purple/PurpleObject")
14 except dbus
.DBusException
, e
:
15 if e
._dbus
_error
_name
== "org.freedesktop.DBus.Error.ServiceUnknown":
16 print "Error: no libpurple-powered client is running. Try starting Pidgin or Finch."
18 purple
= dbus
.Interface(obj
, "im.pidgin.purple.PurpleInterface")
21 def __init__(self
, obj
):
24 def __getattr__(self
, attr
):
25 return CheckedAttribute(self
, attr
)
27 class CheckedAttribute
:
28 def __init__(self
, cobj
, attr
):
32 def __call__(self
, *args
):
33 # Redirect stderr to suppress the printing of an " Introspect error"
34 # message if nothing is listening on the bus. We print a friendly
35 # error message ourselves.
36 real_stderr
= sys
.stderr
38 result
= self
.cobj
.obj
.__getattr
__(self
.attr
)(*args
)
39 sys
.stderr
= real_stderr
41 # This can be useful for debugging.
43 # print "Error: " + self.attr + " " + str(args) + " returned " + str(result)
47 cpurple
= CheckedObject(purple
)
49 def extendlist(list, length
, fill
):
50 if len(list) < length
:
51 return list + [fill
] * (length
- len(list))
61 def account_not_found():
62 print "No matching account found."
65 def bring_account_online(account
):
66 if not cpurple
.PurpleAccountIsConnected(account
):
67 # The last argument is meant to be a GList * but the D-Bus binding
68 # generator thing just wants a UInt32, which is pretty failing.
69 # Happily, passing a 0 to mean an empty list turns out to work anyway.
70 purple
.PurpleAccountSetStatusList(account
, "online", 1, 0)
71 purple
.PurpleAccountConnect(account
)
73 def findaccount(protocolname
, accountname
="", matcher
=None):
75 for account
in cpurple
.PurpleAccountsGetAll():
76 if accountname
!= "" and accountname
!= cpurple
.PurpleAccountGetUsername(a
):
79 bring_account_online(account
)
83 # prefer connected accounts
84 account
= cpurple
.PurpleAccountsFindConnected(accountname
, protocolname
)
88 # try to get any account and connect it
89 account
= cpurple
.PurpleAccountsFindAny(accountname
, protocolname
)
93 bring_account_online(account
)
96 def goim(account
, screenname
, message
=None):
97 # XXX: 1 == PURPLE_CONV_TYPE_IM
98 conversation
= cpurple
.PurpleConversationNew(1, account
, screenname
)
100 purple
.PurpleConvSendConfirm(conversation
, message
)
102 def gochat(account
, params
, message
=None):
103 connection
= cpurple
.PurpleAccountGetConnection(account
)
104 purple
.ServJoinChat(connection
, params
)
108 # XXX: 2 == PURPLE_CONV_TYPE_CHAT
109 conversation
= purple
.PurpleFindConversationWithAccount(2, params
.get("channel", params
.get("room")), account
)
111 purple
.PurpleConvSendConfirm(conversation
, message
)
116 def addbuddy(account
, screenname
, group
="", alias
=""):
117 cpurple
.PurpleBlistRequestAddBuddy(account
, screenname
, group
, alias
)
121 protocol
= "prpl-aim"
122 match
= re
.match(r
"^aim:([^?]*)(\?(.*))", uri
)
124 print "Invalid aim URI: %s" % uri
127 command
= urllib
.unquote_plus(match
.group(1))
128 paramstring
= match
.group(3)
131 for param
in paramstring
.split("&"):
132 key
, value
= extendlist(param
.split("=", 1), 2, "")
133 params
[key
] = urllib
.unquote_plus(value
)
134 accountname
= params
.get("account", "")
135 screenname
= params
.get("screenname", "")
137 account
= findaccount(protocol
, accountname
)
139 if command
.lower() == "goim":
140 goim(account
, screenname
, params
.get("message"))
141 elif command
.lower() == "gochat":
142 gochat(account
, params
)
143 elif command
.lower() == "addbuddy":
144 addbuddy(account
, screenname
, params
.get("group", ""))
148 match
= re
.match(r
"^gg:(.*)", uri
)
150 print "Invalid gg URI: %s" % uri
153 screenname
= urllib
.unquote_plus(match
.group(1))
154 account
= findaccount(protocol
)
155 goim(account
, screenname
)
158 protocol
= "prpl-icq"
159 match
= re
.match(r
"^icq:([^?]*)(\?(.*))", uri
)
161 print "Invalid icq URI: %s" % uri
164 command
= urllib
.unquote_plus(match
.group(1))
165 paramstring
= match
.group(3)
168 for param
in paramstring
.split("&"):
169 key
, value
= extendlist(param
.split("=", 1), 2, "")
170 params
[key
] = urllib
.unquote_plus(value
)
171 accountname
= params
.get("account", "")
172 screenname
= params
.get("screenname", "")
174 account
= findaccount(protocol
, accountname
)
176 if command
.lower() == "goim":
177 goim(account
, screenname
, params
.get("message"))
178 elif command
.lower() == "gochat":
179 gochat(account
, params
)
180 elif command
.lower() == "addbuddy":
181 addbuddy(account
, screenname
, params
.get("group", ""))
184 protocol
= "prpl-irc"
185 match
= re
.match(r
"^irc:(//([^/]*)/)?([^?]*)(\?(.*))?", uri
)
187 print "Invalid irc URI: %s" % uri
190 server
= urllib
.unquote_plus(match
.group(2)) or ""
191 target
= match
.group(3) or ""
192 query
= match
.group(5) or ""
196 for modifier
in target
.split(",")[1:]:
197 modifiers
[modifier
] = True
199 isnick
= modifiers
.has_key("isnick")
201 paramstring
= match
.group(5)
204 for param
in paramstring
.split("&"):
205 key
, value
= extendlist(param
.split("=", 1), 2, "")
206 params
[key
] = urllib
.unquote_plus(value
)
208 def correct_server(account
):
209 username
= cpurple
.PurpleAccountGetUsername(account
)
210 return ("@" in username
) and (server
== (username
.split("@"))[1])
212 account
= findaccount(protocol
, matcher
=correct_server
)
216 goim(account
, urllib
.unquote_plus(target
.split(",")[0]), params
.get("msg"))
218 channel
= urllib
.unquote_plus(target
.split(",")[0])
219 if channel
[0] != "#":
220 channel
= "#" + channel
221 gochat(account
, {"server": server
, "channel": channel
, "password": params
.get("key", "")}, params
.get("msg"))
224 protocol
= "prpl-msn"
225 match
= re
.match(r
"^msnim:([^?]*)(\?(.*))", uri
)
227 print "Invalid msnim URI: %s" % uri
230 command
= urllib
.unquote_plus(match
.group(1))
231 paramstring
= match
.group(3)
234 for param
in paramstring
.split("&"):
235 key
, value
= extendlist(param
.split("=", 1), 2, "")
236 params
[key
] = urllib
.unquote_plus(value
)
237 screenname
= params
.get("contact", "")
239 account
= findaccount(protocol
)
241 if command
.lower() == "chat":
242 goim(account
, screenname
)
243 elif command
.lower() == "add":
244 addbuddy(account
, screenname
)
247 protocol
= "prpl-myspace"
248 print "TODO: send uri: ", uri
249 assert False, "Not implemented"
252 protocol
= "prpl-simple"
253 match
= re
.match(r
"^sip:(.*)", uri
)
255 print "Invalid sip URI: %s" % uri
258 screenname
= urllib
.unquote_plus(match
.group(1))
259 account
= findaccount(protocol
)
260 goim(account
, screenname
)
263 protocol
= "prpl-jabber"
264 match
= re
.match(r
"^xmpp:(//([^/?#]*)/?)?([^?#]*)(\?([^;#]*)(;([^#]*))?)?(#(.*))?", uri
)
266 print "Invalid xmpp URI: %s" % uri
271 accountname
= urllib
.unquote_plus(tmp
)
275 screenname
= urllib
.unquote_plus(match
.group(3))
279 command
= urllib
.unquote_plus(tmp
)
283 paramstring
= match
.group(7)
286 for param
in paramstring
.split(";"):
287 key
, value
= extendlist(param
.split("=", 1), 2, "")
288 params
[key
] = urllib
.unquote_plus(value
)
290 account
= findaccount(protocol
, accountname
)
292 if command
.lower() == "message":
293 goim(account
, screenname
, params
.get("body"))
294 elif command
.lower() == "join":
295 room
, server
= screenname
.split("@")
296 gochat(account
, {"room": room
, "server": server
})
297 elif command
.lower() == "roster":
298 addbuddy(account
, screenname
, params
.get("group", ""), params
.get("name", ""))
300 goim(account
, screenname
)
303 protocol
= "prpl-jabber"
304 match
= re
.match(r
"^gtalk:([^?]*)(\?(.*))", uri
)
306 print "Invalid gtalk URI: %s" % uri
309 command
= urllib
.unquote_plus(match
.group(1))
310 paramstring
= match
.group(3)
313 for param
in paramstring
.split("&"):
314 key
, value
= extendlist(param
.split("=", 1), 2, "")
315 params
[key
] = urllib
.unquote_plus(value
)
316 accountname
= params
.get("from_jid", "")
317 jid
= params
.get("jid", "")
319 account
= findaccount(protocol
, accountname
)
321 if command
.lower() == "chat":
323 elif command
.lower() == "call":
324 # XXX V&V prompt to establish call
328 protocol
= "prpl-yahoo"
329 match
= re
.match(r
"^ymsgr:([^?]*)(\?([^&]*)(&(.*))?)", uri
)
331 print "Invalid ymsgr URI: %s" % uri
334 command
= urllib
.unquote_plus(match
.group(1))
335 screenname
= urllib
.unquote_plus(match
.group(3))
336 paramstring
= match
.group(5)
339 for param
in paramstring
.split("&"):
340 key
, value
= extendlist(param
.split("=", 1), 2, "")
341 params
[key
] = urllib
.unquote_plus(value
)
343 account
= findaccount(protocol
)
345 if command
.lower() == "sendim":
346 goim(account
, screenname
, params
.get("m"))
347 elif command
.lower() == "chat":
348 gochat(account
, {"room": screenname
})
349 elif command
.lower() == "addfriend":
350 addbuddy(account
, screenname
)
353 def main(argv
=sys
.argv
):
354 if len(argv
) != 2 or argv
[1] == "--help" or argv
[1] == "-h":
355 print "Usage: %s URI" % argv
[0]
356 print "Example: %s \"xmpp:romeo@montague.net?message\"" % argv
[0]
364 type = uri
.split(":")[0]
375 elif type == "msnim":
383 elif type == "gtalk":
385 elif type == "ymsgr":
388 print "Unknown protocol: %s" % type
389 except dbus
.DBusException
, e
:
390 print "Error: %s" % (e
.message
)
393 if __name__
== "__main__":