]> code.delx.au - pymsnt/commitdiff
Reintegrated avatars.
authorjamesbunton <jamesbunton@55fbd22a-6204-0410-b2f0-b6c764c7e90a>
Sun, 1 Jan 2006 10:14:31 +0000 (10:14 +0000)
committerjamesbunton <jamesbunton@55fbd22a-6204-0410-b2f0-b6c764c7e90a>
Sun, 1 Jan 2006 10:14:31 +0000 (10:14 +0000)
git-svn-id: http://delx.cjb.net/svn/pymsnt/trunk@71 55fbd22a-6204-0410-b2f0-b6c764c7e90a

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

src/legacy/glue.py
src/tlib/msn/msn.py
src/tlib/msn/msnw.py

index 58db1453c35345bcdaa83aeb6b4bff5e41851d4f..1a0d3204f8e2c9cf969d141a8d71763d33082a51 100644 (file)
@@ -216,6 +216,8 @@ class LegacyGroupchat(groupchat.BaseGroupchat):
 class LegacyConnection(msn.MSNConnection):
        """ A glue class that connects to the legacy network """
        def __init__(self, username, password, session):
+               self.jabberID = session.jabberID
+
                self.session = session
                self.listSynced = False
                self.initialListVersion = 0
@@ -409,12 +411,12 @@ class LegacyConnection(msn.MSNConnection):
                                msnContact.msnobjGot = True
                                c.updateAvatar(av)
                        else:
-                               def updateAvatar((imageData,)):
+                               def updateAvatarCB((imageData,)):
                                        av = self.session.pytrans.avatarCache.setAvatar(imageData)
                                        c.updateAvatar(av)
                                d = self.sendAvatarRequest(userHandle)
                                if d:
-                                       d.addCallback(updateAvatar)
+                                       d.addCallback(updateAvatarCB)
                else:
                        # They've turned off their avatar
                        global defaultAvatar
@@ -480,6 +482,13 @@ class LegacyConnection(msn.MSNConnection):
 
                self.session.pytrans.send(el)
        
+       def gotAvatarImageData(self, userHandle, imageData):
+               LogEvent(INFO, self.session.jabberID)
+               av = self.session.pytrans.avatarCache.setAvatar(imageData)
+               jid = msn2jid(userHandle)
+               c = self.session.contactList.findContact(jid)
+               c.updateAvatar(av)
+       
        
 
 
index e0480ed9f05d5778e579bfd602e4011850d428e8..0970c8da15eec1afc7738b53d07b103cb34e91ae 100644 (file)
@@ -195,15 +195,15 @@ def ljust(s, n, c):
     return s + (n-len(s))*c
 
 if sys.byteorder == "little":
-       def utf16net(s):
-               """ Encodes to utf-16 and ensures network byte order. Strips the BOM """
-               a = array.array("h", s.encode("utf-16")[2:])
-               a.byteswap()
-               return a.tostring()
+    def utf16net(s):
+        """ Encodes to utf-16 and ensures network byte order. Strips the BOM """
+        a = array.array("h", s.encode("utf-16")[2:])
+        a.byteswap()
+        return a.tostring()
 else:
-       def utf16net(s):
-               """ Encodes to utf-16 and ensures network byte order. Strips the BOM """
-               return s.encode("utf-16")[2:]
+    def utf16net(s):
+        """ Encodes to utf-16 and ensures network byte order. Strips the BOM """
+        return s.encode("utf-16")[2:]
 
 def b64enc(s):
     return base64.encodestring(s).replace("\n", "")
@@ -2343,7 +2343,6 @@ class SwitchboardClient(MSNEventBase):
             d.callback((data,))
         buffer = StringBuffer(bufferClosed)
         slpLink = SLPLink_AvatarReceive(remoteUser=msnContact.userHandle, switchboard=self, consumer=buffer, context=msnContact.msnobj.text)
-        slpLink.avatarDataBuffer = buffer
         self.slpLinks[slpLink.sessionID] = slpLink
         return d
 
@@ -2489,7 +2488,7 @@ class FileContext:
             self.filesize = 0
 
     def pack(self):
-        if MSNP2PDEBUG: print "FileContext packing:", self.filename, self.filesize
+        if MSNP2PDEBUG: log.msg("FileContext packing:", self.filename, self.filesize)
         data = struct.pack("<LLQL", 638, 0x03, self.filesize, 0x01)
         data = data[:-1] # Uck, weird, but it works
         data += utf16net(self.filename)
@@ -2503,7 +2502,7 @@ class FileContext:
         chunk = packet[19:540]
         chunk = chunk[:chunk.find('\x00\x00')]
         self.filename = unicode((codecs.BOM_UTF16_BE + chunk).decode("utf-16"))
