]> code.delx.au - pymsnt/blobdiff - src/tlib/msn/msnw.py
Use vCard fullname if nickname isn't around.
[pymsnt] / src / tlib / msn / msnw.py
index ace11f148c4e9f471dec9877f4fb316ebdfbdcd2..6b58f50ed0097698ccb2621451218dc5bce07e87 100644 (file)
@@ -7,17 +7,13 @@ from twisted.internet.defer import Deferred
 from twisted.internet.protocol import ClientFactory
 
 # System imports
-import math, base64, binascii, math
+import math, base64, binascii
 
 # Local imports
 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.
@@ -50,7 +50,9 @@ class MSNConnection:
 
        def _getNotificationReferral(self):
                def timeout():
-                       if not d.called: d.errback()
+                       if not d.called:
+                               d.errback()
+                               self.logOut() # Clean up everything
                self.timeout = reactor.callLater(30, timeout)
                dispatchFactory = msn.DispatchFactory()
                dispatchFactory.userHandle = self.username
@@ -127,7 +129,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()
@@ -219,7 +221,7 @@ class MSNConnection:
        
        def logOut(self):
                """ Shuts down the whole connection. Don't try to call any
-               other methods after this one. """
+               other methods after this one. Except maybe connect() """
                if self.notificationClient:
                        self.notificationClient.logOut()
                for c in self.connectors:
@@ -227,6 +229,9 @@ class MSNConnection:
                if self.notificationFactory:
                        self.notificationFactory.msncon = None
                self.connectors = []
+               for sbs in self.switchboardSessions.values():
+                       if hasattr(sbs, "transport") and sbs.transport:
+                               sbs.transport.loseConnection()
                self.switchboardSessions = {}
                LogEvent(INFO, self.ident)
                
@@ -526,7 +531,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 +541,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:
@@ -615,9 +620,12 @@ class OneSwitchboardSession(SwitchboardSessionBase):
                self.timeout = None
        
        def __del__(self):
+               if self.timeout:
+                       self.timeout.cancel()
+               self.timeout = None
                for message, noerror in self.messageBuffer:
                        if not noerror:
-                               self.failedMessage(self.remoteUser, message)
+                               self.failedMessage(message)
 
        def _ready(self):
                LogEvent(INFO, self.ident)
@@ -648,8 +656,11 @@ class OneSwitchboardSession(SwitchboardSessionBase):
                LogEvent(INFO, self.ident)
                if not self.reply:
                        def failCB(arg=None):
+                               if not (self.msncon and self.msncon.switchboardSessions.has_key(self.remoteUser)):
+                                       return
                                LogEvent(INFO, self.ident, "User has not joined after 30 seconds.")
                                del self.msncon.switchboardSessions[self.remoteUser]
+                               self.timeout = None
                        d = self.inviteUser(self.remoteUser)
                        d.addErrback(failCB)
                        self.timeout = reactor.callLater(30.0, failCB)
@@ -681,7 +692,8 @@ class OneSwitchboardSession(SwitchboardSessionBase):
        def userLeft(self, userHandle):
                def wait():
                        if userHandle == self.remoteUser:
-                               del self.msncon.switchboardSessions[self.remoteUser]
+                               if self.msncon and self.msncon.switchboardSessions.has_key(self.remoteUser):
+                                       del self.msncon.switchboardSessions[self.remoteUser]
                reactor.callLater(0, wait) # Make sure this is handled after everything else
 
        def gotMessage(self, message):