plugin XEP-0085: send 'gone' state before disconnection
This commit is contained in:
parent
34d191608d
commit
5ae8bc7f24
1 changed files with 31 additions and 18 deletions
|
|
@ -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):
|
||||
|
|
|
|||
Loading…
Reference in a new issue