-        if MSNP2PDEBUG: print "FileContext parsed:", self.filesize, self.filename
+        if MSNP2PDEBUG: log.msg("FileContext parsed:", self.filesize, self.filename)
 
 
 class BinaryFields:
@@ -2534,18 +2533,18 @@ class BinaryFields:
         self.fields = struct.unpack("<LLQQLLLLQ", packet[0:48])
         self.fields += struct.unpack(">L", packet[len(packet)-4:])
         if MSNP2PDEBUG:
-            print "Unpacked fields:",
+            out = "Unpacked fields: "
             for i in self.fields:
-                print hex(i),
-            print
+                out += hex(i) + ' '
+            log.msg(out)
     
     def packHeaders(self):
         f = tuple(self.fields)
         if MSNP2PDEBUG:
-            print "Packed fields:",
+            out = "Packed fields: "
             for i in self.fields:
-                print hex(i),
-            print
+                out += hex(i) + ' '
+            log.msg(out)
         return struct.pack("<LLQQLLLLQ", f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7], f[8])
     
     def packFooter(self):
@@ -2599,7 +2598,7 @@ class MSNSLPMessage:
         
         # Get the MSNSLP method or status
         msnslp = lines[0].split(" ")
-        if MSNP2PDEBUG: print "Parsing MSNSLPMessage", len(s), s
+        if MSNP2PDEBUG: log.msg("Parsing MSNSLPMessage %s %s" % (len(s), s))
         if msnslp[0] in ("INVITE", "BYE"):
             self.method = msnslp[0].strip()
         else:
@@ -2631,7 +2630,7 @@ class MSNSLPMessage:
                     self.branch = line[1].split(";")[1].split("=")[1].strip()
             except:
                 if MSNP2PDEBUG:
-                    print "Error parsing MSNSLP message."
+                    log.msg("Error parsing MSNSLP message.")
                     raise
 
     def __str__(self):
@@ -2706,7 +2705,7 @@ class SLPLink:
 
     def warn(self, text):
         if MSNP2PDEBUG:
-            print "Warning in transfer: ", self, text
+            log.msg("Warning in transfer: %s %s" % (self, text))
 
     def sendP2PACK(self, ackHeaders):
         binaryFields = BinaryFields()
@@ -2759,7 +2758,7 @@ class SLPLink_Send(SLPLink):
         self.data = ""
     
     def send_dataprep(self):
-        if MSNP2PDEBUG: print "send_dataprep"
+        if MSNP2PDEBUG: log.msg("send_dataprep")
         binaryFields = BinaryFields()
         binaryFields[0] = self.sessionID
         binaryFields[1] = self.seqID.next()
@@ -2770,7 +2769,7 @@ class SLPLink_Send(SLPLink):
         self.sendP2PMessage(binaryFields, chr(0) * 4)
 
     def write(self, data):
-        if MSNP2PDEBUG: print "write"
+        if MSNP2PDEBUG: log.msg("write")
         i = 0
         length = len(data)
         while i < length:
@@ -2786,7 +2785,7 @@ class SLPLink_Send(SLPLink):
                 return
 
     def _writeChunk(self, chunk):
-        print "writing chunk"
+        log.msg("writing chunk")
         binaryFields = BinaryFields()
         binaryFields[0] = self.sessionID
         if self.offset == 0:
@@ -2846,7 +2845,7 @@ class SLPLink_FileSend(SLPLink_Send):
             self.killLink()
 
     def wait_data_ack(self, packet):
-        if MSNP2PDEBUG: print "wait_data_ack"
+        if MSNP2PDEBUG: log.msg("wait_data_ack")
         binaryFields = BinaryFields()
         binaryFields.unpackFields(packet)
 
@@ -2885,7 +2884,7 @@ class SLPLink_Receive(SLPLink):
         self.pos = 0
 
     def wait_dataprep(self, packet):
-        if MSNP2PDEBUG: print "wait_dataprep"
+        if MSNP2PDEBUG: log.msg("wait_dataprep")
         binaryFields = BinaryFields()
         binaryFields.unpackFields(packet)
 
@@ -2903,7 +2902,7 @@ class SLPLink_Receive(SLPLink):
         self.handlePacket = self.wait_data
 
     def wait_data(self, packet):
-        if MSNP2PDEBUG: print "wait_data"
+        if MSNP2PDEBUG: log.msg("wait_data")
         binaryFields = BinaryFields()
         binaryFields.unpackFields(packet)
 
index 1eb6cc4f008ba63f3c24ac1a9b8628af6ba91b26..1e4f03f6fa3efa8f1e703fc35fabec1fac8af451 100644 (file)
@@ -316,6 +316,10 @@ class MSNConnection:
                """ An MSN Alert (http://alerts.msn.com) was received. Body is the
                text of the alert. 'action' is a url for more information,
                'subscr' is a url to modify your your alerts subscriptions. """
