]> code.delx.au - pymsnt/blobdiff - src/legacy/glue.py
Reject authorisation for new contacts should work now.
[pymsnt] / src / legacy / glue.py
index 67b788f949dbe74cd6523a092e0e75cc6d3a7f8c..176932f247e1a6f743bd5e0d1d48cfaf9cfa9d81 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
@@ -17,26 +17,25 @@ import lang
 
 
 
-name = "MSN Transport"   # The name of the transport
 url = "http://msn-transport.jabberstudio.org"
-version = "0.11-dev"     # The transport version
+version = "0.11-dev"         # The transport version
 mangle = True            # XDB '@' -> '%' mangling
 id = "msn"               # The transport identifier
 
 
 # Load the default avatars
-f = open("src/legacy/defaultJabberAvatar.png")
+f = open(os.path.join("data", "defaultJabberAvatar.png"), "rb")
 defaultJabberAvatarData = f.read()
 f.close()
 
-f = open("src/legacy/defaultAvatar.png")
+f = open(os.path.join("data", "defaultMSNAvatar.png"), "rb")
 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 '%') """
@@ -95,15 +94,16 @@ def updateStats(statistics):
        #stats["FailedAvatarCount"] = msnp2p.MSNP2P_Avatar.ERROR_COUNT
 
 
-def msn2jid(msnid):
+def msn2jid(msnid, withResource):
        """ Converts a MSN passport into a JID representation to be used with the transport """
-       return msnid.replace('@', '%') + "@" + config.jid
+       return msnid.replace('@', '%') + "@" + config.jid + (withResource and "/msn" or "")
 
-translateAccount = msn2jid # Marks this as the function to be used in jabber:iq:gateway (Service ID Translation)
+# Marks this as the function to be used in jabber:iq:gateway (Service ID Translation)
+translateAccount = lambda a: msn2jid(a, False)
 
 def jid2msn(jid):
        """ Converts a JID representation of a MSN passport into the original MSN passport """
-       return unicode(jid[:jid.find('@')].replace('%', '@'))
+       return unicode(jid[:jid.find('@')].replace('%', '@')).split("/")[0]
 
 
 def presence2state(show, ptype): 
@@ -230,7 +230,7 @@ class LegacyConnection(msn.MSNConnection):
                self.remoteNick = ""
 
                # Init the MSN bits
-               msn.MSNConnection.__init__(self, username, password, self.session.jabberID)
+               msn.MSNConnection.__init__(self, username, password, self.jabberID)
 
                # User typing notification stuff
                self.userTyping = dict() # Indexed by contact MSN ID, stores whether the user is typing to this contact
@@ -242,10 +242,10 @@ class LegacyConnection(msn.MSNConnection):
                
                self.legacyList = LegacyList(self.session)
        
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
        
        def removeMe(self):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
        
                self.userTypingSend.stop()
        
@@ -254,15 +254,15 @@ class LegacyConnection(msn.MSNConnection):
                self.session = None
                self.logOut()
        
-       def _sendShowStatus(self):
+
+       # Implemented from baseproto
+       def sendShowStatus(self, jid=None):
                if not self.session: return
                source = config.jid
-               to = self.session.jabberID
-               self.session.sendPresence(to=to, fro=source, show=self.remoteShow, status=self.remoteStatus, nickname=self.remoteNick)
+               if not jid:
+                       jid = self.jabberID
+               self.session.sendPresence(to=jid, fro=source, show=self.remoteShow, status=self.remoteStatus, nickname=self.remoteNick)
        
-       
-
-       # Implemented from baseproto
        def resourceOffline(self, resource):
                pass
 
@@ -321,7 +321,7 @@ class LegacyConnection(msn.MSNConnection):
                for contact in self.contactTyping.keys():
                        self.contactTyping[contact] += 1
                        if self.contactTyping[contact] >= 3:
-                               self.session.sendTypingNotification(self.session.jabberID, msn2jid(contact), False)
+                               self.session.sendTypingNotification(self.jabberID, msn2jid(contact, True), False)
                                del self.contactTyping[contact]
        
        def userTypingNotification(self, dest, resource, composing):
@@ -335,90 +335,92 @@ class LegacyConnection(msn.MSNConnection):
 
        # Implement callbacks from msn.MSNConnection
        def connectionFailed(self, reason):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                text = lang.get(self.session.lang).msnConnectFailed % reason
-               self.session.sendMessage(to=self.session.jabberID, fro=config.jid, body=text)
+               self.session.sendMessage(to=self.jabberID, fro=config.jid, body=text)
                self.session.removeMe()
 
        def loginFailed(self, reason):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                text = lang.get(self.session.lang).msnLoginFailure % (self.session.username)
-               self.session.sendErrorMessage(to=self.session.jabberID, fro=config.jid, etype="auth", condition="not-authorized", explanation=text, body="Login Failure")
+               self.session.sendErrorMessage(to=self.jabberID, fro=config.jid, etype="auth", condition="not-authorized", explanation=text, body="Login Failure")
                self.session.removeMe()
        
        def connectionLost(self, reason):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                text = lang.get(self.session.lang).msnDisconnected % reason
-               self.session.sendMessage(to=self.session.jabberID, fro=config.jid, body=text)
+               self.session.sendMessage(to=self.jabberID, fro=config.jid, body=text)
                self.session.removeMe() # Tear down the session
 
        def multipleLogin(self):
-               LogEvent(INFO, self.session.jabberID)
-               self.session.sendMessage(to=self.session.jabberID, fro=config.jid, body=lang.get(self.session.lang).msnMultipleLogin)
+               LogEvent(INFO, self.jabberID)
+               self.session.sendMessage(to=self.jabberID, fro=config.jid, body=lang.get(self.session.lang).msnMultipleLogin)
                self.session.removeMe()
        
        def serverGoingDown(self):
-               LogEvent(INFO, self.session.jabberID)
-               self.session.sendMessage(to=self.session.jabberID, fro=config.jid, body=lang.get(self.session.lang).msnMaintenance)
+               LogEvent(INFO, self.jabberID)
+               self.session.sendMessage(to=self.jabberID, fro=config.jid, body=lang.get(self.session.lang).msnMaintenance)
        
        def accountNotVerified(self):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                text = lang.get(self.session.lang).msnNotVerified % (self.session.username)
-               self.session.sendMessage(to=self.session.jabberID, fro=config.jid, body=text)
+               self.session.sendMessage(to=self.jabberID, fro=config.jid, body=text)
        
        def userMapping(self, passport, jid):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                text = lang.get(self.session.lang).userMapping % (passport, jid)
-               self.session.sendMessage(to=self.session.jabberID, fro=msn2jid(passport), body=text)
+               self.session.sendMessage(to=self.jabberID, fro=msn2jid(passport, True), body=text)
        
        def loggedIn(self):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                self.session.ready = True
        
        def listSynchronized(self):
-               LogEvent(INFO, self.session.jabberID)
-               self.session.sendPresence(to=self.session.jabberID, fro=config.jid)
+               LogEvent(INFO, self.jabberID)
+               self.session.sendPresence(to=self.jabberID, fro=config.jid)
                self.legacyList.syncJabberLegacyLists()
                self.listSynced = True
                #self.legacyList.flushSubscriptionBuffer()
        
        def ourStatusChanged(self, statusCode, screenName, personal):
                # Send out a new presence packet to the Jabber user so that the transport icon changes
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                self.remoteShow, ptype = state2presence(statusCode)
                self.remoteStatus = personal
                self.remoteNick = screenName
-               self._sendShowStatus()
+               self.sendShowStatus()
 
        def gotMessage(self, remoteUser, text):
-               LogEvent(INFO, self.session.jabberID)
-               source = msn2jid(remoteUser)
-               self.session.sendMessage(self.session.jabberID, fro=source, body=text, mtype="chat")
+               LogEvent(INFO, self.jabberID)
+               source = msn2jid(remoteUser, True)
+               if self.contactTyping.has_key(remoteUser):
+                       del self.contactTyping[remoteUser]
+               self.session.sendMessage(self.jabberID, fro=source, body=text, mtype="chat")
                self.session.pytrans.statistics.stats["MessageCount"] += 1
        
        def gotGroupchat(self, msnGroupchat, userHandle):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                msnGroupchat.groupchat = LegacyGroupchat(self.session, switchboardSession=msnGroupchat)
-               msnGroupchat.groupchat.sendUserInvite(msn2jid(userHandle))
+               msnGroupchat.groupchat.sendUserInvite(msn2jid(userHandle, True))
        
        def gotContactTyping(self, contact):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                # Check if the contact has only just started typing
                if not self.contactTyping.has_key(contact):
-                       self.session.sendTypingNotification(self.session.jabberID, msn2jid(contact), True)
+                       self.session.sendTypingNotification(self.jabberID, msn2jid(contact, True), True)
 
                # Reset the counter
                self.contactTyping[contact] = 0
        
        def failedMessage(self, remoteUser, message):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                self.session.pytrans.statistics.stats["FailedMessageCount"] += 1
-               fro = msn2jid(remoteUser)
-               self.session.sendErrorMessage(to=self.session.jabberID, fro=fro, etype="wait", condition="recipient-unavailable", explanation=lang.get(self.session.lang).msnFailedMessage, body=message)
+               fro = msn2jid(remoteUser, True)
+               self.session.sendErrorMessage(to=self.jabberID, fro=fro, etype="wait", condition="recipient-unavailable", explanation=lang.get(self.session.lang).msnFailedMessage, body=message)
        
        def contactAvatarChanged(self, userHandle, hash):
-               LogEvent(INFO, self.session.jabberID)
-               jid = msn2jid(userHandle)
+               LogEvent(INFO, self.jabberID)
+               jid = msn2jid(userHandle, False)
                c = self.session.contactList.findContact(jid)
                if not c: return
 
@@ -442,10 +444,10 @@ class LegacyConnection(msn.MSNConnection):
                        c.updateAvatar(defaultAvatar)
        
        def contactStatusChanged(self, remoteUser):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                
                msnContact = self.getContacts().getContact(remoteUser)
-               c = self.session.contactList.findContact(msn2jid(remoteUser))
+               c = self.session.contactList.findContact(msn2jid(remoteUser, False))
                if not (c and msnContact): return
 
                show, ptype = state2presence(msnContact.status)
@@ -456,35 +458,37 @@ class LegacyConnection(msn.MSNConnection):
                c.updatePresence(show, status, ptype, force=True)
        
        def gotFileReceive(self, fileReceive):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                # FIXME
-               ft.FTReceive(self.session, msn2jid(fileReceive.userHandle), fileReceive)
+               ft.FTReceive(self.session, msn2jid(fileReceive.userHandle, True), fileReceive)
        
        def contactAddedMe(self, userHandle):
-               LogEvent(INFO, self.session.jabberID)
-               self.session.contactList.getContact(msn2jid(userHandle)).contactRequestsAuth()
+               LogEvent(INFO, self.jabberID)
+               self.session.contactList.getContact(msn2jid(userHandle, False)).contactRequestsAuth()
        
        def contactRemovedMe(self, userHandle):
-               LogEvent(INFO, self.session.jabberID)
-               c = self.session.contactList.getContact(msn2jid(userHandle))
+               LogEvent(INFO, self.jabberID)
+               c = self.session.contactList.getContact(msn2jid(userHandle, True))
                c.contactDerequestsAuth()
                c.contactRemovesAuth()
        
        def gotInitialEmailNotification(self, inboxunread, foldersunread):
-               LogEvent(INFO, self.session.jabberID)
-               text = lang.get(self.session.lang).msnInitialMail % (inboxunread, foldersunread)
-               self.session.sendMessage(to=self.session.jabberID, fro=config.jid, body=text, mtype="headline")
+               if config.mailNotifications:
+                       LogEvent(INFO, self.jabberID)
+                       text = lang.get(self.session.lang).msnInitialMail % (inboxunread, foldersunread)
+                       self.session.sendMessage(to=self.jabberID, fro=config.jid, body=text, mtype="headline")
        
        def gotRealtimeEmailNotification(self, mailfrom, fromaddr, subject):
-               LogEvent(INFO, self.session.jabberID)
-               text = lang.get(self.session.lang).msnRealtimeMail % (mailfrom, fromaddr, subject)
-               self.session.sendMessage(to=self.session.jabberID, fro=config.jid, body=text, mtype="headline")
+               if config.mailNotifications:
+                       LogEvent(INFO, self.jabberID)
+                       text = lang.get(self.session.lang).msnRealtimeMail % (mailfrom, fromaddr, subject)
+                       self.session.sendMessage(to=self.jabberID, fro=config.jid, body=text, mtype="headline")
                
        def gotMSNAlert(self, text, actionurl, subscrurl):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
 
                el = Element((None, "message"))
-               el.attributes["to"] = self.session.jabberID
+               el.attributes["to"] = self.jabberID
                el.attributes["from"] = config.jid
                el.attributes["type"] = "headline"
                body = el.addElement("body")
@@ -503,9 +507,9 @@ class LegacyConnection(msn.MSNConnection):
                self.session.pytrans.send(el)
        
        def gotAvatarImageData(self, userHandle, imageData):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                av = self.session.pytrans.avatarCache.setAvatar(imageData)
-               jid = msn2jid(userHandle)
+               jid = msn2jid(userHandle, False)
                c = self.session.contactList.findContact(jid)
                c.updateAvatar(av)
        
@@ -514,6 +518,7 @@ class LegacyConnection(msn.MSNConnection):
 
 class LegacyList:
        def __init__(self, session):
+               self.jabberID = session.jabberID
                self.session = session
                self.subscriptionBuffer = []
        
@@ -522,19 +527,19 @@ class LegacyList:
                self.session = None
 
        def addContact(self, jid):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                userHandle = jid2msn(jid)
                self.session.legacycon.addContact(msn.FORWARD_LIST, userHandle)
                self.session.contactList.getContact(jid).contactGrantsAuth()
        
        def removeContact(self, jid):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                jid = jid2msn(jid)
                self.session.legacycon.remContact(msn.FORWARD_LIST, jid)
        
        
        def authContact(self, jid):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                jid = jid2msn(jid)
                d = self.session.legacycon.remContact(msn.PENDING_LIST, jid)
                if d:
@@ -543,9 +548,10 @@ class LegacyList:
                self.session.legacycon.addContact(msn.ALLOW_LIST, jid)
        
        def deauthContact(self, jid):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                jid = jid2msn(jid)
                self.session.legacycon.remContact(msn.ALLOW_LIST, jid)
+               self.session.legacycon.remContact(msn.PENDING_LIST, jid)
                self.session.legacycon.addContact(msn.BLOCK_LIST, jid)
 
 
@@ -557,8 +563,8 @@ class LegacyList:
 
                # We have to make an MSNContactList from the XDB data, then compare it with the one the server sent
                # Any subscription changes must be sent to the client, as well as changed in the XDB
-               LogEvent(INFO, self.session.jabberID, "Start.")
-               result = self.session.pytrans.xdb.request(self.session.jabberID, disco.IQROSTER)
+               LogEvent(INFO, self.jabberID, "Start.")
+               result = self.session.pytrans.xdb.request(self.jabberID, disco.IQROSTER)
                oldContactList = msn.MSNContactList()
                if result:
                        for item in result.elements():
@@ -595,7 +601,7 @@ class LegacyList:
                        # Create the Jabber representation of the
                        # contact base on the old list data and then
                        # sync it with current
-                       jabContact = self.session.contactList.createContact(msn2jid(contact.userHandle), msnlist2jabsub(oldLists))
+                       jabContact = self.session.contactList.createContact(msn2jid(contact.userHandle, False), msnlist2jabsub(oldLists))
                        jabContact.updateAvatar(defaultAvatar, push=False)
 
                        if addedToList(msn.FORWARD_LIST):
@@ -616,6 +622,8 @@ class LegacyList:
 
                        if removedFromList(msn.REVERSE_LIST):
                                jabContact.contactDerequestsAuth()
+
+                       jabContact.syncRoster()
                        
                        item = newXDB.addElement("item")
                        item.attributes["jid"] = contact.userHandle
@@ -623,8 +631,8 @@ class LegacyList:
                        item.attributes["lists"] = str(lists)
                
                # Update the XDB
-               self.session.pytrans.xdb.set(self.session.jabberID, disco.IQROSTER, newXDB)
-               LogEvent(INFO, self.session.jabberID, "End.")
+               self.session.pytrans.xdb.set(self.jabberID, disco.IQROSTER, newXDB)
+               LogEvent(INFO, self.jabberID, "End.")
        
        def saveLegacyList(self):
                contactList = self.session.legacycon.getContacts()
@@ -639,7 +647,7 @@ class LegacyList:
                        item.attributes["subscription"] = msnlist2jabsub(contact.lists) # Backwards compat
                        item.attributes["lists"] = str(contact.lists)
 
-               self.session.pytrans.xdb.set(self.session.jabberID, disco.IQROSTER, newXDB)
-               LogEvent(INFO, self.session.jabberID, "Finished saving list.")
+               self.session.pytrans.xdb.set(self.jabberID, disco.IQROSTER, newXDB)
+               LogEvent(INFO, self.jabberID, "Finished saving list.")