plugin XEP-0085: send 'gone' state before disconnection

This commit is contained in:
souliane 2014-10-20 20:26:46 +02:00
commit 5ae8bc7f24

View file

@ -94,6 +94,7 @@ class XEP_0085(object):
def __init__(self, host):
log.info(_("Chat State Notifications plugin initialization"))
self.host = host
self.map = {}
# parameter value is retrieved before each use
host.memory.updateParams(self.params)
@ -102,7 +103,6 @@ class XEP_0085(object):
host.trigger.add("MessageReceived", self.messageReceivedTrigger)
host.trigger.add("sendMessage", self.sendMessageTrigger)
host.trigger.add("paramUpdateTrigger", self.paramUpdateTrigger)
# TODO: handle profile disconnection (free memory in entity data)
# args: to_s (jid as string), profile
host.bridge.addMethod("chatStateComposing", ".plugin", in_sign='ss',
@ -114,6 +114,17 @@ class XEP_0085(object):
def getHandler(self, profile):
return XEP_0085_handler(self, profile)
def profileDisconnected(self, profile):
"""Eventually send a 'gone' state to all one2one contacts."""
if profile not in self.map:
return
for to_jid in self.map[profile]:
# FIXME: the "unavailable" presence stanza is received by to_jid
# before the chat state, so it will be ignored... find a way to
# actually defer the disconnection
self.map[profile][to_jid]._onEvent('gone')
del self.map[profile]
def updateEntityData(self, entity_jid, value, profile):
"""
Update the entity data of the given profile for one or all contacts.
@ -259,8 +270,6 @@ class XEP_0085(object):
"""
if mess_type is None:
return
if not hasattr(self, "map"):
self.map = {}
profile_map = self.map.setdefault(profile, {})
if to_jid not in profile_map:
machine = ChatStateMachine(self.host, to_jid,
@ -338,28 +347,32 @@ class ChatStateMachine:
notification to the contact (the "active" state is
automatically sent with each message) and set the timer.
"""
assert(state in TRANSITIONS)
transition = TRANSITIONS[state]
assert("next_state" in transition and "delay" in transition)
if state != self.state and state != "active":
if state != 'gone' or self.mess_type != 'groupchat':
# send a new message without body
self.host.sendMessage(self.to_jid, '', '', self.mess_type,
extra={"chat_state": state},
profile_key=self.profile)
log.debug(u"sending state '{state}' to {jid}".format(state=state, jid=self.to_jid.full()))
client = self.host.getClient(self.profile)
mess_data = {'message': None,
'type': self.mess_type,
'from': client.jid,
'to': self.to_jid,
'subject': None
}
self.host.generateMessageXML(mess_data)
mess_data['xml'].addElement(state, NS_CHAT_STATES)
client.xmlstream.send(mess_data['xml'])
self.state = state
if self.timer is not None:
self.timer.cancel()
if state not in TRANSITIONS:
return
if "next_state" not in TRANSITIONS[state]:
return
if "delay" not in TRANSITIONS[state]:
return
next_state = TRANSITIONS[state]["next_state"]
delay = TRANSITIONS[state]["delay"]
if next_state == "" or delay < 0:
return
self.timer = Timer(delay, self._onEvent, [next_state])
self.timer.start()
if transition["next_state"] and transition["delay"] > 0:
self.timer = Timer(transition["delay"], self._onEvent, [transition["next_state"]])
self.timer.start()
class XEP_0085_handler(XMPPHandler):