Mercurial > libervia-backend
comparison src/plugins/plugin_xep_0085.py @ 1253:c13a46207410
plugin XEP-0085: send 'gone' state before disconnection
author | souliane <souliane@mailoo.org> |
---|---|
date | Mon, 20 Oct 2014 20:26:46 +0200 |
parents | 5ff9f9af9d1f |
children | 60dfa2f5d61f |
comparison
equal
deleted
inserted
replaced
1252:5ff9f9af9d1f | 1253:c13a46207410 |
---|---|
92 } | 92 } |
93 | 93 |
94 def __init__(self, host): | 94 def __init__(self, host): |
95 log.info(_("Chat State Notifications plugin initialization")) | 95 log.info(_("Chat State Notifications plugin initialization")) |
96 self.host = host | 96 self.host = host |
97 self.map = {} | |
97 | 98 |
98 # parameter value is retrieved before each use | 99 # parameter value is retrieved before each use |
99 host.memory.updateParams(self.params) | 100 host.memory.updateParams(self.params) |
100 | 101 |
101 # triggers from core | 102 # triggers from core |
102 host.trigger.add("MessageReceived", self.messageReceivedTrigger) | 103 host.trigger.add("MessageReceived", self.messageReceivedTrigger) |
103 host.trigger.add("sendMessage", self.sendMessageTrigger) | 104 host.trigger.add("sendMessage", self.sendMessageTrigger) |
104 host.trigger.add("paramUpdateTrigger", self.paramUpdateTrigger) | 105 host.trigger.add("paramUpdateTrigger", self.paramUpdateTrigger) |
105 # TODO: handle profile disconnection (free memory in entity data) | |
106 | 106 |
107 # args: to_s (jid as string), profile | 107 # args: to_s (jid as string), profile |
108 host.bridge.addMethod("chatStateComposing", ".plugin", in_sign='ss', | 108 host.bridge.addMethod("chatStateComposing", ".plugin", in_sign='ss', |
109 out_sign='', method=self.chatStateComposing) | 109 out_sign='', method=self.chatStateComposing) |
110 | 110 |
111 # args: from (jid as string), state in CHAT_STATES, profile | 111 # args: from (jid as string), state in CHAT_STATES, profile |
112 host.bridge.addSignal("chatStateReceived", ".plugin", signature='sss') | 112 host.bridge.addSignal("chatStateReceived", ".plugin", signature='sss') |
113 | 113 |
114 def getHandler(self, profile): | 114 def getHandler(self, profile): |
115 return XEP_0085_handler(self, profile) | 115 return XEP_0085_handler(self, profile) |
116 | |
117 def profileDisconnected(self, profile): | |
118 """Eventually send a 'gone' state to all one2one contacts.""" | |
119 if profile not in self.map: | |
120 return | |
121 for to_jid in self.map[profile]: | |
122 # FIXME: the "unavailable" presence stanza is received by to_jid | |
123 # before the chat state, so it will be ignored... find a way to | |
124 # actually defer the disconnection | |
125 self.map[profile][to_jid]._onEvent('gone') | |
126 del self.map[profile] | |
116 | 127 |
117 def updateEntityData(self, entity_jid, value, profile): | 128 def updateEntityData(self, entity_jid, value, profile): |
118 """ | 129 """ |
119 Update the entity data of the given profile for one or all contacts. | 130 Update the entity data of the given profile for one or all contacts. |
120 Reset the chat state(s) display if the notification has been disabled. | 131 Reset the chat state(s) display if the notification has been disabled. |
257 @param mess_type (str): "one2one" or "groupchat" | 268 @param mess_type (str): "one2one" or "groupchat" |
258 @param profile (str): %(doc_profile)s | 269 @param profile (str): %(doc_profile)s |
259 """ | 270 """ |
260 if mess_type is None: | 271 if mess_type is None: |
261 return | 272 return |
262 if not hasattr(self, "map"): | |
263 self.map = {} | |
264 profile_map = self.map.setdefault(profile, {}) | 273 profile_map = self.map.setdefault(profile, {}) |
265 if to_jid not in profile_map: | 274 if to_jid not in profile_map: |
266 machine = ChatStateMachine(self.host, to_jid, | 275 machine = ChatStateMachine(self.host, to_jid, |
267 mess_type, profile) | 276 mess_type, profile) |
268 self.map[profile][to_jid] = machine | 277 self.map[profile][to_jid] = machine |
336 """ | 345 """ |
337 Move to the specified state, eventually send the | 346 Move to the specified state, eventually send the |
338 notification to the contact (the "active" state is | 347 notification to the contact (the "active" state is |
339 automatically sent with each message) and set the timer. | 348 automatically sent with each message) and set the timer. |
340 """ | 349 """ |
350 assert(state in TRANSITIONS) | |
351 transition = TRANSITIONS[state] | |
352 assert("next_state" in transition and "delay" in transition) | |
353 | |
341 if state != self.state and state != "active": | 354 if state != self.state and state != "active": |
342 if state != 'gone' or self.mess_type != 'groupchat': | 355 if state != 'gone' or self.mess_type != 'groupchat': |
343 # send a new message without body | 356 # send a new message without body |
344 self.host.sendMessage(self.to_jid, '', '', self.mess_type, | 357 log.debug(u"sending state '{state}' to {jid}".format(state=state, jid=self.to_jid.full())) |
345 extra={"chat_state": state}, | 358 client = self.host.getClient(self.profile) |
346 profile_key=self.profile) | 359 mess_data = {'message': None, |
360 'type': self.mess_type, | |
361 'from': client.jid, | |
362 'to': self.to_jid, | |
363 'subject': None | |
364 } | |
365 self.host.generateMessageXML(mess_data) | |
366 mess_data['xml'].addElement(state, NS_CHAT_STATES) | |
367 client.xmlstream.send(mess_data['xml']) | |
368 | |
347 self.state = state | 369 self.state = state |
348 if self.timer is not None: | 370 if self.timer is not None: |
349 self.timer.cancel() | 371 self.timer.cancel() |
350 | 372 |
351 if state not in TRANSITIONS: | 373 if transition["next_state"] and transition["delay"] > 0: |
352 return | 374 self.timer = Timer(transition["delay"], self._onEvent, [transition["next_state"]]) |
353 if "next_state" not in TRANSITIONS[state]: | 375 self.timer.start() |
354 return | |
355 if "delay" not in TRANSITIONS[state]: | |
356 return | |
357 next_state = TRANSITIONS[state]["next_state"] | |
358 delay = TRANSITIONS[state]["delay"] | |
359 if next_state == "" or delay < 0: | |
360 return | |
361 self.timer = Timer(delay, self._onEvent, [next_state]) | |
362 self.timer.start() | |
363 | 376 |
364 | 377 |
365 class XEP_0085_handler(XMPPHandler): | 378 class XEP_0085_handler(XMPPHandler): |
366 implements(iwokkel.IDisco) | 379 implements(iwokkel.IDisco) |
367 | 380 |