Mercurial > libervia-backend
comparison sat_frontends/quick_frontend/quick_chat.py @ 2624:56f94936df1e
code style reformatting using black
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 27 Jun 2018 20:14:46 +0200 |
parents | 5e54afd17321 |
children | 96911768b0f3 |
comparison
equal
deleted
inserted
replaced
2623:49533de4540b | 2624:56f94936df1e |
---|---|
17 # You should have received a copy of the GNU Affero General Public License | 17 # You should have received a copy of the GNU Affero General Public License |
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 | 19 |
20 from sat.core.i18n import _ | 20 from sat.core.i18n import _ |
21 from sat.core.log import getLogger | 21 from sat.core.log import getLogger |
22 | |
22 log = getLogger(__name__) | 23 log = getLogger(__name__) |
23 from sat.core import exceptions | 24 from sat.core import exceptions |
24 from sat_frontends.quick_frontend import quick_widgets | 25 from sat_frontends.quick_frontend import quick_widgets |
25 from sat_frontends.quick_frontend.constants import Const as C | 26 from sat_frontends.quick_frontend.constants import Const as C |
26 from collections import OrderedDict | 27 from collections import OrderedDict |
27 from sat_frontends.tools import jid | 28 from sat_frontends.tools import jid |
28 import time | 29 import time |
30 | |
29 try: | 31 try: |
30 from locale import getlocale | 32 from locale import getlocale |
31 except ImportError: | 33 except ImportError: |
32 # FIXME: pyjamas workaround | 34 # FIXME: pyjamas workaround |
33 getlocale = lambda x: (None, 'utf-8') | 35 getlocale = lambda x: (None, "utf-8") |
34 | 36 |
35 | 37 |
36 ROOM_USER_JOINED = 'ROOM_USER_JOINED' | 38 ROOM_USER_JOINED = "ROOM_USER_JOINED" |
37 ROOM_USER_LEFT = 'ROOM_USER_LEFT' | 39 ROOM_USER_LEFT = "ROOM_USER_LEFT" |
38 ROOM_USER_MOVED = (ROOM_USER_JOINED, ROOM_USER_LEFT) | 40 ROOM_USER_MOVED = (ROOM_USER_JOINED, ROOM_USER_LEFT) |
39 | 41 |
40 # from datetime import datetime | 42 # from datetime import datetime |
41 | 43 |
42 try: | 44 try: |
43 # FIXME: to be removed when an acceptable solution is here | 45 # FIXME: to be removed when an acceptable solution is here |
44 unicode('') # XXX: unicode doesn't exist in pyjamas | 46 unicode("") # XXX: unicode doesn't exist in pyjamas |
45 except (TypeError, AttributeError): # Error raised is not the same depending on pyjsbuild options | 47 except ( |
48 TypeError, | |
49 AttributeError, | |
50 ): # Error raised is not the same depending on pyjsbuild options | |
46 unicode = str | 51 unicode = str |
47 | 52 |
48 # FIXME: day_format need to be settable (i18n) | 53 # FIXME: day_format need to be settable (i18n) |
54 | |
49 | 55 |
50 class Message(object): | 56 class Message(object): |
51 """Message metadata""" | 57 """Message metadata""" |
52 | 58 |
53 def __init__(self, parent, uid, timestamp, from_jid, to_jid, msg, subject, type_, extra, profile): | 59 def __init__( |
60 self, | |
61 parent, | |
62 uid, | |
63 timestamp, | |
64 from_jid, | |
65 to_jid, | |
66 msg, | |
67 subject, | |
68 type_, | |
69 extra, | |
70 profile, | |
71 ): | |
54 self.parent = parent | 72 self.parent = parent |
55 self.profile = profile | 73 self.profile = profile |
56 self.uid = uid | 74 self.uid = uid |
57 self.timestamp = timestamp | 75 self.timestamp = timestamp |
58 self.from_jid = from_jid | 76 self.from_jid = from_jid |
62 self.type = type_ | 80 self.type = type_ |
63 self.extra = extra | 81 self.extra = extra |
64 self.nick = self.getNick(from_jid) | 82 self.nick = self.getNick(from_jid) |
65 self._status = None | 83 self._status = None |
66 # own_mess is True if message was sent by profile's jid | 84 # own_mess is True if message was sent by profile's jid |
67 self.own_mess = (from_jid.resource == self.parent.nick) if self.parent.type == C.CHAT_GROUP else (from_jid.bare == self.host.profiles[profile].whoami.bare) | 85 self.own_mess = ( |
86 (from_jid.resource == self.parent.nick) | |
87 if self.parent.type == C.CHAT_GROUP | |
88 else (from_jid.bare == self.host.profiles[profile].whoami.bare) | |
89 ) | |
68 # is user mentioned here ? | 90 # is user mentioned here ? |
69 if self.parent.type == C.CHAT_GROUP and not self.own_mess: | 91 if self.parent.type == C.CHAT_GROUP and not self.own_mess: |
70 for m in msg.itervalues(): | 92 for m in msg.itervalues(): |
71 if self.parent.nick.lower() in m.lower(): | 93 if self.parent.nick.lower() in m.lower(): |
72 self._mention = True | 94 self._mention = True |
78 def host(self): | 100 def host(self): |
79 return self.parent.host | 101 return self.parent.host |
80 | 102 |
81 @property | 103 @property |
82 def info_type(self): | 104 def info_type(self): |
83 return self.extra.get('info_type') | 105 return self.extra.get("info_type") |
84 | 106 |
85 @property | 107 @property |
86 def mention(self): | 108 def mention(self): |
87 try: | 109 try: |
88 return self._mention | 110 return self._mention |
90 return False | 112 return False |
91 | 113 |
92 @property | 114 @property |
93 def history(self): | 115 def history(self): |
94 """True if message come from history""" | 116 """True if message come from history""" |
95 return self.extra.get('history', False) | 117 return self.extra.get("history", False) |
96 | 118 |
97 @property | 119 @property |
98 def main_message(self): | 120 def main_message(self): |
99 """currently displayed message""" | 121 """currently displayed message""" |
100 if self.parent.lang in self.message: | 122 if self.parent.lang in self.message: |
101 self.selected_lang = self.parent.lang | 123 self.selected_lang = self.parent.lang |
102 return self.message[self.parent.lang] | 124 return self.message[self.parent.lang] |
103 try: | 125 try: |
104 self.selected_lang = '' | 126 self.selected_lang = "" |
105 return self.message[''] | 127 return self.message[""] |
106 except KeyError: | 128 except KeyError: |
107 try: | 129 try: |
108 lang, mess = self.message.iteritems().next() | 130 lang, mess = self.message.iteritems().next() |
109 self.selected_lang = lang | 131 self.selected_lang = lang |
110 return mess | 132 return mess |
111 except StopIteration: | 133 except StopIteration: |
112 log.error(u"Can't find message for uid {}".format(self.uid)) | 134 log.error(u"Can't find message for uid {}".format(self.uid)) |
113 return '' | 135 return "" |
114 | 136 |
115 @property | 137 @property |
116 def main_message_xhtml(self): | 138 def main_message_xhtml(self): |
117 """rich message""" | 139 """rich message""" |
118 xhtml = {k:v for k,v in self.extra.iteritems() if 'html' in k} | 140 xhtml = {k: v for k, v in self.extra.iteritems() if "html" in k} |
119 if xhtml: | 141 if xhtml: |
120 # FIXME: we only return first found value for now | 142 # FIXME: we only return first found value for now |
121 return next(xhtml.itervalues()) | 143 return next(xhtml.itervalues()) |
122 | |
123 | 144 |
124 @property | 145 @property |
125 def time_text(self): | 146 def time_text(self): |
126 """Return timestamp in a nicely formatted way""" | 147 """Return timestamp in a nicely formatted way""" |
127 # if the message was sent before today, we print the full date | 148 # if the message was sent before today, we print the full date |
128 timestamp = time.localtime(self.timestamp) | 149 timestamp = time.localtime(self.timestamp) |
129 time_format = u"%c" if timestamp < self.parent.day_change else u"%H:%M" | 150 time_format = u"%c" if timestamp < self.parent.day_change else u"%H:%M" |
130 return time.strftime(time_format, timestamp).decode(getlocale()[1] or 'utf-8') | 151 return time.strftime(time_format, timestamp).decode(getlocale()[1] or "utf-8") |
131 | 152 |
132 @property | 153 @property |
133 def avatar(self): | 154 def avatar(self): |
134 """avatar full path or None if no avatar is found""" | 155 """avatar full path or None if no avatar is found""" |
135 ret = self.host.getAvatar(self.from_jid, profile=self.profile) | 156 ret = self.host.getAvatar(self.from_jid, profile=self.profile) |
138 def getNick(self, entity): | 159 def getNick(self, entity): |
139 """Return nick of an entity when possible""" | 160 """Return nick of an entity when possible""" |
140 contact_list = self.host.contact_lists[self.profile] | 161 contact_list = self.host.contact_lists[self.profile] |
141 if self.type == C.MESS_TYPE_INFO and self.info_type in ROOM_USER_MOVED: | 162 if self.type == C.MESS_TYPE_INFO and self.info_type in ROOM_USER_MOVED: |
142 try: | 163 try: |
143 return self.extra['user_nick'] | 164 return self.extra["user_nick"] |
144 except KeyError: | 165 except KeyError: |
145 log.error(u"extra data is missing user nick for uid {}".format(self.uid)) | 166 log.error(u"extra data is missing user nick for uid {}".format(self.uid)) |
146 return "" | 167 return "" |
147 # FIXME: converted getSpecials to list for pyjamas | 168 # FIXME: converted getSpecials to list for pyjamas |
148 if self.parent.type == C.CHAT_GROUP or entity in list(contact_list.getSpecials(C.CONTACT_SPECIAL_GROUP)): | 169 if self.parent.type == C.CHAT_GROUP or entity in list( |
170 contact_list.getSpecials(C.CONTACT_SPECIAL_GROUP) | |
171 ): | |
149 return entity.resource or "" | 172 return entity.resource or "" |
150 if entity.bare in contact_list: | 173 if entity.bare in contact_list: |
151 return contact_list.getCache(entity, 'nick') or contact_list.getCache(entity, 'name') or entity.node or entity | 174 return ( |
175 contact_list.getCache(entity, "nick") | |
176 or contact_list.getCache(entity, "name") | |
177 or entity.node | |
178 or entity | |
179 ) | |
152 return entity.node or entity | 180 return entity.node or entity |
153 | 181 |
154 @property | 182 @property |
155 def status(self): | 183 def status(self): |
156 return self._status | 184 return self._status |
176 else: | 204 else: |
177 me = False | 205 me = False |
178 break | 206 break |
179 if me: | 207 if me: |
180 self.type = C.MESS_TYPE_INFO | 208 self.type = C.MESS_TYPE_INFO |
181 self.extra['info_type'] = 'me' | 209 self.extra["info_type"] = "me" |
182 nick = self.nick | 210 nick = self.nick |
183 for lang, mess in self.message.iteritems(): | 211 for lang, mess in self.message.iteritems(): |
184 self.message[lang] = u"* " + nick + mess[3:] | 212 self.message[lang] = u"* " + nick + mess[3:] |
185 | 213 |
186 | 214 |
188 """Occupant metadata""" | 216 """Occupant metadata""" |
189 | 217 |
190 def __init__(self, parent, data, profile): | 218 def __init__(self, parent, data, profile): |
191 self.parent = parent | 219 self.parent = parent |
192 self.profile = profile | 220 self.profile = profile |
193 self.nick = data['nick'] | 221 self.nick = data["nick"] |
194 self._entity = data.get('entity') | 222 self._entity = data.get("entity") |
195 self.affiliation = data['affiliation'] | 223 self.affiliation = data["affiliation"] |
196 self.role = data['role'] | 224 self.role = data["role"] |
197 self.widgets = set() # widgets linked to this occupant | 225 self.widgets = set() # widgets linked to this occupant |
198 self._state = None | 226 self._state = None |
199 | 227 |
200 @property | 228 @property |
201 def data(self): | 229 def data(self): |
202 """reconstruct data dict from attributes""" | 230 """reconstruct data dict from attributes""" |
203 data = {} | 231 data = {} |
204 data['nick'] = self.nick | 232 data["nick"] = self.nick |
205 if self._entity is not None: | 233 if self._entity is not None: |
206 data['entity'] = self._entity | 234 data["entity"] = self._entity |
207 data['affiliation'] = self.affiliation | 235 data["affiliation"] = self.affiliation |
208 data['role'] = self.role | 236 data["role"] = self.role |
209 return data | 237 return data |
210 | 238 |
211 @property | 239 @property |
212 def jid(self): | 240 def jid(self): |
213 """jid in the room""" | 241 """jid in the room""" |
237 for w in self.widgets: | 265 for w in self.widgets: |
238 w.update(update_dict) | 266 w.update(update_dict) |
239 | 267 |
240 | 268 |
241 class QuickChat(quick_widgets.QuickWidget): | 269 class QuickChat(quick_widgets.QuickWidget): |
242 visible_states = ['chat_state'] # FIXME: to be removed, used only in quick_games | 270 visible_states = ["chat_state"] # FIXME: to be removed, used only in quick_games |
243 | 271 |
244 def __init__(self, host, target, type_=C.CHAT_ONE2ONE, nick=None, occupants=None, subject=None, profiles=None): | 272 def __init__( |
273 self, | |
274 host, | |
275 target, | |
276 type_=C.CHAT_ONE2ONE, | |
277 nick=None, | |
278 occupants=None, | |
279 subject=None, | |
280 profiles=None, | |
281 ): | |
245 """ | 282 """ |
246 @param type_: can be C.CHAT_ONE2ONE for single conversation or C.CHAT_GROUP for chat à la IRC | 283 @param type_: can be C.CHAT_ONE2ONE for single conversation or C.CHAT_GROUP for chat à la IRC |
247 """ | 284 """ |
248 self.lang = '' # default language to use for messages | 285 self.lang = "" # default language to use for messages |
249 quick_widgets.QuickWidget.__init__(self, host, target, profiles=profiles) | 286 quick_widgets.QuickWidget.__init__(self, host, target, profiles=profiles) |
250 self._locked = True # True when we are waiting for history/search | 287 self._locked = True # True when we are waiting for history/search |
251 # messageNew signals are cached when locked | 288 # messageNew signals are cached when locked |
252 self._cache = OrderedDict() | 289 self._cache = OrderedDict() |
253 assert type_ in (C.CHAT_ONE2ONE, C.CHAT_GROUP) | 290 assert type_ in (C.CHAT_ONE2ONE, C.CHAT_GROUP) |
254 self.current_target = target | 291 self.current_target = target |
255 self.type = type_ | 292 self.type = type_ |
256 if type_ == C.CHAT_GROUP: | 293 if type_ == C.CHAT_GROUP: |
257 if target.resource: | 294 if target.resource: |
258 raise exceptions.InternalError(u"a group chat entity can't have a resource") | 295 raise exceptions.InternalError( |
296 u"a group chat entity can't have a resource" | |
297 ) | |
259 if nick is None: | 298 if nick is None: |
260 raise exceptions.InternalError(u"nick must not be None for group chat") | 299 raise exceptions.InternalError(u"nick must not be None for group chat") |
261 | 300 |
262 self.nick = nick | 301 self.nick = nick |
263 self.occupants = {} | 302 self.occupants = {} |
264 self.setOccupants(occupants) | 303 self.setOccupants(occupants) |
265 else: | 304 else: |
266 if occupants is not None or nick is not None: | 305 if occupants is not None or nick is not None: |
267 raise exceptions.InternalError(u"only group chat can have occupants or nick") | 306 raise exceptions.InternalError( |
307 u"only group chat can have occupants or nick" | |
308 ) | |
268 self.messages = OrderedDict() # key: uid, value: Message instance | 309 self.messages = OrderedDict() # key: uid, value: Message instance |
269 self.games = {} # key=game name (unicode), value=instance of quick_games.RoomGame | 310 self.games = {} # key=game name (unicode), value=instance of quick_games.RoomGame |
270 self.subject = subject | 311 self.subject = subject |
271 lt = time.localtime() | 312 lt = time.localtime() |
272 self.day_change = (lt.tm_year, lt.tm_mon, lt.tm_mday, 0, 0, 0, lt.tm_wday, lt.tm_yday, lt.tm_isdst) # struct_time of day changing time | 313 self.day_change = ( |
314 lt.tm_year, | |
315 lt.tm_mon, | |
316 lt.tm_mday, | |
317 0, | |
318 0, | |
319 0, | |
320 lt.tm_wday, | |
321 lt.tm_yday, | |
322 lt.tm_isdst, | |
323 ) # struct_time of day changing time | |
273 if self.host.AVATARS_HANDLER: | 324 if self.host.AVATARS_HANDLER: |
274 self.host.addListener('avatar', self.onAvatar, profiles) | 325 self.host.addListener("avatar", self.onAvatar, profiles) |
275 | 326 |
276 def postInit(self): | 327 def postInit(self): |
277 """Method to be called by frontend after widget is initialised | 328 """Method to be called by frontend after widget is initialised |
278 | 329 |
279 handle the display of history and subject | 330 handle the display of history and subject |
282 if self.subject is not None: | 333 if self.subject is not None: |
283 self.setSubject(self.subject) | 334 self.setSubject(self.subject) |
284 | 335 |
285 def onDelete(self): | 336 def onDelete(self): |
286 if self.host.AVATARS_HANDLER: | 337 if self.host.AVATARS_HANDLER: |
287 self.host.removeListener('avatar', self.onAvatar) | 338 self.host.removeListener("avatar", self.onAvatar) |
288 | 339 |
289 @property | 340 @property |
290 def contact_list(self): | 341 def contact_list(self): |
291 return self.host.contact_lists[self.profile] | 342 return self.host.contact_lists[self.profile] |
292 | 343 |
293 ## Widget management ## | 344 ## Widget management ## |
294 | 345 |
295 def __str__(self): | 346 def __str__(self): |
296 return u"Chat Widget [target: {}, type: {}, profile: {}]".format(self.target, self.type, self.profile) | 347 return u"Chat Widget [target: {}, type: {}, profile: {}]".format( |
348 self.target, self.type, self.profile | |
349 ) | |
297 | 350 |
298 @staticmethod | 351 @staticmethod |
299 def getWidgetHash(target, profiles): | 352 def getWidgetHash(target, profiles): |
300 profile = list(profiles)[0] | 353 profile = list(profiles)[0] |
301 return profile + "\n" + unicode(target.bare) | 354 return profile + "\n" + unicode(target.bare) |
309 return (unicode(profile), target) | 362 return (unicode(profile), target) |
310 | 363 |
311 def addTarget(self, target): | 364 def addTarget(self, target): |
312 super(QuickChat, self).addTarget(target) | 365 super(QuickChat, self).addTarget(target) |
313 if target.resource: | 366 if target.resource: |
314 self.current_target = target # FIXME: tmp, must use resource priority throught contactList instead | 367 self.current_target = ( |
368 target | |
369 ) # FIXME: tmp, must use resource priority throught contactList instead | |
315 | 370 |
316 def recreateArgs(self, args, kwargs): | 371 def recreateArgs(self, args, kwargs): |
317 """copy important attribute for a new widget""" | 372 """copy important attribute for a new widget""" |
318 kwargs['type_'] = self.type | 373 kwargs["type_"] = self.type |
319 if self.type == C.CHAT_GROUP: | 374 if self.type == C.CHAT_GROUP: |
320 kwargs['occupants'] = {o.nick: o.data for o in self.occupants.itervalues()} | 375 kwargs["occupants"] = {o.nick: o.data for o in self.occupants.itervalues()} |
321 kwargs['subject'] = self.subject | 376 kwargs["subject"] = self.subject |
322 try: | 377 try: |
323 kwargs['nick'] = self.nick | 378 kwargs["nick"] = self.nick |
324 except AttributeError: | 379 except AttributeError: |
325 pass | 380 pass |
326 | 381 |
327 def onPrivateCreated(self, widget): | 382 def onPrivateCreated(self, widget): |
328 """Method called when a new widget for private conversation (MUC) is created""" | 383 """Method called when a new widget for private conversation (MUC) is created""" |
331 def getOrCreatePrivateWidget(self, entity): | 386 def getOrCreatePrivateWidget(self, entity): |
332 """Create a widget for private conversation, or get it if it already exists | 387 """Create a widget for private conversation, or get it if it already exists |
333 | 388 |
334 @param entity: full jid of the target | 389 @param entity: full jid of the target |
335 """ | 390 """ |
336 return self.host.widgets.getOrCreateWidget(QuickChat, entity, type_=C.CHAT_ONE2ONE, force_hash=self.getPrivateHash(self.profile, entity), on_new_widget=self.onPrivateCreated, profile=self.profile) # we force hash to have a new widget, not this one again | 391 return self.host.widgets.getOrCreateWidget( |
392 QuickChat, | |
393 entity, | |
394 type_=C.CHAT_ONE2ONE, | |
395 force_hash=self.getPrivateHash(self.profile, entity), | |
396 on_new_widget=self.onPrivateCreated, | |
397 profile=self.profile, | |
398 ) # we force hash to have a new widget, not this one again | |
337 | 399 |
338 @property | 400 @property |
339 def target(self): | 401 def target(self): |
340 if self.type == C.CHAT_GROUP: | 402 if self.type == C.CHAT_GROUP: |
341 return self.current_target.bare | 403 return self.current_target.bare |
345 | 407 |
346 def setOccupants(self, occupants): | 408 def setOccupants(self, occupants): |
347 """set the whole list of occupants""" | 409 """set the whole list of occupants""" |
348 assert len(self.occupants) == 0 | 410 assert len(self.occupants) == 0 |
349 for nick, data in occupants.iteritems(): | 411 for nick, data in occupants.iteritems(): |
350 self.occupants[nick] = Occupant( | 412 self.occupants[nick] = Occupant(self, data, self.profile) |
351 self, | |
352 data, | |
353 self.profile | |
354 ) | |
355 | 413 |
356 def addUser(self, occupant_data): | 414 def addUser(self, occupant_data): |
357 """Add user if it is not in the group list""" | 415 """Add user if it is not in the group list""" |
358 occupant = Occupant( | 416 occupant = Occupant(self, occupant_data, self.profile) |
359 self, | |
360 occupant_data, | |
361 self.profile | |
362 ) | |
363 self.occupants[occupant.nick] = occupant | 417 self.occupants[occupant.nick] = occupant |
364 return occupant | 418 return occupant |
365 | 419 |
366 def removeUser(self, occupant_data): | 420 def removeUser(self, occupant_data): |
367 """Remove a user from the group list""" | 421 """Remove a user from the group list""" |
368 nick = occupant_data['nick'] | 422 nick = occupant_data["nick"] |
369 try: | 423 try: |
370 occupant = self.occupants.pop(nick) | 424 occupant = self.occupants.pop(nick) |
371 except KeyError: | 425 except KeyError: |
372 log.warning(u"Trying to remove an unknown occupant: {}".format(nick)) | 426 log.warning(u"Trying to remove an unknown occupant: {}".format(nick)) |
373 else: | 427 else: |
389 @param entity (jid.JID): (full) jid of the sending entity | 443 @param entity (jid.JID): (full) jid of the sending entity |
390 @param mess_type (str): message type as given by messageNew | 444 @param mess_type (str): message type as given by messageNew |
391 @return (bool): True if this Chat Widget manage this couple | 445 @return (bool): True if this Chat Widget manage this couple |
392 """ | 446 """ |
393 if self.type == C.CHAT_GROUP: | 447 if self.type == C.CHAT_GROUP: |
394 if mess_type in (C.MESS_TYPE_GROUPCHAT, C.MESS_TYPE_INFO) and self.target == entity.bare: | 448 if ( |
449 mess_type in (C.MESS_TYPE_GROUPCHAT, C.MESS_TYPE_INFO) | |
450 and self.target == entity.bare | |
451 ): | |
395 return True | 452 return True |
396 else: | 453 else: |
397 if mess_type != C.MESS_TYPE_GROUPCHAT and entity in self.targets: | 454 if mess_type != C.MESS_TYPE_GROUPCHAT and entity in self.targets: |
398 return True | 455 return True |
399 return False | 456 return False |
400 | 457 |
401 def updateHistory(self, size=C.HISTORY_LIMIT_DEFAULT, filters=None, profile='@NONE@'): | 458 def updateHistory(self, size=C.HISTORY_LIMIT_DEFAULT, filters=None, profile="@NONE@"): |
402 """Called when history need to be recreated | 459 """Called when history need to be recreated |
403 | 460 |
404 Remove all message from history then call historyPrint | 461 Remove all message from history then call historyPrint |
405 Must probably be overriden by frontend to clear widget | 462 Must probably be overriden by frontend to clear widget |
406 @param size (int): number of messages | 463 @param size (int): number of messages |
421 self._locked = False | 478 self._locked = False |
422 for data in self._cache.itervalues(): | 479 for data in self._cache.itervalues(): |
423 self.messageNew(*data) | 480 self.messageNew(*data) |
424 del self._cache | 481 del self._cache |
425 | 482 |
426 def historyPrint(self, size=C.HISTORY_LIMIT_DEFAULT, filters=None, profile='@NONE@'): | 483 def historyPrint(self, size=C.HISTORY_LIMIT_DEFAULT, filters=None, profile="@NONE@"): |
427 """Print the current history | 484 """Print the current history |
428 | 485 |
429 @param size (int): number of messages | 486 @param size (int): number of messages |
430 @param search (str): pattern to filter the history results | 487 @param search (str): pattern to filter the history results |
431 @param profile (str): %(doc_profile)s | 488 @param profile (str): %(doc_profile)s |
440 if size != C.HISTORY_LIMIT_DEFAULT: | 497 if size != C.HISTORY_LIMIT_DEFAULT: |
441 log_msg += _(u" ({} messages)".format(size)) | 498 log_msg += _(u" ({} messages)".format(size)) |
442 log.debug(log_msg) | 499 log.debug(log_msg) |
443 | 500 |
444 if self.type == C.CHAT_ONE2ONE: | 501 if self.type == C.CHAT_ONE2ONE: |
445 special = self.host.contact_lists[self.profile].getCache(self.target, C.CONTACT_SPECIAL) | 502 special = self.host.contact_lists[self.profile].getCache( |
503 self.target, C.CONTACT_SPECIAL | |
504 ) | |
446 if special == C.CONTACT_SPECIAL_GROUP: | 505 if special == C.CONTACT_SPECIAL_GROUP: |
447 # we have a private conversation | 506 # we have a private conversation |
448 # so we need full jid for the history | 507 # so we need full jid for the history |
449 # (else we would get history from group itself) | 508 # (else we would get history from group itself) |
450 # and to filter out groupchat message | 509 # and to filter out groupchat message |
451 target = self.target | 510 target = self.target |
452 filters['not_types'] = C.MESS_TYPE_GROUPCHAT | 511 filters["not_types"] = C.MESS_TYPE_GROUPCHAT |
453 else: | 512 else: |
454 target = self.target.bare | 513 target = self.target.bare |
455 else: | 514 else: |
456 # groupchat | 515 # groupchat |
457 target = self.target.bare | 516 target = self.target.bare |
458 # FIXME: info not handled correctly | 517 # FIXME: info not handled correctly |
459 filters['types'] = C.MESS_TYPE_GROUPCHAT | 518 filters["types"] = C.MESS_TYPE_GROUPCHAT |
460 | 519 |
461 def _historyGetCb(history): | 520 def _historyGetCb(history): |
462 # day_format = "%A, %d %b %Y" # to display the day change | 521 # day_format = "%A, %d %b %Y" # to display the day change |
463 # previous_day = datetime.now().strftime(day_format) | 522 # previous_day = datetime.now().strftime(day_format) |
464 # message_day = datetime.fromtimestamp(timestamp).strftime(self.day_format) | 523 # message_day = datetime.fromtimestamp(timestamp).strftime(self.day_format) |
474 from_jid = jid.JID(from_jid) | 533 from_jid = jid.JID(from_jid) |
475 to_jid = jid.JID(to_jid) | 534 to_jid = jid.JID(to_jid) |
476 # if ((self.type == C.CHAT_GROUP and type_ != C.MESS_TYPE_GROUPCHAT) or | 535 # if ((self.type == C.CHAT_GROUP and type_ != C.MESS_TYPE_GROUPCHAT) or |
477 # (self.type == C.CHAT_ONE2ONE and type_ == C.MESS_TYPE_GROUPCHAT)): | 536 # (self.type == C.CHAT_ONE2ONE and type_ == C.MESS_TYPE_GROUPCHAT)): |
478 # continue | 537 # continue |
479 extra['history'] = True | 538 extra["history"] = True |
480 self.messages[uid] = Message(self, uid, timestamp, from_jid, to_jid, message, subject, type_, extra, profile) | 539 self.messages[uid] = Message( |
540 self, | |
541 uid, | |
542 timestamp, | |
543 from_jid, | |
544 to_jid, | |
545 message, | |
546 subject, | |
547 type_, | |
548 extra, | |
549 profile, | |
550 ) | |
481 self._onHistoryPrinted() | 551 self._onHistoryPrinted() |
482 | 552 |
483 def _historyGetEb(err): | 553 def _historyGetEb(err): |
484 log.error(_(u"Can't get history: {}").format(err)) | 554 log.error(_(u"Can't get history: {}").format(err)) |
485 self._onHistoryPrinted() | 555 self._onHistoryPrinted() |
486 | 556 |
487 self.host.bridge.historyGet(unicode(self.host.profiles[profile].whoami.bare), unicode(target), size, True, filters, profile, callback=_historyGetCb, errback=_historyGetEb) | 557 self.host.bridge.historyGet( |
488 | 558 unicode(self.host.profiles[profile].whoami.bare), |
489 def messageNew(self, uid, timestamp, from_jid, to_jid, msg, subject, type_, extra, profile): | 559 unicode(target), |
560 size, | |
561 True, | |
562 filters, | |
563 profile, | |
564 callback=_historyGetCb, | |
565 errback=_historyGetEb, | |
566 ) | |
567 | |
568 def messageNew( | |
569 self, uid, timestamp, from_jid, to_jid, msg, subject, type_, extra, profile | |
570 ): | |
490 if self._locked: | 571 if self._locked: |
491 self._cache[uid] = (uid, timestamp, from_jid, to_jid, msg, subject, type_, extra, profile) | 572 self._cache[uid] = ( |
573 uid, | |
574 timestamp, | |
575 from_jid, | |
576 to_jid, | |
577 msg, | |
578 subject, | |
579 type_, | |
580 extra, | |
581 profile, | |
582 ) | |
492 return | 583 return |
493 if self.type == C.CHAT_GROUP: | 584 if self.type == C.CHAT_GROUP: |
494 if to_jid.resource and type_ != C.MESS_TYPE_GROUPCHAT: | 585 if to_jid.resource and type_ != C.MESS_TYPE_GROUPCHAT: |
495 # we have a private message, we forward it to a private conversation widget | 586 # we have a private message, we forward it to a private conversation widget |
496 chat_widget = self.getOrCreatePrivateWidget(to_jid) | 587 chat_widget = self.getOrCreatePrivateWidget(to_jid) |
497 chat_widget.messageNew(uid, timestamp, from_jid, to_jid, msg, subject, type_, extra, profile) | 588 chat_widget.messageNew( |
589 uid, timestamp, from_jid, to_jid, msg, subject, type_, extra, profile | |
590 ) | |
498 return | 591 return |
499 if type_ == C.MESS_TYPE_INFO: | 592 if type_ == C.MESS_TYPE_INFO: |
500 try: | 593 try: |
501 info_type = extra['info_type'] | 594 info_type = extra["info_type"] |
502 except KeyError: | 595 except KeyError: |
503 pass | 596 pass |
504 else: | 597 else: |
505 user_data = {k[5:]:v for k,v in extra.iteritems() if k.startswith('user_')} | 598 user_data = { |
599 k[5:]: v for k, v in extra.iteritems() if k.startswith("user_") | |
600 } | |
506 if info_type == ROOM_USER_JOINED: | 601 if info_type == ROOM_USER_JOINED: |
507 self.addUser(user_data) | 602 self.addUser(user_data) |
508 elif info_type == ROOM_USER_LEFT: | 603 elif info_type == ROOM_USER_LEFT: |
509 self.removeUser(user_data) | 604 self.removeUser(user_data) |
510 | 605 |
511 message = Message(self, uid, timestamp, from_jid, to_jid, msg, subject, type_, extra, profile) | 606 message = Message( |
607 self, uid, timestamp, from_jid, to_jid, msg, subject, type_, extra, profile | |
608 ) | |
512 self.messages[uid] = message | 609 self.messages[uid] = message |
513 | 610 |
514 if 'received_timestamp' in extra: | 611 if "received_timestamp" in extra: |
515 log.warning(u"Delayed message received after history, this should not happen") | 612 log.warning(u"Delayed message received after history, this should not happen") |
516 self.createMessage(message) | 613 self.createMessage(message) |
517 | 614 |
518 def createMessage(self, message, append=False): | 615 def createMessage(self, message, append=False): |
519 """Must be implemented by frontend to create and show a new message widget | 616 """Must be implemented by frontend to create and show a new message widget |
535 ## Room ## | 632 ## Room ## |
536 | 633 |
537 def setSubject(self, subject): | 634 def setSubject(self, subject): |
538 """Set title for a group chat""" | 635 """Set title for a group chat""" |
539 if self.type != C.CHAT_GROUP: | 636 if self.type != C.CHAT_GROUP: |
540 raise exceptions.InternalError("trying to set subject for a non group chat window") | 637 raise exceptions.InternalError( |
638 "trying to set subject for a non group chat window" | |
639 ) | |
541 self.subject = subject | 640 self.subject = subject |
542 | 641 |
543 def changeSubject(self, new_subject): | 642 def changeSubject(self, new_subject): |
544 """Change the subject of the room | 643 """Change the subject of the room |
545 | 644 |
577 if self.type == C.CHAT_GROUP: | 676 if self.type == C.CHAT_GROUP: |
578 nick = from_jid.resource | 677 nick = from_jid.resource |
579 try: | 678 try: |
580 self.occupants[nick].state = state | 679 self.occupants[nick].state = state |
581 except KeyError: | 680 except KeyError: |
582 log.warning(u"{nick} not found in {room}, ignoring new chat state".format( | 681 log.warning( |
583 nick=nick, room=self.target.bare)) | 682 u"{nick} not found in {room}, ignoring new chat state".format( |
683 nick=nick, room=self.target.bare | |
684 ) | |
685 ) | |
584 | 686 |
585 def onMessageState(self, uid, status, profile): | 687 def onMessageState(self, uid, status, profile): |
586 try: | 688 try: |
587 mess_data = self.messages[uid] | 689 mess_data = self.messages[uid] |
588 except KeyError: | 690 except KeyError: |
592 | 694 |
593 def onAvatar(self, entity, filename, profile): | 695 def onAvatar(self, entity, filename, profile): |
594 if self.type == C.CHAT_GROUP: | 696 if self.type == C.CHAT_GROUP: |
595 if entity.bare == self.target: | 697 if entity.bare == self.target: |
596 try: | 698 try: |
597 self.occupants[entity.resource].update({'avatar': filename}) | 699 self.occupants[entity.resource].update({"avatar": filename}) |
598 except KeyError: | 700 except KeyError: |
599 # can happen for a message in history where the | 701 # can happen for a message in history where the |
600 # entity is not here anymore | 702 # entity is not here anymore |
601 pass | 703 pass |
602 | 704 |
603 for m in self.messages.values(): | 705 for m in self.messages.values(): |
604 if m.nick == entity.resource: | 706 if m.nick == entity.resource: |
605 for w in m.widgets: | 707 for w in m.widgets: |
606 w.update({'avatar': filename}) | 708 w.update({"avatar": filename}) |
607 else: | 709 else: |
608 if entity.bare == self.target.bare or entity.bare == self.host.profiles[profile].whoami.bare: | 710 if ( |
711 entity.bare == self.target.bare | |
712 or entity.bare == self.host.profiles[profile].whoami.bare | |
713 ): | |
609 log.info(u"avatar updated for {}".format(entity)) | 714 log.info(u"avatar updated for {}".format(entity)) |
610 for m in self.messages.values(): | 715 for m in self.messages.values(): |
611 if m.from_jid.bare == entity.bare: | 716 if m.from_jid.bare == entity.bare: |
612 for w in m.widgets: | 717 for w in m.widgets: |
613 w.update({'avatar': filename}) | 718 w.update({"avatar": filename}) |
614 | 719 |
615 | 720 |
616 quick_widgets.register(QuickChat) | 721 quick_widgets.register(QuickChat) |