]> code.delx.au - pymsnt/commitdiff
New msnw can send messages
authorjamesbunton <jamesbunton@55fbd22a-6204-0410-b2f0-b6c764c7e90a>
Mon, 12 Dec 2005 02:21:42 +0000 (02:21 +0000)
committerjamesbunton <jamesbunton@55fbd22a-6204-0410-b2f0-b6c764c7e90a>
Mon, 12 Dec 2005 02:21:42 +0000 (02:21 +0000)
git-svn-id: http://delx.cjb.net/svn/pymsnt/trunk@51 55fbd22a-6204-0410-b2f0-b6c764c7e90a

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

src/tlib/msn/msn.py
src/tlib/msn/msnw.py
src/tlib/msn/test_msnw.py

index 2bffefcff68e3aae7fe5d127851fca9ec1a152bd..bf011e1d989934fdba615fafc44e3c234352fc8b 100644 (file)
@@ -1252,7 +1252,7 @@ class NotificationClient(MSNEventBase):
     def handle_ADC(self, params):
         if not self.factory.contacts: raise MSNProtocolError, "handle_ADC called with no contact list"
         numParams = len(params)
-        if numParams < 3 or params[1].upper() not in ('AL','BL','RL','FL', 'PL'):
+        if numParams < 3 or params[1].upper() not in ('AL','BL','RL','FL','PL'):
             raise MSNProtocolError, "Invalid Paramaters for ADC" # debug
         id = int(params[0])
         listType = params[1].lower()
@@ -1272,7 +1272,7 @@ class NotificationClient(MSNEventBase):
     def handle_REM(self, params):
         if not self.factory.contacts: raise MSNProtocolError, "handle_REM called with no contact list available!"
         numParams = len(params)
-        if numParams < 3 or params[1].upper() not in ('AL','BL','FL','RL'):
+        if numParams < 3 or params[1].upper() not in ('AL','BL','FL','RL','PL'):
             raise MSNProtocolError, "Invalid Paramaters for REM" # debug
         id = int(params[0])
         listType = params[1].lower()
index 3204827fc8f007888f6733fa7210467c8b9de157..66d2105c2f71a74b3d5f1a1eaf6fb43d0689363a 100644 (file)
@@ -220,6 +220,8 @@ class MSNConnection:
                        c.disconnect()
                if self.notificationFactory:
                        self.notificationFactory.msncon = None
+               self.connectors = []
+               self.switchboardSessions = {}
                LogEvent(INFO, self.ident)
                
        
@@ -376,7 +378,8 @@ class NotificationClient(msn.NotificationClient):
 
        def gotSwitchboardInvitation(self, sessionID, host, port, key, userHandle, screenName):
                LogEvent(INFO, self.factory.msncon.ident)
-               sb = SwitchboardSession(self.factory.msncon, userHandle, host, port, key, sessionID)
+               sb = OneSwitchboardSession(self.factory.msncon, userHandle)
+               sb.connectReply(host, port, key, sessionID)
                sbOld = self.factory.msncon.switchboardSessions.get(userHandle)
                if sbOld:
                        sbOld.disconnect()
@@ -399,10 +402,10 @@ def switchToGroupchat(*args):
 class SwitchboardSessionBase:
        def __init__(self, msncon):
                self.msncon = msncon
+               self.userHandle = msncon.username
                self.ident = (msncon.ident, "INVALID!!")
                self.messageBuffer = []
                self.ready = False
-               self.killTimer = reactor.callLater(SWITCHBOARDTIMEOUT, self.transport.loseConnection)
 
        def __del__(self):
                LogEvent(INFO, self.ident)
@@ -413,17 +416,14 @@ class SwitchboardSessionBase:
                        if not noerror:
                                self.msncon.failedMessage(self.remoteUser, message)
 
-               if not self.killTimer.called:
-                       self.killTimer.cancel()
-               del self.killTimer
-       
        def connect(self):
                LogEvent(INFO, self.ident)
                def sbRequestAccepted((host, port, key)):
                        LogEvent(INFO, self.ident)
                        self.key = key
+                       self.reply = 0
                        factory = ClientFactory()
-                       factory.buildProtocol = lambda: self
+                       factory.buildProtocol = lambda addr: self
                        reactor.connectTCP(host, port, factory)
                def sbRequestFailed(ignored=None):
                        LogEvent(INFO, self.ident)