+       
+       def gotAvatarImageData(self, userHandle, imageData):
+               """ An contact's avatar has been received because a switchboard
+               session with them was started. """
 
 
 class SavedEvents:
@@ -438,6 +442,7 @@ class SwitchboardSessionBase(msn.SwitchboardClient):
        def __init__(self, msncon):
                msn.SwitchboardClient.__init__(self)
                self.msncon = msncon
+               self.msnobj = msncon.notificationClient.msnobj
                self.userHandle = msncon.username
                self.ident = (msncon.ident, "INVALID!!")
                self.messageBuffer = []
@@ -491,7 +496,25 @@ class SwitchboardSessionBase(msn.SwitchboardClient):
        def failedMessage(self, *ignored):
                raise NotImplementedError
 
-       def sendMessage(self, text, noerror=False):
+       def sendClientCaps(self):
+               message = msn.MSNMessage()
+               message.setHeader("Content-Type", "text/x-clientcaps")
+               message.setHeader("Client-Name", "PyMSNt")
+               if hasattr(self.msncon, "jabberID"):
+                       message.setHeader("JabberID", str(self.msncon.jabberID))
+               self.sendMessage(message)
+       
+       def sendMessage(self, message, noerror=False):
+               # Check to make sure that clientcaps only gets sent after
+               # the first text type message.
+               if isinstance(message, msn.MSNMessage) and message.getHeader("Content-Type").startswith("text"):
+                       self.sendMessage = self.sendMessageReal
+                       self.sendClientCaps()
+                       return self.sendMessage(message, noerror)
+               else:
+                       return self.sendMessageReal(message, noerror)
+       
+       def sendMessageReal(self, text, noerror=False):
                if not isinstance(text, basestring):
                        msn.SwitchboardClient.sendMessage(self, text)
                        return
@@ -548,7 +571,7 @@ class MultiSwitchboardSession(SwitchboardSessionBase):
        def failedMessage(self, text):
                self.groupchat.gotMessage("BOUNCE", text)
        
-       def sendMessage(self, text, noerror):
+       def sendMessage(self, text, noerror=False):
                """ Used to send a mesage to the groupchat. Can be called immediately
                after instantiation. """
                if self.contactCount > 0:
@@ -647,6 +670,13 @@ class OneSwitchboardSession(SwitchboardSessionBase):
                        self._switchToMulti(remoteUser)
                        self.userJoined(remoteUser)
                        self.userJoined(userHandle)
+               else:
+                       def updateAvatarCB((imageData, )):
+                               if self.msncon:
+                                       self.msncon.gotAvatarImageData(self.remoteUser, imageData)
+                       d = self.sendAvatarRequest()
+                       if d:
+                               d.addCallback(updateAvatarCB)
 
        def userLeft(self, userHandle):
                def wait():
@@ -656,7 +686,23 @@ class OneSwitchboardSession(SwitchboardSessionBase):
 
        def gotMessage(self, message):
                LogEvent(INFO, self.ident)
-               self.msncon.gotMessage(self.remoteUser, message.getMessage())
+               cTypes = [s.strip() for s in message.getHeader("Content-Type").split(';')]
+               if "text/plain" == cTypes[0]:
+                       try:
+                               if len(cTypes) > 1 and cTypes[1].lower().find("utf-8") >= 0:
+                                       text = message.getMessage().decode("utf-8")
+                               else:
+                                       text = message.getMessage()
+                               self.msncon.gotMessage(self.remoteUser, text)
+                       except:
+                               self.msncon.gotMessage("A message was lost.")
+                               raise
+               elif "text/x-clientcaps" == cTypes[0]:
+                       if message.hasHeader("JabberID"):
+                               jid = message.getHeader("JabberID")
+                               self.switchboardSession.msncon.userMapping(message.userHandle, jid)
+               else:
+                       LogEvent(INFO, self.ident, "Discarding unknown message type.")
        
        def gotFileReceive(self, fileReceive):
                LogEvent(INFO, self.ident)
@@ -680,7 +726,7 @@ class OneSwitchboardSession(SwitchboardSessionBase):
                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
-               msn.SwitchboardClient.sendAvatarRequest(self, msnContact)
+               return msn.SwitchboardClient.sendAvatarRequest(self, msnContact)
        
        def sendFile(self, msnContact, filename, filesize):
                def doSendFile(ignored=None):
@@ -692,4 +738,3 @@ class OneSwitchboardSession(SwitchboardSessionBase):
                        self.funcBuffer.append(doSendFile)
                return d
        
-