11 sys
.stdin
= codecs
.getwriter('utf-8')(sys
.stdin
);
12 sys
.stdout
= codecs
.getwriter('utf-8')(sys
.stdout
);
14 xml
.dom
.minidom
.Element
.all
= xml
.dom
.minidom
.Element
.getElementsByTagName
18 obj
= dbus
.SessionBus().get_object("im.pidgin.purple.PurpleService", "/im/pidgin/purple/PurpleObject")
22 purple
= dbus
.Interface(obj
, "im.pidgin.purple.PurpleInterface")
25 def __init__(self
, obj
):
28 def __getattr__(self
, attr
):
29 return CheckedAttribute(self
, attr
)
31 class CheckedAttribute
:
32 def __init__(self
, cobj
, attr
):
36 def __call__(self
, *args
):
37 result
= self
.cobj
.obj
.__getattr
__(self
.attr
)(*args
)
39 raise Exception("Error: %s %s returned %s" %
40 (self
.attr
, args
, result
))
43 def show_help(requested
=False):
44 print """This program uses D-Bus to communicate with purple.
48 %s "command1" "command2" ...
50 Each command is of one of the three types:
52 [protocol:]commandname?param1=value1¶m2=value2&...
53 FunctionName?param1=value1¶m2=value2&...
54 FunctionName(value1,value2,...)
56 The second and third form are provided for completeness but their use
57 is not recommended; use purple-send or purple-send-async instead. The
58 second form uses introspection to find out the parameter names and
59 their types, therefore it is rather slow.
63 jabber:goim?screenname=testone@localhost&message=hi
64 jabber:gochat?room=TestRoom&server=conference.localhost
65 jabber:getinfo?screenname=testone@localhost
66 jabber:addbuddy?screenname=my friend
68 setstatus?status=away&message=don't disturb
73 PurpleAccountsFindConnected?name=&protocol=prpl-jabber
74 PurpleAccountsFindConnected(,prpl-jabber)
81 cpurple
= CheckedObject(purple
)
83 urlregexp
= r
"^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?"
85 def extendlist(list, length
, fill
):
86 if len(list) < length
:
87 return list + [fill
] * (length
- len(list))
97 def findaccount(accountname
, protocolname
):
99 # prefer connected accounts
100 account
= cpurple
.PurpleAccountsFindConnected(accountname
, protocolname
)
103 # try to get any account and connect it
104 account
= cpurple
.PurpleAccountsFindAny(accountname
, protocolname
)
105 purple
.PurpleAccountSetStatusVargs(account
, "online", 1)
106 purple
.PurpleAccountConnect(account
)
111 match
= re
.match(urlregexp
, uri
)
112 protocol
= match
.group(2)
113 if protocol
== "xmpp":
115 if protocol
is not None:
116 protocol
= "prpl-" + protocol
117 command
= match
.group(5)
118 paramstring
= match
.group(7)
120 if paramstring
is not None:
121 for param
in paramstring
.split("&"):
122 key
, value
= extendlist(param
.split("=",1), 2, "")
123 params
[key
] = urllib
.unquote(value
)
125 accountname
= params
.get("account", "")
127 if command
== "goim":
128 account
= findaccount(accountname
, protocol
)
129 conversation
= cpurple
.PurpleConversationNew(1, account
, params
["screenname"])
130 if "message" in params
:
131 im
= cpurple
.PurpleConversationGetImData(conversation
)
132 purple
.PurpleConvImSend(im
, params
["message"])
135 elif command
== "gochat":
136 account
= findaccount(accountname
, protocol
)
137 connection
= cpurple
.PurpleAccountGetConnection(account
)
138 return purple
.ServJoinChat(connection
, params
)
140 elif command
== "addbuddy":
141 account
= findaccount(accountname
, protocol
)
142 return cpurple
.PurpleBlistRequestAddBuddy(account
, params
["screenname"],
143 params
.get("group", ""), "")
145 elif command
== "setstatus":
146 current
= purple
.PurpleSavedstatusGetCurrent()
148 if "status" in params
:
149 status_id
= params
["status"]
150 status_type
= purple
.PurplePrimitiveGetTypeFromId(status_id
)
152 status_type
= purple
.PurpleSavedstatusGetType(current
)
153 status_id
= purple
.PurplePrimitiveGetIdFromType(status_type
)
155 if "message" in params
:
156 message
= params
["message"];
158 message
= purple
.PurpleSavedstatusGetMessage(current
)
160 if "account" in params
:
161 accounts
= [cpurple
.PurpleAccountsFindAny(accountname
, protocol
)]
163 for account
in accounts
:
164 status
= purple
.PurpleAccountGetStatus(account
, status_id
)
165 type = purple
.PurpleStatusGetType(status
)
166 purple
.PurpleSavedstatusSetSubstatus(current
, account
, type, message
)
167 purple
.PurpleSavedstatusActivateForAccount(current
, account
)
169 saved
= purple
.PurpleSavedstatusNew("", status_type
)
170 purple
.PurpleSavedstatusSetMessage(saved
, message
)
171 purple
.PurpleSavedstatusActivate(saved
)
175 elif command
== "getstatus":
176 current
= purple
.PurpleSavedstatusGetCurrent()
177 status_type
= purple
.PurpleSavedstatusGetType(current
)
178 status_id
= purple
.PurplePrimitiveGetIdFromType(status_type
)
181 elif command
== "getstatusmessage":
182 current
= purple
.PurpleSavedstatusGetCurrent()
183 return purple
.PurpleSavedstatusGetMessage(current
)
185 elif command
== "getinfo":
186 account
= findaccount(accountname
, protocol
)
187 connection
= cpurple
.PurpleAccountGetConnection(account
)
188 return purple
.ServGetInfo(connection
, params
["screenname"])
190 elif command
== "quit":
191 return purple
.PurpleCoreQuit()
193 elif command
== "uri":
197 match
= re
.match(r
"(\w+)\s*\(([^)]*)\)", command
)
198 if match
is not None:
199 name
= match
.group(1)
200 argstr
= match
.group(2)
204 args
= argstr
.split(",")
207 fargs
.append(convert(arg
.strip()))
208 return purple
.__getattr
__(name
)(*fargs
)
210 # introspect the object to get parameter names and types
211 # this is slow because the entire introspection info must be downloaded
212 data
= dbus
.Interface(obj
, "org.freedesktop.DBus.Introspectable").\
214 introspect
= xml
.dom
.minidom
.parseString(data
).documentElement
215 for method
in introspect
.all("method"):
216 if command
== method
.getAttribute("name"):
218 for arg
in method
.all("arg"):
219 if arg
.getAttribute("direction") == "in":
220 value
= params
[arg
.getAttribute("name")]
221 type = arg
.getAttribute("type")
223 methodparams
.append(value
)
225 methodparams
.append(int(value
))
227 raise Exception("Don't know how to handle type \"%s\"" % type)
228 return purple
.__getattr
__(command
)(*methodparams
)
231 if len(sys
.argv
) == 1:
233 elif (sys
.argv
[1] == "--help" or sys
.argv
[1] == "-h"):
236 print "No existing libpurple instance detected."
239 for arg
in sys
.argv
[1:]:
240 output
= execute(arg
)