Mercurial > pidgin.yaz
view libpurple/purple-url-handler @ 30673:e1b511df0d3e
Make the combobox a tiny bit friendlier.
Pressing the first letter of an item will now jump to that item (and
popup the dropdown first if necessary). Add some API in libgnt in the
process.
author | Sadrul Habib Chowdhury <imadil@gmail.com> |
---|---|
date | Mon, 05 Jul 2010 15:01:56 +0000 |
parents | 971b89243a20 |
children | adef21420870 |
line wrap: on
line source
#!/usr/bin/env python import dbus import re import sys import time import urllib bus = dbus.SessionBus() obj = None try: obj = bus.get_object("im.pidgin.purple.PurpleService", "/im/pidgin/purple/PurpleObject") except dbus.DBusException, e: if e._dbus_error_name == "org.freedesktop.DBus.Error.ServiceUnknown": print "Error: no libpurple-powered client is running. Try starting Pidgin or Finch." sys.exit(1) 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 account_not_found(): print "No matching account found." sys.exit(1) def bring_account_online(account): if not cpurple.PurpleAccountIsConnected(account): # The last argument is meant to be a GList * but the D-Bus binding # generator thing just wants a UInt32, which is pretty failing. # Happily, passing a 0 to mean an empty list turns out to work anyway. purple.PurpleAccountSetStatusList(account, "online", 1, 0) purple.PurpleAccountConnect(account) def findaccount(protocolname, accountname="", matcher=None): if matcher: for account in cpurple.PurpleAccountsGetAll(): if accountname != "" and accountname != cpurple.PurpleAccountGetUsername(a): continue if matcher(account): bring_account_online(account) return account account_not_found() # 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): account_not_found() bring_account_online(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) def correct_server(account): username = cpurple.PurpleAccountGetUsername(account) return ("@" in username) and (server == (username.split("@"))[1]) account = findaccount(protocol, matcher=correct_server) 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 myim(uri): protocol = "prpl-myspace" print "TODO: send uri: ", uri assert False, "Not implemented" 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 gtalk(uri): protocol = "prpl-jabber" match = re.match(r"^gtalk:([^?]*)(\?(.*))", uri) if not match: print "Invalid gtalk 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("from_jid", "") jid = params.get("jid", "") account = findaccount(protocol, accountname) if command.lower() == "chat": goim(account, jid) elif command.lower() == "call": # XXX V&V prompt to establish call goim(account, jid) 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 or argv[1] == "--help" or argv[1] == "-h": print "Usage: %s URI" % argv[0] print "Example: %s \"xmpp:romeo@montague.net?message\"" % argv[0] if len(argv) != 2: sys.exit(1) else: return 0 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 == "myim": myim(uri) elif type == "sip": sip(uri) elif type == "xmpp": xmpp(uri) elif type == "gtalk": gtalk(uri) elif type == "ymsgr": ymsgr(uri) else: print "Unknown protocol: %s" % type except dbus.DBusException, e: print "Error: %s" % (e.message) sys.exit(1) if __name__ == "__main__": main()