|
13765
|
1 #!/usr/bin/python
|
|
|
2
|
|
|
3 import dbus
|
|
|
4 import re
|
|
|
5 import urllib
|
|
|
6 import sys
|
|
|
7
|
|
|
8 import xml.dom.minidom
|
|
|
9
|
|
|
10 xml.dom.minidom.Element.all = xml.dom.minidom.Element.getElementsByTagName
|
|
|
11
|
|
|
12 obj = dbus.SessionBus().get_object("net.sf.gaim.GaimService", "/net/sf/gaim/GaimObject")
|
|
|
13 gaim = dbus.Interface(obj, "net.sf.gaim.GaimInterface")
|
|
|
14
|
|
|
15 class CheckedObject:
|
|
|
16 def __init__(self, obj):
|
|
|
17 self.obj = obj
|
|
|
18
|
|
|
19 def __getattr__(self, attr):
|
|
|
20 return CheckedAttribute(self, attr)
|
|
|
21
|
|
|
22 class CheckedAttribute:
|
|
|
23 def __init__(self, cobj, attr):
|
|
|
24 self.cobj = cobj
|
|
|
25 self.attr = attr
|
|
|
26
|
|
|
27 def __call__(self, *args):
|
|
|
28 result = self.cobj.obj.__getattr__(self.attr)(*args)
|
|
|
29 if result == 0:
|
|
|
30 raise "Error: " + self.attr + " " + str(args) + " returned " + str(result)
|
|
|
31 return result
|
|
|
32
|
|
|
33 cgaim = CheckedObject(gaim)
|
|
|
34
|
|
|
35 urlregexp = r"^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?"
|
|
|
36
|
|
|
37 def extendlist(list, length, fill):
|
|
|
38 if len(list) < length:
|
|
|
39 return list + [fill] * (length - len(list))
|
|
|
40 else:
|
|
|
41 return list
|
|
|
42
|
|
|
43 def convert(value):
|
|
|
44 try:
|
|
|
45 return int(value)
|
|
|
46 except:
|
|
|
47 return value
|
|
|
48
|
|
|
49 def findaccount(accountname, protocolname):
|
|
|
50 try:
|
|
|
51 # prefer connected accounts
|
|
|
52 account = cgaim.GaimAccountsFindConnected(accountname, protocolname)
|
|
|
53 return account
|
|
|
54 except:
|
|
|
55 # try to get any account and connect it
|
|
|
56 account = cgaim.GaimAccountsFindAny(accountname, protocolname)
|
|
|
57 print gaim.GaimAccountGetUsername(account)
|
|
|
58 gaim.GaimAccountSetStatusVargs(account, "online", 1)
|
|
|
59 gaim.GaimAccountConnect(account)
|
|
|
60 return account
|
|
|
61
|
|
|
62
|
|
|
63 def execute(uri):
|
|
|
64 match = re.match(urlregexp, uri)
|
|
|
65 protocol = match.group(2)
|
|
|
66 if protocol == "aim" or protocol == "icq":
|
|
|
67 protocol = "oscar"
|
|
|
68 if protocol is not None:
|
|
|
69 protocol = "prpl-" + protocol
|
|
|
70 command = match.group(5)
|
|
|
71 paramstring = match.group(7)
|
|
|
72 params = {}
|
|
|
73 if paramstring is not None:
|
|
|
74 for param in paramstring.split("&"):
|
|
|
75 key, value = extendlist(param.split("=",1), 2, "")
|
|
|
76 params[key] = urllib.unquote(value)
|
|
|
77
|
|
|
78 accountname = params.get("account", "")
|
|
|
79
|
|
|
80 if command == "goim":
|
|
|
81 print params
|
|
|
82 account = findaccount(accountname, protocol)
|
|
|
83 conversation = cgaim.GaimConversationNew(1, account, params["screenname"])
|
|
|
84 if "message" in params:
|
|
|
85 im = cgaim.GaimConversationGetImData(conversation)
|
|
|
86 gaim.GaimConvImSend(im, params["message"])
|
|
|
87 return None
|
|
|
88
|
|
|
89 elif command == "gochat":
|
|
|
90 account = findaccount(accountname, protocol)
|
|
|
91 connection = cgaim.GaimAccountGetConnection(account)
|
|
|
92 return gaim.ServJoinChat(connection, params)
|
|
|
93
|
|
|
94 elif command == "addbuddy":
|
|
|
95 account = findaccount(accountname, protocol)
|
|
|
96 return cgaim.GaimBlistRequestAddBuddy(account, params["screenname"],
|
|
|
97 params.get("group", ""), "")
|
|
|
98
|
|
|
99 elif command == "setstatus":
|
|
|
100 current = gaim.GaimSavedstatusGetCurrent()
|
|
|
101
|
|
|
102 if "status" in params:
|
|
|
103 status_id = params["status"]
|
|
|
104 status_type = gaim.GaimPrimitiveGetTypeFromId(status_id)
|
|
|
105 else:
|
|
|
106 status_type = gaim.GaimSavedStatusGetType(current)
|
|
|
107 status_id = gaim.GaimPrimitiveGetIdFromType(status_type)
|
|
|
108
|
|
|
109 if "message" in params:
|
|
|
110 message = params["message"];
|
|
|
111 else:
|
|
|
112 message = gaim.GaimSavedstatusGetMessage(current)
|
|
|
113
|
|
|
114 if "account" in params:
|
|
|
115 accounts = [cgaim.GaimAccountsFindAny(accountname, protocol)]
|
|
|
116
|
|
|
117 for account in accounts:
|
|
|
118 status = gaim.GaimAccountGetStatus(account, status_id)
|
|
|
119 type = gaim.GaimStatusGetType(status)
|
|
|
120 gaim.GaimSavedstatusSetSubstatus(current, account, type, message)
|
|
|
121 gaim.GaimSavedstatusActivateForAccount(current, account)
|
|
|
122 else:
|
|
|
123 accounts = gaim.GaimAccountsGetAllActive()
|
|
|
124 saved = gaim.GaimSavedstatusNew("", status_type)
|
|
|
125 gaim.GaimSavedstatusSetMessage(saved, message)
|
|
|
126 gaim.GaimSavedstatusActivate(saved)
|
|
|
127
|
|
|
128 return None
|
|
|
129
|
|
|
130 elif command == "getinfo":
|
|
|
131 account = findaccount(accountname, protocol)
|
|
|
132 connection = cgaim.GaimAccountGetConnection(account)
|
|
|
133 return gaim.ServGetInfo(connection, params["screenname"])
|
|
|
134
|
|
|
135 elif command == "quit":
|
|
|
136 return gaim.GaimCoreQuit()
|
|
|
137
|
|
|
138 elif command == "uri":
|
|
|
139 return None
|
|
|
140
|
|
|
141 else:
|
|
|
142 match = re.match(r"(\w+)\s*\(([^)]*)\)", command)
|
|
|
143 if match is not None:
|
|
|
144 name = match.group(1)
|
|
|
145 argstr = match.group(2)
|
|
|
146 if argstr == "":
|
|
|
147 args = []
|
|
|
148 else:
|
|
|
149 args = argstr.split(",")
|
|
|
150 fargs = []
|
|
|
151 for arg in args:
|
|
|
152 fargs.append(convert(arg.strip()))
|
|
|
153 return gaim.__getattr__(name)(*fargs)
|
|
|
154 else:
|
|
|
155 # introspect the object to get parameter names and types
|
|
|
156 # this is slow because the entire introspection info must be downloaded
|
|
|
157 data = dbus.Interface(obj, "org.freedesktop.DBus.Introspectable").\
|
|
|
158 Introspect()
|
|
|
159 introspect = xml.dom.minidom.parseString(data).documentElement
|
|
|
160 for method in introspect.all("method"):
|
|
|
161 if command == method.getAttribute("name"):
|
|
|
162 methodparams = []
|
|
|
163 for arg in method.all("arg"):
|
|
|
164 if arg.getAttribute("direction") == "in":
|
|
|
165 value = params[arg.getAttribute("name")]
|
|
|
166 type = arg.getAttribute("type")
|
|
|
167 if type == "s":
|
|
|
168 methodparams.append(value)
|
|
|
169 elif type == "i":
|
|
|
170 methodparams.append(int(value))
|
|
|
171 else:
|
|
|
172 raise "Don't know how to handle type \"%s\"" % type
|
|
|
173 return gaim.__getattr__(command)(*methodparams)
|
|
|
174 raise "Unknown command: %s" % command
|
|
|
175
|
|
|
176
|
|
|
177 if len(sys.argv) == 1:
|
|
|
178 print """This program uses DBus to communicate with gaim.
|
|
|
179
|
|
|
180 Usage:
|
|
|
181
|
|
|
182 %s "command1" "command2" ...
|
|
|
183
|
|
|
184 Each command is of one of the three types:
|
|
|
185
|
|
|
186 [protocol:]commandname?param1=value1¶m2=value2&...
|
|
|
187 FunctionName?param1=value1¶m2=value2&...
|
|
|
188 FunctionName(value1,value2,...)
|
|
|
189
|
|
|
190 The second and third form are provided for completeness but their use
|
|
|
191 is not recommended; use gaim-send or gaim-send-async instead. The
|
|
|
192 second form uses introspection to find out the parameter names and
|
|
|
193 their types, therefore it is rather slow.
|
|
|
194
|
|
|
195 Examples of commands:
|
|
|
196
|
|
|
197 jabber:goim?screenname=testone@localhost&message=hi
|
|
|
198 jabber:gochat?room=TestRoom&server=conference.localhost
|
|
|
199 jabber:getinfo?screenname=testone@localhost
|
|
|
200 jabber:addbuddy?screenname=my friend
|
|
|
201
|
|
|
202 setstatus?status=away&message=don't disturb
|
|
|
203 quit
|
|
|
204
|
|
|
205 GaimAccountsFindConnected?name=&protocol=prpl-jabber
|
|
|
206 GaimAccountFindConnected(,prpl-jabber)
|
|
|
207 """ % sys.argv[0]
|
|
|
208
|
|
|
209 for arg in sys.argv[1:]:
|
|
|
210 print execute(arg)
|
|
|
211
|
|
|
212
|