]> code.delx.au - pymsnt/commitdiff
Moved presence probe to session.py
authorjamesbunton <jamesbunton@55fbd22a-6204-0410-b2f0-b6c764c7e90a>
Thu, 26 Jan 2006 01:50:09 +0000 (01:50 +0000)
committerjamesbunton <jamesbunton@55fbd22a-6204-0410-b2f0-b6c764c7e90a>
Thu, 26 Jan 2006 01:50:09 +0000 (01:50 +0000)
Fixed bug with personal messages.
Moved default avatar images to a data dir.
Switch to using twisted.scripts.twistd code for daemonising and pid file
Cleaned up config-example.xml
Fixed GETALLAVATARS option so it works again.

git-svn-id: http://delx.cjb.net/svn/pymsnt/trunk@104 55fbd22a-6204-0410-b2f0-b6c764c7e90a

committer: jamesbunton <jamesbunton@55fbd22a-6204-0410-b2f0-b6c764c7e90a>

config-example.xml
data/defaultJabberAvatar.png [moved from src/legacy/defaultJabberAvatar.png with 100% similarity]
data/defaultMSNAvatar.png [moved from src/legacy/defaultAvatar.png with 100% similarity]
src/jabw.py
src/legacy/glue.py
src/main.py
src/session.py
src/tlib/msn/__init__.py
src/tlib/msn/msn.py
src/tlib/msn/msnw.py

index c25dcc3e237ac92b2588777626a81ee3eee67007..e8092696483cb16469f98537ddd11d7dbf8b77d7 100644 (file)
@@ -17,22 +17,24 @@ Do not include the jid of the transport -->
 <pid>PyMSNt.pid</pid>
 <!-- If set, the transport will background itself when run -->
 <background/>
+<!-- The Twisted reactor to choose. Pick poll or epoll on Linux, kqueue on BSD. Or leave as default (select) -->
+<!-- <reactor>poll</reactor> -->
 
 
 <!-- The IP address of the main Jabber server to connect to -->
 <mainServer>127.0.0.1</mainServer>
-<!-- The website of the Jabber service -->
-<website>http://host.com</website>
 <!-- The TCP port to connect to the Jabber server on (this is the default for Jabberd2) -->
 <port>5347</port>
 <!-- The authentication token to use when connecting to the Jabber server -->
 <secret>secret</secret>
-<!-- The Twisted reactor to choose. Pick poll or epoll on Linux, kqueue on BSD. Or leave as default (select) -->
-<!-- <reactor>poll</reactor> -->
+<!-- Use Jabber.com's XCP component protocol extensions. --> 
+<!-- <useXCP/> -->
 
 
 <!-- The default language to use -->
 <lang>en</lang>
+<!-- The website of the Jabber service -->
+<website>http://host.com</website>
 
 
 <!-- Comment out the following options to disable them, or uncomment them to enable them -->
@@ -46,8 +48,6 @@ Do not include the jid of the transport -->
 <allowRegister/>
 <!-- Get all avatars. If this is set to true then avatars are grabbed for all your contacts immediately. If false then avatars are only grabbed when you're in a chat with a contact -->
 <getAllAvatars/>
-<!-- Use Jabber.com's XCP component protocol extensions. --> 
-<!-- <useXCP/> -->
 
 
 <!-- File transfer settings -->
@@ -74,6 +74,6 @@ Do not include the jid of the transport -->
 <!-- <debugLevel>0</debugLevel> -->
 
 <!-- The file to log to. Leave this disabled for stdout -->
-<!-- <debugFile>debug.log</debugLog> -->
+<!-- <debugFile>debug.log</debugFile> -->
 
 </pymsnt>
index f063cefa2e12d4d55a8d308272d71d2e4cdca0e1..ec2904fe608143e891716aaefa8eb63cb6361546 100644 (file)
@@ -253,9 +253,6 @@ class JabberConnection:
                if ptype and (ptype.startswith("subscribe") or ptype.startswith("unsubscribe")):
                        LogEvent(INFO, self.jabberID, "Parsed subscription presence packet")
                        self.subscriptionReceived(toj.userhost(), ptype)
