Mercurial > libervia-backend
comparison src/plugins/plugin_xep_0085.py @ 908:2ef523f0b5c3
plugin XEP-0085: bug fixes, especially for groupchat messages
author | souliane <souliane@mailoo.org> |
---|---|
date | Tue, 18 Mar 2014 13:52:12 +0100 |
parents | 967b94ef821e |
children | 1a759096ccbd |
comparison
equal
deleted
inserted
replaced
907:cd02f5ef30df | 908:2ef523f0b5c3 |
---|---|
135 if (category, name) == (PARAM_KEY, PARAM_NAME): | 135 if (category, name) == (PARAM_KEY, PARAM_NAME): |
136 self.updateEntityData("@ALL@", True if value == "true" else "@NONE@", profile) | 136 self.updateEntityData("@ALL@", True if value == "true" else "@NONE@", profile) |
137 return False | 137 return False |
138 return True | 138 return True |
139 | 139 |
140 | |
141 def messageReceivedTrigger(self, message, post_treat, profile): | 140 def messageReceivedTrigger(self, message, post_treat, profile): |
142 """ | 141 """ |
143 Update the entity cache when we receive a message with body. | 142 Update the entity cache when we receive a message with body. |
144 Check for a check state in the incoming message and broadcast signal. | 143 Check for a chat state in the message and signal frontends. |
145 """ | 144 """ |
146 if not self.host.memory.getParamA(PARAM_NAME, PARAM_KEY, profile_key=profile): | 145 if not self.host.memory.getParamA(PARAM_NAME, PARAM_KEY, profile_key=profile): |
147 return True | 146 return True |
148 | 147 |
148 from_jid = JID(message.getAttribute("from")) | |
149 try: | 149 try: |
150 domish.generateElementsNamed(message.elements(), name="body").next() | 150 domish.generateElementsNamed(message.elements(), name="body").next() |
151 from_jid = JID(message.getAttribute("from")) | |
152 try: | 151 try: |
153 domish.generateElementsNamed(message.elements(), name="active").next() | 152 domish.generateElementsNamed(message.elements(), name="active").next() |
154 # contact enabled Chat State Notifications | 153 # contact enabled Chat State Notifications |
155 self.updateEntityData(from_jid, True, profile) | 154 self.updateEntityData(from_jid, True, profile) |
156 # init to send following "composing" state | |
157 self.__chatStateInit(from_jid, message.getAttribute("type"), profile) | |
158 except StopIteration: | 155 except StopIteration: |
159 # contact didn't enable Chat State Notifications | 156 if message.getAttribute('type') == 'chat': |
160 self.updateEntityData(from_jid, False, profile) | 157 # contact didn't enable Chat State Notifications |
161 return True | 158 self.updateEntityData(from_jid, False, profile) |
159 return True | |
162 except StopIteration: | 160 except StopIteration: |
163 pass | 161 pass |
162 | |
163 # send our next "composing" states to any MUC and to the contacts who enabled the feature | |
164 self.__chatStateInit(from_jid, message.getAttribute("type"), profile) | |
164 | 165 |
165 state_list = [child.name for child in message.elements() if | 166 state_list = [child.name for child in message.elements() if |
166 message.getAttribute("type") in MESSAGE_TYPES | 167 message.getAttribute("type") in MESSAGE_TYPES |
167 and child.name in CHAT_STATES | 168 and child.name in CHAT_STATES |
168 and child.defaultUri == NS_CHAT_STATES] | 169 and child.defaultUri == NS_CHAT_STATES] |
169 for state in state_list: | 170 for state in state_list: |
170 # there must be only one state according to the XEP | 171 # there must be only one state according to the XEP |
171 self.host.bridge.chatStateReceived(message.getAttribute("from"), state, profile) | 172 if state != 'gone' or message.getAttribute('type') != 'groupchat': |
173 self.host.bridge.chatStateReceived(message.getAttribute("from"), state, profile) | |
172 break | 174 break |
173 return True | 175 return True |
174 | 176 |
175 def sendMessageTrigger(self, mess_data, treatments, profile): | 177 def sendMessageTrigger(self, mess_data, treatments, profile): |
176 """ | 178 """ |
209 # check if the parameter is active | 211 # check if the parameter is active |
210 if not self.host.memory.getParamA(PARAM_NAME, PARAM_KEY, profile_key=profile): | 212 if not self.host.memory.getParamA(PARAM_NAME, PARAM_KEY, profile_key=profile): |
211 return False | 213 return False |
212 # check if notifications should be sent to this contact | 214 # check if notifications should be sent to this contact |
213 try: | 215 try: |
216 type_ = self.host.memory.getEntityData(to_jid, ['type'], profile)['type'] | |
217 if type_ == 'groupchat': # always send to groupchat | |
218 return True | |
219 except (exceptions.UnknownEntityError, KeyError): | |
220 pass # private chat | |
221 try: | |
214 return self.host.memory.getEntityData(to_jid, [ENTITY_KEY], profile)[ENTITY_KEY] | 222 return self.host.memory.getEntityData(to_jid, [ENTITY_KEY], profile)[ENTITY_KEY] |
215 except (exceptions.UnknownEntityError, KeyError): | 223 except (exceptions.UnknownEntityError, KeyError): |
216 if forceEntityData: | 224 if forceEntityData: |
217 # enable it for the first time | 225 # enable it for the first time |
218 self.updateEntityData(to_jid, True, profile) | 226 self.updateEntityData(to_jid, True, profile) |
222 | 230 |
223 def __chatStateInit(self, to_jid, mess_type, profile): | 231 def __chatStateInit(self, to_jid, mess_type, profile): |
224 """ | 232 """ |
225 Data initialization for the chat state machine. | 233 Data initialization for the chat state machine. |
226 """ | 234 """ |
227 # TODO: use also the resource in map key | 235 # TODO: use also the resource in map key (not for groupchat) |
228 to_jid = to_jid.userhostJID() | 236 to_jid = to_jid.userhostJID() |
229 if mess_type is None: | 237 if mess_type is None: |
230 return | 238 return |
231 if not hasattr(self, "map"): | 239 if not hasattr(self, "map"): |
232 self.map = {} | 240 self.map = {} |
238 | 246 |
239 def __chatStateActive(self, to_jid, mess_type, profile_key): | 247 def __chatStateActive(self, to_jid, mess_type, profile_key): |
240 """ | 248 """ |
241 Launch the chat state machine on "active" state. | 249 Launch the chat state machine on "active" state. |
242 """ | 250 """ |
243 # TODO: use also the JID resource in the map key | 251 # TODO: use also the JID resource in the map key (not for groupchat) |
244 to_jid = to_jid.userhostJID() | 252 to_jid = to_jid.userhostJID() |
245 profile = self.host.memory.getProfileName(profile_key) | 253 profile = self.host.memory.getProfileName(profile_key) |
246 if profile is None: | 254 if profile is None: |
247 raise exceptions.ProfileUnknownError | 255 raise exceptions.ProfileUnknownError |
248 return | 256 return |
255 from the front-end, it needs to check the values of the | 263 from the front-end, it needs to check the values of the |
256 parameter "Send chat state notifications" and the entity | 264 parameter "Send chat state notifications" and the entity |
257 data associated to the target JID. | 265 data associated to the target JID. |
258 TODO: try to optimize this method which is called often | 266 TODO: try to optimize this method which is called often |
259 """ | 267 """ |
260 # TODO: use also the JID resource in the map key | 268 # TODO: use also the JID resource in the map key (not for groupchat) |
261 to_jid = JID(to_jid_s).userhostJID() | 269 to_jid = JID(to_jid_s).userhostJID() |
262 profile = self.host.memory.getProfileName(profile_key) | 270 profile = self.host.memory.getProfileName(profile_key) |
263 if profile is None: | 271 if profile is None: |
264 raise exceptions.ProfileUnknownError | 272 raise exceptions.ProfileUnknownError |
265 return | 273 return |
266 if not self.__checkActivation(to_jid, forceEntityData=False, profile=profile): | 274 if not self.__checkActivation(to_jid, forceEntityData=False, profile=profile): |
267 return | 275 return |
268 try: | 276 try: |
269 self.map[profile][to_jid]._onEvent("composing") | 277 self.map[profile][to_jid]._onEvent("composing") |
270 except AttributeError: | 278 except (KeyError, AttributeError): |
271 # no message has been sent/received since the notifications | 279 # no message has been sent/received since the notifications |
272 # have been enabled, it's better to wait for a first one | 280 # have been enabled, it's better to wait for a first one |
273 pass | 281 pass |
274 | 282 |
275 | 283 |
300 Move to the specified state, eventually send the | 308 Move to the specified state, eventually send the |
301 notification to the contact (the "active" state is | 309 notification to the contact (the "active" state is |
302 automatically sent with each message) and set the timer. | 310 automatically sent with each message) and set the timer. |
303 """ | 311 """ |
304 if state != self.state and state != "active": | 312 if state != self.state and state != "active": |
305 # send a new message without body | 313 if state != 'gone' or self.mess_type != 'groupchat': |
306 self.host.sendMessage(self.to_jid, | 314 # send a new message without body |
307 '', | 315 self.host.sendMessage(self.to_jid, '', '', self.mess_type, |
308 '', | 316 extra={"chat_state": state}, |
309 self.mess_type, | 317 profile_key=self.profile) |
310 extra={"chat_state": state}, | |
311 profile_key=self.profile) | |
312 self.state = state | 318 self.state = state |
313 if not self.timer is None: | 319 if not self.timer is None: |
314 self.timer.cancel() | 320 self.timer.cancel() |
315 | 321 |
316 if not state in TRANSITIONS: | 322 if not state in TRANSITIONS: |