]> code.delx.au - pymsnt/blobdiff - src/main.py
Added SVN version number to result from jabber:iq:version requests.
[pymsnt] / src / main.py
index f4f80f93c0f81ed52f4c36d1835903c873c09682..6be4c742b811403765ba08a646d28df013c6f307 100644 (file)
@@ -6,6 +6,31 @@ reload(sys)
 sys.setdefaultencoding("utf-8")
 sys.stdout = codecs.lookup('utf-8')[-1](sys.stdout)
 
+# Find the best reactor
+selectWarning = "Unable to install any good reactors (kqueue, epoll, poll).\nWe fell back to using select. You may have scalability problems.\nThis reactor will not support more than 1024 connections at a time."
+try:
+       from twisted.internet import epollreactor as bestreactor
+except:
+       try:
+               from twisted.internet import kqreactor as bestreactor
+       except:
+               try:
+                       from twisted.internet import pollreactor as bestreactor
+               except:
+                       try:
+                               from twisted.internet import selectreactor as bestreactor
+                               print selectWarning
+                       except:
+                               try:
+                                       from twisted.internet import default as bestreactor
+                                       print selectWarning
+                               except:
+                                       print "Unable to find a reactor.\nExiting..."
+                                       sys.exit(1)
+bestreactor.install()
+
+
+
 # Must load config before everything else
 import config
 import xmlconfig
@@ -16,7 +41,7 @@ for o, v in opts:
        if o in ("-c", "--config"):
                configFile = v
        elif o in ("-b", "--background"):
-               config.daemonise = True
+               config.background = True
        elif o in ("-d", "--debug"):
                config.debugLevel = "2"
        elif o in ("-D", "--Debug"):
@@ -49,19 +74,20 @@ for o, v in opts:
 
 xmlconfig.reloadConfig(configFile, configOptions)
 
-del sys.modules["twisted.internet.reactor"]
-# Choose a reactor
-if config.reactor == "epoll":
-       from twisted.internet import epollreactor
-       epollreactor.install()
-elif config.reactor == "poll":
-       from twisted.internet import pollreactor
-       pollreactor.install()
-elif config.reactor == "kqueue":
-       from twisted.internet import kqreactor
-       kqreactor.install()
-elif len(config.reactor) > 0:
-       print "Unknown reactor: ", config.reactor, ". Using default, select(), reactor."
+if config.reactor:
+       # They picked their own reactor. Lets install it.
+       del sys.modules["twisted.internet.reactor"]
+       if config.reactor == "epoll":
+               from twisted.internet import epollreactor
+               epollreactor.install()
+       elif config.reactor == "poll":
+               from twisted.internet import pollreactor
+               pollreactor.install()
+       elif config.reactor == "kqueue":
+               from twisted.internet import kqreactor
+               kqreactor.install()
+       elif len(config.reactor) > 0:
+               print "Unknown reactor: ", config.reactor, ". Using select(), reactor."
 
 
 from twisted.internet import reactor, task
@@ -70,6 +96,7 @@ from tlib.xmlw import Element, jid, component
 from debug import LogEvent, INFO, WARN, ERROR
 
 import debug
+import svninfo
 import utils
 import xdb
 import avatar
@@ -88,13 +115,18 @@ import housekeep
 class PyTransport(component.Service):
        def __init__(self):
                LogEvent(INFO)
+               try:
+                       LogEvent(INFO, msg="SVN r" + svninfo.getSVNVersion())
+               except:
+                       pass
 
                # Discovery, as well as some builtin features
                self.discovery = disco.ServerDiscovery(self)
-               self.discovery.addIdentity("gateway", legacy.id, legacy.name, config.jid)
-               self.discovery.addIdentity("conference", "text", legacy.name + " Chatrooms", config.jid)
+               self.discovery.addIdentity("gateway", legacy.id, config.discoName, config.jid)
+               self.discovery.addIdentity("conference", "text", config.discoName + " Chatrooms", config.jid)
                self.discovery.addFeature(disco.XCONFERENCE, None, config.jid) # So that clients know you can create groupchat rooms on the server
                self.discovery.addFeature("jabber:iq:conference", None, config.jid) # We don't actually support this, but Psi has a bug where it looks for this instead of the above
+               self.discovery.addIdentity("client", "pc", "MSN Messenger", "USER")
                
                self.xdb = xdb.XDB(config.jid, legacy.mangle)
                self.avatarCache = avatar.AvatarCache()
@@ -125,8 +157,8 @@ class PyTransport(component.Service):
                # Message IDs
                self.messageID = 0
                
-               self.loopCall = task.LoopingCall(self.loopCall)
-               self.loopCall.start(60.0)
+               self.loopTask = task.LoopingCall(self.loopFunc)
+               self.loopTask.start(60.0)
 
        def removeMe(self):
                LogEvent(INFO)
@@ -149,7 +181,7 @@ class PyTransport(component.Service):
        def reserveID(self, ID):
                self.reservedIDs.append(ID)
        
-       def loopCall(self):
+       def loopFunc(self):
                numsessions = len(self.sessions)
 
                #if config.debugOn and numsessions > 0:
@@ -164,12 +196,12 @@ class PyTransport(component.Service):
                        oldDict = self.sessions.copy()
                        self.sessions = {}
                        for key in oldDict:
-                               session = oldDict[key]
-                               if not session.alive:
+                               s = oldDict[key]
+                               if not s.alive:
                                        LogEvent(WARN, "", "Ghost session found.")
                                        # Don't add it to the new dictionary. Effectively removing it
                                else:
-                                       self.sessions[key] = session
+                                       self.sessions[key] = s
        
        def componentConnected(self, xmlstream):
                LogEvent(INFO)
@@ -213,8 +245,12 @@ class PyTransport(component.Service):
                        LogEvent(WARN, "", "Failed stringprep.")
                        return
                mtype = el.getAttribute("type")
-               if self.sessions.has_key(froj.userhost()):
-                       self.sessions[froj.userhost()].onMessage(el)
+               s = self.sessions.get(froj.userhost(), None)
+               if mtype == "error" and s:
+                       LogEvent(INFO, s.jabberID, "Removing session because of message type=error")
+                       s.removeMe()
+               elif s:
+                       s.onMessage(el)
                elif mtype != "error":
                        to = el.getAttribute("to")
                        ulang = utils.getLang(el)
@@ -235,8 +271,13 @@ class PyTransport(component.Service):
                        LogEvent(WARN, "", "Failed stringprep.")
                        return
 
-               if self.sessions.has_key(froj.userhost()):
-                       self.sessions[froj.userhost()].onPresence(el)
+               ptype = el.getAttribute("type")
+               s = self.sessions.get(froj.userhost())
+               if ptype == "error" and s:
+                       LogEvent(INFO, s.jabberID, "Removing session because of message type=error")
+                       s.removeMe()
+               elif s:
+                       s.onPresence(el)
                else:
                        ulang = utils.getLang(el)
                        ptype = el.getAttribute("type")
@@ -316,10 +357,6 @@ class App:
                pf.write("%s\n" % pid)
                pf.close()
 
-       def alreadyRunning(self):
-               sys.__stdout__.write("There is already a transport instance running with this configuration.\nExiting...\n\n")
-               sys.exit(1)
-       
        def shuttingDown(self):
                self.transportSvc.removeMe()
                # Keep the transport running for another 3 seconds