-               elif ptype == "probe":
-                       LogEvent(INFO, self.jabberID, "Parsed presence probe")
-                       self.contactList.getContact(toj.userhost()).sendPresence(fro)
                else:
                        status = None
                        show = None
index 67b788f949dbe74cd6523a092e0e75cc6d3a7f8c..4c06e0a15eea22ab6a058bc8cbf70a6fee365d36 100644 (file)
@@ -1,13 +1,13 @@
 # Copyright 2004-2005 James Bunton <james@delx.cjb.net>
 # Licensed for distribution under the GPL version 2, check COPYING for details
 
+import os.path
 import utils
 from twisted.internet import task
 from tlib.xmlw import Element
 from tlib import msn
 from debug import LogEvent, INFO, WARN, ERROR
 import disco
-import sha
 import groupchat
 import ft
 import avatar
@@ -25,18 +25,18 @@ id = "msn"               # The transport identifier
 
 
 # Load the default avatars
-f = open("src/legacy/defaultJabberAvatar.png")
+f = open(os.path.join("data", "defaultJabberAvatar.png"))
 defaultJabberAvatarData = f.read()
 f.close()
 
-f = open("src/legacy/defaultAvatar.png")
+f = open(os.path.join("data", "defaultMSNAvatar.png"))
 defaultAvatarData = f.read()
 f.close()
 defaultAvatar = avatar.AvatarCache().setAvatar(defaultAvatarData)
 
 
 def reloadConfig():
-       msn.GETALLAVATARS = config.getAllAvatars
+       msn.MSNConnection.GETALLAVATARS = config.getAllAvatars
 
 def isGroupJID(jid):
        """ Returns True if the JID passed is a valid groupchat JID (for MSN, does not contain '%') """
index 598d245acd4f7e54c32512694c4264bcc3da62ac..f4f80f93c0f81ed52f4c36d1835903c873c09682 100644 (file)
@@ -11,7 +11,7 @@ import config
 import xmlconfig
 configFile = "config.xml"
 configOptions = {}
-opts, args = getopt.getopt(sys.argv[1:], "bc:o:dDgtl:h", ["background", "config=", "option=", "debug", "Debug", "garbage", "traceback", "log=", "help"])
+opts, args = getopt.getopt(sys.argv[1:], "bc:o:dDgtlp:h", ["background", "config=", "option=", "debug", "Debug", "garbage", "traceback", "log=", "pid=", "help"])
 for o, v in opts:
        if o in ("-c", "--config"):
                configFile = v
@@ -28,6 +28,8 @@ for o, v in opts:
                config.debugLevel = "1"
        elif o in ("-l", "--log"):
                config.debugFile = v
+       elif o in ("-p", "--pid"):
+               config.pid = v
        elif o in ("-o", "--option"):
                var, setting = v.split("=", 2)
                configOptions[var] = setting
@@ -41,6 +43,7 @@ for o, v in opts:
                print "   -g                  print garbage collection output"
                print "   -t                  print debugging only on traceback"
                print "   -l <file>           write debugging output to file"
+               print "   -p <file>           write process ID to file"
                print "   -o <var>=<setting>  set config var to setting"
                sys.exit(0)
 
@@ -278,15 +281,17 @@ class PyTransport(component.Service):
 class App:
        def __init__(self):
                # Check for any other instances
+               if config.pid and os.name != "posix":
+                       config.pid = ""
                if config.pid:
-                       self.checkPID()
+                       twistd.checkPID(config.pid)
 
                # Do any auto-update stuff
                housekeep.init()
                
                # Daemonise the process and write the PID file
-               if config.background:
-                       self.daemonise()
+               if config.background and os.name == "posix":
+                       twistd.daemonize()
                if config.pid:
                        self.writePID()
 
