SàT improvement:
- subscription & presence refactoring - multilingual statuses are now correctly sent - registration: error condition now specified in error message
This commit is contained in:
parent
c5295f4c98
commit
94dd813a9a
1 changed files with 77 additions and 48 deletions
125
sat.tac
125
sat.tac
|
|
@ -70,8 +70,8 @@ def sat_next_id():
|
|||
|
||||
class SatXMPPClient(client.XMPPClient):
|
||||
|
||||
def __init__(self, jid, password, host=None, port=5222):
|
||||
client.XMPPClient.__init__(self, jid, password, host, port)
|
||||
def __init__(self, user_jid, password, host=None, port=5222):
|
||||
client.XMPPClient.__init__(self, user_jid, password, host, port)
|
||||
self.factory.clientConnectionLost = self.connectionLost
|
||||
self.__connected=False
|
||||
|
||||
|
|
@ -120,11 +120,8 @@ class SatRosterProtocol(xmppim.RosterClientProtocol):
|
|||
self.host = host
|
||||
|
||||
def rosterCb(self, roster):
|
||||
for jid, item in roster.iteritems():
|
||||
info ("new contact in roster list: %s", jid)
|
||||
#FIXME: fill attributes
|
||||
self.host.memory.addContact(jid, {}, item.groups)
|
||||
self.host.bridge.newContact(jid, {}, item.groups)
|
||||
for raw_jid, item in roster.iteritems():
|
||||
self.onRosterSet(item)
|
||||
|
||||
def requestRoster(self):
|
||||
""" ask the server for Roster list """
|
||||
|
|
@ -133,16 +130,33 @@ class SatRosterProtocol(xmppim.RosterClientProtocol):
|
|||
|
||||
def removeItem(self, to):
|
||||
"""Remove a contact from roster list"""
|
||||
to_jid=jid.JID(to)
|
||||
xmppim.RosterClientProtocol.removeItem(self, to_jid)
|
||||
xmppim.RosterClientProtocol.removeItem(self, to)
|
||||
#TODO: check IQ result
|
||||
|
||||
def addItem(self, to):
|
||||
"""Add a contact to roster list"""
|
||||
to_jid=jid.JID(to)
|
||||
xmppim.RosterClientProtocol.addItem(self, to_jid)
|
||||
xmppim.RosterClientProtocol.addItem(self, to)
|
||||
#TODO: check IQ result
|
||||
|
||||
def onRosterSet(self, item):
|
||||
"""Called when a new/update roster item is received"""
|
||||
#TODO: send a signal to frontends
|
||||
item_attr = {'to': str(item.subscriptionTo),
|
||||
'from': str(item.subscriptionFrom),
|
||||
'ask': str(item.ask)
|
||||
}
|
||||
if item.name:
|
||||
item_attr['name'] = item.name
|
||||
info ("new contact in roster list: %s", item.jid.full())
|
||||
self.host.memory.addContact(item.jid, item_attr, item.groups)
|
||||
self.host.bridge.newContact(item.jid.full(), item_attr, item.groups)
|
||||
|
||||
def onRosterRemove(self, entity):
|
||||
"""Called when a roster removal event is received"""
|
||||
#TODO: send a signal to frontends
|
||||
print "removing %s from roster list" % entity.full()
|
||||
self.host.memory.delContact(entity)
|
||||
|
||||
class SatPresenceProtocol(xmppim.PresenceClientProtocol):
|
||||
|
||||
def __init__(self, host):
|
||||
|
|
@ -151,42 +165,53 @@ class SatPresenceProtocol(xmppim.PresenceClientProtocol):
|
|||
|
||||
def availableReceived(self, entity, show=None, statuses=None, priority=0):
|
||||
info ("presence update for [%s]", entity)
|
||||
|
||||
if statuses.has_key(None): #we only want string keys
|
||||
statuses["default"] = statuses[None]
|
||||
del statuses[None]
|
||||
|
||||
### we check if the status is not about subscription ###
|
||||
#FIXME: type is not needed anymore
|
||||
#TODO: management of differents statuses (differents languages)
|
||||
status = statuses.values()[0] if len(statuses) else ""
|
||||
self.host.memory.addPresenceStatus(entity.full(), "", show or "",
|
||||
status or "", int(priority))
|
||||
self.host.memory.addPresenceStatus(entity, show or "",
|
||||
int(priority), statuses)
|
||||
|
||||
#now it's time to notify frontends
|
||||
self.host.bridge.presenceUpdate(entity.full(), "", show or "",
|
||||
status or "", int(priority))
|
||||
self.host.bridge.presenceUpdate(entity.full(), show or "",
|
||||
int(priority), statuses)
|
||||
|
||||
def unavailableReceived(self, entity, statuses=None):
|
||||
#TODO: management of differents statuses (differents languages)
|
||||
status = statuses.values()[0] if len(statuses) else ""
|
||||
self.host.memory.addPresenceStatus(entity.full(), "unavailable", "",
|
||||
status or "", 0)
|
||||
if statuses and statuses.has_key(None): #we only want string keys
|
||||
statuses["default"] = statuses[None]
|
||||
del statuses[None]
|
||||
self.host.memory.addPresenceStatus(entity, "unavailable", 0, statuses)
|
||||
|
||||
#now it's time to notify frontends
|
||||
self.host.bridge.presenceUpdate(entity.full(), "unavailable", "",
|
||||
status or "", 0)
|
||||
self.host.bridge.presenceUpdate(entity.full(), "unavailable", 0, statuses)
|
||||
|
||||
|
||||
|
||||
def available(self, entity=None, show=None, statuses=None, priority=0):
|
||||
if statuses and statuses.has_key('default'):
|
||||
statuses[None] = statuses['default']
|
||||
del statuses['default']
|
||||
xmppim.PresenceClientProtocol.available(self, entity, show, statuses, priority)
|
||||
|
||||
def subscribedReceived(self, entity):
|
||||
debug ("subscription approved for [%s]" % entity)
|
||||
debug ("subscription approved for [%s]" % entity.userhost())
|
||||
self.host.memory.delWaitingSub(entity.userhost())
|
||||
self.host.bridge.subscribe('subscribed', entity.userhost())
|
||||
|
||||
def unsubscribedReceived(self, entity):
|
||||
debug ("unsubscription confirmed for [%s]" % entity)
|
||||
debug ("unsubscription confirmed for [%s]" % entity.userhost())
|
||||
self.host.memory.delWaitingSub(entity.userhost())
|
||||
self.host.bridge.subscribe('unsubscribed', entity.userhost())
|
||||
|
||||
def subscribeReceived(self, entity):
|
||||
#FIXME: auto answer for subscribe request, must be checked !
|
||||
debug ("subscription request for [%s]" % entity)
|
||||
self.subscribed(entity)
|
||||
debug ("subscription request for [%s]" % entity.userhost())
|
||||
self.host.memory.addWaitingSub('subscribe', entity.userhost())
|
||||
self.host.bridge.subscribe('subscribe', entity.userhost())
|
||||
|
||||
def unsubscribeReceived(self, entity):
|
||||
debug ("unsubscription asked for [%s]" % entity)
|
||||
debug ("unsubscription asked for [%s]" % entity.userhost())
|
||||
self.host.memory.addWaitingSub('unsubscribe', entity.userhost())
|
||||
self.host.bridge.subscribe('unsubscribe', entity.userhost())
|
||||
|
||||
class SatDiscoProtocol(disco.DiscoClientProtocol):
|
||||
def __init__(self, host):
|
||||
|
|
@ -243,7 +268,7 @@ class RegisteringAuthenticator(xmlstream.ConnectAuthenticator):
|
|||
answer_data={"message":"Username already exists, please choose an other one"}
|
||||
else:
|
||||
answer_data['reason'] = 'unknown'
|
||||
answer_data={"message":"Registration failed"}
|
||||
answer_data={"message":"Registration failed (%s)" % str(failure.value.condition)}
|
||||
self.host.bridge.actionResult(answer_type, self.answer_id, answer_data)
|
||||
self.xmlstream.sendFooter()
|
||||
|
||||
|
|
@ -289,6 +314,7 @@ class SAT(service.Service):
|
|||
self.bridge.register("disconnect", self.disconnect)
|
||||
self.bridge.register("getContacts", self.memory.getContacts)
|
||||
self.bridge.register("getPresenceStatus", self.memory.getPresenceStatus)
|
||||
self.bridge.register("getWaitingSub", self.memory.getWaitingSub)
|
||||
self.bridge.register("sendMessage", self.sendMessage)
|
||||
self.bridge.register("setParam", self.setParam)
|
||||
self.bridge.register("getParamA", self.memory.getParamA)
|
||||
|
|
@ -297,6 +323,7 @@ class SAT(service.Service):
|
|||
self.bridge.register("getParamsCategories", self.memory.getParamsCategories)
|
||||
self.bridge.register("getHistory", self.memory.getHistory)
|
||||
self.bridge.register("setPresence", self.setPresence)
|
||||
self.bridge.register("subscription", self.subscription)
|
||||
self.bridge.register("addContact", self.addContact)
|
||||
self.bridge.register("delContact", self.delContact)
|
||||
self.bridge.register("isConnected", self.isConnected)
|
||||
|
|
@ -523,22 +550,23 @@ class SAT(service.Service):
|
|||
self.bridge.newMessage(message['from'], unicode(msg), to=message['to']) #We send back the message, so all clients are aware of it
|
||||
|
||||
|
||||
def setPresence(self, to="", type="", show="", status="", priority=0):
|
||||
def setPresence(self, to="", show="", priority = 0, statuses={}):
|
||||
"""Send our presence information"""
|
||||
if not type in ["", "unavailable", "subscribed", "subscribe",
|
||||
"unsubscribe", "unsubscribed", "prob", "error"]:
|
||||
error("Type error !")
|
||||
#TODO: throw an error
|
||||
return
|
||||
to_jid=jid.JID(to)
|
||||
status = None if not status else {None:status} #FIXME: use the proper way here (change signature to use dict)
|
||||
#TODO: refactor subscription bridge API
|
||||
if type=="":
|
||||
self.presence.available(to_jid, show, status, priority)
|
||||
elif type=="subscribe":
|
||||
to_jid = jid.JID(to) if to else None
|
||||
self.presence.available(to_jid, show, statuses, priority)
|
||||
|
||||
def subscription(self, type, raw_jid):
|
||||
"""Called to manage subscription"""
|
||||
to_jid = jid.JID(raw_jid)
|
||||
debug ('subsciption request [%s] for %s', type, to_jid.full())
|
||||
if type=="subscribe":
|
||||
self.presence.subscribe(to_jid)
|
||||
elif type=="subscribed":
|
||||
self.presence.subscribed(to_jid)
|
||||
contact = self.memory.getContact(to_jid)
|
||||
if not contact or not bool(contact['to']): #we automatically subscribe to 'to' presence
|
||||
debug('sending automatic "to" subscription request')
|
||||
self.subscription('subscribe', to_jid.userhost())
|
||||
elif type=="unsubscribe":
|
||||
self.presence.unsubscribe(to_jid)
|
||||
elif type=="unsubscribed":
|
||||
|
|
@ -548,13 +576,14 @@ class SAT(service.Service):
|
|||
def addContact(self, to):
|
||||
"""Add a contact in roster list"""
|
||||
to_jid=jid.JID(to)
|
||||
self.roster.addItem(to_jid.userhost())
|
||||
self.setPresence(to_jid.userhost(), "subscribe")
|
||||
self.roster.addItem(to_jid)
|
||||
self.presence.subscribe(to_jid)
|
||||
|
||||
def delContact(self, to):
|
||||
"""Remove contact from roster list"""
|
||||
to_jid=jid.JID(to)
|
||||
self.roster.removeItem(to_jid.userhost())
|
||||
self.roster.removeItem(to_jid)
|
||||
self.presence.unsubscribe(to_jid)
|
||||
self.bridge.contactDeleted(to)
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue