Mercurial > libervia-desktop-kivy
comparison cagou/core/cagou_main.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 | f55b60659ec1 |
children | 86566968837a |
comparison
equal
deleted
inserted
replaced
311:a0d978d3ce84 | 312:772c170b47a9 |
---|---|
22 import glob | 22 import glob |
23 import sys | 23 import sys |
24 from sat.core.i18n import _ | 24 from sat.core.i18n import _ |
25 from . import kivy_hack | 25 from . import kivy_hack |
26 kivy_hack.do_hack() | 26 kivy_hack.do_hack() |
27 from constants import Const as C | 27 from .constants import Const as C |
28 from sat.core import log as logging | 28 from sat.core import log as logging |
29 log = logging.getLogger(__name__) | 29 log = logging.getLogger(__name__) |
30 from sat.core import exceptions | 30 from sat.core import exceptions |
31 from sat_frontends.quick_frontend.quick_app import QuickApp | 31 from sat_frontends.quick_frontend.quick_app import QuickApp |
32 from sat_frontends.quick_frontend import quick_widgets | 32 from sat_frontends.quick_frontend import quick_widgets |
47 elif bridge_name in ('pb', 'embedded'): | 47 elif bridge_name in ('pb', 'embedded'): |
48 kivy.support.install_twisted_reactor() | 48 kivy.support.install_twisted_reactor() |
49 from kivy.app import App | 49 from kivy.app import App |
50 from kivy.lang import Builder | 50 from kivy.lang import Builder |
51 from kivy import properties | 51 from kivy import properties |
52 import xmlui | 52 from . import xmlui |
53 from profile_manager import ProfileManager | 53 from .profile_manager import ProfileManager |
54 from kivy.clock import Clock | 54 from kivy.clock import Clock |
55 from kivy.uix.label import Label | 55 from kivy.uix.label import Label |
56 from kivy.uix.boxlayout import BoxLayout | 56 from kivy.uix.boxlayout import BoxLayout |
57 from kivy.uix.floatlayout import FloatLayout | 57 from kivy.uix.floatlayout import FloatLayout |
58 from kivy.uix.screenmanager import (ScreenManager, Screen, | 58 from kivy.uix.screenmanager import (ScreenManager, Screen, |
62 from kivy.core.window import Window | 62 from kivy.core.window import Window |
63 from kivy.animation import Animation | 63 from kivy.animation import Animation |
64 from kivy.metrics import dp | 64 from kivy.metrics import dp |
65 from kivy import utils as kivy_utils | 65 from kivy import utils as kivy_utils |
66 from kivy.config import Config as KivyConfig | 66 from kivy.config import Config as KivyConfig |
67 from cagou_widget import CagouWidget | 67 from .cagou_widget import CagouWidget |
68 from . import widgets_handler | 68 from . import widgets_handler |
69 from .common import IconButton | 69 from .common import IconButton |
70 from . import menu | 70 from . import menu |
71 from . import dialog | 71 from . import dialog |
72 from importlib import import_module | 72 from importlib import import_module |
76 import cagou.kv | 76 import cagou.kv |
77 try: | 77 try: |
78 from plyer import notification | 78 from plyer import notification |
79 except ImportError: | 79 except ImportError: |
80 notification = None | 80 notification = None |
81 log.warning(_(u"Can't import plyer, some features disabled")) | 81 log.warning(_("Can't import plyer, some features disabled")) |
82 | 82 |
83 | 83 |
84 ## platform specific settings ## | 84 ## platform specific settings ## |
85 | 85 |
86 if kivy_utils.platform == "android": | 86 if kivy_utils.platform == "android": |
151 | 151 |
152 def open(self, widget): | 152 def open(self, widget): |
153 self.clear_widgets() | 153 self.clear_widgets() |
154 for n in self.notes: | 154 for n in self.notes: |
155 kwargs = { | 155 kwargs = { |
156 u'title': n.title, | 156 'title': n.title, |
157 u'message': n.message, | 157 'message': n.message, |
158 u'level': n.level | 158 'level': n.level |
159 } | 159 } |
160 if n.symbol is not None: | 160 if n.symbol is not None: |
161 kwargs[u'symbol'] = n.symbol | 161 kwargs['symbol'] = n.symbol |
162 if n.action is not None: | 162 if n.action is not None: |
163 kwargs[u'action'] = n.action | 163 kwargs['action'] = n.action |
164 self.add_widget(NoteDrop(title=n.title, message=n.message, level=n.level, | 164 self.add_widget(NoteDrop(title=n.title, message=n.message, level=n.level, |
165 symbol=n.symbol, action=n.action)) | 165 symbol=n.symbol, action=n.action)) |
166 self.add_widget(self.clear_btn) | 166 self.add_widget(self.clear_btn) |
167 super(NotesDrop, self).open(widget) | 167 super(NotesDrop, self).open(widget) |
168 | 168 |
192 """ | 192 """ |
193 self.notifs_icon.addNotif(callback, *args, **kwargs) | 193 self.notifs_icon.addNotif(callback, *args, **kwargs) |
194 | 194 |
195 def addNote(self, title, message, level, symbol, action): | 195 def addNote(self, title, message, level, symbol, action): |
196 kwargs = { | 196 kwargs = { |
197 u'title': title, | 197 'title': title, |
198 u'message': message, | 198 'message': message, |
199 u'level': level | 199 'level': level |
200 } | 200 } |
201 if symbol is not None: | 201 if symbol is not None: |
202 kwargs[u'symbol'] = symbol | 202 kwargs['symbol'] = symbol |
203 if action is not None: | 203 if action is not None: |
204 kwargs[u'action'] = action | 204 kwargs['action'] = action |
205 note = Note(**kwargs) | 205 note = Note(**kwargs) |
206 self.notes.append(note) | 206 self.notes.append(note) |
207 if self.notes_event is None: | 207 if self.notes_event is None: |
208 self.notes_event = Clock.schedule_interval(self._displayNextNote, 5) | 208 self.notes_event = Clock.schedule_interval(self._displayNextNote, 5) |
209 self._displayNextNote() | 209 self._displayNextNote() |
317 # a settings screen when pressing F1 or platform specific key | 317 # a settings screen when pressing F1 or platform specific key |
318 return | 318 return |
319 | 319 |
320 def build(self): | 320 def build(self): |
321 Window.bind(on_keyboard=self.key_input) | 321 Window.bind(on_keyboard=self.key_input) |
322 wid = CagouRootWidget(Label(text=u"Loading please wait")) | 322 wid = CagouRootWidget(Label(text="Loading please wait")) |
323 if sys.platform == 'android': | 323 if sys.platform == 'android': |
324 # we don't want menu on Android | 324 # we don't want menu on Android |
325 wid.root_menus.height = 0 | 325 wid.root_menus.height = 0 |
326 return wid | 326 return wid |
327 | 327 |
411 service.start(mActivity, argument) | 411 service.start(mActivity, argument) |
412 self.service = service | 412 self.service = service |
413 | 413 |
414 bridge_module = dynamic_import.bridge(bridge_name, 'sat_frontends.bridge') | 414 bridge_module = dynamic_import.bridge(bridge_name, 'sat_frontends.bridge') |
415 if bridge_module is None: | 415 if bridge_module is None: |
416 log.error(u"Can't import {} bridge".format(bridge_name)) | 416 log.error("Can't import {} bridge".format(bridge_name)) |
417 sys.exit(3) | 417 sys.exit(3) |
418 else: | 418 else: |
419 log.debug(u"Loading {} bridge".format(bridge_name)) | 419 log.debug("Loading {} bridge".format(bridge_name)) |
420 super(Cagou, self).__init__(bridge_factory=bridge_module.Bridge, | 420 super(Cagou, self).__init__(bridge_factory=bridge_module.Bridge, |
421 xmlui=xmlui, | 421 xmlui=xmlui, |
422 check_options=quick_utils.check_options, | 422 check_options=quick_utils.check_options, |
423 connect_bridge=False) | 423 connect_bridge=False) |
424 self._import_kv() | 424 self._import_kv() |
430 'downloads_dir') | 430 'downloads_dir') |
431 if not os.path.exists(self.downloads_dir): | 431 if not os.path.exists(self.downloads_dir): |
432 try: | 432 try: |
433 os.makedirs(self.downloads_dir) | 433 os.makedirs(self.downloads_dir) |
434 except OSError as e: | 434 except OSError as e: |
435 log.warnings(_(u"Can't create downloads dir: {reason}").format(reason=e)) | 435 log.warnings(_("Can't create downloads dir: {reason}").format(reason=e)) |
436 self.app.default_avatar = os.path.join(self.media_dir, "misc/default_avatar.png") | 436 self.app.default_avatar = os.path.join(self.media_dir, "misc/default_avatar.png") |
437 self.app.icon = os.path.join(self.media_dir, | 437 self.app.icon = os.path.join(self.media_dir, |
438 "icons/muchoslava/png/cagou_profil_bleu_96.png") | 438 "icons/muchoslava/png/cagou_profil_bleu_96.png") |
439 self._plg_wids = [] # main widgets plugins | 439 self._plg_wids = [] # main widgets plugins |
440 self._plg_wids_transfer = [] # transfer widgets plugins | 440 self._plg_wids_transfer = [] # transfer widgets plugins |
454 'no_certificate_validation', | 454 'no_certificate_validation', |
455 C.BOOL_FALSE)) | 455 C.BOOL_FALSE)) |
456 if not self.tls_validation: | 456 if not self.tls_validation: |
457 from cagou.core import patches | 457 from cagou.core import patches |
458 patches.apply() | 458 patches.apply() |
459 log.warning(u"SSL certificate validation is disabled, this is unsecure!") | 459 log.warning("SSL certificate validation is disabled, this is unsecure!") |
460 | 460 |
461 @property | 461 @property |
462 def visible_widgets(self): | 462 def visible_widgets(self): |
463 for w_list in self._visible_widgets.itervalues(): | 463 for w_list in self._visible_widgets.values(): |
464 for w in w_list: | 464 for w in w_list: |
465 yield w | 465 yield w |
466 | 466 |
467 @QuickApp.sync.setter | 467 @QuickApp.sync.setter |
468 def sync(self, state): | 468 def sync(self, state): |
570 else: | 570 else: |
571 raise exceptions.InternalError("base.kv is missing") | 571 raise exceptions.InternalError("base.kv is missing") |
572 | 572 |
573 for kv_file in kv_files: | 573 for kv_file in kv_files: |
574 Builder.load_file(kv_file) | 574 Builder.load_file(kv_file) |
575 log.debug(u"kv file {} loaded".format(kv_file)) | 575 log.debug("kv file {} loaded".format(kv_file)) |
576 | 576 |
577 def _import_plugins(self): | 577 def _import_plugins(self): |
578 """import all plugins""" | 578 """import all plugins""" |
579 self.default_wid = None | 579 self.default_wid = None |
580 plugins_path = os.path.dirname(cagou.plugins.__file__) | 580 plugins_path = os.path.dirname(cagou.plugins.__file__) |
581 plugin_glob = u"plugin*." + C.PLUGIN_EXT | 581 plugin_glob = "plugin*." + C.PLUGIN_EXT |
582 plug_lst = [os.path.splitext(p)[0] for p in | 582 plug_lst = [os.path.splitext(p)[0] for p in |
583 map(os.path.basename, glob.glob(os.path.join(plugins_path, | 583 map(os.path.basename, glob.glob(os.path.join(plugins_path, |
584 plugin_glob)))] | 584 plugin_glob)))] |
585 | 585 |
586 imported_names_main = set() # used to avoid loading 2 times | 586 imported_names_main = set() # used to avoid loading 2 times |
589 for plug in plug_lst: | 589 for plug in plug_lst: |
590 plugin_path = 'cagou.plugins.' + plug | 590 plugin_path = 'cagou.plugins.' + plug |
591 | 591 |
592 # we get type from plugin name | 592 # we get type from plugin name |
593 suff = plug[7:] | 593 suff = plug[7:] |
594 if u'_' not in suff: | 594 if '_' not in suff: |
595 log.error(u"invalid plugin name: {}, skipping".format(plug)) | 595 log.error("invalid plugin name: {}, skipping".format(plug)) |
596 continue | 596 continue |
597 plugin_type = suff[:suff.find(u'_')] | 597 plugin_type = suff[:suff.find('_')] |
598 | 598 |
599 # and select the variable to use according to type | 599 # and select the variable to use according to type |
600 if plugin_type == C.PLUG_TYPE_WID: | 600 if plugin_type == C.PLUG_TYPE_WID: |
601 imported_names = imported_names_main | 601 imported_names = imported_names_main |
602 default_factory = self._defaultFactoryMain | 602 default_factory = self._defaultFactoryMain |
603 elif plugin_type == C.PLUG_TYPE_TRANSFER: | 603 elif plugin_type == C.PLUG_TYPE_TRANSFER: |
604 imported_names = imported_names_transfer | 604 imported_names = imported_names_transfer |
605 default_factory = self._defaultFactoryTransfer | 605 default_factory = self._defaultFactoryTransfer |
606 else: | 606 else: |
607 log.error(u"unknown plugin type {type_} for plugin {file_}, skipping" | 607 log.error("unknown plugin type {type_} for plugin {file_}, skipping" |
608 .format( | 608 .format( |
609 type_ = plugin_type, | 609 type_ = plugin_type, |
610 file_ = plug | 610 file_ = plug |
611 )) | 611 )) |
612 continue | 612 continue |
621 plugin_info['plugin_file'] = plug | 621 plugin_info['plugin_file'] = plug |
622 plugin_info['plugin_type'] = plugin_type | 622 plugin_info['plugin_type'] = plugin_type |
623 | 623 |
624 if 'platforms' in plugin_info: | 624 if 'platforms' in plugin_info: |
625 if sys.platform not in plugin_info['platforms']: | 625 if sys.platform not in plugin_info['platforms']: |
626 log.info(u"{plugin_file} is not used on this platform, skipping" | 626 log.info("{plugin_file} is not used on this platform, skipping" |
627 .format(**plugin_info)) | 627 .format(**plugin_info)) |
628 continue | 628 continue |
629 | 629 |
630 # import name is used to differentiate plugins | 630 # import name is used to differentiate plugins |
631 if 'import_name' not in plugin_info: | 631 if 'import_name' not in plugin_info: |
632 plugin_info['import_name'] = plug | 632 plugin_info['import_name'] = plug |
633 if plugin_info['import_name'] in imported_names: | 633 if plugin_info['import_name'] in imported_names: |
634 log.warning(_(u"there is already a plugin named {}, " | 634 log.warning(_("there is already a plugin named {}, " |
635 u"ignoring new one").format(plugin_info['import_name'])) | 635 "ignoring new one").format(plugin_info['import_name'])) |
636 continue | 636 continue |
637 if plugin_info['import_name'] == C.WID_SELECTOR: | 637 if plugin_info['import_name'] == C.WID_SELECTOR: |
638 if plugin_type != C.PLUG_TYPE_WID: | 638 if plugin_type != C.PLUG_TYPE_WID: |
639 log.error(u"{import_name} import name can only be used with {type_} " | 639 log.error("{import_name} import name can only be used with {type_} " |
640 u"type, skipping {name}".format(type_=C.PLUG_TYPE_WID, | 640 "type, skipping {name}".format(type_=C.PLUG_TYPE_WID, |
641 **plugin_info)) | 641 **plugin_info)) |
642 continue | 642 continue |
643 # if WidgetSelector exists, it will be our default widget | 643 # if WidgetSelector exists, it will be our default widget |
644 self.default_wid = plugin_info | 644 self.default_wid = plugin_info |
645 | 645 |
649 name_start = 8 + len(plugin_type) | 649 name_start = 8 + len(plugin_type) |
650 plugin_info['name'] = plug[name_start:] | 650 plugin_info['name'] = plug[name_start:] |
651 | 651 |
652 # we need to load the kv file | 652 # we need to load the kv file |
653 if 'kv_file' not in plugin_info: | 653 if 'kv_file' not in plugin_info: |
654 plugin_info['kv_file'] = u'{}.kv'.format(plug) | 654 plugin_info['kv_file'] = '{}.kv'.format(plug) |
655 kv_path = os.path.join(plugins_path, plugin_info['kv_file']) | 655 kv_path = os.path.join(plugins_path, plugin_info['kv_file']) |
656 if not os.path.exists(kv_path): | 656 if not os.path.exists(kv_path): |
657 log.debug(u"no kv found for {plugin_file}".format(**plugin_info)) | 657 log.debug("no kv found for {plugin_file}".format(**plugin_info)) |
658 else: | 658 else: |
659 Builder.load_file(kv_path) | 659 Builder.load_file(kv_path) |
660 | 660 |
661 # what is the main class ? | 661 # what is the main class ? |
662 main_cls = getattr(mod, plugin_info['main']) | 662 main_cls = getattr(mod, plugin_info['main']) |
667 if 'factory' not in plugin_info: | 667 if 'factory' not in plugin_info: |
668 plugin_info['factory'] = default_factory | 668 plugin_info['factory'] = default_factory |
669 | 669 |
670 # icons | 670 # icons |
671 for size in ('small', 'medium'): | 671 for size in ('small', 'medium'): |
672 key = u'icon_{}'.format(size) | 672 key = 'icon_{}'.format(size) |
673 try: | 673 try: |
674 path = plugin_info[key] | 674 path = plugin_info[key] |
675 except KeyError: | 675 except KeyError: |
676 path = C.DEFAULT_WIDGET_ICON.format(media=self.media_dir) | 676 path = C.DEFAULT_WIDGET_ICON.format(media=self.media_dir) |
677 else: | 677 else: |
680 path = C.DEFAULT_WIDGET_ICON.format(media=self.media_dir) | 680 path = C.DEFAULT_WIDGET_ICON.format(media=self.media_dir) |
681 plugin_info[key] = path | 681 plugin_info[key] = path |
682 | 682 |
683 plugins_set.append(plugin_info) | 683 plugins_set.append(plugin_info) |
684 if not self._plg_wids: | 684 if not self._plg_wids: |
685 log.error(_(u"no widget plugin found")) | 685 log.error(_("no widget plugin found")) |
686 return | 686 return |
687 | 687 |
688 # we want widgets sorted by names | 688 # we want widgets sorted by names |
689 self._plg_wids.sort(key=lambda p: p['name'].lower()) | 689 self._plg_wids.sort(key=lambda p: p['name'].lower()) |
690 self._plg_wids_transfer.sort(key=lambda p: p['name'].lower()) | 690 self._plg_wids_transfer.sort(key=lambda p: p['name'].lower()) |
697 if type_ == C.PLUG_TYPE_WID: | 697 if type_ == C.PLUG_TYPE_WID: |
698 return self._plg_wids | 698 return self._plg_wids |
699 elif type_ == C.PLUG_TYPE_TRANSFER: | 699 elif type_ == C.PLUG_TYPE_TRANSFER: |
700 return self._plg_wids_transfer | 700 return self._plg_wids_transfer |
701 else: | 701 else: |
702 raise KeyError(u"{} plugin type is unknown".format(type_)) | 702 raise KeyError("{} plugin type is unknown".format(type_)) |
703 | 703 |
704 def getPluggedWidgets(self, type_=C.PLUG_TYPE_WID, except_cls=None): | 704 def getPluggedWidgets(self, type_=C.PLUG_TYPE_WID, except_cls=None): |
705 """get available widgets plugin infos | 705 """get available widgets plugin infos |
706 | 706 |
707 @param type_(unicode): type of widgets to get | 707 @param type_(unicode): type of widgets to get |
725 exist and be of the same value in requested plugin info | 725 exist and be of the same value in requested plugin info |
726 @return (dict, None): found plugin info or None | 726 @return (dict, None): found plugin info or None |
727 """ | 727 """ |
728 plugins_set = self._getPluginsSet(type_) | 728 plugins_set = self._getPluginsSet(type_) |
729 for plugin_info in plugins_set: | 729 for plugin_info in plugins_set: |
730 for k, w in kwargs.iteritems(): | 730 for k, w in kwargs.items(): |
731 try: | 731 try: |
732 if plugin_info[k] != w: | 732 if plugin_info[k] != w: |
733 continue | 733 continue |
734 except KeyError: | 734 except KeyError: |
735 continue | 735 continue |
736 return plugin_info | 736 return plugin_info |
737 | 737 |
738 ## widgets handling | 738 ## widgets handling |
739 | 739 |
740 def newWidget(self, widget): | 740 def newWidget(self, widget): |
741 log.debug(u"new widget created: {}".format(widget)) | 741 log.debug("new widget created: {}".format(widget)) |
742 if isinstance(widget, quick_chat.QuickChat) and widget.type == C.CHAT_GROUP: | 742 if isinstance(widget, quick_chat.QuickChat) and widget.type == C.CHAT_GROUP: |
743 self.addNote(u"", _(u"room {} has been joined").format(widget.target)) | 743 self.addNote("", _("room {} has been joined").format(widget.target)) |
744 | 744 |
745 def switchWidget(self, old, new): | 745 def switchWidget(self, old, new): |
746 """Replace old widget by new one | 746 """Replace old widget by new one |
747 | 747 |
748 old(CagouWidgetn None): CagouWidget instance or a child | 748 old(CagouWidgetn None): CagouWidget instance or a child |
759 if isinstance(w, CagouWidget): | 759 if isinstance(w, CagouWidget): |
760 to_change = w | 760 to_change = w |
761 break | 761 break |
762 | 762 |
763 if to_change is None: | 763 if to_change is None: |
764 raise exceptions.InternalError(u"no CagouWidget found when " | 764 raise exceptions.InternalError("no CagouWidget found when " |
765 u"trying to switch widget") | 765 "trying to switch widget") |
766 | 766 |
767 wrapper = to_change.parent | 767 wrapper = to_change.parent |
768 while wrapper is not None and not(isinstance(wrapper, widgets_handler.WHWrapper)): | 768 while wrapper is not None and not(isinstance(wrapper, widgets_handler.WHWrapper)): |
769 wrapper = wrapper.parent | 769 wrapper = wrapper.parent |
770 | 770 |
771 if wrapper is None: | 771 if wrapper is None: |
772 raise exceptions.InternalError(u"no wrapper found") | 772 raise exceptions.InternalError("no wrapper found") |
773 | 773 |
774 wrapper.changeWidget(new) | 774 wrapper.changeWidget(new) |
775 self.selected_widget = new | 775 self.selected_widget = new |
776 | 776 |
777 def _addVisibleWidget(self, widget): | 777 def _addVisibleWidget(self, widget): |
816 if isinstance(widget, quick_widgets.QuickWidget): | 816 if isinstance(widget, quick_widgets.QuickWidget): |
817 for w in self.widgets.getWidgetInstances(widget): | 817 for w in self.widgets.getWidgetInstances(widget): |
818 if w.parent is None and w != widget: | 818 if w.parent is None and w != widget: |
819 to_delete.append(w) | 819 to_delete.append(w) |
820 for w in to_delete: | 820 for w in to_delete: |
821 log.debug(u"cleaning widget: {wid}".format(wid=w)) | 821 log.debug("cleaning widget: {wid}".format(wid=w)) |
822 self.widgets.deleteWidget(w) | 822 self.widgets.deleteWidget(w) |
823 | 823 |
824 def getOrClone(self, widget): | 824 def getOrClone(self, widget): |
825 """Get a QuickWidget if it has not parent set else clone it | 825 """Get a QuickWidget if it has not parent set else clone it |
826 | 826 |
871 # FIXME: Q&D way to get chat plugin, should be replaced by a clean method | 871 # FIXME: Q&D way to get chat plugin, should be replaced by a clean method |
872 # in host | 872 # in host |
873 plg_infos = [p for p in self.getPluggedWidgets() | 873 plg_infos = [p for p in self.getPluggedWidgets() |
874 if action in p['import_name']][0] | 874 if action in p['import_name']][0] |
875 except IndexError: | 875 except IndexError: |
876 log.warning(u"No plugin widget found to do {action}".format(action=action)) | 876 log.warning("No plugin widget found to do {action}".format(action=action)) |
877 else: | 877 else: |
878 factory = plg_infos['factory'] | 878 factory = plg_infos['factory'] |
879 self.switchWidget(None, | 879 self.switchWidget(None, |
880 factory(plg_infos, target=target, profiles=profiles)) | 880 factory(plg_infos, target=target, profiles=profiles)) |
881 | 881 |
883 | 883 |
884 def _menusGetCb(self, backend_menus): | 884 def _menusGetCb(self, backend_menus): |
885 main_menu = self.app.root.root_menus | 885 main_menu = self.app.root.root_menus |
886 self.menus.addMenus(backend_menus) | 886 self.menus.addMenus(backend_menus) |
887 self.menus.addMenu(C.MENU_GLOBAL, | 887 self.menus.addMenu(C.MENU_GLOBAL, |
888 (_(u"Help"), _(u"About")), | 888 (_("Help"), _("About")), |
889 callback=main_menu.onAbout) | 889 callback=main_menu.onAbout) |
890 main_menu.update(C.MENU_GLOBAL) | 890 main_menu.update(C.MENU_GLOBAL) |
891 | 891 |
892 ## bridge handlers ## | 892 ## bridge handlers ## |
893 | 893 |
900 for widget in self.widgets.getWidgets(quick_chat.QuickChat, profiles=(profile,)): | 900 for widget in self.widgets.getWidgets(quick_chat.QuickChat, profiles=(profile,)): |
901 if widget.type == C.CHAT_ONE2ONE and widget.target == bare_jid: | 901 if widget.type == C.CHAT_ONE2ONE and widget.target == bare_jid: |
902 widget.onOTRState(state, dest_jid, profile) | 902 widget.onOTRState(state, dest_jid, profile) |
903 | 903 |
904 def _debugHandler(self, action, parameters, profile): | 904 def _debugHandler(self, action, parameters, profile): |
905 if action == u"visible_widgets_dump": | 905 if action == "visible_widgets_dump": |
906 from pprint import pformat | 906 from pprint import pformat |
907 log.info(u"Visible widgets dump:\n{data}".format( | 907 log.info("Visible widgets dump:\n{data}".format( |
908 data=pformat(self._visible_widgets))) | 908 data=pformat(self._visible_widgets))) |
909 else: | 909 else: |
910 return super(Cagou, self)._debugHandler(action, parameters, profile) | 910 return super(Cagou, self)._debugHandler(action, parameters, profile) |
911 | 911 |
912 ## misc ## | 912 ## misc ## |
914 def plugging_profiles(self): | 914 def plugging_profiles(self): |
915 self.app.root.changeWidget(widgets_handler.WidgetsHandler()) | 915 self.app.root.changeWidget(widgets_handler.WidgetsHandler()) |
916 self.bridge.menusGet("", C.NO_SECURITY_LIMIT, callback=self._menusGetCb) | 916 self.bridge.menusGet("", C.NO_SECURITY_LIMIT, callback=self._menusGetCb) |
917 | 917 |
918 def setPresenceStatus(self, show='', status=None, profile=C.PROF_KEY_NONE): | 918 def setPresenceStatus(self, show='', status=None, profile=C.PROF_KEY_NONE): |
919 log.info(u"Profile presence status set to {show}/{status}".format(show=show, | 919 log.info("Profile presence status set to {show}/{status}".format(show=show, |
920 status=status)) | 920 status=status)) |
921 | 921 |
922 def errback(self, failure_, title=_('error'), | 922 def errback(self, failure_, title=_('error'), |
923 message=_(u'error while processing: {msg}')): | 923 message=_('error while processing: {msg}')): |
924 self.addNote(title, message.format(msg=failure_), level=C.XMLUI_DATA_LVL_WARNING) | 924 self.addNote(title, message.format(msg=failure_), level=C.XMLUI_DATA_LVL_WARNING) |
925 | 925 |
926 def addNote(self, title, message, level=C.XMLUI_DATA_LVL_INFO, symbol=None, | 926 def addNote(self, title, message, level=C.XMLUI_DATA_LVL_INFO, symbol=None, |
927 action=None): | 927 action=None): |
928 """add a note (message which disappear) to root widget's header""" | 928 """add a note (message which disappear) to root widget's header""" |
980 False, | 980 False, |
981 answer_data) | 981 answer_data) |
982 ) | 982 ) |
983 self.addNotifWidget(wid) | 983 self.addNotifWidget(wid) |
984 else: | 984 else: |
985 log.warning(_(u"unknown dialog type: {dialog_type}").format(dialog_type=type)) | 985 log.warning(_("unknown dialog type: {dialog_type}").format(dialog_type=type)) |
986 | 986 |
987 | 987 |
988 def desktop_notif(self, message, title=u'', duration=5000): | 988 def desktop_notif(self, message, title='', duration=5000): |
989 global notification | |
989 if notification is not None: | 990 if notification is not None: |
990 try: | 991 try: |
991 notification.notify(title=title, | 992 notification.notify(title=title, |
992 message=message, | 993 message=message, |
993 app_name=C.APP_NAME, | 994 app_name=C.APP_NAME, |
994 app_icon=self.app.icon, | 995 app_icon=self.app.icon, |
995 timeout = duration) | 996 timeout = duration) |
996 except Exception as e: | 997 except Exception as e: |
997 log.warning(_(u"Can't use notifications, disabling: {msg}").format( | 998 log.warning(_("Can't use notifications, disabling: {msg}").format( |
998 msg = e)) | 999 msg = e)) |
999 global notification | |
1000 notification = None | 1000 notification = None |