@@ -431,28 +431,33 @@ class SwitchboardSessionBase:
                d = self.msncon.notificationClient.requestSwitchboardServer()
                d.addCallbacks(sbRequestAccepted, sbRequestFailed)
        
+       def connectReply(self, host, port, key, sessionID):
+               LogEvent(INFO, self.ident)
+               self.key = key
+               self.sessionID = sessionID
+               self.reply = 1
+               factory = ClientFactory()
+               factory.buildProtocol = lambda addr: self
+               reactor.connectTCP(host, port, factory)
+       
        def flushBuffer(self):
                for message, noerror in self.messageBuffer[:]:
-                       self.messageBuffer.remove((m, noerror))
-                       self.sendMessage(m, noerror)
-
-       def resetTimer(self):
-               self.killTimer.cancel()
-               self.killTimer = reactor.callLater(SWITCHBOARDTIMEOUT, self.transport.loseConnection)
+                       self.messageBuffer.remove((message, noerror))
+                       self.sendMessage(message, noerror)
 
        def failedMessage(self, ignored):
                raise NotImplementedError
 
-       def sendMessage(text, noerror):
+       def sendMessage(self, text, noerror):
                if not self.ready:
-                       self.messageBuffer.append((message, noerror))
+                       self.messageBuffer.append((text, noerror))
                else:
                        LogEvent(INFO, self.ident)
                        def failedMessage(ignored):
                                if not noerror:
                                        self.failedMessage(text)
 
-                       if len(message) < MAXMESSAGESIZE:
+                       if len(text) < 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
@@ -482,8 +487,6 @@ class SwitchboardSessionBase:
 
                                        chunk += 1
 
-                       self.resetTimer()
-       
        def gotFileReceive(self, fileReceive):
                LogEvent(INFO, self.ident)
                self.msncon.gotFileReceive(fileReceive)
@@ -497,13 +500,14 @@ class OneSwitchboardSession(SwitchboardSessionBase, msn.SwitchboardClient):
                self.remoteUser = remoteUser
                self.ident = (self.msncon, self.remoteUser)
                self.chattingUsers = []
+               self.timeout = None
        
        def _ready(self):
                LogEvent(INFO, self.ident)
                self.ready = True
                for user in self.chattingUsers:
                        self.userJoined(user)
-               if not self.timeout.called:
+               if self.timeout:
                        self.timeout.cancel()
                del self.timeout
                self.flushBuffer()
@@ -528,7 +532,7 @@ class OneSwitchboardSession(SwitchboardSessionBase, msn.SwitchboardClient):
                for userHandle in users.keys():
                        self.chattingUsers.append(userHandle)
        
-       def userJoined(self, userHandle, screenName):
+       def userJoined(self, userHandle, screenName=''):
                LogEvent(INFO, self.ident)
                if not self.reply:
                        self._ready()
@@ -566,7 +570,7 @@ class OneSwitchboardSession(SwitchboardSessionBase, msn.SwitchboardClient):
                if not self.ready: return
                msnContacts = self.msncon.getContacts()
                if not msnContacts: return
-               msnContact = msnContacts.getContact(self.remoteUSer)
+               msnContact = msnContacts.getContact(self.remoteUser)
                if not (msnContact and msnContact.caps & self.CAPS and msnContact.msnobj): return
                if msnContact.msnobjGot: return
                msnContact.msnobjGot = True # This is deliberately set before we get the avatar. So that we don't try to reget failed avatars over & over
index 165e93285fca820d660e4c8e737c2eb488d5ed6c..0dfd652049c9f88cfcc7e28fa918cbfa5f67d4c6 100644 (file)
@@ -20,7 +20,7 @@ import msnw
 
 # Settings
 TIMEOUT = 30.0 # Connection timeout in seconds
-LOGGING = True
+LOGGING = False
 USER1 = "messengertest1@hotmail.com"
 PASS1 = "hellohello"
 USER2 = "messengertest2@hotmail.com"
@@ -66,6 +66,8 @@ class MSNConnection(msnw.MSNConnection):
        def __init__(self, username, password, ident, testCase):
                msnw.MSNConnection.__init__(self, username, password, ident)
                self.testCase = testCase
+               self.message = None
+               self.contactAdded = None
 
        def listSynchronized(self):
                # Now we're fully connected
