home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/python
-
- import dbus
- import re
- import sys
- import time
- import urllib
-
- obj = dbus.SessionBus().get_object("im.pidgin.purple.PurpleService", "/im/pidgin/purple/PurpleObject")
- purple = dbus.Interface(obj, "im.pidgin.purple.PurpleInterface")
-
- 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):
- # Redirect stderr to suppress the printing of an " Introspect error"
- # message if nothing is listening on the bus. We print a friendly
- # error message ourselves.
- real_stderr = sys.stderr
- sys.stderr = None
- result = self.cobj.obj.__getattr__(self.attr)(*args)
- sys.stderr = real_stderr
-
- # This can be useful for debugging.
- # if (result == 0):
- # print "Error: " + self.attr + " " + str(args) + " returned " + str(result)
-
- return result
-
- cpurple = CheckedObject(purple)
-
- 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(protocolname, accountname=""):
- # prefer connected accounts
- account = cpurple.PurpleAccountsFindConnected(accountname, protocolname)
- if (account != 0):
- return account
-
- # try to get any account and connect it
- account = cpurple.PurpleAccountsFindAny(accountname, protocolname)
- if (account == 0):
- print "No matching account found."
- sys.exit(1)
-
- purple.PurpleAccountSetStatusVargs(account, "online", 1)
- purple.PurpleAccountConnect(account)
- return account
-
- def goim(account, screenname, message=None):
- # XXX: 1 == PURPLE_CONV_TYPE_IM
- conversation = cpurple.PurpleConversationNew(1, account, screenname)
- if message:
- purple.PurpleConvSendConfirm(conversation, message)
-
- def gochat(account, params, message=None):
- connection = cpurple.PurpleAccountGetConnection(account)
- purple.ServJoinChat(connection, params)
-
- if message != None:
- for i in range(20):
- # XXX: 2 == PURPLE_CONV_TYPE_CHAT
- conversation = purple.PurpleFindConversationWithAccount(2, params.get("channel", params.get("room")), account)
- if conversation:
- purple.PurpleConvSendConfirm(conversation, message)
- break
- else:
- time.sleep(0.5)
-
- def addbuddy(account, screenname, group="", alias=""):
- cpurple.PurpleBlistRequestAddBuddy(account, screenname, group, alias)
-
-
- def aim(uri):
- protocol = "prpl-aim"
- match = re.match(r"^aim:([^?]*)(\?(.*))", uri)
- if not match:
- print "Invalid aim URI: %s" % uri
- return
-
- command = urllib.unquote_plus(match.group(1))
- paramstring = match.group(3)
- params = {}
- if paramstring:
- for param in paramstring.split("&"):
- key, value = extendlist(param.split("=", 1), 2, "")
- params[key] = urllib.unquote_plus(value)
- accountname = params.get("account", "")
- screenname = params.get("screenname", "")
-
- account = findaccount(protocol, accountname)
-
- if command.lower() == "goim":
- goim(account, screenname, params.get("message"))
- elif command.lower() == "gochat":
- gochat(account, params)
- elif command.lower() == "addbuddy":
- addbuddy(account, screenname, params.get("group", ""))
-
- def gg(uri):
- protocol = "prpl-gg"
- match = re.match(r"^gg:(.*)", uri)
- if not match:
- print "Invalid gg URI: %s" % uri
- return
-
- screenname = urllib.unquote_plus(match.group(1))
- account = findaccount(protocol)
- goim(account, screenname)
-
- def icq(uri):
- protocol = "prpl-icq"
- match = re.match(r"^icq:([^?]*)(\?(.*))", uri)
- if not match:
- print "Invalid icq URI: %s" % uri
- return
-
- command = urllib.unquote_plus(match.group(1))
- paramstring = match.group(3)
- params = {}
- if paramstring:
- for param in paramstring.split("&"):
- key, value = extendlist(param.split("=", 1), 2, "")
- params[key] = urllib.unquote_plus(value)
- accountname = params.get("account", "")
- screenname = params.get("screenname", "")
-
- account = findaccount(protocol, accountname)
-
- if command.lower() == "goim":
- goim(account, screenname, params.get("message"))
- elif command.lower() == "gochat":
- gochat(account, params)
- elif command.lower() == "addbuddy":
- addbuddy(account, screenname, params.get("group", ""))
-
- def irc(uri):
- protocol = "prpl-irc"
- match = re.match(r"^irc:(//([^/]*)/)?([^?]*)(\?(.*))?", uri)
- if not match:
- print "Invalid irc URI: %s" % uri
- return
-
- server = urllib.unquote_plus(match.group(2)) or ""
- target = match.group(3) or ""
- query = match.group(5) or ""
-
- modifiers = {}
- if target:
- for modifier in target.split(",")[1:]:
- modifiers[modifier] = True
-
- isnick = modifiers.has_key("isnick")
-
- paramstring = match.group(5)
- params = {}
- if paramstring:
- for param in paramstring.split("&"):
- key, value = extendlist(param.split("=", 1), 2, "")
- params[key] = urllib.unquote_plus(value)
-
- account = findaccount(protocol)
-
- if (target != ""):
- if (isnick):
- goim(account, urllib.unquote_plus(target.split(",")[0]), params.get("msg"))
- else:
- channel = urllib.unquote_plus(target.split(",")[0])
- if channel[0] != "#":
- channel = "#" + channel
- gochat(account, {"server": server, "channel": channel, "password": params.get("key", "")}, params.get("msg"))
-
- def msnim(uri):
- protocol = "prpl-msn"
- match = re.match(r"^msnim:([^?]*)(\?(.*))", uri)
- if not match:
- print "Invalid msnim URI: %s" % uri
- return
-
- command = urllib.unquote_plus(match.group(1))
- paramstring = match.group(3)
- params = {}
- if paramstring:
- for param in paramstring.split("&"):
- key, value = extendlist(param.split("=", 1), 2, "")
- params[key] = urllib.unquote_plus(value)
- screenname = params.get("contact", "")
-
- account = findaccount(protocol)
-
- if command.lower() == "chat":
- goim(account, screenname)
- elif command.lower() == "add":
- addbuddy(account, screenname)
-
- def sip(uri):
- protocol = "prpl-simple"
- match = re.match(r"^sip:(.*)", uri)
- if not match:
- print "Invalid sip URI: %s" % uri
- return
-
- screenname = urllib.unquote_plus(match.group(1))
- account = findaccount(protocol)
- goim(account, screenname)
-
- def xmpp(uri):
- protocol = "prpl-jabber"
- match = re.match(r"^xmpp:(//([^/?#]*)/?)?([^?#]*)(\?([^;#]*)(;([^#]*))?)?(#(.*))?", uri)
- if not match:
- print "Invalid xmpp URI: %s" % uri
- return
-
- tmp = match.group(2)
- if (tmp):
- accountname = urllib.unquote_plus(tmp)
- else:
- accountname = ""
-
- screenname = urllib.unquote_plus(match.group(3))
-
- tmp = match.group(5)
- if (tmp):
- command = urllib.unquote_plus(tmp)
- else:
- command = ""
-
- paramstring = match.group(7)
- params = {}
- if paramstring:
- for param in paramstring.split(";"):
- key, value = extendlist(param.split("=", 1), 2, "")
- params[key] = urllib.unquote_plus(value)
-
- account = findaccount(protocol, accountname)
-
- if command.lower() == "message":
- goim(account, screenname, params.get("body"))
- elif command.lower() == "join":
- room, server = screenname.split("@")
- gochat(account, {"room": room, "server": server})
- elif command.lower() == "roster":
- addbuddy(account, screenname, params.get("group", ""), params.get("name", ""))
- else:
- goim(account, screenname)
-
- def ymsgr(uri):
- protocol = "prpl-yahoo"
- match = re.match(r"^ymsgr:([^?]*)(\?([^&]*)(&(.*))?)", uri)
- if not match:
- print "Invalid ymsgr URI: %s" % uri
- return
-
- command = urllib.unquote_plus(match.group(1))
- screenname = urllib.unquote_plus(match.group(3))
- paramstring = match.group(5)
- params = {}
- if paramstring:
- for param in paramstring.split("&"):
- key, value = extendlist(param.split("=", 1), 2, "")
- params[key] = urllib.unquote_plus(value)
-
- account = findaccount(protocol)
-
- if command.lower() == "sendim":
- goim(account, screenname, params.get("m"))
- elif command.lower() == "chat":
- gochat(account, {"room": screenname})
- elif command.lower() == "addfriend":
- addbuddy(account, screenname)
-
-
- def main(argv=sys.argv):
- if len(argv) != 2:
- print "Usage: %s URI" % argv[0]
- print "Example: %s \"xmpp:romeo@montague.net?message\"" % argv[0]
- return
-
- uri = argv[1]
- type = uri.split(":")[0]
-
- try:
- if type == "aim":
- aim(uri)
- elif type == "gg":
- gg(uri)
- elif type == "icq":
- icq(uri)
- elif type == "irc":
- irc(uri)
- elif type == "msnim":
- msnim(uri)
- elif type == "sip":
- sip(uri)
- elif type == "xmpp":
- xmpp(uri)
- elif type == "ymsgr":
- ymsgr(uri)
- else:
- print "Unkown protocol: %s" % type
- except dbus.dbus_bindings.DBusException:
- print "ERROR: Is there a libpurple-powered client (e.g. Pidgin or Finch) running?"
-
-
- if __name__ == "__main__":
- main()
-