home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2007 September / PCWSEP07.iso / Software / Linux / Linux Mint 3.0 Light / LinuxMint-3.0-Light.iso / casper / filesystem.squashfs / usr / bin / purple-url-handler < prev    next >
Encoding:
Text File  |  2007-05-04  |  9.4 KB  |  326 lines

  1. #!/usr/bin/python
  2.  
  3. import dbus
  4. import re
  5. import sys
  6. import time
  7. import urllib
  8.  
  9. obj = dbus.SessionBus().get_object("im.pidgin.purple.PurpleService", "/im/pidgin/purple/PurpleObject")
  10. purple = dbus.Interface(obj, "im.pidgin.purple.PurpleInterface")
  11.  
  12. class CheckedObject:
  13.     def __init__(self, obj):
  14.         self.obj = obj
  15.  
  16.     def __getattr__(self, attr):
  17.         return CheckedAttribute(self, attr)
  18.  
  19. class CheckedAttribute:
  20.     def __init__(self, cobj, attr):
  21.         self.cobj = cobj
  22.         self.attr = attr
  23.  
  24.     def __call__(self, *args):
  25.         # Redirect stderr to suppress the printing of an " Introspect error"
  26.         # message if nothing is listening on the bus.  We print a friendly
  27.         # error message ourselves.
  28.         real_stderr = sys.stderr
  29.         sys.stderr = None
  30.         result = self.cobj.obj.__getattr__(self.attr)(*args)
  31.         sys.stderr = real_stderr
  32.  
  33. # This can be useful for debugging.
  34. #        if (result == 0):
  35. #            print "Error: " + self.attr + " " + str(args) + " returned " + str(result)
  36.  
  37.         return result
  38.  
  39. cpurple = CheckedObject(purple)
  40.  
  41. def extendlist(list, length, fill):
  42.     if len(list) < length:
  43.         return list + [fill] * (length - len(list))
  44.     else:
  45.         return list
  46.  
  47. def convert(value):
  48.     try:
  49.         return int(value)
  50.     except:
  51.         return value
  52.  
  53. def findaccount(protocolname, accountname=""):
  54.     # prefer connected accounts
  55.     account = cpurple.PurpleAccountsFindConnected(accountname, protocolname)
  56.     if (account != 0):
  57.     return account
  58.  
  59.     # try to get any account and connect it
  60.     account = cpurple.PurpleAccountsFindAny(accountname, protocolname)
  61.     if (account == 0):
  62.         print "No matching account found."
  63.     sys.exit(1)
  64.  
  65.     purple.PurpleAccountSetStatusVargs(account, "online", 1)
  66.     purple.PurpleAccountConnect(account)
  67.     return account
  68.  
  69. def goim(account, screenname, message=None):
  70.     # XXX: 1 == PURPLE_CONV_TYPE_IM
  71.     conversation = cpurple.PurpleConversationNew(1, account, screenname)
  72.     if message:
  73.         purple.PurpleConvSendConfirm(conversation, message)
  74.  
  75. def gochat(account, params, message=None):
  76.     connection = cpurple.PurpleAccountGetConnection(account)
  77.     purple.ServJoinChat(connection, params)
  78.  
  79.     if message != None:
  80.         for i in range(20):
  81.             # XXX: 2 == PURPLE_CONV_TYPE_CHAT
  82.             conversation = purple.PurpleFindConversationWithAccount(2, params.get("channel", params.get("room")), account)
  83.             if conversation:
  84.                 purple.PurpleConvSendConfirm(conversation, message)
  85.                 break
  86.             else:
  87.                 time.sleep(0.5)
  88.  
  89. def addbuddy(account, screenname, group="", alias=""):
  90.     cpurple.PurpleBlistRequestAddBuddy(account, screenname, group, alias)
  91.  
  92.  
  93. def aim(uri):
  94.     protocol = "prpl-aim"
  95.     match = re.match(r"^aim:([^?]*)(\?(.*))", uri)
  96.     if not match:
  97.         print "Invalid aim URI: %s" % uri
  98.         return
  99.  
  100.     command = urllib.unquote_plus(match.group(1))
  101.     paramstring = match.group(3)
  102.     params = {}
  103.     if paramstring:
  104.         for param in paramstring.split("&"):
  105.             key, value = extendlist(param.split("=", 1), 2, "")
  106.             params[key] = urllib.unquote_plus(value)
  107.     accountname = params.get("account", "")
  108.     screenname = params.get("screenname", "")
  109.  
  110.     account = findaccount(protocol, accountname)
  111.  
  112.     if command.lower() == "goim":
  113.         goim(account, screenname, params.get("message"))
  114.     elif command.lower() == "gochat":
  115.         gochat(account, params)
  116.     elif command.lower() == "addbuddy":
  117.         addbuddy(account, screenname, params.get("group", ""))
  118.  
  119. def gg(uri):
  120.     protocol = "prpl-gg"
  121.     match = re.match(r"^gg:(.*)", uri)
  122.     if not match:
  123.         print "Invalid gg URI: %s" % uri
  124.         return
  125.  
  126.     screenname = urllib.unquote_plus(match.group(1))
  127.     account = findaccount(protocol)
  128.     goim(account, screenname)
  129.  
  130. def icq(uri):
  131.     protocol = "prpl-icq"
  132.     match = re.match(r"^icq:([^?]*)(\?(.*))", uri)
  133.     if not match:
  134.         print "Invalid icq URI: %s" % uri
  135.         return
  136.  
  137.     command = urllib.unquote_plus(match.group(1))
  138.     paramstring = match.group(3)
  139.     params = {}
  140.     if paramstring:
  141.         for param in paramstring.split("&"):
  142.             key, value = extendlist(param.split("=", 1), 2, "")
  143.             params[key] = urllib.unquote_plus(value)
  144.     accountname = params.get("account", "")
  145.     screenname = params.get("screenname", "")
  146.  
  147.     account = findaccount(protocol, accountname)
  148.  
  149.     if command.lower() == "goim":
  150.         goim(account, screenname, params.get("message"))
  151.     elif command.lower() == "gochat":
  152.         gochat(account, params)
  153.     elif command.lower() == "addbuddy":
  154.         addbuddy(account, screenname, params.get("group", ""))
  155.  
  156. def irc(uri):
  157.     protocol = "prpl-irc"
  158.     match = re.match(r"^irc:(//([^/]*)/)?([^?]*)(\?(.*))?", uri)
  159.     if not match:
  160.         print "Invalid irc URI: %s" % uri
  161.         return
  162.  
  163.     server = urllib.unquote_plus(match.group(2)) or ""
  164.     target = match.group(3) or ""
  165.     query = match.group(5) or ""
  166.  
  167.     modifiers = {}
  168.     if target:
  169.         for modifier in target.split(",")[1:]:
  170.             modifiers[modifier] = True
  171.  
  172.     isnick = modifiers.has_key("isnick")
  173.  
  174.     paramstring = match.group(5)
  175.     params = {}
  176.     if paramstring:
  177.         for param in paramstring.split("&"):
  178.             key, value = extendlist(param.split("=", 1), 2, "")
  179.             params[key] = urllib.unquote_plus(value)
  180.  
  181.     account = findaccount(protocol)
  182.  
  183.     if (target != ""):
  184.         if (isnick):
  185.             goim(account, urllib.unquote_plus(target.split(",")[0]), params.get("msg"))
  186.     else:
  187.             channel = urllib.unquote_plus(target.split(",")[0])
  188.             if channel[0] != "#":
  189.                 channel = "#" + channel
  190.             gochat(account, {"server": server, "channel": channel, "password": params.get("key", "")}, params.get("msg"))
  191.  
  192. def msnim(uri):
  193.     protocol = "prpl-msn"
  194.     match = re.match(r"^msnim:([^?]*)(\?(.*))", uri)
  195.     if not match:
  196.         print "Invalid msnim URI: %s" % uri
  197.         return
  198.  
  199.     command = urllib.unquote_plus(match.group(1))
  200.     paramstring = match.group(3)
  201.     params = {}
  202.     if paramstring:
  203.         for param in paramstring.split("&"):
  204.             key, value = extendlist(param.split("=", 1), 2, "")
  205.             params[key] = urllib.unquote_plus(value)
  206.     screenname = params.get("contact", "")
  207.  
  208.     account = findaccount(protocol)
  209.  
  210.     if command.lower() == "chat":
  211.         goim(account, screenname)
  212.     elif command.lower() == "add":
  213.         addbuddy(account, screenname)
  214.  
  215. def sip(uri):
  216.     protocol = "prpl-simple"
  217.     match = re.match(r"^sip:(.*)", uri)
  218.     if not match:
  219.         print "Invalid sip URI: %s" % uri
  220.         return
  221.  
  222.     screenname = urllib.unquote_plus(match.group(1))
  223.     account = findaccount(protocol)
  224.     goim(account, screenname)
  225.  
  226. def xmpp(uri):
  227.     protocol = "prpl-jabber"
  228.     match = re.match(r"^xmpp:(//([^/?#]*)/?)?([^?#]*)(\?([^;#]*)(;([^#]*))?)?(#(.*))?", uri)
  229.     if not match:
  230.         print "Invalid xmpp URI: %s" % uri
  231.         return
  232.  
  233.     tmp = match.group(2)
  234.     if (tmp):
  235.         accountname = urllib.unquote_plus(tmp)
  236.     else:
  237.         accountname = ""
  238.  
  239.     screenname = urllib.unquote_plus(match.group(3))
  240.  
  241.     tmp = match.group(5)
  242.     if (tmp):
  243.         command = urllib.unquote_plus(tmp)
  244.     else:
  245.         command = ""
  246.  
  247.     paramstring = match.group(7)
  248.     params = {}
  249.     if paramstring:
  250.         for param in paramstring.split(";"):
  251.             key, value = extendlist(param.split("=", 1), 2, "")
  252.             params[key] = urllib.unquote_plus(value)
  253.  
  254.     account = findaccount(protocol, accountname)
  255.  
  256.     if command.lower() == "message":
  257.         goim(account, screenname, params.get("body"))
  258.     elif command.lower() == "join":
  259.         room, server = screenname.split("@")
  260.         gochat(account, {"room": room, "server": server})
  261.     elif command.lower() == "roster":
  262.         addbuddy(account, screenname, params.get("group", ""), params.get("name", ""))
  263.     else:
  264.         goim(account, screenname)
  265.  
  266. def ymsgr(uri):
  267.     protocol = "prpl-yahoo"
  268.     match = re.match(r"^ymsgr:([^?]*)(\?([^&]*)(&(.*))?)", uri)
  269.     if not match:
  270.         print "Invalid ymsgr URI: %s" % uri
  271.         return
  272.  
  273.     command = urllib.unquote_plus(match.group(1))
  274.     screenname = urllib.unquote_plus(match.group(3))
  275.     paramstring = match.group(5)
  276.     params = {}
  277.     if paramstring:
  278.         for param in paramstring.split("&"):
  279.             key, value = extendlist(param.split("=", 1), 2, "")
  280.             params[key] = urllib.unquote_plus(value)
  281.  
  282.     account = findaccount(protocol)
  283.  
  284.     if command.lower() == "sendim":
  285.         goim(account, screenname, params.get("m"))
  286.     elif command.lower() == "chat":
  287.         gochat(account, {"room": screenname})
  288.     elif command.lower() == "addfriend":
  289.         addbuddy(account, screenname)
  290.  
  291.  
  292. def main(argv=sys.argv):
  293.     if len(argv) != 2:
  294.         print "Usage: %s URI" % argv[0]
  295.         print "Example: %s \"xmpp:romeo@montague.net?message\"" % argv[0]
  296.         return
  297.  
  298.     uri = argv[1]
  299.     type = uri.split(":")[0]
  300.  
  301.     try:
  302.         if type == "aim":
  303.             aim(uri)
  304.         elif type == "gg":
  305.             gg(uri)
  306.         elif type == "icq":
  307.             icq(uri)
  308.         elif type == "irc":
  309.             irc(uri)
  310.         elif type == "msnim":
  311.             msnim(uri)
  312.         elif type == "sip":
  313.             sip(uri)
  314.         elif type == "xmpp":
  315.             xmpp(uri)
  316.         elif type == "ymsgr":
  317.             ymsgr(uri)
  318.         else:
  319.             print "Unkown protocol: %s" % type
  320.     except dbus.dbus_bindings.DBusException:
  321.         print "ERROR: Is there a libpurple-powered client (e.g. Pidgin or Finch) running?"
  322.  
  323.  
  324. if __name__ == "__main__":
  325.     main()
  326.