]> jfr.im git - irc/quakenet/qwebirc.git/blobdiff - qwebirc/ircclient.py
Merge soczol's patch from https://bitbucket.org/soczol/qwebirc/changeset/450739e6defd
[irc/quakenet/qwebirc.git] / qwebirc / ircclient.py
index 744e62923bb5c43f581a49188e2ea83ffc34f6bf..f517430fccb5efe12919c5b4487d5c64458ba715 100644 (file)
@@ -1,12 +1,19 @@
-import twisted, sys, codecs
+import twisted, sys, codecs, traceback
 from twisted.words.protocols import irc
-from twisted.internet import reactor, protocol
+from twisted.internet import reactor, protocol, abstract
 from twisted.web import resource, server
 from twisted.protocols import basic
-
-import hmac, time, config
+from twisted.names.client import Resolver
+import hmac, time, config, random, qwebirc.config_options as config_options
 from config import HMACTEMPORAL
-HMACKEY = hmac.HMAC(key=config.HMACKEY)
+
+if config.get("CONNECTION_RESOLVER"):
+  CONNECTION_RESOLVER = Resolver(servers=config.get("CONNECTION_RESOLVER"))
+else:
+  CONNECTION_RESOLVER = None
+
+if hasattr(config, "WEBIRC_MODE") and config.WEBIRC_MODE == "hmac":
+  HMACKEY = hmac.HMAC(key=config.HMACKEY)
 
 def hmacfn(*args):
   h = HMACKEY.copy()
@@ -39,8 +46,10 @@ class QWebIRCClient(basic.LineReceiver):
       prefix, command, params = irc.parsemsg(line)
       self.handleCommand(command, prefix, params)
     except irc.IRCBadMessage:
-      self.badMessage(line, *sys.exc_info())
-      
+      # emit and ignore
+      traceback.print_exc()
+      return
+
     if command == "001":
       self.__nickname = params[0]
       
@@ -53,9 +62,6 @@ class QWebIRCClient(basic.LineReceiver):
       if nick == self.__nickname:
         self.__nickname = params[0]
         
-  def badMessage(self, args):
-    self("badmessage", args)
-  
   def handleCommand(self, command, prefix, params):
     self("c", command, prefix, params)
     
@@ -70,12 +76,31 @@ class QWebIRCClient(basic.LineReceiver):
     
     self.lastError = None
     f = self.factory.ircinit
-    nick, ident, ip, realname = f["nick"], f["ident"], f["ip"], f["realname"]
+    nick, ident, ip, realname, hostname, pass_ = f["nick"], f["ident"], f["ip"], f["realname"], f["hostname"], f.get("password")
     self.__nickname = nick
     self.__perform = f.get("perform")
-    
-    hmac = hmacfn(ident, ip)
-    self.write("USER %s bleh bleh %s %s :%s" % (ident, ip, hmac, realname))
+
+    if not hasattr(config, "WEBIRC_MODE"):
+      self.write("USER %s bleh bleh %s :%s" % (ident, ip, realname))
+    elif config.WEBIRC_MODE == "hmac":
+      hmac = hmacfn(ident, ip)
+      self.write("USER %s bleh bleh %s %s :%s" % (ident, ip, hmac, realname))
+    elif config.WEBIRC_MODE == "webirc":
+      self.write("WEBIRC %s qwebirc %s %s" % (config.WEBIRC_PASSWORD, hostname, ip))
+      self.write("USER %s bleh %s :%s" % (ident, ip, realname))
+    elif config.WEBIRC_MODE == "cgiirc":
+      self.write("PASS %s_%s_%s" % (config.CGIIRC_STRING, ip, hostname))
+      self.write("USER %s bleh %s :%s" % (ident, ip, realname))
+    elif config.WEBIRC_MODE == config_options.WEBIRC_REALNAME or config.WEBIRC_MODE is None: # last bit is legacy
+      if ip == hostname:
+        dispip = ip
+      else:
+        dispip = "%s/%s" % (hostname, ip)
+
+      self.write("USER %s bleh bleh :%s - %s" % (ident, dispip, realname))
+
+    if pass_ is not None:
+      self.write("PASS :%s" % pass_)
     self.write("NICK %s" % nick)
     
     self.factory.client = self
@@ -121,9 +146,25 @@ class QWebIRCFactory(protocol.ClientFactory):
 
 def createIRC(*args, **kwargs):
   f = QWebIRCFactory(*args, **kwargs)
-  reactor.connectTCP(config.IRCSERVER, config.IRCPORT, f)
+  
+  tcpkwargs = {}
+  if hasattr(config, "OUTGOING_IP"):
+    tcpkwargs["bindAddress"] = (config.OUTGOING_IP, 0)
+  
+  if CONNECTION_RESOLVER is None:
+    reactor.connectTCP(config.IRCSERVER, config.IRCPORT, f, **tcpkwargs)
+    return f
+
+  def callback(result):
+    name, port = random.choice(sorted((str(x.payload.target), x.payload.port) for x in result[0]))
+    reactor.connectTCP(name, port, f, **tcpkwargs)
+  def errback(err):
+    f.clientConnectionFailed(None, err) # None?!
+
+  d = CONNECTION_RESOLVER.lookupService(config.IRCSERVER, (1, 3, 11))
+  d.addCallbacks(callback, errback)
   return f
 
 if __name__ == "__main__":
-  e = createIRC(lambda x: 2, nick="slug__moo", ident="mooslug", ip="1.2.3.6", realname="mooooo")
+  e = createIRC(lambda x: 2, nick="slug__moo", ident="mooslug", ip="1.2.3.6", realname="mooooo", hostname="1.2.3.4")
   reactor.run()