Partial support for reading ICQ 6 status notes. The status note will
show up next to the person's name in the buddy list, but only if they
don't have another status message set.
This is from Collin from ComBOTS GmbH. Fixes #3208.
line source
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 #!/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 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 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 == "myim":
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 myim(uri)
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 elif type == "sip":
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 sip(uri)
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 elif type == "xmpp":
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmpp(uri)
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 elif type == "ymsgr":
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 ymsgr(uri)
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 else:
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 print "Unknown 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()