@@ -76,46 +78,41 @@ class MSNConnection(msnw.MSNConnection):
                self.message = (userHandle, text)
        
        def contactAddedMe(self, userHandle):
-               print "CONTACT ADDED ME"
                self.contactAdded = userHandle
        
 
-class BasicConnection(unittest.TestCase):
-       def failed(self, why):
-               self.done = True
-       
-       def testConnect(self):
-               self.done = False
-               self.timeout = reactor.callLater(TIMEOUT, self.failed)
-               self.user = MSNConnection(USER1, PASS1, "user", self)
-               while not self.done:
-                       reactor.iterate(0.1)
-               self.failUnless((self.done == "SYNCED"), "Failed to connect to MSN servers.")
-               self.user.logOut()
-               reactor.iterate(0.1)
-               try:
-                       self.timeout.cancel()
-               except (error.AlreadyCancelled, error.AlreadyCalled):
-                       pass
-
-class BasicTests(unittest.TestCase):
+class TestsUtil:
        def setUp(self):
                self.failure = None
                self.timeout = None
                self.done = False
-               
-               # Login both accounts
+               self.user1 = None
+               self.user2 = None
+
+       def tearDown(self):
+               if self.user1:
+                       self.user1.logOut()
+                       reactor.iterate(0.1)
+               if self.user2:
+                       self.user2.logOut()
+                       reactor.iterate(0.1)
+       
+       def doLogins(self, both=True):
+               # Connect two accounts
                self.user1 = MSNConnection(USER1, PASS1, "user1", self)
-               self.loop("Logging in.", cond="SYNCED")
-               self.user2 = MSNConnection(USER2, PASS2, "user2", self)
-               self.loop("Logging in.", cond="SYNCED")
+               self.loop("Logging in user1.", cond="SYNCED")
+               if both:
+                       self.user2 = MSNConnection(USER2, PASS2, "user2", self)
+                       self.loop("Logging in user2.", cond="SYNCED")
 
+       def doPurgeContacts(self):
                # Purge both contact lists
                clearAccount(self.user1).addCallback(self.cb)
                self.loop("Purging user1 contact list.")
                clearAccount(self.user2).addCallback(self.cb)
                self.loop("Purging user2 contact list.")
 
+       def doAddContacts(self):
                # Adding users to each other's lists
                self.user1.addContact(msnw.FORWARD_LIST, USER2).addCallback(self.cb)
                self.loop("Adding user2 to user1's forward list.")
@@ -127,15 +124,9 @@ class BasicTests(unittest.TestCase):
                self.loop("Adding user1 to user2's allow list.")
 
                # Check the contacts have seen each other
-               self.loop("Waiting...")
+               reactor.iterate(0.1) # One last chance to notice each other
                self.failUnless((self.user1.contactAdded == USER2 and self.user2.contactAdded == USER1), "Contacts can't see each other.")
 
-
-       def tearDown(self):
-               self.user1.logOut()
-               self.user2.logOut()
-               reactor.iterate(0.1)
-       
        def cb(self, ignored=None):
                self.done = True
 
@@ -158,10 +149,33 @@ class BasicTests(unittest.TestCase):
                self.failure = why
                self.done = True
 
-       # The tests!
+# The tests!
+
+class BasicTests(unittest.TestCase, TestsUtil):
+       def setUp(self):
+               TestsUtil.setUp(self)
+
+       def tearDown(self):
+               TestsUtil.tearDown(self)
+
+       def testConnect(self):
+               self.doLogins(both=False)
+       
+       def testPurgeContacts(self):
+               self.doLogins()
+               self.doPurgeContacts()
+       
+       def testAddContacts(self):
+               self.doLogins()
+               self.doPurgeContacts()
+               self.doAddContacts()
+
        def testMessageExchange(self):
+               self.doLogins()
+               self.doPurgeContacts()
+               self.doAddContacts()
                self.user1.sendMessage(USER2, "Hi user2")
-               self.loop("Timeout exchanging message 1.", cond="GOTMESSAGE")
-               self.failUnless((self.user1.message == (USER2, "Hi user1")), "Failed to transfer message 1.")
+               self.loop("Timeout exchanging message.", cond="GOTMESSAGE")
+               self.failUnless((self.user2.message == (USER1, "Hi user2")), "Failed to transfer message.")