+++ /dev/null
-# Copyright 2004 James Bunton <james@delx.cjb.net>
-# Licensed for distribution under the GPL version 2, check COPYING for details
-
-import utils
-if(utils.checkTwisted()):
- from twisted.xish.domish import Element
-else:
- from tlib.domish import Element
-from tlib import msn
-from legacy import glue
-import debug
-
-
-def getGroupNames(msnContact, msnContactList):
- groups = []
- for groupID in msnContact.groups:
- try:
- groups.append(msnContactList.groups[groupID])
- except:
- pass
- return groups
-
-
-def msnlist2jabsub(lists):
- """ Converts MSN contact lists ORed together into the corresponding Jabber subscription state """
- if(lists & msn.FORWARD_LIST and lists & msn.REVERSE_LIST):
- return "both"
- elif(lists & msn.REVERSE_LIST):
- return "from"
- elif(lists & msn.FORWARD_LIST):
- return "to"
- else:
- return "none"
-
-
-def jabsub2msnlist(sub):
- """ Converts a Jabber subscription state into the corresponding MSN contact lists ORed together """
- if(sub == "to"):
- return msn.FORWARD_LIST
- elif(sub == "from"):
- return msn.REVERSE_LIST
- elif(sub == "both"):
- return (msn.FORWARD_LIST | msn.REVERSE_LIST)
- else:
- return 0
-
-
-
-class SubscriptionManager:
- def __init__(self, session):
- self.session = session
- self.subscriptionBuffer = []
-
- def removeMe(self):
- self.subscriptionBuffer = None
- self.session = None
-
- def syncJabberLegacyLists(self):
- """ Synchronises the MSN contact list on server with the Jabber contact list """
- # 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
- debug.log("Subscriptions: Session \"%s\" starting syncJabberLegacyLists()" % (self.session.jabberID))
- result = self.session.pytrans.xdb.request(self.session.jabberID, "jabber:iq:roster")
- oldContactList = msn.MSNContactList()
- if(result):
- for item in result.elements():
- user = item.getAttribute("jid")
- sub = item.getAttribute("subscription")
- lists = jabsub2msnlist(sub)
- contact = msn.MSNContact(userHandle=user, screenName="", lists=lists)
- oldContactList.addContact(contact)
-
- newXDB = Element((None, "query"))
- newXDB.attributes["xmlns"] = "jabber:iq:roster"
-
- contactList = self.session.legacycon.getContacts()
- for contact in contactList.contacts.values():
- # Compare with the XDB <item/> entry
- oldContact = oldContactList.getContact(contact.userHandle)
- if(oldContact == None):
- oldLists = 0
- else:
- oldLists = oldContact.lists
- lists = contact.lists
-
-
- def updatePresence(ptype): # Convienence
- self.session.sendPresence(to=self.session.jabberID, fro=glue.msn2jid(contact.userHandle), ptype=ptype)
-
- if(not (oldLists & msn.FORWARD_LIST)):
- if(lists & msn.FORWARD_LIST):
- # User has been added to forward list
- groups = getGroupNames(contact, self.session.legacycon.getContacts())
- self.session.sendRosterImport(glue.msn2jid(contact.userHandle), "subscribe", "both", contact.screenName, groups)
- else:
- if(not (lists & msn.FORWARD_LIST)):
- # User has been removed from forward list
- updatePresence("unsubscribed")
-
- if(oldLists & msn.REVERSE_LIST):
- if(not (lists & msn.REVERSE_LIST)):
- # User has been removed from reverse list
- updatePresence("unsubscribe")
-
- if(not (lists & msn.ALLOW_LIST) and not (lists & msn.BLOCK_LIST) and (lists & msn.REVERSE_LIST)):
- # User isn't blocked, and isn't currently allowed, so will subscribe to your presence
- updatePresence("subscribe")
-
- item = newXDB.addElement("item")
- item.attributes["jid"] = contact.userHandle
- item.attributes["subscription"] = msnlist2jabsub(lists)
-
- # Update the XDB
- self.session.pytrans.xdb.set(self.session.jabberID, "jabber:iq:roster", newXDB)
- debug.log("Subscriptions: Session \"%s\" finished syncJabberLegacyLists()" % (self.session.jabberID))
-
-
-
- def msnContactAddedMe(self, userHandle):
- # User has been added to our reverse list (we are now on their forward list)
- debug.log("Subscriptions: Session \"%s\" msnContactAddedMe(\"%s\")" % (self.session.jabberID, userHandle))
-
- # Update the XDB if needed
- document = self.session.pytrans.xdb.request(self.session.jabberID, "jabber:iq:roster")
- if(not document): return # We can ignore this error. It will get fixed at next logon. It's fixed better in the next version :)
- for item in document.elements():
- user = item.getAttribute("jid")
- if(user == userHandle):
- break
- else:
- # Not found, so we need to add it
- item = document.addElement("item")
- item.attributes["jid"] = userHandle
- item.attributes["subscription"] = "from"
- self.session.pytrans.xdb.set(self.session.jabberID, "jabber:iq:roster", document)
-
- # Send a subscription packet
- source = glue.msn2jid(userHandle)
- self.session.sendPresence(to=self.session.jabberID, fro=source, ptype="subscribe")
-
- def msnContactRemovedMe(self, userHandle):
- # User has been removed from our reverse list (we are no longer on their forward list)
- debug.log("Subscriptions: Session \"%s\" msnContactRemovedMe(\"%s\")" % (self.session.jabberID, userHandle))
-
- # Update the XDB
- document = self.session.pytrans.xdb.request(self.session.jabberID, "jabber:iq:roster")
- for item in document.elements():
- user = item.getAttribute("jid")
- if(user == userHandle):
- document.children.remove(item)
- break
- self.session.pytrans.xdb.set(self.session.jabberID, "jabber:iq:roster", document)
-
- # Send an unsubscribe packet (the contact is no longer viewing the user's presence)
- source = glue.msn2jid(userHandle)
- self.session.sendPresence(to=self.session.jabberID, fro=source, ptype="unsubscribe")
-
-
- def flushSubscriptionBuffer(self):
- for (to, subtype) in self.subscriptionBuffer:
- self.jabberSubscriptionReceived(to, subtype)
-
- def jabberSubscriptionReceived(self, to, subtype):
- debug.log("Subscriptions: Session \"%s\" - jabberSubscriptionReceived(\"%s\", \"%s\")" % (self.session.jabberID, to, subtype))
-
- if(not (self.session.ready and self.session.legacycon.getContacts())):
- # Buffer until we have received the MSN contact list
- self.subscriptionBuffer.append((to, subtype))
- return
-
- def updatePresence(ptype): # Convienence
- self.session.sendPresence(to=self.session.jabberID, fro=to, ptype=ptype)
-
- if(to.find('@') > 0): # For contacts
- userHandle = glue.jid2msn(to)
-
- msnContact = self.session.legacycon.getContacts().getContact(userHandle)
- lists = 0 # Lists default to none
- if(msnContact and msnContact.lists):
- lists = msnContact.lists # We know extra information about what lists they're in.
-
- if(subtype == "subscribe"):
- # User wants to subscribe to contact's presence
- if(lists & msn.FORWARD_LIST):
- # The contact is already on the user's MSN list, so tell the user that this is so
- groups = getGroupNames(msnContact, self.session.legacycon.getContacts())
- self.session.sendRosterImport(glue.msn2jid(msnContact.userHandle), "subscribed", "both", msnContact.screenName, groups)
- else:
- # Add the contact to the user's MSN list
- def cb(arg=None):
- updatePresence("subscribed")
- self.session.legacycon.addContact(msn.FORWARD_LIST, userHandle).addCallback(cb)
-
- elif(subtype == "subscribed"):
- # The user has granted this contact subscription.
- def remFromBlockList(arg=None):
- if(lists & msn.BLOCK_LIST):
- # If they were on the block list remove them
- def cb(arg=None):
- pass
- self.session.legacycon.remContact(msn.BLOCK_LIST, userHandle).addCallback(cb)
-
- if(not (lists & msn.ALLOW_LIST)):
- # We add the contact to the allow list
- self.session.legacycon.addContact(msn.ALLOW_LIST, userHandle).addCallback(remFromBlockList)
-
- elif(subtype == "unsubscribe"):
- # User wants to unsubscribe to this contact's presence. (User is removing the contact from their list)
- if(lists & msn.FORWARD_LIST):
- # Contact is in the forward list, so remove them
- def cb(arg=None):
- pass
- self.session.legacycon.remContact(msn.FORWARD_LIST, userHandle).addCallback(cb)
- else:
- updatePresence("unsubscribed")
-
- elif(subtype == "unsubscribed"):
- # The user wants to remove this contact's authorisation. Contact will no longer be able to see user
- def addToBlockList(arg=None):
- if(not (lists & msn.BLOCK_LIST)):
- # If they're not on the block list then add them to it
- def cb(arg=None):
- pass
- self.session.legacycon.addContact(msn.BLOCK_LIST, userHandle).addCallback(cb)
-
- if(lists & msn.ALLOW_LIST):
- # If they're currently on the allow list then remove them
- # Should we add them to the block list?
- # Yes we should. The MSN client seems to. So we'll follow their lead.
- self.session.legacycon.remContact(msn.ALLOW_LIST, userHandle)#.addCallback(addToBlockList)
- else:
- addToBlockList()
-
- else: # The user wants to change subscription to the transport
- if(subtype == "subscribe"):
- updatePresence("subscribed")
-
- elif(subtype == "subscribed"):
- return # Nothing to do
-
- elif(subtype == "unsubscribe" or subtype == "unsubscribed"):
- # They want to unregister. Ok, we can do that
- jid = self.session.jabberID
- debug.log("Subscriptions: Session \"%s\" is about to be unregistered" % (jid))
- self.session.pytrans.registermanager.removeRegInfo(jid)
- debug.log("Subscriptions: Session \"%s\" has been unregistered" % (jid))
-