@@ -304,21 +309,6 @@ class App:
                self.c.startService()
                reactor.addSystemEventTrigger('before', 'shutdown', self.shuttingDown)
        
-       def checkPID(self):
-               # Check that we're not already running
-               if os.path.isfile(config.pid):
-                       if os.name == "posix":
-                               pf = open(config.pid)
-                               pid = int(str(pf.readline().strip()))
-                               pf.close()
-                               try:
-                                       os.kill(pid, signal.SIGHUP)
-                                       self.alreadyRunning()
-                               except OSError:
-                                       pass
-                       else:
-                               self.alreadyRunning()
-       
        def writePID(self):
                # Create a PID file
                pid = str(os.getpid())
@@ -330,21 +320,12 @@ class App:
                sys.__stdout__.write("There is already a transport instance running with this configuration.\nExiting...\n\n")
                sys.exit(1)
        
-       def daemonise(self):
-               try:
-                       pid = os.fork()
-                       if pid > 0:
-                               sys.exit(0)
-               except OSError, e:
-                       sys.stderr.write("Daemonise failed: (%d) %s\n" % (e.errno, e.strerror))
-                       sys.exit(1)
-
        def shuttingDown(self):
                self.transportSvc.removeMe()
                # Keep the transport running for another 3 seconds
                def cb(ignored=None):
                        if config.pid:
-                               os.remove(config.pid)
+                               twistd.removePID(config.pid)
                d = Deferred()
                d.addCallback(cb)
                reactor.callLater(3.0, d.callback, None)
@@ -355,6 +336,8 @@ class App:
 def SIGHUPstuff(*args):
        global configFile, configOptions
        xmlconfig.reloadConfig(configFile, configOptions)
+       if config.pid and os.name != "posix":
+               config.pid = ""
        debug.reloadConfig()
        legacy.reloadConfig()
 
@@ -362,6 +345,8 @@ if os.name == "posix":
        import signal
        # Set SIGHUP to reload the config file & close & open debug file
        signal.signal(signal.SIGHUP, SIGHUPstuff)
+       # Load some scripts for PID and daemonising
+       from twisted.scripts import twistd
 
 
 def main():
index 22c00c0a543ac596b37ac91c69e8c4bbe5a949fc..57e7ff449640e23c008e2eed613afcd246ec8623 100644 (file)
@@ -264,6 +264,9 @@ class Session(jabw.JabberConnection):
                        groupchat = legacy.LegacyGroupchat(self, resource, gcID) # Creates an empty groupchat
                        groupchat.userJoined(tor)
                
+               elif ptype == "probe":
+                       LogEvent(INFO, self.jabberID, "Responding to presence probe")
+                       self.contactList.getContact(toj.userhost()).sendPresence(fro)
                else:
                        # Not for groupchat
                        self.handleResourcePresence(source, resource, to, tor, priority, ptype, show, status)
index f4870c5c6503eeee802f6fc709a04ee711099485..edc622ab29b900cf56446584be1107438cd63f18 100644 (file)
@@ -1,4 +1,4 @@
-from msnw import MSNConnection, MultiSwitchboardSession, GETALLAVATARS
+from msnw import MSNConnection, MultiSwitchboardSession
 from msn import FORWARD_LIST, ALLOW_LIST, BLOCK_LIST, REVERSE_LIST, PENDING_LIST
 from msn import STATUS_ONLINE, STATUS_OFFLINE, STATUS_HIDDEN, STATUS_IDLE, STATUS_AWAY, STATUS_BUSY, STATUS_BRB, STATUS_PHONE, STATUS_LUNCH
 from msn import MSNContact, MSNContactList
index cc665ad8b984ee4ba4a123dcd98f69aa37b506d8..0e82e6f65cd126f4a5e659b7b749bbb4ecec185e 100644 (file)
@@ -1045,16 +1045,17 @@ class NotificationClient(MSNEventBase):
         self.gotMSNAlert(bodytext, actionurl, subscrurl)
 
     def _gotUBX(self, message):
