comparison cagou/plugins/plugin_wid_chat.py @ 312:772c170b47a9

Python3 port: /!\ Cagou now runs with Python 3.6+ Port has been done in the same way as for backend (check backend commit b2d067339de3 message for details).
author Goffi <goffi@goffi.org>
date Tue, 13 Aug 2019 19:14:22 +0200
parents fe8639e64c69
children e2b51663d8b8
comparison
equal deleted inserted replaced
311:a0d978d3ce84 312:772c170b47a9
44 from cagou.core import menu 44 from cagou.core import menu
45 45
46 log = logging.getLogger(__name__) 46 log = logging.getLogger(__name__)
47 47
48 PLUGIN_INFO = { 48 PLUGIN_INFO = {
49 "name": _(u"chat"), 49 "name": _("chat"),
50 "main": "Chat", 50 "main": "Chat",
51 "description": _(u"instant messaging with one person or a group"), 51 "description": _("instant messaging with one person or a group"),
52 "icon_symbol": u"chat", 52 "icon_symbol": "chat",
53 } 53 }
54 54
55 # FIXME: OTR specific code is legacy, and only used nowadays for lock color 55 # FIXME: OTR specific code is legacy, and only used nowadays for lock color
56 # we can probably get rid of them. 56 # we can probably get rid of them.
57 OTR_STATE_UNTRUSTED = 'untrusted' 57 OTR_STATE_UNTRUSTED = 'untrusted'
97 def _get_message(self): 97 def _get_message(self):
98 """Return currently displayed message""" 98 """Return currently displayed message"""
99 return self.mess_data.main_message 99 return self.mess_data.main_message
100 100
101 def _set_message(self, message): 101 def _set_message(self, message):
102 if message == self.mess_data.message.get(u""): 102 if message == self.mess_data.message.get(""):
103 return False 103 return False
104 self.mess_data.message = {u"": message} 104 self.mess_data.message = {"": message}
105 return True 105 return True
106 106
107 message = properties.AliasProperty(_get_message, _set_message) 107 message = properties.AliasProperty(_get_message, _set_message)
108 108
109 @property 109 @property
133 def update(self, update_dict): 133 def update(self, update_dict):
134 if 'avatar' in update_dict: 134 if 'avatar' in update_dict:
135 self.avatar.source = update_dict['avatar'] 135 self.avatar.source = update_dict['avatar']
136 if 'status' in update_dict: 136 if 'status' in update_dict:
137 status = update_dict['status'] 137 status = update_dict['status']
138 self.delivery.text = u'\u2714' if status == 'delivered' else u'' 138 self.delivery.text = '\u2714' if status == 'delivered' else ''
139 139
140 140
141 class SendButton(SymbolButton): 141 class SendButton(SymbolButton):
142 message_input_box = properties.ObjectProperty() 142 message_input_box = properties.ObjectProperty()
143 143
189 class ExtraMenu(DropDown): 189 class ExtraMenu(DropDown):
190 chat = properties.ObjectProperty() 190 chat = properties.ObjectProperty()
191 191
192 def on_select(self, menu): 192 def on_select(self, menu):
193 if menu == 'bookmark': 193 if menu == 'bookmark':
194 G.host.bridge.menuLaunch(C.MENU_GLOBAL, (u"groups", u"bookmarks"), 194 G.host.bridge.menuLaunch(C.MENU_GLOBAL, ("groups", "bookmarks"),
195 {}, C.NO_SECURITY_LIMIT, self.chat.profile, 195 {}, C.NO_SECURITY_LIMIT, self.chat.profile,
196 callback=partial( 196 callback=partial(
197 G.host.actionManager, profile=self.chat.profile), 197 G.host.actionManager, profile=self.chat.profile),
198 errback=G.host.errback) 198 errback=G.host.errback)
199 else: 199 else:
200 raise exceptions.InternalError(u"Unknown menu: {}".format(menu)) 200 raise exceptions.InternalError("Unknown menu: {}".format(menu))
201 201
202 202
203 class ExtraButton(SymbolButton): 203 class ExtraButton(SymbolButton):
204 chat = properties.ObjectProperty() 204 chat = properties.ObjectProperty()
205 205
251 class EncryptionButton(BoxLayout): 251 class EncryptionButton(BoxLayout):
252 selected = properties.BooleanProperty(False) 252 selected = properties.BooleanProperty(False)
253 text = properties.StringProperty() 253 text = properties.StringProperty()
254 trust_button = properties.BooleanProperty(False) 254 trust_button = properties.BooleanProperty(False)
255 best_width = properties.NumericProperty(0) 255 best_width = properties.NumericProperty(0)
256 bold = properties.BooleanProperty(True)
256 257
257 def __init__(self, **kwargs): 258 def __init__(self, **kwargs):
259 super(EncryptionButton, self).__init__(**kwargs)
258 self.register_event_type('on_release') 260 self.register_event_type('on_release')
259 self.register_event_type('on_trust_release') 261 self.register_event_type('on_trust_release')
260 super(EncryptionButton, self).__init__(**kwargs)
261 if self.trust_button: 262 if self.trust_button:
262 self.add_widget(TrustManagementButton()) 263 self.add_widget(TrustManagementButton())
263 264
264 def on_release(self): 265 def on_release(self):
265 pass 266 pass
277 @param chat(Chat): Chat instance 278 @param chat(Chat): Chat instance
278 """ 279 """
279 self.chat = chat 280 self.chat = chat
280 super(EncryptionMenu, self).__init__(**kwargs) 281 super(EncryptionMenu, self).__init__(**kwargs)
281 btn = EncryptionButton( 282 btn = EncryptionButton(
282 text=_(u"unencrypted (plain text)"), 283 text=_("unencrypted (plain text)"),
283 on_release=self.unencrypted, 284 on_release=self.unencrypted,
284 selected=True, 285 selected=True,
285 bold=False, 286 bold=False,
286 ) 287 )
287 self.add_widget(btn) 288 self.add_widget(btn)
288 for plugin in G.host.encryption_plugins: 289 for plugin in G.host.encryption_plugins:
289 btn = EncryptionButton( 290 btn = EncryptionButton(
290 text=plugin[u'name'], 291 text=plugin['name'],
291 on_release=partial(self.startEncryption, plugin=plugin), 292 on_release=partial(self.startEncryption, plugin=plugin),
292 on_trust_release=partial(self.getTrustUI, plugin=plugin), 293 on_trust_release=partial(self.getTrustUI, plugin=plugin),
293 trust_button=True, 294 trust_button=True,
294 ) 295 )
295 self.add_widget(btn) 296 self.add_widget(btn)
296 log.info("added encryption: {}".format(plugin['name'])) 297 log.info("added encryption: {}".format(plugin['name']))
297 298
298 def messageEncryptionStopCb(self): 299 def messageEncryptionStopCb(self):
299 log.info(_(u"Session with {destinee} is now in plain text").format( 300 log.info(_("Session with {destinee} is now in plain text").format(
300 destinee = self.chat.target)) 301 destinee = self.chat.target))
301 302
302 def messageEncryptionStopEb(self, failure_): 303 def messageEncryptionStopEb(self, failure_):
303 msg = _(u"Error while stopping encryption with {destinee}: {reason}").format( 304 msg = _("Error while stopping encryption with {destinee}: {reason}").format(
304 destinee = self.chat.target, 305 destinee = self.chat.target,
305 reason = failure_) 306 reason = failure_)
306 log.warning(msg) 307 log.warning(msg)
307 G.host.addNote(_(u"encryption problem"), msg, C.XMLUI_DATA_LVL_ERROR) 308 G.host.addNote(_("encryption problem"), msg, C.XMLUI_DATA_LVL_ERROR)
308 309
309 def unencrypted(self, button): 310 def unencrypted(self, button):
310 self.dismiss() 311 self.dismiss()
311 G.host.bridge.messageEncryptionStop( 312 G.host.bridge.messageEncryptionStop(
312 unicode(self.chat.target), 313 str(self.chat.target),
313 self.chat.profile, 314 self.chat.profile,
314 callback=self.messageEncryptionStopCb, 315 callback=self.messageEncryptionStopCb,
315 errback=self.messageEncryptionStopEb) 316 errback=self.messageEncryptionStopEb)
316 317
317 def messageEncryptionStartCb(self, plugin): 318 def messageEncryptionStartCb(self, plugin):
318 log.info(_(u"Session with {destinee} is now encrypted with {encr_name}").format( 319 log.info(_("Session with {destinee} is now encrypted with {encr_name}").format(
319 destinee = self.chat.target, 320 destinee = self.chat.target,
320 encr_name = plugin['name'])) 321 encr_name = plugin['name']))
321 322
322 def messageEncryptionStartEb(self, failure_): 323 def messageEncryptionStartEb(self, failure_):
323 msg = _(u"Session can't be encrypted with {destinee}: {reason}").format( 324 msg = _("Session can't be encrypted with {destinee}: {reason}").format(
324 destinee = self.chat.target, 325 destinee = self.chat.target,
325 reason = failure_) 326 reason = failure_)
326 log.warning(msg) 327 log.warning(msg)
327 G.host.addNote(_(u"encryption problem"), msg, C.XMLUI_DATA_LVL_ERROR) 328 G.host.addNote(_("encryption problem"), msg, C.XMLUI_DATA_LVL_ERROR)
328 329
329 def startEncryption(self, button, plugin): 330 def startEncryption(self, button, plugin):
330 """Request encryption with given plugin for this session 331 """Request encryption with given plugin for this session
331 332
332 @param button(EncryptionButton): button which has been pressed 333 @param button(EncryptionButton): button which has been pressed
333 @param plugin(dict): plugin data 334 @param plugin(dict): plugin data
334 """ 335 """
335 self.dismiss() 336 self.dismiss()
336 G.host.bridge.messageEncryptionStart( 337 G.host.bridge.messageEncryptionStart(
337 unicode(self.chat.target), 338 str(self.chat.target),
338 plugin['namespace'], 339 plugin['namespace'],
339 True, 340 True,
340 self.chat.profile, 341 self.chat.profile,
341 callback=partial(self.messageEncryptionStartCb, plugin=plugin), 342 callback=partial(self.messageEncryptionStartCb, plugin=plugin),
342 errback=self.messageEncryptionStartEb) 343 errback=self.messageEncryptionStartEb)
345 xml_ui = xmlui.create( 346 xml_ui = xmlui.create(
346 G.host, xmlui_raw, profile=self.chat.profile) 347 G.host, xmlui_raw, profile=self.chat.profile)
347 xml_ui.show() 348 xml_ui.show()
348 349
349 def encryptionTrustUIGetEb(self, failure_): 350 def encryptionTrustUIGetEb(self, failure_):
350 msg = _(u"Trust manager interface can't be retrieved: {reason}").format( 351 msg = _("Trust manager interface can't be retrieved: {reason}").format(
351 reason = failure_) 352 reason = failure_)
352 log.warning(msg) 353 log.warning(msg)
353 G.host.addNote(_(u"encryption trust management problem"), msg, 354 G.host.addNote(_("encryption trust management problem"), msg,
354 C.XMLUI_DATA_LVL_ERROR) 355 C.XMLUI_DATA_LVL_ERROR)
355 356
356 def getTrustUI(self, button, plugin): 357 def getTrustUI(self, button, plugin):
357 """Request and display trust management UI 358 """Request and display trust management UI
358 359
359 @param button(EncryptionButton): button which has been pressed 360 @param button(EncryptionButton): button which has been pressed
360 @param plugin(dict): plugin data 361 @param plugin(dict): plugin data
361 """ 362 """
362 self.dismiss() 363 self.dismiss()
363 G.host.bridge.encryptionTrustUIGet( 364 G.host.bridge.encryptionTrustUIGet(
364 unicode(self.chat.target), 365 str(self.chat.target),
365 plugin['namespace'], 366 plugin['namespace'],
366 self.chat.profile, 367 self.chat.profile,
367 callback=self.encryptionTrustUIGetCb, 368 callback=self.encryptionTrustUIGetCb,
368 errback=self.encryptionTrustUIGetEb) 369 errback=self.encryptionTrustUIGetEb)
369 370
370 def otr_start(self): 371 def otr_start(self):
371 self.dismiss() 372 self.dismiss()
372 G.host.launchMenu( 373 G.host.launchMenu(
373 C.MENU_SINGLE, 374 C.MENU_SINGLE,
374 (u"otr", u"start/refresh"), 375 ("otr", "start/refresh"),
375 {u'jid': unicode(self.chat.target)}, 376 {'jid': str(self.chat.target)},
376 None, 377 None,
377 C.NO_SECURITY_LIMIT, 378 C.NO_SECURITY_LIMIT,
378 self.chat.profile 379 self.chat.profile
379 ) 380 )
380 381
381 def otr_end(self): 382 def otr_end(self):
382 self.dismiss() 383 self.dismiss()
383 G.host.launchMenu( 384 G.host.launchMenu(
384 C.MENU_SINGLE, 385 C.MENU_SINGLE,
385 (u"otr", u"end session"), 386 ("otr", "end session"),
386 {u'jid': unicode(self.chat.target)}, 387 {'jid': str(self.chat.target)},
387 None, 388 None,
388 C.NO_SECURITY_LIMIT, 389 C.NO_SECURITY_LIMIT,
389 self.chat.profile 390 self.chat.profile
390 ) 391 )
391 392
392 def otr_authenticate(self): 393 def otr_authenticate(self):
393 self.dismiss() 394 self.dismiss()
394 G.host.launchMenu( 395 G.host.launchMenu(
395 C.MENU_SINGLE, 396 C.MENU_SINGLE,
396 (u"otr", u"authenticate"), 397 ("otr", "authenticate"),
397 {u'jid': unicode(self.chat.target)}, 398 {'jid': str(self.chat.target)},
398 None, 399 None,
399 C.NO_SECURITY_LIMIT, 400 C.NO_SECURITY_LIMIT,
400 self.chat.profile 401 self.chat.profile
401 ) 402 )
402 403
423 self.encryption_btn = EncryptionMainButton(self) 424 self.encryption_btn = EncryptionMainButton(self)
424 self.headerInputAddExtra(self.encryption_btn) 425 self.headerInputAddExtra(self.encryption_btn)
425 self.extra_menu = ExtraMenu(chat=self) 426 self.extra_menu = ExtraMenu(chat=self)
426 extra_btn = ExtraButton(chat=self) 427 extra_btn = ExtraButton(chat=self)
427 self.headerInputAddExtra(extra_btn) 428 self.headerInputAddExtra(extra_btn)
428 self.header_input.hint_text = u"{}".format(target) 429 self.header_input.hint_text = "{}".format(target)
429 self.postInit() 430 self.postInit()
430 431
431 def __unicode__(self):
432 return u"Chat({})".format(self.target)
433
434 def __str__(self): 432 def __str__(self):
435 return self.__unicode__().encode('utf-8') 433 return "Chat({})".format(self.target)
436 434
437 def __repr__(self): 435 def __repr__(self):
438 return self.__str__() 436 return self.__str__()
439 437
440 @classmethod 438 @classmethod
441 def factory(cls, plugin_info, target, profiles): 439 def factory(cls, plugin_info, target, profiles):
442 profiles = list(profiles) 440 profiles = list(profiles)
443 if len(profiles) > 1: 441 if len(profiles) > 1:
444 raise NotImplementedError(u"Multi-profiles is not available yet for chat") 442 raise NotImplementedError("Multi-profiles is not available yet for chat")
445 if target is None: 443 if target is None:
446 target = G.host.profiles[profiles[0]].whoami 444 target = G.host.profiles[profiles[0]].whoami
447 return G.host.widgets.getOrCreateWidget(cls, target, on_new_widget=None, 445 return G.host.widgets.getOrCreateWidget(cls, target, on_new_widget=None,
448 on_existing_widget=G.host.getOrClone, 446 on_existing_widget=G.host.getOrClone,
449 profiles=profiles) 447 profiles=profiles)
465 self.header_input.text = '' 463 self.header_input.text = ''
466 464
467 def onHeaderInput(self): 465 def onHeaderInput(self):
468 text = self.header_input.text.strip() 466 text = self.header_input.text.strip()
469 try: 467 try:
470 if text.count(u'@') != 1 or text.count(u' '): 468 if text.count('@') != 1 or text.count(' '):
471 raise ValueError 469 raise ValueError
472 jid_ = jid.JID(text) 470 jid_ = jid.JID(text)
473 except ValueError: 471 except ValueError:
474 log.info(u"entered text is not a jid") 472 log.info("entered text is not a jid")
475 return 473 return
476 474
477 def discoCb(disco): 475 def discoCb(disco):
478 # TODO: check if plugin XEP-0045 is activated 476 # TODO: check if plugin XEP-0045 is activated
479 if "conference" in [i[0] for i in disco[1]]: 477 if "conference" in [i[0] for i in disco[1]]:
480 G.host.bridge.mucJoin(unicode(jid_), "", "", self.profile, 478 G.host.bridge.mucJoin(str(jid_), "", "", self.profile,
481 callback=self._mucJoinCb, errback=self._mucJoinEb) 479 callback=self._mucJoinCb, errback=self._mucJoinEb)
482 else: 480 else:
483 self.changeWidget(jid_) 481 self.changeWidget(jid_)
484 482
485 def discoEb(failure): 483 def discoEb(failure):
486 log.warning(u"Disco failure, ignore this text: {}".format(failure)) 484 log.warning("Disco failure, ignore this text: {}".format(failure))
487 485
488 G.host.bridge.discoInfos(jid_.domain, self.profile, callback=discoCb, 486 G.host.bridge.discoInfos(jid_.domain, self.profile, callback=discoCb,
489 errback=discoEb) 487 errback=discoEb)
490 488
491 def onHeaderInputCompleted(self, input_wid, completed_text): 489 def onHeaderInputCompleted(self, input_wid, completed_text):
524 if not text.startswith(self._hi_comp_last) or not self._hi_comp_last: 522 if not text.startswith(self._hi_comp_last) or not self._hi_comp_last:
525 # text has changed or backspace has been pressed, we restart 523 # text has changed or backspace has been pressed, we restart
526 dropdown.clear_widgets() 524 dropdown.clear_widgets()
527 525
528 for jid_, jid_data in comp_data: 526 for jid_, jid_data in comp_data:
529 nick = jid_data.get(u'nick', u'') 527 nick = jid_data.get('nick', '')
530 if text in jid_.bare or text in nick.lower(): 528 if text in jid_.bare or text in nick.lower():
531 btn = JidButton( 529 btn = JidButton(
532 jid = jid_.bare, 530 jid = jid_.bare,
533 profile = profile, 531 profile = profile,
534 size_hint = (0.5, None), 532 size_hint = (0.5, None),
552 return {"mess_data": self.messages[mess_id]} 550 return {"mess_data": self.messages[mess_id]}
553 551
554 def _onHistoryPrinted(self): 552 def _onHistoryPrinted(self):
555 """Refresh or scroll down the focus after the history is printed""" 553 """Refresh or scroll down the focus after the history is printed"""
556 # self.adapter.data = self.messages 554 # self.adapter.data = self.messages
557 for mess_data in self.messages.itervalues(): 555 for mess_data in self.messages.values():
558 self.appendMessage(mess_data) 556 self.appendMessage(mess_data)
559 super(Chat, self)._onHistoryPrinted() 557 super(Chat, self)._onHistoryPrinted()
560 558
561 def createMessage(self, message): 559 def createMessage(self, message):
562 self.appendMessage(message) 560 self.appendMessage(message)
570 return 568 return
571 self.messages_widget.add_widget(MessageWidget(mess_data=mess_data)) 569 self.messages_widget.add_widget(MessageWidget(mess_data=mess_data))
572 self.notify(mess_data) 570 self.notify(mess_data)
573 571
574 def _get_notif_msg(self, mess_data): 572 def _get_notif_msg(self, mess_data):
575 return _(u"{nick}: {message}").format( 573 return _("{nick}: {message}").format(
576 nick=mess_data.nick, 574 nick=mess_data.nick,
577 message=mess_data.main_message) 575 message=mess_data.main_message)
578 576
579 def notify(self, mess_data): 577 def notify(self, mess_data):
580 """Notify user when suitable 578 """Notify user when suitable
595 if self.type == C.CHAT_ONE2ONE: 593 if self.type == C.CHAT_ONE2ONE:
596 if (not Window.focus or not is_visible) and not mess_data.history: 594 if (not Window.focus or not is_visible) and not mess_data.history:
597 notif_msg = self._get_notif_msg(mess_data) 595 notif_msg = self._get_notif_msg(mess_data)
598 G.host.desktop_notif( 596 G.host.desktop_notif(
599 notif_msg, 597 notif_msg,
600 title=_(u"private message")) 598 title=_("private message"))
601 if not is_visible: 599 if not is_visible:
602 G.host.addNote( 600 G.host.addNote(
603 _(u"private message"), 601 _("private message"),
604 notif_msg, 602 notif_msg,
605 symbol = u"chat", 603 symbol = "chat",
606 action = { 604 action = {
607 "action": u'chat', 605 "action": 'chat',
608 "target": self.target, 606 "target": self.target,
609 "profiles": self.profiles} 607 "profiles": self.profiles}
610 ) 608 )
611 else: 609 else:
612 if mess_data.mention and not mess_data.history: 610 if mess_data.mention and not mess_data.history:
613 notif_msg = self._get_notif_msg(mess_data) 611 notif_msg = self._get_notif_msg(mess_data)
614 G.host.addNote( 612 G.host.addNote(
615 _(u"mention"), 613 _("mention"),
616 notif_msg, 614 notif_msg,
617 symbol = u"chat", 615 symbol = "chat",
618 action = { 616 action = {
619 "action": u'chat', 617 "action": 'chat',
620 "target": self.target, 618 "target": self.target,
621 "profiles": self.profiles} 619 "profiles": self.profiles}
622 ) 620 )
623 if not Window.focus: 621 if not Window.focus:
624 G.host.desktop_notif( 622 G.host.desktop_notif(
625 notif_msg, 623 notif_msg,
626 title=_(u"mention ({room_jid})").format( 624 title=_("mention ({room_jid})").format(
627 room_jid=self.target) 625 room_jid=self.target)
628 ) 626 )
629 627
630 def onSend(self, input_widget): 628 def onSend(self, input_widget):
631 G.host.messageSend( 629 G.host.messageSend(
638 input_widget.text = '' 636 input_widget.text = ''
639 637
640 def fileTransferEb(self, err_msg, cleaning_cb, profile): 638 def fileTransferEb(self, err_msg, cleaning_cb, profile):
641 if cleaning_cb is not None: 639 if cleaning_cb is not None:
642 cleaning_cb() 640 cleaning_cb()
643 msg = _(u"can't transfer file: {reason}").format(reason=err_msg) 641 msg = _("can't transfer file: {reason}").format(reason=err_msg)
644 log.warning(msg) 642 log.warning(msg)
645 G.host.addNote(_(u"File transfer error"), 643 G.host.addNote(_("File transfer error"),
646 msg, 644 msg,
647 level=C.XMLUI_DATA_LVL_WARNING) 645 level=C.XMLUI_DATA_LVL_WARNING)
648 646
649 def fileTransferCb(self, metadata, cleaning_cb, profile): 647 def fileTransferCb(self, metadata, cleaning_cb, profile):
650 log.debug("file transfered: {}".format(metadata)) 648 log.debug("file transfered: {}".format(metadata))
651 extra = {} 649 extra = {}
652 650
653 # FIXME: Q&D way of getting file type, upload plugins shouls give it 651 # FIXME: Q&D way of getting file type, upload plugins shouls give it
654 mime_type = mimetypes.guess_type(metadata['url'])[0] 652 mime_type = mimetypes.guess_type(metadata['url'])[0]
655 if mime_type is not None: 653 if mime_type is not None:
656 if mime_type.split(u'/')[0] == 'image': 654 if mime_type.split('/')[0] == 'image':
657 # we generate url ourselves, so this formatting is safe 655 # we generate url ourselves, so this formatting is safe
658 extra['xhtml'] = u"<img src='{url}' />".format(**metadata) 656 extra['xhtml'] = "<img src='{url}' />".format(**metadata)
659 657
660 G.host.messageSend( 658 G.host.messageSend(
661 self.target, 659 self.target,
662 {'': metadata['url']}, 660 {'': metadata['url']},
663 mess_type = (C.MESS_TYPE_GROUPCHAT 661 mess_type = (C.MESS_TYPE_GROUPCHAT
680 progress_cb = partial(self.fileTransferCb, cleaning_cb=cleaning_cb), 678 progress_cb = partial(self.fileTransferCb, cleaning_cb=cleaning_cb),
681 progress_eb = partial(self.fileTransferEb, cleaning_cb=cleaning_cb), 679 progress_eb = partial(self.fileTransferEb, cleaning_cb=cleaning_cb),
682 profile = self.profile, 680 profile = self.profile,
683 ), 681 ),
684 errback = partial(G.host.errback, 682 errback = partial(G.host.errback,
685 message=_(u"can't upload file: {msg}")) 683 message=_("can't upload file: {msg}"))
686 ) 684 )
687 elif transfer_type == C.TRANSFER_SEND: 685 elif transfer_type == C.TRANSFER_SEND:
688 if self.type == C.CHAT_GROUP: 686 if self.type == C.CHAT_GROUP:
689 log.warning(u"P2P transfer is not possible for group chat") 687 log.warning("P2P transfer is not possible for group chat")
690 # TODO: show an error dialog to user, or better hide the send button for 688 # TODO: show an error dialog to user, or better hide the send button for
691 # MUC 689 # MUC
692 else: 690 else:
693 jid_ = self.target 691 jid_ = self.target
694 if not jid_.resource: 692 if not jid_.resource:
695 jid_ = G.host.contact_lists[self.profile].getFullJid(jid_) 693 jid_ = G.host.contact_lists[self.profile].getFullJid(jid_)
696 G.host.bridge.fileSend(unicode(jid_), file_path, "", "", {}, 694 G.host.bridge.fileSend(str(jid_), file_path, "", "", {},
697 profile=self.profile) 695 profile=self.profile)
698 # TODO: notification of sending/failing 696 # TODO: notification of sending/failing
699 else: 697 else:
700 raise log.error(u"transfer of type {} are not handled".format(transfer_type)) 698 raise log.error("transfer of type {} are not handled".format(transfer_type))
701 699
702 def messageEncryptionStarted(self, plugin_data): 700 def messageEncryptionStarted(self, plugin_data):
703 quick_chat.QuickChat.messageEncryptionStarted(self, plugin_data) 701 quick_chat.QuickChat.messageEncryptionStarted(self, plugin_data)
704 self.encryption_btn.symbol = SYMBOL_ENCRYPTED 702 self.encryption_btn.symbol = SYMBOL_ENCRYPTED
705 self.encryption_btn.color = COLOR_ENCRYPTED 703 self.encryption_btn.color = COLOR_ENCRYPTED
706 self.encryption_btn.selectAlgo(plugin_data[u'name']) 704 self.encryption_btn.selectAlgo(plugin_data['name'])
707 705
708 def messageEncryptionStopped(self, plugin_data): 706 def messageEncryptionStopped(self, plugin_data):
709 quick_chat.QuickChat.messageEncryptionStopped(self, plugin_data) 707 quick_chat.QuickChat.messageEncryptionStopped(self, plugin_data)
710 self.encryption_btn.symbol = SYMBOL_UNENCRYPTED 708 self.encryption_btn.symbol = SYMBOL_UNENCRYPTED
711 self.encryption_btn.color = COLOR_UNENCRYPTED 709 self.encryption_btn.color = COLOR_UNENCRYPTED
716 self.host.mucRoomJoinedHandler(*joined_data[1:]) 714 self.host.mucRoomJoinedHandler(*joined_data[1:])
717 jid_ = jid.JID(room_jid_s) 715 jid_ = jid.JID(room_jid_s)
718 self.changeWidget(jid_) 716 self.changeWidget(jid_)
719 717
720 def _mucJoinEb(self, failure): 718 def _mucJoinEb(self, failure):
721 log.warning(u"Can't join room: {}".format(failure)) 719 log.warning("Can't join room: {}".format(failure))
722 720
723 def onOTRState(self, state, dest_jid, profile): 721 def onOTRState(self, state, dest_jid, profile):
724 assert profile in self.profiles 722 assert profile in self.profiles
725 if state in OTR_STATE_ENCRYPTION: 723 if state in OTR_STATE_ENCRYPTION:
726 self.otr_state_encryption = state 724 self.otr_state_encryption = state
727 elif state in OTR_STATE_TRUST: 725 elif state in OTR_STATE_TRUST:
728 self.otr_state_trust = state 726 self.otr_state_trust = state
729 else: 727 else:
730 log.error(_(u"Unknown OTR state received: {}".format(state))) 728 log.error(_("Unknown OTR state received: {}".format(state)))
731 return 729 return
732 self.encryption_btn.symbol = self.encryption_btn.getSymbol() 730 self.encryption_btn.symbol = self.encryption_btn.getSymbol()
733 self.encryption_btn.color = self.encryption_btn.getColor() 731 self.encryption_btn.color = self.encryption_btn.getColor()
734 732
735 def onVisible(self): 733 def onVisible(self):