pidgin/pidgin

1966704b3e42
file isExecutable
merge of '77693555855fe9cd3215414f79964dba346cc5fa'
and '19a87e98e5857ad0289f2c760d460f7f1dbbb42d'
#!/usr/bin/python
import dbus
import re
import urllib
import sys
import xml.dom.minidom
xml.dom.minidom.Element.all = xml.dom.minidom.Element.getElementsByTagName
obj = dbus.SessionBus().get_object("net.sf.gaim.GaimService", "/net/sf/gaim/GaimObject")
gaim = dbus.Interface(obj, "net.sf.gaim.GaimInterface")
class CheckedObject:
def __init__(self, obj):
self.obj = obj
def __getattr__(self, attr):
return CheckedAttribute(self, attr)
class CheckedAttribute:
def __init__(self, cobj, attr):
self.cobj = cobj
self.attr = attr
def __call__(self, *args):
result = self.cobj.obj.__getattr__(self.attr)(*args)
if result == 0:
raise "Error: " + self.attr + " " + str(args) + " returned " + str(result)
return result
cgaim = CheckedObject(gaim)
urlregexp = r"^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?"
def extendlist(list, length, fill):
if len(list) < length:
return list + [fill] * (length - len(list))
else:
return list
def convert(value):
try:
return int(value)
except:
return value
def findaccount(accountname, protocolname):
try:
# prefer connected accounts
account = cgaim.GaimAccountsFindConnected(accountname, protocolname)
return account
except:
# try to get any account and connect it
account = cgaim.GaimAccountsFindAny(accountname, protocolname)
gaim.GaimAccountSetStatusVargs(account, "online", 1)
gaim.GaimAccountConnect(account)
return account
def execute(uri):
match = re.match(urlregexp, uri)
protocol = match.group(2)
if protocol == "aim" or protocol == "icq":
protocol = "oscar"
if protocol is not None:
protocol = "prpl-" + protocol
command = match.group(5)
paramstring = match.group(7)
params = {}
if paramstring is not None:
for param in paramstring.split("&"):
key, value = extendlist(param.split("=",1), 2, "")
params[key] = urllib.unquote(value)
accountname = params.get("account", "")
if command == "goim":
account = findaccount(accountname, protocol)
conversation = cgaim.GaimConversationNew(1, account, params["screenname"])
if "message" in params:
im = cgaim.GaimConversationGetImData(conversation)
gaim.GaimConvImSend(im, params["message"])
return None
elif command == "gochat":
account = findaccount(accountname, protocol)
connection = cgaim.GaimAccountGetConnection(account)
return gaim.ServJoinChat(connection, params)
elif command == "addbuddy":
account = findaccount(accountname, protocol)
return cgaim.GaimBlistRequestAddBuddy(account, params["screenname"],
params.get("group", ""), "")
elif command == "setstatus":
current = gaim.GaimSavedstatusGetCurrent()
if "status" in params:
status_id = params["status"]
status_type = gaim.GaimPrimitiveGetTypeFromId(status_id)
else:
status_type = gaim.GaimSavedstatusGetType(current)
status_id = gaim.GaimPrimitiveGetIdFromType(status_type)
if "message" in params:
message = params["message"];
else:
message = gaim.GaimSavedstatusGetMessage(current)
if "account" in params:
accounts = [cgaim.GaimAccountsFindAny(accountname, protocol)]
for account in accounts:
status = gaim.GaimAccountGetStatus(account, status_id)
type = gaim.GaimStatusGetType(status)
gaim.GaimSavedstatusSetSubstatus(current, account, type, message)
gaim.GaimSavedstatusActivateForAccount(current, account)
else:
accounts = gaim.GaimAccountsGetAllActive()
saved = gaim.GaimSavedstatusNew("", status_type)
gaim.GaimSavedstatusSetMessage(saved, message)
gaim.GaimSavedstatusActivate(saved)
return None
elif command == "getinfo":
account = findaccount(accountname, protocol)
connection = cgaim.GaimAccountGetConnection(account)
return gaim.ServGetInfo(connection, params["screenname"])
elif command == "quit":
return gaim.GaimCoreQuit()
elif command == "uri":
return None
else:
match = re.match(r"(\w+)\s*\(([^)]*)\)", command)
if match is not None:
name = match.group(1)
argstr = match.group(2)
if argstr == "":
args = []
else:
args = argstr.split(",")
fargs = []
for arg in args:
fargs.append(convert(arg.strip()))
return gaim.__getattr__(name)(*fargs)
else:
# introspect the object to get parameter names and types
# this is slow because the entire introspection info must be downloaded
data = dbus.Interface(obj, "org.freedesktop.DBus.Introspectable").\
Introspect()
introspect = xml.dom.minidom.parseString(data).documentElement
for method in introspect.all("method"):
if command == method.getAttribute("name"):
methodparams = []
for arg in method.all("arg"):
if arg.getAttribute("direction") == "in":
value = params[arg.getAttribute("name")]
type = arg.getAttribute("type")
if type == "s":
methodparams.append(value)
elif type == "i":
methodparams.append(int(value))
else:
raise "Don't know how to handle type \"%s\"" % type
return gaim.__getattr__(command)(*methodparams)
raise "Unknown command: %s" % command
if len(sys.argv) == 1:
print """This program uses DBus to communicate with gaim.
Usage:
%s "command1" "command2" ...
Each command is of one of the three types:
[protocol:]commandname?param1=value1&param2=value2&...
FunctionName?param1=value1&param2=value2&...
FunctionName(value1,value2,...)
The second and third form are provided for completeness but their use
is not recommended; use gaim-send or gaim-send-async instead. The
second form uses introspection to find out the parameter names and
their types, therefore it is rather slow.
Examples of commands:
jabber:goim?screenname=testone@localhost&message=hi
jabber:gochat?room=TestRoom&server=conference.localhost
jabber:getinfo?screenname=testone@localhost
jabber:addbuddy?screenname=my friend
setstatus?status=away&message=don't disturb
quit
GaimAccountsFindConnected?name=&protocol=prpl-jabber
GaimAccountFindConnected(,prpl-jabber)
""" % sys.argv[0]
for arg in sys.argv[1:]:
output = execute(arg)
if (output != None):
print output