+        msnContact = self.factory.contacts.getContact(message.userHandle)
+        if not msnContact: return
         lm = message.message.lower()
         p1 = lm.find("<psm>") + 5
         p2 = lm.find("</psm>")
         if p1 >= 0 and p2 >= 0:
             personal = unescapeFromXml(message.message[p1:p2])
-            msnContact = self.factory.contacts.getContact(message.userHandle)
-            if not msnContact: return
             msnContact.personal = personal
             self.contactPersonalChanged(message.userHandle, personal)
         else:
+            msnContact.personal = ''
             self.contactPersonalChanged(message.userHandle, '')
 
     def checkMessage(self, message):
@@ -1368,7 +1369,7 @@ class NotificationClient(MSNEventBase):
             self.currentMessage = MSNMessage(length=messageLen, userHandle=params[0], screenName="UBX", specialMessage=True)
             self.setRawMode()
         else:
-            self.contactPersonalChanged(params[0], '')
+            self._gotUBX(MSNMessage(userHandle=params[0]))
 
     def handle_UUX(self, params):
         checkParamLen(len(params), 2, 'UUX')
index ace11f148c4e9f471dec9877f4fb316ebdfbdcd2..d0e132f338ed14e9751ba1ec2dc053c291eb938c 100644 (file)
@@ -14,10 +14,6 @@ from debug import LogEvent, INFO, WARN, ERROR
 from tlib.msn import msn
 
 
-MAXMESSAGESIZE     = 1400
-SWITCHBOARDTIMEOUT = 30.0*60.0
-GETALLAVATARS      = False
-
 
 """
 All interaction should be with the MSNConnection and MultiSwitchboardSession classes.
@@ -26,6 +22,10 @@ You should not directly instantiate any objects of other classes.
 
 class MSNConnection:
        """ Manages all the Twisted factories, etc """
+       MAXMESSAGESIZE     = 1400
+       SWITCHBOARDTIMEOUT = 30.0*60.0
+       GETALLAVATARS      = False
+
        def __init__(self, username, password, ident):
                """ Connects to the MSN servers.
                @param username: the MSN passport to connect with.
@@ -127,7 +127,7 @@ class MSNConnection:
 
                LogEvent(INFO, self.ident)
                if not self.notificationClient: return
-               if GETALLAVATARS:
+               if MSNConnection.GETALLAVATARS:
                        self._ensureSwitchboardSession(userHandle)
                sb = self.switchboardSessions.get(userHandle)
                if sb: return sb.sendAvatarRequest()
@@ -526,7 +526,7 @@ class SwitchboardSessionBase(msn.SwitchboardClient):
                                if not noerror:
                                        self.failedMessage(text)
 
-                       if len(text) < MAXMESSAGESIZE:
+                       if len(text) < MSNConnection.MAXMESSAGESIZE:
                                message = msn.MSNMessage(message=str(text.replace("\n", "\r\n").encode("utf-8")))
                                message.setHeader("Content-Type", "text/plain; charset=UTF-8")
                                message.ack = msn.MSNMessage.MESSAGE_NACK
@@ -536,12 +536,12 @@ class SwitchboardSessionBase(msn.SwitchboardClient):
                                        d.addCallback(failedMessage)
 
                        else:
-                               chunks = int(math.ceil(len(text) / float(MAXMESSAGESIZE)))
+                               chunks = int(math.ceil(len(text) / float(MSNConnection.MAXMESSAGESIZE)))
                                chunk = 0
                                guid = msn.random_guid()
                                while chunk < chunks:
-                                       offset = chunk * MAXMESSAGESIZE
-                                       text = message[offset : offset + MAXMESSAGESIZE]
+                                       offset = chunk * MSNConnection.MAXMESSAGESIZE
+                                       text = message[offset : offset + MSNConnection.MAXMESSAGESIZE]
                                        message = msn.MSNMessage(message=str(text.replace("\n", "\r\n").encode("utf-8")))
                                        message.ack = msn.MSNMessage.MESSAGE_NACK
                                        if chunk == 0: