# HG changeset patch # User Goffi # Date 1565716462 -7200 # Node ID 772c170b47a9224d1f364fdcae5882d64680a5b2 # Parent a0d978d3ce841ce4e59d607f8675652173242f0c 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). diff -r a0d978d3ce84 -r 772c170b47a9 bin/cagou --- a/bin/cagou Mon Aug 05 11:21:54 2019 +0200 +++ b/bin/cagou Tue Aug 13 19:14:22 2019 +0200 @@ -1,4 +1,4 @@ -#!/usr//bin/env python2 +#!/usr//bin/env python3 # -*- coding: utf-8 -*- # Cagou: desktop/mobile frontend for Salut à Toi XMPP client diff -r a0d978d3ce84 -r 772c170b47a9 cagou/__init__.py --- a/cagou/__init__.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/__init__.py Tue Aug 13 19:14:22 2019 +0200 @@ -31,7 +31,7 @@ G = Global() # this import must be done after G is created -from core import cagou_main +from .core import cagou_main def run(): host = G._host = cagou_main.Cagou() diff -r a0d978d3ce84 -r 772c170b47a9 cagou/core/cagou_main.py --- a/cagou/core/cagou_main.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/core/cagou_main.py Tue Aug 13 19:14:22 2019 +0200 @@ -24,7 +24,7 @@ from sat.core.i18n import _ from . import kivy_hack kivy_hack.do_hack() -from constants import Const as C +from .constants import Const as C from sat.core import log as logging log = logging.getLogger(__name__) from sat.core import exceptions @@ -49,8 +49,8 @@ from kivy.app import App from kivy.lang import Builder from kivy import properties -import xmlui -from profile_manager import ProfileManager +from . import xmlui +from .profile_manager import ProfileManager from kivy.clock import Clock from kivy.uix.label import Label from kivy.uix.boxlayout import BoxLayout @@ -64,7 +64,7 @@ from kivy.metrics import dp from kivy import utils as kivy_utils from kivy.config import Config as KivyConfig -from cagou_widget import CagouWidget +from .cagou_widget import CagouWidget from . import widgets_handler from .common import IconButton from . import menu @@ -78,7 +78,7 @@ from plyer import notification except ImportError: notification = None - log.warning(_(u"Can't import plyer, some features disabled")) + log.warning(_("Can't import plyer, some features disabled")) ## platform specific settings ## @@ -153,14 +153,14 @@ self.clear_widgets() for n in self.notes: kwargs = { - u'title': n.title, - u'message': n.message, - u'level': n.level + 'title': n.title, + 'message': n.message, + 'level': n.level } if n.symbol is not None: - kwargs[u'symbol'] = n.symbol + kwargs['symbol'] = n.symbol if n.action is not None: - kwargs[u'action'] = n.action + kwargs['action'] = n.action self.add_widget(NoteDrop(title=n.title, message=n.message, level=n.level, symbol=n.symbol, action=n.action)) self.add_widget(self.clear_btn) @@ -194,14 +194,14 @@ def addNote(self, title, message, level, symbol, action): kwargs = { - u'title': title, - u'message': message, - u'level': level + 'title': title, + 'message': message, + 'level': level } if symbol is not None: - kwargs[u'symbol'] = symbol + kwargs['symbol'] = symbol if action is not None: - kwargs[u'action'] = action + kwargs['action'] = action note = Note(**kwargs) self.notes.append(note) if self.notes_event is None: @@ -319,7 +319,7 @@ def build(self): Window.bind(on_keyboard=self.key_input) - wid = CagouRootWidget(Label(text=u"Loading please wait")) + wid = CagouRootWidget(Label(text="Loading please wait")) if sys.platform == 'android': # we don't want menu on Android wid.root_menus.height = 0 @@ -413,10 +413,10 @@ bridge_module = dynamic_import.bridge(bridge_name, 'sat_frontends.bridge') if bridge_module is None: - log.error(u"Can't import {} bridge".format(bridge_name)) + log.error("Can't import {} bridge".format(bridge_name)) sys.exit(3) else: - log.debug(u"Loading {} bridge".format(bridge_name)) + log.debug("Loading {} bridge".format(bridge_name)) super(Cagou, self).__init__(bridge_factory=bridge_module.Bridge, xmlui=xmlui, check_options=quick_utils.check_options, @@ -432,7 +432,7 @@ try: os.makedirs(self.downloads_dir) except OSError as e: - log.warnings(_(u"Can't create downloads dir: {reason}").format(reason=e)) + log.warnings(_("Can't create downloads dir: {reason}").format(reason=e)) self.app.default_avatar = os.path.join(self.media_dir, "misc/default_avatar.png") self.app.icon = os.path.join(self.media_dir, "icons/muchoslava/png/cagou_profil_bleu_96.png") @@ -456,11 +456,11 @@ if not self.tls_validation: from cagou.core import patches patches.apply() - log.warning(u"SSL certificate validation is disabled, this is unsecure!") + log.warning("SSL certificate validation is disabled, this is unsecure!") @property def visible_widgets(self): - for w_list in self._visible_widgets.itervalues(): + for w_list in self._visible_widgets.values(): for w in w_list: yield w @@ -572,13 +572,13 @@ for kv_file in kv_files: Builder.load_file(kv_file) - log.debug(u"kv file {} loaded".format(kv_file)) + log.debug("kv file {} loaded".format(kv_file)) def _import_plugins(self): """import all plugins""" self.default_wid = None plugins_path = os.path.dirname(cagou.plugins.__file__) - plugin_glob = u"plugin*." + C.PLUGIN_EXT + plugin_glob = "plugin*." + C.PLUGIN_EXT plug_lst = [os.path.splitext(p)[0] for p in map(os.path.basename, glob.glob(os.path.join(plugins_path, plugin_glob)))] @@ -591,10 +591,10 @@ # we get type from plugin name suff = plug[7:] - if u'_' not in suff: - log.error(u"invalid plugin name: {}, skipping".format(plug)) + if '_' not in suff: + log.error("invalid plugin name: {}, skipping".format(plug)) continue - plugin_type = suff[:suff.find(u'_')] + plugin_type = suff[:suff.find('_')] # and select the variable to use according to type if plugin_type == C.PLUG_TYPE_WID: @@ -604,7 +604,7 @@ imported_names = imported_names_transfer default_factory = self._defaultFactoryTransfer else: - log.error(u"unknown plugin type {type_} for plugin {file_}, skipping" + log.error("unknown plugin type {type_} for plugin {file_}, skipping" .format( type_ = plugin_type, file_ = plug @@ -623,7 +623,7 @@ if 'platforms' in plugin_info: if sys.platform not in plugin_info['platforms']: - log.info(u"{plugin_file} is not used on this platform, skipping" + log.info("{plugin_file} is not used on this platform, skipping" .format(**plugin_info)) continue @@ -631,13 +631,13 @@ if 'import_name' not in plugin_info: plugin_info['import_name'] = plug if plugin_info['import_name'] in imported_names: - log.warning(_(u"there is already a plugin named {}, " - u"ignoring new one").format(plugin_info['import_name'])) + log.warning(_("there is already a plugin named {}, " + "ignoring new one").format(plugin_info['import_name'])) continue if plugin_info['import_name'] == C.WID_SELECTOR: if plugin_type != C.PLUG_TYPE_WID: - log.error(u"{import_name} import name can only be used with {type_} " - u"type, skipping {name}".format(type_=C.PLUG_TYPE_WID, + log.error("{import_name} import name can only be used with {type_} " + "type, skipping {name}".format(type_=C.PLUG_TYPE_WID, **plugin_info)) continue # if WidgetSelector exists, it will be our default widget @@ -651,10 +651,10 @@ # we need to load the kv file if 'kv_file' not in plugin_info: - plugin_info['kv_file'] = u'{}.kv'.format(plug) + plugin_info['kv_file'] = '{}.kv'.format(plug) kv_path = os.path.join(plugins_path, plugin_info['kv_file']) if not os.path.exists(kv_path): - log.debug(u"no kv found for {plugin_file}".format(**plugin_info)) + log.debug("no kv found for {plugin_file}".format(**plugin_info)) else: Builder.load_file(kv_path) @@ -669,7 +669,7 @@ # icons for size in ('small', 'medium'): - key = u'icon_{}'.format(size) + key = 'icon_{}'.format(size) try: path = plugin_info[key] except KeyError: @@ -682,7 +682,7 @@ plugins_set.append(plugin_info) if not self._plg_wids: - log.error(_(u"no widget plugin found")) + log.error(_("no widget plugin found")) return # we want widgets sorted by names @@ -699,7 +699,7 @@ elif type_ == C.PLUG_TYPE_TRANSFER: return self._plg_wids_transfer else: - raise KeyError(u"{} plugin type is unknown".format(type_)) + raise KeyError("{} plugin type is unknown".format(type_)) def getPluggedWidgets(self, type_=C.PLUG_TYPE_WID, except_cls=None): """get available widgets plugin infos @@ -727,7 +727,7 @@ """ plugins_set = self._getPluginsSet(type_) for plugin_info in plugins_set: - for k, w in kwargs.iteritems(): + for k, w in kwargs.items(): try: if plugin_info[k] != w: continue @@ -738,9 +738,9 @@ ## widgets handling def newWidget(self, widget): - log.debug(u"new widget created: {}".format(widget)) + log.debug("new widget created: {}".format(widget)) if isinstance(widget, quick_chat.QuickChat) and widget.type == C.CHAT_GROUP: - self.addNote(u"", _(u"room {} has been joined").format(widget.target)) + self.addNote("", _("room {} has been joined").format(widget.target)) def switchWidget(self, old, new): """Replace old widget by new one @@ -761,15 +761,15 @@ break if to_change is None: - raise exceptions.InternalError(u"no CagouWidget found when " - u"trying to switch widget") + raise exceptions.InternalError("no CagouWidget found when " + "trying to switch widget") wrapper = to_change.parent while wrapper is not None and not(isinstance(wrapper, widgets_handler.WHWrapper)): wrapper = wrapper.parent if wrapper is None: - raise exceptions.InternalError(u"no wrapper found") + raise exceptions.InternalError("no wrapper found") wrapper.changeWidget(new) self.selected_widget = new @@ -818,7 +818,7 @@ if w.parent is None and w != widget: to_delete.append(w) for w in to_delete: - log.debug(u"cleaning widget: {wid}".format(wid=w)) + log.debug("cleaning widget: {wid}".format(wid=w)) self.widgets.deleteWidget(w) def getOrClone(self, widget): @@ -873,7 +873,7 @@ plg_infos = [p for p in self.getPluggedWidgets() if action in p['import_name']][0] except IndexError: - log.warning(u"No plugin widget found to do {action}".format(action=action)) + log.warning("No plugin widget found to do {action}".format(action=action)) else: factory = plg_infos['factory'] self.switchWidget(None, @@ -885,7 +885,7 @@ main_menu = self.app.root.root_menus self.menus.addMenus(backend_menus) self.menus.addMenu(C.MENU_GLOBAL, - (_(u"Help"), _(u"About")), + (_("Help"), _("About")), callback=main_menu.onAbout) main_menu.update(C.MENU_GLOBAL) @@ -902,9 +902,9 @@ widget.onOTRState(state, dest_jid, profile) def _debugHandler(self, action, parameters, profile): - if action == u"visible_widgets_dump": + if action == "visible_widgets_dump": from pprint import pformat - log.info(u"Visible widgets dump:\n{data}".format( + log.info("Visible widgets dump:\n{data}".format( data=pformat(self._visible_widgets))) else: return super(Cagou, self)._debugHandler(action, parameters, profile) @@ -916,11 +916,11 @@ self.bridge.menusGet("", C.NO_SECURITY_LIMIT, callback=self._menusGetCb) def setPresenceStatus(self, show='', status=None, profile=C.PROF_KEY_NONE): - log.info(u"Profile presence status set to {show}/{status}".format(show=show, + log.info("Profile presence status set to {show}/{status}".format(show=show, status=status)) def errback(self, failure_, title=_('error'), - message=_(u'error while processing: {msg}')): + message=_('error while processing: {msg}')): self.addNote(title, message.format(msg=failure_), level=C.XMLUI_DATA_LVL_WARNING) def addNote(self, title, message, level=C.XMLUI_DATA_LVL_INFO, symbol=None, @@ -982,10 +982,11 @@ ) self.addNotifWidget(wid) else: - log.warning(_(u"unknown dialog type: {dialog_type}").format(dialog_type=type)) + log.warning(_("unknown dialog type: {dialog_type}").format(dialog_type=type)) - def desktop_notif(self, message, title=u'', duration=5000): + def desktop_notif(self, message, title='', duration=5000): + global notification if notification is not None: try: notification.notify(title=title, @@ -994,7 +995,6 @@ app_icon=self.app.icon, timeout = duration) except Exception as e: - log.warning(_(u"Can't use notifications, disabling: {msg}").format( + log.warning(_("Can't use notifications, disabling: {msg}").format( msg = e)) - global notification notification = None diff -r a0d978d3ce84 -r 772c170b47a9 cagou/core/cagou_widget.py --- a/cagou/core/cagou_widget.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/core/cagou_widget.py Tue Aug 13 19:14:22 2019 +0200 @@ -76,7 +76,7 @@ G.host.switchWidget(self, new_widget) def onHeaderInput(self): - log.info(u"header input text entered") + log.info("header input text entered") def onHeaderInputComplete(self, wid, text): return diff -r a0d978d3ce84 -r 772c170b47a9 cagou/core/common.py --- a/cagou/core/common.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/core/common.py Tue Aug 13 19:14:22 2019 +0200 @@ -33,7 +33,7 @@ log = logging.getLogger(__name__) -UNKNOWN_SYMBOL = u'Unknown symbol name' +UNKNOWN_SYMBOL = 'Unknown symbol name' class IconButton(ButtonBehavior, Image): @@ -96,9 +96,9 @@ try: code = self.symbol_map[symbol] except KeyError: - log.warning(_(u"Invalid symbol {symbol}").format(symbol=symbol)) + log.warning(_("Invalid symbol {symbol}").format(symbol=symbol)) else: - self.text = unichr(code) + self.text = chr(code) class SymbolButton(ButtonBehavior, Symbol): diff -r a0d978d3ce84 -r 772c170b47a9 cagou/core/common_widgets.py --- a/cagou/core/common_widgets.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/core/common_widgets.py Tue Aug 13 19:14:22 2019 +0200 @@ -53,7 +53,7 @@ @property def name(self): - return self.identities.values()[0].values()[0][0] + return list(self.identities.values())[0].values()[0][0] class ItemWidget(TouchMenuItemBehaviour, BoxLayout): @@ -66,14 +66,14 @@ def __init__(self, main_wid, entity_jid, identities, **kw): self.entity_jid = entity_jid self.identities = identities - own_jid = next(G.host.profiles.itervalues()).whoami + own_jid = next(iter(G.host.profiles.values())).whoami self.own_device = entity_jid.bare == own_jid if self.own_device: name = self.identities.name elif self.entity_jid.node: name = self.entity_jid.node elif self.entity_jid == own_jid.domain: - name = _(u"your server") + name = _("your server") else: name = entity_jid diff -r a0d978d3ce84 -r 772c170b47a9 cagou/core/constants.py --- a/cagou/core/constants.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/core/constants.py Tue Aug 13 19:14:22 2019 +0200 @@ -22,19 +22,19 @@ class Const(constants.Const): - APP_NAME = u"Cagou" + APP_NAME = "Cagou" APP_VERSION = cagou.__version__ LOG_OPT_SECTION = APP_NAME.lower() CONFIG_SECTION = APP_NAME.lower() - WID_SELECTOR = u'selector' - ICON_SIZES = (u'small', u'medium') # small = 32, medium = 44 - DEFAULT_WIDGET_ICON = u'{media}/misc/black.png' + WID_SELECTOR = 'selector' + ICON_SIZES = ('small', 'medium') # small = 32, medium = 44 + DEFAULT_WIDGET_ICON = '{media}/misc/black.png' - PLUG_TYPE_WID = u'wid' - PLUG_TYPE_TRANSFER = u'transfer' + PLUG_TYPE_WID = 'wid' + PLUG_TYPE_TRANSFER = 'transfer' - TRANSFER_UPLOAD = u"upload" - TRANSFER_SEND = u"send" + TRANSFER_UPLOAD = "upload" + TRANSFER_SEND = "send" COLOR_PRIM = (0.98, 0.98, 0.98, 1) COLOR_PRIM_LIGHT = (1, 1, 1, 1) diff -r a0d978d3ce84 -r 772c170b47a9 cagou/core/dialog.py --- a/cagou/core/dialog.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/core/dialog.py Tue Aug 13 19:14:22 2019 +0200 @@ -37,7 +37,7 @@ class ConfirmDialog(BoxLayout): title = properties.StringProperty() - message = properties.StringProperty(_(u"Are you sure?")) + message = properties.StringProperty(_("Are you sure?")) # callback for no/cancel no_cb = properties.ObjectProperty() # callback for yes/ok diff -r a0d978d3ce84 -r 772c170b47a9 cagou/core/image.py --- a/cagou/core/image.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/core/image.py Tue Aug 13 19:14:22 2019 +0200 @@ -58,14 +58,14 @@ # internal decompressed representation from pillow # and im.save would need processing to handle format data = io.BytesIO(open(filename, "rb").read()) - cache_filename = u"{}.{}".format(filename,ext) # needed for kivy's Image to use cache + cache_filename = "{}.{}".format(filename,ext) # needed for kivy's Image to use cache self._coreimage = ci = CoreImage(data, ext=ext, filename=cache_filename, mipmap=mipmap, anim_delay=self.anim_delay, keep_data=self.keep_data, nocache=self.nocache) except Exception as e: - log.warning(u"Can't load image: {}".format(e)) + log.warning("Can't load image: {}".format(e)) self._coreimage = ci = None if ci: diff -r a0d978d3ce84 -r 772c170b47a9 cagou/core/kivy_hack.py --- a/cagou/core/kivy_hack.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/core/kivy_hack.py Tue Aug 13 19:14:22 2019 +0200 @@ -27,11 +27,11 @@ import sys ori_argv = sys.argv[:] sys.argv = sys.argv[:1] - from constants import Const as C + from .constants import Const as C from sat.core import log_config log_config.satConfigure(C.LOG_BACKEND_STANDARD, C) - import config + from . import config kivy_level = config.getConfig(C.CONFIG_SECTION, CONF_KIVY_LEVEL, 'follow').upper() # kivy handles its own loggers, we don't want that! @@ -51,7 +51,7 @@ kivy_logger.setLevel(kivy_level) kivy_logger.setLevel = lambda level: None else: - raise ValueError(u"Unknown value for {name}: {value}".format(name=CONF_KIVY_LEVEL, value=kivy_level)) + raise ValueError("Unknown value for {name}: {value}".format(name=CONF_KIVY_LEVEL, value=kivy_level)) # during import kivy set its logging stuff import kivy diff -r a0d978d3ce84 -r 772c170b47a9 cagou/core/menu.py --- a/cagou/core/menu.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/core/menu.py Tue Aug 13 19:14:22 2019 +0200 @@ -39,8 +39,8 @@ log = logging.getLogger(__name__) -ABOUT_TITLE = _(u"About {}".format(C.APP_NAME)) -ABOUT_CONTENT = _(u"""[b]Cagou (Salut à Toi)[/b] +ABOUT_TITLE = _("About {}".format(C.APP_NAME)) +ABOUT_CONTENT = _("""[b]Cagou (Salut à Toi)[/b] [u]cagou version[/u]: {version} @@ -99,7 +99,7 @@ try: profile = list(G.host.profiles)[0] except IndexError: - log.warning(u"Can't find profile") + log.warning("Can't find profile") self.item.call(selected, profile) @@ -162,7 +162,7 @@ wid = MenuItem(item=child) caller.add_widget(wid) else: - log.error(u"Unknown child type: {}".format(child)) + log.error("Unknown child type: {}".format(child)) def createMenus(self, caller): self.clear_widgets() @@ -273,7 +273,7 @@ G.host.closeUI() def do_callback(self, *args, **kwargs): - log.warning(u"callback not implemented") + log.warning("callback not implemented") class TransferMenu(SideMenu): @@ -281,11 +281,11 @@ # callback will be called with path to file to transfer # profiles if set will be sent to transfer widget, may be used to get specific files profiles = properties.ObjectProperty() - transfer_txt = _(u"Beware! The file will be sent to your server and stay unencrypted " - u"there\nServer admin(s) can see the file, and they choose how, " - u"when and if it will be deleted") - send_txt = _(u"The file will be sent unencrypted directly to your contact " - u"(without transiting by the server), except in some cases") + transfer_txt = _("Beware! The file will be sent to your server and stay unencrypted " + "there\nServer admin(s) can see the file, and they choose how, " + "when and if it will be deleted") + send_txt = _("The file will be sent unencrypted directly to your contact " + "(without transiting by the server), except in some cases") items_layout = properties.ObjectProperty() size_hint_close = (1, 0) size_hint_open = (1, 0.5) @@ -303,7 +303,7 @@ def do_callback(self, plug_info): self.parent.remove_widget(self) if self.callback is None: - log.warning(u"TransferMenu callback is not set") + log.warning("TransferMenu callback is not set") else: wid = None external = plug_info.get('external', False) @@ -327,7 +327,7 @@ """allow to select entities from roster""" profiles = properties.ObjectProperty() layout = properties.ObjectProperty() - instructions = properties.StringProperty(_(u"Please select entities")) + instructions = properties.StringProperty(_("Please select entities")) filter_input = properties.ObjectProperty() size_hint_close = (None, 1) size_hint_open = (None, 1) diff -r a0d978d3ce84 -r 772c170b47a9 cagou/core/patches.py --- a/cagou/core/patches.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/core/patches.py Tue Aug 13 19:14:22 2019 +0200 @@ -17,7 +17,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -import urllib2 +import urllib.request, urllib.error, urllib.parse import ssl @@ -27,14 +27,14 @@ ctx_no_verify.check_hostname = False ctx_no_verify.verify_mode = ssl.CERT_NONE - class HTTPSHandler(urllib2.HTTPSHandler): + class HTTPSHandler(urllib.request.HTTPSHandler): no_certificate_check = False def __init__(self, *args, **kwargs): - urllib2._HTTPSHandler_ori.__init__(self, *args, **kwargs) + urllib.request._HTTPSHandler_ori.__init__(self, *args, **kwargs) if self.no_certificate_check: self._context = ctx_no_verify - urllib2._HTTPSHandler_ori = urllib2.HTTPSHandler - urllib2.HTTPSHandler = HTTPSHandler - urllib2.HTTPSHandler.no_certificate_check = True + urllib.request._HTTPSHandler_ori = urllib.request.HTTPSHandler + urllib.request.HTTPSHandler = HTTPSHandler + urllib.request.HTTPSHandler.no_certificate_check = True diff -r a0d978d3ce84 -r 772c170b47a9 cagou/core/profile_manager.py --- a/cagou/core/profile_manager.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/core/profile_manager.py Tue Aug 13 19:14:22 2019 +0200 @@ -42,12 +42,12 @@ error_msg = properties.StringProperty('') def __init__(self, pm): - super(NewProfileScreen, self).__init__(name=u'new_profile') + super(NewProfileScreen, self).__init__(name='new_profile') self.pm = pm def onCreationFailure(self, failure): - msg = [l for l in unicode(failure).split('\n') if l][-1] - self.error_msg = unicode(msg) + msg = [l for l in str(failure).split('\n') if l][-1] + self.error_msg = str(msg) def onCreationSuccess(self, profile): self.pm.profiles_screen.reload() @@ -68,7 +68,7 @@ # XXX: we use XMPP password for profile password to simplify # if user want to change profile password, he can do it in preferences G.host.bridge.profileCreate( - name, self.password.text, u'', + name, self.password.text, '', callback=lambda: self.onCreationSuccess(name), errback=self.onCreationFailure) @@ -77,7 +77,7 @@ def __init__(self, pm): self.pm = pm - super(DeleteProfilesScreen, self).__init__(name=u'delete_profiles') + super(DeleteProfilesScreen, self).__init__(name='delete_profiles') def doDelete(self): """This method will delete *ALL* selected profiles""" @@ -92,7 +92,7 @@ self.pm.screen_manager.current = 'profiles' for profile in to_delete: - log.info(u"Deleteing profile [{}]".format(profile)) + log.info("Deleteing profile [{}]".format(profile)) G.host.bridge.asyncDeleteProfile( profile, callback=deleteInc, errback=deleteInc) @@ -103,7 +103,7 @@ def __init__(self, pm): self.pm = pm - super(ProfilesScreen, self).__init__(name=u'profiles') + super(ProfilesScreen, self).__init__(name='profiles') self.reload() def _profilesListGetCb(self, profiles): @@ -134,7 +134,7 @@ self.profiles_screen = ProfilesScreen(self) self.new_profile_screen = NewProfileScreen(self) self.delete_profiles_screen = DeleteProfilesScreen(self) - self.xmlui_screen = Screen(name=u'xmlui') + self.xmlui_screen = Screen(name='xmlui') self.screen_manager.add_widget(self.profiles_screen) self.screen_manager.add_widget(self.xmlui_screen) self.screen_manager.add_widget(self.new_profile_screen) diff -r a0d978d3ce84 -r 772c170b47a9 cagou/core/simple_xhtml.py --- a/cagou/core/simple_xhtml.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/core/simple_xhtml.py Tue Aug 13 19:14:22 2019 +0200 @@ -31,12 +31,9 @@ import webbrowser -class Escape(unicode): +class Escape(str): """Class used to mark that a message need to be escaped""" - def __init__(self, text): - super(Escape, self).__init__(text) - class SimpleXHTMLWidgetEscapedText(Label): @@ -52,9 +49,9 @@ m = sat_strings.RE_URL.search(text[idx:]) if m is not None: text_elts.append(escape_markup(m.string[0:m.start()])) - link_key = u'link_' + unicode(links) + link_key = 'link_' + str(links) url = m.group() - text_elts.append(u'[color=5500ff][ref={link}]{url}[/ref][/color]'.format( + text_elts.append('[color=5500ff][ref={link}]{url}[/ref][/color]'.format( link = link_key, url = url )) @@ -68,7 +65,7 @@ if links: text_elts.append(escape_markup(text[idx:])) self.markup = True - self.text = u''.join(text_elts) + self.text = ''.join(text_elts) break def on_text(self, instance, text): @@ -107,7 +104,7 @@ while parent and not isinstance(parent, SimpleXHTMLWidget): parent = parent.parent if parent is None: - log.error(u"no SimpleXHTMLWidget parent found") + log.error("no SimpleXHTMLWidget parent found") return parent def _on_source_load(self, value): @@ -208,12 +205,12 @@ self.splitted except AttributeError: # XXX: to make things easier, we split labels in words - log.debug(u"split start") + log.debug("split start") children = self.children[::-1] self.clear_widgets() for child in children: if isinstance(child, Label): - log.debug(u"label before split: {}".format(child.text)) + log.debug("label before split: {}".format(child.text)) styles = [] tag = False new_text = [] @@ -228,9 +225,9 @@ for c in child.text: if tag: # we are parsing a markup tag - if c == u']': - current_tag_s = u''.join(current_tag) - current_style = (current_tag_s, u''.join(current_value)) + if c == ']': + current_tag_s = ''.join(current_tag) + current_style = (current_tag_s, ''.join(current_value)) if close: for idx, s in enumerate(reversed(styles)): if s[0] == current_tag_s: @@ -243,9 +240,9 @@ tag = False value = False close = False - elif c == u'/': + elif c == '/': close = True - elif c == u'=': + elif c == '=': value = True elif value: current_value.append(c) @@ -254,38 +251,38 @@ new_text.append(c) else: # we are parsing regular text - if c == u'[': + if c == '[': new_text.append(c) tag = True - elif c == u' ': + elif c == ' ': # new word, we do a new widget - new_text.append(u' ') + new_text.append(' ') for t, v in reversed(styles): - new_text.append(u'[/{}]'.format(t)) - current_wid.text = u''.join(new_text) + new_text.append('[/{}]'.format(t)) + current_wid.text = ''.join(new_text) new_text = [] self.add_widget(current_wid) - log.debug(u"new widget: {}".format(current_wid.text)) + log.debug("new widget: {}".format(current_wid.text)) current_wid = self._createText() for t, v in styles: - new_text.append(u'[{tag}{value}]'.format( + new_text.append('[{tag}{value}]'.format( tag = t, - value = u'={}'.format(v) if v else u'')) + value = '={}'.format(v) if v else '')) else: new_text.append(c) if current_wid.text: # we may have a remaining widget after the parsing close_styles = [] for t, v in reversed(styles): - close_styles.append(u'[/{}]'.format(t)) - current_wid.text = u''.join(close_styles) + close_styles.append('[/{}]'.format(t)) + current_wid.text = ''.join(close_styles) self.add_widget(current_wid) - log.debug(u"new widget: {}".format(current_wid.text)) + log.debug("new widget: {}".format(current_wid.text)) else: # non Label widgets, we just add them self.add_widget(child) self.splitted = True - log.debug(u"split OK") + log.debug("split OK") # we now set the content width # FIXME: for now we just use the full width @@ -303,7 +300,7 @@ try: method = getattr(self, "xhtml_{}".format(e.tag)) except AttributeError: - log.warning(u"Unhandled XHTML tag: {}".format(e.tag)) + log.warning("Unhandled XHTML tag: {}".format(e.tag)) method = self.xhtml_generic method(e) @@ -317,9 +314,9 @@ should most probably be set to True """ label = self._getLabel() - label.text += u'[{tag}{value}]'.format( + label.text += '[{tag}{value}]'.format( tag = tag, - value = u'={}'.format(value) if value else '' + value = '={}'.format(value) if value else '' ) if append_to_list: self.styles.append((tag, value)) @@ -332,7 +329,7 @@ should most probably be set to True """ label = self._getLabel() - label.text += u'[/{tag}]'.format( + label.text += '[/{tag}]'.format( tag = tag ) if remove_from_list: @@ -382,19 +379,19 @@ @param e(ET.Element): element which may have a "style" attribute """ styles_limit = len(self.styles) - styles = e.attrib['style'].split(u';') + styles = e.attrib['style'].split(';') for style in styles: try: - prop, value = style.split(u':') + prop, value = style.split(':') except ValueError: - log.warning(u"can't parse style: {}".format(style)) + log.warning("can't parse style: {}".format(style)) continue - prop = prop.strip().replace(u'-', '_') + prop = prop.strip().replace('-', '_') value = value.strip() try: method = getattr(self, "css_{}".format(prop)) except AttributeError: - log.warning(u"Unhandled CSS: {}".format(prop)) + log.warning("Unhandled CSS: {}".format(prop)) else: method(e, value) self._css_styles = self.styles[styles_limit:] @@ -419,7 +416,7 @@ """ # we first add markup and CSS style if markup is not None: - if isinstance(markup, basestring): + if isinstance(markup, str): tag, value = markup, None else: tag, value = markup @@ -460,17 +457,17 @@ try: src = elem.attrib['src'] except KeyError: - log.warning(u" element without src: {}".format(ET.tostring(elem))) + log.warning(" element without src: {}".format(ET.tostring(elem))) return try: - target_height = int(elem.get(u'height', 0)) + target_height = int(elem.get('height', 0)) except ValueError: - log.warning(u"Can't parse image height: {}".format(elem.get(u'height'))) + log.warning("Can't parse image height: {}".format(elem.get('height'))) target_height = 0 try: - target_width = int(elem.get(u'width', 0)) + target_width = int(elem.get('width', 0)) except ValueError: - log.warning(u"Can't parse image width: {}".format(elem.get(u'width'))) + log.warning("Can't parse image width: {}".format(elem.get('width'))) target_width = 0 img = SimpleXHTMLWidgetImage(source=src, target_height=target_height, target_width=target_width) @@ -491,12 +488,12 @@ # methods handling CSS properties def css_color(self, elem, value): - self._addStyle(u"color", css_color.parse(value)) + self._addStyle("color", css_color.parse(value)) def css_text_decoration(self, elem, value): - if value == u'underline': + if value == 'underline': self._addStyle('u') - elif value == u'line-through': + elif value == 'line-through': self._addStyle('s') else: - log.warning(u"unhandled text decoration: {}".format(value)) + log.warning("unhandled text decoration: {}".format(value)) diff -r a0d978d3ce84 -r 772c170b47a9 cagou/core/utils.py --- a/cagou/core/utils.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/core/utils.py Tue Aug 13 19:14:22 2019 +0200 @@ -28,7 +28,7 @@ def __init__(self, *args, **kwargs): super(FilterBehavior, self).__init__(*args, **kwargs) - self._filter_last = u'' + self._filter_last = '' self._filter_anim = Animation(width = 0, height = 0, opacity = 0, diff -r a0d978d3ce84 -r 772c170b47a9 cagou/core/widgets_handler.py --- a/cagou/core/widgets_handler.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/core/widgets_handler.py Tue Aug 13 19:14:22 2019 +0200 @@ -357,9 +357,9 @@ @return: a value which will be used for sorting """ try: - return unicode(widget.target).lower() + return str(widget.target).lower() except AttributeError: - return unicode(list(widget.targets)[0]).lower() + return str(list(widget.targets)[0]).lower() def updateHiddenSlides(self): """adjust carousel slides according to visible widgets""" diff -r a0d978d3ce84 -r 772c170b47a9 cagou/core/xmlui.py --- a/cagou/core/xmlui.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/core/xmlui.py Tue Aug 13 19:14:22 2019 +0200 @@ -316,7 +316,7 @@ while parent is not None and not isinstance(parent, AdvancedListContainer): parent = parent.parent if parent is None: - log.error(u"Can't find parent AdvancedListContainer") + log.error("Can't find parent AdvancedListContainer") else: if parent.selectable: self.selected = parent._xmluiToggleSelected(self) @@ -353,7 +353,7 @@ def _xmluiAppend(self, widget): if self._current_row is None: - log.error(u"No row set, ignoring append") + log.error("No row set, ignoring append") return self._current_row.add_widget(widget) @@ -589,15 +589,15 @@ submit_btn.bind(on_press=self.onFormSubmitted) self.layout.add_widget(submit_btn) if not 'NO_CANCEL' in self.flags: - cancel_btn = CancelButton(text=_(u"Cancel")) + cancel_btn = CancelButton(text=_("Cancel")) cancel_btn.bind(on_press=self.onFormCancelled) self.layout.add_widget(cancel_btn) elif self.type == 'param': - self.save_btn = SaveButton(text=_(u"Save"), disabled=True) + self.save_btn = SaveButton(text=_("Save"), disabled=True) self.save_btn.bind(on_press=self._saveButtonCb) self.layout.add_widget(self.save_btn) elif self.type == 'window': - cancel_btn = CancelButton(text=_(u"Cancel")) + cancel_btn = CancelButton(text=_("Cancel")) cancel_btn.bind( on_press=partial(self._xmluiClose, reason=C.XMLUI_DATA_CANCELLED)) self.layout.add_widget(cancel_btn) diff -r a0d978d3ce84 -r 772c170b47a9 cagou/plugins/plugin_transfer_android_gallery.py --- a/cagou/plugins/plugin_transfer_android_gallery.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/plugins/plugin_transfer_android_gallery.py Tue Aug 13 19:14:22 2019 +0200 @@ -37,12 +37,12 @@ PLUGIN_INFO = { - "name": _(u"gallery"), + "name": _("gallery"), "main": "AndroidGallery", "platforms": ('android',), "external": True, - "description": _(u"upload a photo from photo gallery"), - "icon_medium": u"{media}/icons/muchoslava/png/gallery_50.png", + "description": _("upload a photo from photo gallery"), + "icon_medium": "{media}/icons/muchoslava/png/gallery_50.png", } @@ -61,7 +61,7 @@ # TODO: move file dump to a thread or use async callbacks during file writting if requestCode == PHOTO_GALLERY and resultCode == RESULT_OK: if data is None: - log.warning(u"No data found in activity result") + log.warning("No data found in activity result") self.cancel_cb(self, None) return uri = data.getData() @@ -80,7 +80,7 @@ def cleaning(): os.unlink(tmp_file) os.rmdir(tmp_dir) - log.debug(u'temporary file cleaned') + log.debug('temporary file cleaned') buff = bytearray(4096) with open(tmp_file, 'wb') as f: while True: diff -r a0d978d3ce84 -r 772c170b47a9 cagou/plugins/plugin_transfer_android_photo.py --- a/cagou/plugins/plugin_transfer_android_photo.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/plugins/plugin_transfer_android_photo.py Tue Aug 13 19:14:22 2019 +0200 @@ -34,12 +34,12 @@ PLUGIN_INFO = { - "name": _(u"take photo"), + "name": _("take photo"), "main": "AndroidPhoto", "platforms": ('android',), "external": True, - "description": _(u"upload a photo from photo application"), - "icon_medium": u"{media}/icons/muchoslava/png/camera_off_50.png", + "description": _("upload a photo from photo application"), + "icon_medium": "{media}/icons/muchoslava/png/camera_off_50.png", } @@ -51,7 +51,7 @@ filename = time.strftime("%Y-%m-%d_%H:%M:%S.jpg", time.gmtime()) tmp_dir = self.getTmpDir() tmp_file = os.path.join(tmp_dir, filename) - log.debug(u"Picture will be saved to {}".format(tmp_file)) + log.debug("Picture will be saved to {}".format(tmp_file)) camera.take_picture(tmp_file, self.callback) # we don't delete the file, as it is nice to keep it locally diff -r a0d978d3ce84 -r 772c170b47a9 cagou/plugins/plugin_transfer_android_video.py --- a/cagou/plugins/plugin_transfer_android_video.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/plugins/plugin_transfer_android_video.py Tue Aug 13 19:14:22 2019 +0200 @@ -34,12 +34,12 @@ PLUGIN_INFO = { - "name": _(u"take video"), + "name": _("take video"), "main": "AndroidVideo", "platforms": ('android',), "external": True, - "description": _(u"upload a video from video application"), - "icon_medium": u"{media}/icons/muchoslava/png/film_camera_off_50.png", + "description": _("upload a video from video application"), + "icon_medium": "{media}/icons/muchoslava/png/film_camera_off_50.png", } @@ -51,7 +51,7 @@ filename = time.strftime("%Y-%m-%d_%H:%M:%S.mpg", time.gmtime()) tmp_dir = self.getTmpDir() tmp_file = os.path.join(tmp_dir, filename) - log.debug(u"Video will be saved to {}".format(tmp_file)) + log.debug("Video will be saved to {}".format(tmp_file)) camera.take_video(tmp_file, self.callback) # we don't delete the file, as it is nice to keep it locally diff -r a0d978d3ce84 -r 772c170b47a9 cagou/plugins/plugin_transfer_file.py --- a/cagou/plugins/plugin_transfer_file.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/plugins/plugin_transfer_file.py Tue Aug 13 19:14:22 2019 +0200 @@ -31,10 +31,10 @@ PLUGIN_INFO = { - "name": _(u"file"), + "name": _("file"), "main": "FileTransmitter", - "description": _(u"transmit a local file"), - "icon_medium": u"{media}/icons/muchoslava/png/fichier_50.png", + "description": _("transmit a local file"), + "icon_medium": "{media}/icons/muchoslava/png/fichier_50.png", } @@ -66,7 +66,7 @@ cancel_cb=partial(self.cancel_cb, self))) def _nativeFileChooser(self, *args, **kwargs): - title=_(u"Please select a file to upload") + title=_("Please select a file to upload") files = filechooser.open_file(title=title, path=self.default_path, multiple=False, diff -r a0d978d3ce84 -r 772c170b47a9 cagou/plugins/plugin_transfer_voice.py --- a/cagou/plugins/plugin_transfer_voice.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/plugins/plugin_transfer_voice.py Tue Aug 13 19:14:22 2019 +0200 @@ -31,11 +31,11 @@ PLUGIN_INFO = { - "name": _(u"voice"), + "name": _("voice"), "main": "VoiceRecorder", "platforms": ["android"], - "description": _(u"transmit a voice record"), - "icon_medium": u"{media}/icons/muchoslava/png/micro_off_50.png", + "description": _("transmit a voice record"), + "icon_medium": "{media}/icons/muchoslava/png/micro_off_50.png", } @@ -67,7 +67,7 @@ except Exception as e: # an exception can happen if record is pressed # repeatedly in a short time (not a normal use) - log.warning(u"Exception on stop: {}".format(e)) + log.warning("Exception on stop: {}".format(e)) self._counter_timer.cancel() self.time = self.time + 1 else: @@ -99,7 +99,7 @@ except Exception as e: # an exception can happen in the same situation # as for audio.stop() above (i.e. bad record) - log.warning(u"Exception on play: {}".format(e)) + log.warning("Exception on play: {}".format(e)) self.time = 0 return diff -r a0d978d3ce84 -r 772c170b47a9 cagou/plugins/plugin_wid_chat.kv --- a/cagou/plugins/plugin_wid_chat.kv Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/plugins/plugin_wid_chat.kv Tue Aug 13 19:14:22 2019 +0200 @@ -185,7 +185,7 @@ size_hint: 1, 1 padding: dp(5), dp(10) color: 0, 0, 0, 1 - bold: True + bold: root.bold background_normal: app.expand('{media}/misc/borders/border_filled_black.png') background_color: app.c_sec if root.selected else app.c_prim_dark on_release: root.dispatch("on_release") diff -r a0d978d3ce84 -r 772c170b47a9 cagou/plugins/plugin_wid_chat.py --- a/cagou/plugins/plugin_wid_chat.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/plugins/plugin_wid_chat.py Tue Aug 13 19:14:22 2019 +0200 @@ -46,10 +46,10 @@ log = logging.getLogger(__name__) PLUGIN_INFO = { - "name": _(u"chat"), + "name": _("chat"), "main": "Chat", - "description": _(u"instant messaging with one person or a group"), - "icon_symbol": u"chat", + "description": _("instant messaging with one person or a group"), + "icon_symbol": "chat", } # FIXME: OTR specific code is legacy, and only used nowadays for lock color @@ -99,9 +99,9 @@ return self.mess_data.main_message def _set_message(self, message): - if message == self.mess_data.message.get(u""): + if message == self.mess_data.message.get(""): return False - self.mess_data.message = {u"": message} + self.mess_data.message = {"": message} return True message = properties.AliasProperty(_get_message, _set_message) @@ -135,7 +135,7 @@ self.avatar.source = update_dict['avatar'] if 'status' in update_dict: status = update_dict['status'] - self.delivery.text = u'\u2714' if status == 'delivered' else u'' + self.delivery.text = '\u2714' if status == 'delivered' else '' class SendButton(SymbolButton): @@ -191,13 +191,13 @@ def on_select(self, menu): if menu == 'bookmark': - G.host.bridge.menuLaunch(C.MENU_GLOBAL, (u"groups", u"bookmarks"), + G.host.bridge.menuLaunch(C.MENU_GLOBAL, ("groups", "bookmarks"), {}, C.NO_SECURITY_LIMIT, self.chat.profile, callback=partial( G.host.actionManager, profile=self.chat.profile), errback=G.host.errback) else: - raise exceptions.InternalError(u"Unknown menu: {}".format(menu)) + raise exceptions.InternalError("Unknown menu: {}".format(menu)) class ExtraButton(SymbolButton): @@ -253,11 +253,12 @@ text = properties.StringProperty() trust_button = properties.BooleanProperty(False) best_width = properties.NumericProperty(0) + bold = properties.BooleanProperty(True) def __init__(self, **kwargs): + super(EncryptionButton, self).__init__(**kwargs) self.register_event_type('on_release') self.register_event_type('on_trust_release') - super(EncryptionButton, self).__init__(**kwargs) if self.trust_button: self.add_widget(TrustManagementButton()) @@ -279,7 +280,7 @@ self.chat = chat super(EncryptionMenu, self).__init__(**kwargs) btn = EncryptionButton( - text=_(u"unencrypted (plain text)"), + text=_("unencrypted (plain text)"), on_release=self.unencrypted, selected=True, bold=False, @@ -287,7 +288,7 @@ self.add_widget(btn) for plugin in G.host.encryption_plugins: btn = EncryptionButton( - text=plugin[u'name'], + text=plugin['name'], on_release=partial(self.startEncryption, plugin=plugin), on_trust_release=partial(self.getTrustUI, plugin=plugin), trust_button=True, @@ -296,35 +297,35 @@ log.info("added encryption: {}".format(plugin['name'])) def messageEncryptionStopCb(self): - log.info(_(u"Session with {destinee} is now in plain text").format( + log.info(_("Session with {destinee} is now in plain text").format( destinee = self.chat.target)) def messageEncryptionStopEb(self, failure_): - msg = _(u"Error while stopping encryption with {destinee}: {reason}").format( + msg = _("Error while stopping encryption with {destinee}: {reason}").format( destinee = self.chat.target, reason = failure_) log.warning(msg) - G.host.addNote(_(u"encryption problem"), msg, C.XMLUI_DATA_LVL_ERROR) + G.host.addNote(_("encryption problem"), msg, C.XMLUI_DATA_LVL_ERROR) def unencrypted(self, button): self.dismiss() G.host.bridge.messageEncryptionStop( - unicode(self.chat.target), + str(self.chat.target), self.chat.profile, callback=self.messageEncryptionStopCb, errback=self.messageEncryptionStopEb) def messageEncryptionStartCb(self, plugin): - log.info(_(u"Session with {destinee} is now encrypted with {encr_name}").format( + log.info(_("Session with {destinee} is now encrypted with {encr_name}").format( destinee = self.chat.target, encr_name = plugin['name'])) def messageEncryptionStartEb(self, failure_): - msg = _(u"Session can't be encrypted with {destinee}: {reason}").format( + msg = _("Session can't be encrypted with {destinee}: {reason}").format( destinee = self.chat.target, reason = failure_) log.warning(msg) - G.host.addNote(_(u"encryption problem"), msg, C.XMLUI_DATA_LVL_ERROR) + G.host.addNote(_("encryption problem"), msg, C.XMLUI_DATA_LVL_ERROR) def startEncryption(self, button, plugin): """Request encryption with given plugin for this session @@ -334,7 +335,7 @@ """ self.dismiss() G.host.bridge.messageEncryptionStart( - unicode(self.chat.target), + str(self.chat.target), plugin['namespace'], True, self.chat.profile, @@ -347,10 +348,10 @@ xml_ui.show() def encryptionTrustUIGetEb(self, failure_): - msg = _(u"Trust manager interface can't be retrieved: {reason}").format( + msg = _("Trust manager interface can't be retrieved: {reason}").format( reason = failure_) log.warning(msg) - G.host.addNote(_(u"encryption trust management problem"), msg, + G.host.addNote(_("encryption trust management problem"), msg, C.XMLUI_DATA_LVL_ERROR) def getTrustUI(self, button, plugin): @@ -361,7 +362,7 @@ """ self.dismiss() G.host.bridge.encryptionTrustUIGet( - unicode(self.chat.target), + str(self.chat.target), plugin['namespace'], self.chat.profile, callback=self.encryptionTrustUIGetCb, @@ -371,8 +372,8 @@ self.dismiss() G.host.launchMenu( C.MENU_SINGLE, - (u"otr", u"start/refresh"), - {u'jid': unicode(self.chat.target)}, + ("otr", "start/refresh"), + {'jid': str(self.chat.target)}, None, C.NO_SECURITY_LIMIT, self.chat.profile @@ -382,8 +383,8 @@ self.dismiss() G.host.launchMenu( C.MENU_SINGLE, - (u"otr", u"end session"), - {u'jid': unicode(self.chat.target)}, + ("otr", "end session"), + {'jid': str(self.chat.target)}, None, C.NO_SECURITY_LIMIT, self.chat.profile @@ -393,8 +394,8 @@ self.dismiss() G.host.launchMenu( C.MENU_SINGLE, - (u"otr", u"authenticate"), - {u'jid': unicode(self.chat.target)}, + ("otr", "authenticate"), + {'jid': str(self.chat.target)}, None, C.NO_SECURITY_LIMIT, self.chat.profile @@ -425,14 +426,11 @@ self.extra_menu = ExtraMenu(chat=self) extra_btn = ExtraButton(chat=self) self.headerInputAddExtra(extra_btn) - self.header_input.hint_text = u"{}".format(target) + self.header_input.hint_text = "{}".format(target) self.postInit() - def __unicode__(self): - return u"Chat({})".format(self.target) - def __str__(self): - return self.__unicode__().encode('utf-8') + return "Chat({})".format(self.target) def __repr__(self): return self.__str__() @@ -441,7 +439,7 @@ def factory(cls, plugin_info, target, profiles): profiles = list(profiles) if len(profiles) > 1: - raise NotImplementedError(u"Multi-profiles is not available yet for chat") + raise NotImplementedError("Multi-profiles is not available yet for chat") if target is None: target = G.host.profiles[profiles[0]].whoami return G.host.widgets.getOrCreateWidget(cls, target, on_new_widget=None, @@ -467,23 +465,23 @@ def onHeaderInput(self): text = self.header_input.text.strip() try: - if text.count(u'@') != 1 or text.count(u' '): + if text.count('@') != 1 or text.count(' '): raise ValueError jid_ = jid.JID(text) except ValueError: - log.info(u"entered text is not a jid") + log.info("entered text is not a jid") return def discoCb(disco): # TODO: check if plugin XEP-0045 is activated if "conference" in [i[0] for i in disco[1]]: - G.host.bridge.mucJoin(unicode(jid_), "", "", self.profile, + G.host.bridge.mucJoin(str(jid_), "", "", self.profile, callback=self._mucJoinCb, errback=self._mucJoinEb) else: self.changeWidget(jid_) def discoEb(failure): - log.warning(u"Disco failure, ignore this text: {}".format(failure)) + log.warning("Disco failure, ignore this text: {}".format(failure)) G.host.bridge.discoInfos(jid_.domain, self.profile, callback=discoCb, errback=discoEb) @@ -526,7 +524,7 @@ dropdown.clear_widgets() for jid_, jid_data in comp_data: - nick = jid_data.get(u'nick', u'') + nick = jid_data.get('nick', '') if text in jid_.bare or text in nick.lower(): btn = JidButton( jid = jid_.bare, @@ -554,7 +552,7 @@ def _onHistoryPrinted(self): """Refresh or scroll down the focus after the history is printed""" # self.adapter.data = self.messages - for mess_data in self.messages.itervalues(): + for mess_data in self.messages.values(): self.appendMessage(mess_data) super(Chat, self)._onHistoryPrinted() @@ -572,7 +570,7 @@ self.notify(mess_data) def _get_notif_msg(self, mess_data): - return _(u"{nick}: {message}").format( + return _("{nick}: {message}").format( nick=mess_data.nick, message=mess_data.main_message) @@ -597,14 +595,14 @@ notif_msg = self._get_notif_msg(mess_data) G.host.desktop_notif( notif_msg, - title=_(u"private message")) + title=_("private message")) if not is_visible: G.host.addNote( - _(u"private message"), + _("private message"), notif_msg, - symbol = u"chat", + symbol = "chat", action = { - "action": u'chat', + "action": 'chat', "target": self.target, "profiles": self.profiles} ) @@ -612,18 +610,18 @@ if mess_data.mention and not mess_data.history: notif_msg = self._get_notif_msg(mess_data) G.host.addNote( - _(u"mention"), + _("mention"), notif_msg, - symbol = u"chat", + symbol = "chat", action = { - "action": u'chat', + "action": 'chat', "target": self.target, "profiles": self.profiles} ) if not Window.focus: G.host.desktop_notif( notif_msg, - title=_(u"mention ({room_jid})").format( + title=_("mention ({room_jid})").format( room_jid=self.target) ) @@ -640,9 +638,9 @@ def fileTransferEb(self, err_msg, cleaning_cb, profile): if cleaning_cb is not None: cleaning_cb() - msg = _(u"can't transfer file: {reason}").format(reason=err_msg) + msg = _("can't transfer file: {reason}").format(reason=err_msg) log.warning(msg) - G.host.addNote(_(u"File transfer error"), + G.host.addNote(_("File transfer error"), msg, level=C.XMLUI_DATA_LVL_WARNING) @@ -653,9 +651,9 @@ # FIXME: Q&D way of getting file type, upload plugins shouls give it mime_type = mimetypes.guess_type(metadata['url'])[0] if mime_type is not None: - if mime_type.split(u'/')[0] == 'image': + if mime_type.split('/')[0] == 'image': # we generate url ourselves, so this formatting is safe - extra['xhtml'] = u"".format(**metadata) + extra['xhtml'] = "".format(**metadata) G.host.messageSend( self.target, @@ -682,28 +680,28 @@ profile = self.profile, ), errback = partial(G.host.errback, - message=_(u"can't upload file: {msg}")) + message=_("can't upload file: {msg}")) ) elif transfer_type == C.TRANSFER_SEND: if self.type == C.CHAT_GROUP: - log.warning(u"P2P transfer is not possible for group chat") + log.warning("P2P transfer is not possible for group chat") # TODO: show an error dialog to user, or better hide the send button for # MUC else: jid_ = self.target if not jid_.resource: jid_ = G.host.contact_lists[self.profile].getFullJid(jid_) - G.host.bridge.fileSend(unicode(jid_), file_path, "", "", {}, + G.host.bridge.fileSend(str(jid_), file_path, "", "", {}, profile=self.profile) # TODO: notification of sending/failing else: - raise log.error(u"transfer of type {} are not handled".format(transfer_type)) + raise log.error("transfer of type {} are not handled".format(transfer_type)) def messageEncryptionStarted(self, plugin_data): quick_chat.QuickChat.messageEncryptionStarted(self, plugin_data) self.encryption_btn.symbol = SYMBOL_ENCRYPTED self.encryption_btn.color = COLOR_ENCRYPTED - self.encryption_btn.selectAlgo(plugin_data[u'name']) + self.encryption_btn.selectAlgo(plugin_data['name']) def messageEncryptionStopped(self, plugin_data): quick_chat.QuickChat.messageEncryptionStopped(self, plugin_data) @@ -718,7 +716,7 @@ self.changeWidget(jid_) def _mucJoinEb(self, failure): - log.warning(u"Can't join room: {}".format(failure)) + log.warning("Can't join room: {}".format(failure)) def onOTRState(self, state, dest_jid, profile): assert profile in self.profiles @@ -727,7 +725,7 @@ elif state in OTR_STATE_TRUST: self.otr_state_trust = state else: - log.error(_(u"Unknown OTR state received: {}".format(state))) + log.error(_("Unknown OTR state received: {}".format(state))) return self.encryption_btn.symbol = self.encryption_btn.getSymbol() self.encryption_btn.color = self.encryption_btn.getColor() diff -r a0d978d3ce84 -r 772c170b47a9 cagou/plugins/plugin_wid_contact_list.py --- a/cagou/plugins/plugin_wid_contact_list.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/plugins/plugin_wid_contact_list.py Tue Aug 13 19:14:22 2019 +0200 @@ -38,10 +38,10 @@ PLUGIN_INFO = { - "name": _(u"contacts"), + "name": _("contacts"), "main": "ContactList", - "description": _(u"list of contacts"), - "icon_medium": u"{media}/icons/muchoslava/png/contact_list_no_border_blue_44.png" + "description": _("list of contacts"), + "icon_medium": "{media}/icons/muchoslava/png/contact_list_no_border_blue_44.png" } @@ -53,7 +53,7 @@ def __init__(self, **kwargs): super(AddContactMenu, self).__init__(**kwargs) if self.profile is None: - log.warning(_(u"profile not set in AddContactMenu")) + log.warning(_("profile not set in AddContactMenu")) self.profile = next(iter(G.host.profiles)) def addContact(self, contact_jid): @@ -67,15 +67,15 @@ if not contact_jid or not re.match(r"[^@ ]+@[^@ ]+", contact_jid): return contact_jid = jid.JID(contact_jid).bare - G.host.bridge.addContact(unicode(contact_jid), + G.host.bridge.addContact(str(contact_jid), self.profile, callback=lambda: G.host.addNote( - _(u"contact request"), - _(u"a contact request has been sent to {contact_jid}").format( + _("contact request"), + _("a contact request has been sent to {contact_jid}").format( contact_jid=contact_jid)), errback=partial(G.host.errback, - title=_(u"can't add contact"), - message=_(u"error while trying to add contact: {msg}"))) + title=_("can't add contact"), + message=_("error while trying to add contact: {msg}"))) class DelContactMenu(SideMenu): @@ -88,15 +88,15 @@ def do_delete_contact(self): self.hide() - G.host.bridge.delContact(unicode(self.contact_item.jid.bare), + G.host.bridge.delContact(str(self.contact_item.jid.bare), self.contact_item.profile, callback=lambda: G.host.addNote( - _(u"contact removed"), - _(u"{contact_jid} has been removed from your contacts list").format( + _("contact removed"), + _("{contact_jid} has been removed from your contacts list").format( contact_jid=self.contact_item.jid.bare)), errback=partial(G.host.errback, - title=_(u"can't remove contact"), - message=_(u"error while trying to remove contact: {msg}"))) + title=_("can't remove contact"), + message=_("error while trying to remove contact: {msg}"))) @@ -117,11 +117,11 @@ assert self.profile # XXX: for now clicking on an item launch the corresponding Chat widget # behaviour should change in the future - G.host.doAction(u'chat', jid.JID(self.jid), [self.profile]) + G.host.doAction('chat', jid.JID(self.jid), [self.profile]) def getMenuChoices(self): choices = [] - choices.append(dict(text=_(u'delete'), + choices.append(dict(text=_('delete'), index=len(choices)+1, callback=self.main_wid.removeContact)) return choices @@ -180,7 +180,7 @@ if type_ == None or type_ == C.UPDATE_STRUCTURE: log.debug("full contact list update") self.layout.clear_widgets() - for bare_jid, data in self.items_sorted.iteritems(): + for bare_jid, data in self.items_sorted.items(): wid = ContactItem(profile=profile, data=data, jid=bare_jid, main_wid=self) self.layout.add_widget(wid) self._wid_map[(profile, bare_jid)] = wid diff -r a0d978d3ce84 -r 772c170b47a9 cagou/plugins/plugin_wid_file_sharing.py --- a/cagou/plugins/plugin_wid_file_sharing.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/plugins/plugin_wid_file_sharing.py Tue Aug 13 19:14:22 2019 +0200 @@ -42,22 +42,22 @@ PLUGIN_INFO = { - "name": _(u"file sharing"), + "name": _("file sharing"), "main": "FileSharing", - "description": _(u"share/transfer files between devices"), - "icon_symbol": u"exchange", + "description": _("share/transfer files between devices"), + "icon_symbol": "exchange", } -MODE_VIEW = u"view" -MODE_LOCAL = u"local" -SELECT_INSTRUCTIONS = _(u"Please select entities to share with") +MODE_VIEW = "view" +MODE_LOCAL = "local" +SELECT_INSTRUCTIONS = _("Please select entities to share with") if kivy_utils.platform == "android": from jnius import autoclass Environment = autoclass("android.os.Environment") base_dir = Environment.getExternalStorageDirectory().getAbsolutePath() def expanduser(path): - if path == u'~' or path.startswith(u'~/'): - return path.replace(u'~', base_dir, 1) + if path == '~' or path.startswith('~/'): + return path.replace('~', base_dir, 1) return path else: expanduser = os.path.expanduser @@ -72,11 +72,11 @@ def on_mode(self, parent, new_mode): if new_mode == MODE_VIEW: - self.text = _(u"view shared files") + self.text = _("view shared files") elif new_mode == MODE_LOCAL: - self.text = _(u"share local files") + self.text = _("share local files") else: - exceptions.InternalError(u"Unknown mode: {mode}".format(mode=new_mode)) + exceptions.InternalError("Unknown mode: {mode}".format(mode=new_mode)) class PathWidget(ItemWidget): @@ -84,8 +84,8 @@ def __init__(self, filepath, main_wid, **kw): name = os.path.basename(filepath) self.filepath = os.path.normpath(filepath) - if self.filepath == u'.': - self.filepath = u'' + if self.filepath == '.': + self.filepath = '' super(PathWidget, self).__init__(name=name, main_wid=main_wid, **kw) @property @@ -97,7 +97,7 @@ self.main_wid.current_dir = self.filepath def open_menu(self, touch, dt): - log.debug(_(u"opening menu for {path}").format(path=self.filepath)) + log.debug(_("opening menu for {path}").format(path=self.filepath)) super(PathWidget, self).open_menu(touch, dt) @@ -110,11 +110,11 @@ def getMenuChoices(self): choices = [] if self.shared: - choices.append(dict(text=_(u'unshare'), + choices.append(dict(text=_('unshare'), index=len(choices)+1, callback=self.main_wid.unshare)) else: - choices.append(dict(text=_(u'share'), + choices.append(dict(text=_('share'), index=len(choices)+1, callback=self.main_wid.share)) return choices @@ -132,8 +132,8 @@ def do_item_action(self, touch): if self.is_dir: - if self.filepath == u'..': - self.main_wid.remote_entity = u'' + if self.filepath == '..': + self.main_wid.remote_entity = '' else: super(RemotePathWidget, self).do_item_action(touch) else: @@ -144,7 +144,7 @@ def do_item_action(self, touch): self.main_wid.remote_entity = self.entity_jid - self.main_wid.remote_dir = u'' + self.main_wid.remote_dir = '' class FileSharing(quick_widgets.QuickWidget, cagou_widget.CagouWidget, FilterBehavior, @@ -152,9 +152,9 @@ SINGLE=False layout = properties.ObjectProperty() mode = properties.OptionProperty(MODE_VIEW, options=[MODE_VIEW, MODE_LOCAL]) - local_dir = properties.StringProperty(expanduser(u'~')) - remote_dir = properties.StringProperty(u'') - remote_entity = properties.StringProperty(u'') + local_dir = properties.StringProperty(expanduser('~')) + remote_dir = properties.StringProperty('') + remote_entity = properties.StringProperty('') shared_paths = properties.ListProperty() signals_registered = False @@ -208,12 +208,12 @@ self.update_view(None, self.local_dir) def onHeaderInput(self): - if u'/' in self.header_input.text or self.header_input.text == u'~': + if '/' in self.header_input.text or self.header_input.text == '~': self.current_dir = expanduser(self.header_input.text) def onHeaderInputComplete(self, wid, text, **kwargs): """we filter items when text is entered in input box""" - if u'/' in text: + if '/' in text: return self.do_filter(self.layout.children, text, @@ -221,7 +221,7 @@ width_cb=lambda c: c.base_width, height_cb=lambda c: c.minimum_height, continue_tests=[lambda c: not isinstance(c, ItemWidget), - lambda c: c.name == u'..']) + lambda c: c.name == '..']) ## remote sharing callback ## @@ -229,14 +229,14 @@ def _discoFindByFeaturesCb(self, data): entities_services, entities_own, entities_roster = data for entities_map, title in ((entities_services, - _(u'services')), + _('services')), (entities_own, - _(u'your devices')), + _('your devices')), (entities_roster, - _(u'your contacts devices'))): + _('your contacts devices'))): if entities_map: self.layout.add_widget(CategorySeparator(text=title)) - for entity_str, entity_ids in entities_map.iteritems(): + for entity_str, entity_ids in entities_map.items(): entity_jid = jid.JID(entity_str) item = SharingDeviceWidget( self, entity_jid, Identities(entity_ids)) @@ -246,39 +246,39 @@ size_hint=(1, 1), halign='center', text_size=self.size, - text=_(u"No sharing device found"))) + text=_("No sharing device found"))) def discover_devices(self): """Looks for devices handling file "File Information Sharing" and display them""" try: namespace = self.host.ns_map['fis'] except KeyError: - msg = _(u"can't find file information sharing namespace, " - u"is the plugin running?") + msg = _("can't find file information sharing namespace, " + "is the plugin running?") log.warning(msg) - G.host.addNote(_(u"missing plugin"), msg, C.XMLUI_DATA_LVL_ERROR) + G.host.addNote(_("missing plugin"), msg, C.XMLUI_DATA_LVL_ERROR) return self.host.bridge.discoFindByFeatures( [namespace], [], False, True, True, True, False, self.profile, callback=self._discoFindByFeaturesCb, errback=partial(G.host.errback, - title=_(u"shared folder error"), - message=_(u"can't check sharing devices: {msg}"))) + title=_("shared folder error"), + message=_("can't check sharing devices: {msg}"))) def FISListCb(self, files_data): for file_data in files_data: - filepath = os.path.join(self.current_dir, file_data[u'name']) + filepath = os.path.join(self.current_dir, file_data['name']) item = RemotePathWidget( filepath=filepath, main_wid=self, - type_=file_data[u'type']) + type_=file_data['type']) self.layout.add_widget(item) def FISListEb(self, failure_): - self.remote_dir = u'' + self.remote_dir = '' G.host.addNote( - _(u"shared folder error"), - _(u"can't list files for {remote_entity}: {msg}").format( + _("shared folder error"), + _("can't list files for {remote_entity}: {msg}").format( remote_entity=self.remote_entity, msg=failure_), level=C.XMLUI_DATA_LVL_WARNING) @@ -287,25 +287,25 @@ def update_view(self, *args): """update items according to current mode, entity and dir""" - log.debug(u'updating {}, {}'.format(self.current_dir, args)) + log.debug('updating {}, {}'.format(self.current_dir, args)) self.layout.clear_widgets() - self.header_input.text = u'' + self.header_input.text = '' self.header_input.hint_text = self.current_dir if self.mode == MODE_LOCAL: - filepath = os.path.join(self.local_dir, u'..') + filepath = os.path.join(self.local_dir, '..') self.layout.add_widget(LocalPathWidget(filepath=filepath, main_wid=self)) try: files = sorted(os.listdir(self.local_dir)) except OSError as e: - msg = _(u"can't list files in \"{local_dir}\": {msg}").format( + msg = _("can't list files in \"{local_dir}\": {msg}").format( local_dir=self.local_dir, msg=e) G.host.addNote( - _(u"shared folder error"), + _("shared folder error"), msg, level=C.XMLUI_DATA_LVL_WARNING) - self.local_dir = expanduser(u'~') + self.local_dir = expanduser('~') return for f in files: filepath = os.path.join(self.local_dir, f) @@ -317,14 +317,14 @@ else: # we always a way to go back # so user can return to previous list even in case of error - parent_path = os.path.join(self.remote_dir, u'..') + parent_path = os.path.join(self.remote_dir, '..') item = RemotePathWidget( filepath = parent_path, main_wid=self, type_ = C.FILE_TYPE_DIRECTORY) self.layout.add_widget(item) self.host.bridge.FISList( - unicode(self.remote_entity), + str(self.remote_entity), self.remote_dir, {}, self.profile, @@ -335,8 +335,8 @@ def do_share(self, entities_jids, item): if entities_jids: - access = {u'read': {u'type': 'whitelist', - u'jids': entities_jids}} + access = {'read': {'type': 'whitelist', + 'jids': entities_jids}} else: access = {} @@ -346,11 +346,11 @@ json.dumps(access, ensure_ascii=False), self.profile, callback=lambda name: G.host.addNote( - _(u"sharing folder"), - _(u"{name} is now shared").format(name=name)), + _("sharing folder"), + _("{name} is now shared").format(name=name)), errback=partial(G.host.errback, - title=_(u"sharing folder"), - message=_(u"can't share folder: {msg}"))) + title=_("sharing folder"), + message=_("can't share folder: {msg}"))) def share(self, menu): item = self.menu_item @@ -365,16 +365,16 @@ item.filepath, self.profile, callback=lambda: G.host.addNote( - _(u"sharing folder"), - _(u"{name} is not shared anymore").format(name=item.name)), + _("sharing folder"), + _("{name} is not shared anymore").format(name=item.name)), errback=partial(G.host.errback, - title=_(u"sharing folder"), - message=_(u"can't unshare folder: {msg}"))) + title=_("sharing folder"), + message=_("can't unshare folder: {msg}"))) def fileJingleRequestCb(self, progress_id, item, dest_path): G.host.addNote( - _(u"file request"), - _(u"{name} download started at {dest_path}").format( + _("file request"), + _("{name} download started at {dest_path}").format( name = item.name, dest_path = dest_path)) @@ -388,19 +388,19 @@ assert self.remote_entity extra = {'path': path} dest_path = files_utils.get_unique_name(os.path.join(G.host.downloads_dir, name)) - G.host.bridge.fileJingleRequest(unicode(self.remote_entity), + G.host.bridge.fileJingleRequest(str(self.remote_entity), dest_path, name, - u'', - u'', + '', + '', extra, self.profile, callback=partial(self.fileJingleRequestCb, item=item, dest_path=dest_path), errback=partial(G.host.errback, - title = _(u"file request error"), - message = _(u"can't request file: {msg}"))) + title = _("file request error"), + message = _("can't request file: {msg}"))) @classmethod def shared_path_new(cls, shared_path, name, profile): @@ -414,5 +414,5 @@ if shared_path in wid.shared_paths: wid.shared_paths.remove(shared_path) else: - log.warning(_(u"shared path {path} not found in {widget}".format( + log.warning(_("shared path {path} not found in {widget}".format( path = shared_path, widget = wid))) diff -r a0d978d3ce84 -r 772c170b47a9 cagou/plugins/plugin_wid_remote.py --- a/cagou/plugins/plugin_wid_remote.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/plugins/plugin_wid_remote.py Tue Aug 13 19:14:22 2019 +0200 @@ -41,13 +41,13 @@ PLUGIN_INFO = { - "name": _(u"remote control"), + "name": _("remote control"), "main": "RemoteControl", - "description": _(u"universal remote control"), - "icon_symbol": u"signal", + "description": _("universal remote control"), + "icon_symbol": "signal", } -NOTE_TITLE = _(u"Media Player Remote Control") +NOTE_TITLE = _("Media Player Remote Control") class RemoteItemWidget(ItemWidget): @@ -66,7 +66,7 @@ class MediaPlayerControlWidget(BoxLayout): main_wid = properties.ObjectProperty() remote_item = properties.ObjectProperty() - status = properties.OptionProperty(u"play", options=(u"play", u"pause", u"stop")) + status = properties.OptionProperty("play", options=("play", "pause", "stop")) title = properties.StringProperty() identity = properties.StringProperty() command = properties.DictProperty() @@ -84,34 +84,34 @@ try: setattr(self, prop.lower(), ui_tpl.widgets[prop].value) except KeyError: - log.warning(_(u"Missing field: {name}").format(name=prop)) + log.warning(_("Missing field: {name}").format(name=prop)) playback_status = self.ui_tpl.widgets['PlaybackStatus'].value - if playback_status == u"Playing": - self.status = u"pause" - elif playback_status == u"Paused": - self.status = u"play" - elif playback_status == u"Stopped": - self.status = u"play" + if playback_status == "Playing": + self.status = "pause" + elif playback_status == "Paused": + self.status = "play" + elif playback_status == "Stopped": + self.status = "play" else: G.host.addNote( title=NOTE_TITLE, - message=_(u"Unknown playback status: playback_status") + message=_("Unknown playback status: playback_status") .format(playback_status=playback_status), level=C.XMLUI_DATA_LVL_WARNING) self.commands = {v:k for k,v in ui_tpl.widgets['command'].options} def adHocRunCb(self, xmlui_raw): ui_tpl = template_xmlui.create(G.host, xmlui_raw) - data = {xmlui.XMLUIPanel.escape(u"media_player"): self.remote_item.node, - u"session_id": ui_tpl.session_id} + data = {xmlui.XMLUIPanel.escape("media_player"): self.remote_item.node, + "session_id": ui_tpl.session_id} G.host.bridge.launchAction( ui_tpl.submit_id, data, self.profile, callback=self.updateUI, errback=self.main_wid.errback) def on_remote_item(self, __, remote): - NS_MEDIA_PLAYER = G.host.ns_map[u"mediaplayer"] - G.host.bridge.adHocRun(unicode(remote.device_jid), NS_MEDIA_PLAYER, self.profile, + NS_MEDIA_PLAYER = G.host.ns_map["mediaplayer"] + G.host.bridge.adHocRun(str(remote.device_jid), NS_MEDIA_PLAYER, self.profile, callback=self.adHocRunCb, errback=self.main_wid.errback) @@ -121,15 +121,15 @@ except KeyError: G.host.addNote( title=NOTE_TITLE, - message=_(u"{command} command is not managed").format(command=command), + message=_("{command} command is not managed").format(command=command), level=C.XMLUI_DATA_LVL_WARNING) else: - data = {xmlui.XMLUIPanel.escape(u"command"): cmd_value, - u"session_id": self.ui_tpl.session_id} + data = {xmlui.XMLUIPanel.escape("command"): cmd_value, + "session_id": self.ui_tpl.session_id} # hidden values are normally transparently managed by XMLUIPanel # but here we have to add them by hand hidden = {xmlui.XMLUIPanel.escape(k):v - for k,v in self.ui_tpl.hidden.iteritems()} + for k,v in self.ui_tpl.hidden.items()} data.update(hidden) G.host.bridge.launchAction( self.ui_tpl.submit_id, data, self.profile, @@ -140,9 +140,9 @@ class RemoteDeviceWidget(DeviceWidget): def xmluiCb(self, data, cb_id, profile): - if u'xmlui' in data: + if 'xmlui' in data: xml_ui = xmlui.create( - G.host, data[u'xmlui'], callback=self.xmluiCb, profile=profile) + G.host, data['xmlui'], callback=self.xmluiCb, profile=profile) if isinstance(xml_ui, xmlui.XMLUIDialog): self.main_wid.showRootWidget() xml_ui.show() @@ -151,7 +151,7 @@ self.main_wid.layout.add_widget(xml_ui) else: if data: - log.warning(_(u"Unhandled data: {data}").format(data=data)) + log.warning(_("Unhandled data: {data}").format(data=data)) self.main_wid.showRootWidget() def onClose(self, __, reason): @@ -167,7 +167,7 @@ def do_item_action(self, touch): self.main_wid.layout.clear_widgets() - G.host.bridge.adHocRun(unicode(self.entity_jid), u'', self.profile, + G.host.bridge.adHocRun(str(self.entity_jid), '', self.profile, callback=self.adHocRunCb, errback=self.main_wid.errback) @@ -194,7 +194,7 @@ """Generic errback which add a warning note and go back to root widget""" G.host.addNote( title=NOTE_TITLE, - message=_(u"Can't use remote control: {reason}").format(reason=failure_), + message=_("Can't use remote control: {reason}").format(reason=failure_), level=C.XMLUI_DATA_LVL_WARNING) self.showRootWidget() @@ -218,8 +218,8 @@ self.show_devices(found) def adHocRemotesGetEb(self, failure_, found): - G.host.errback(failure_, title=_(u"discovery error"), - message=_(u"can't check remote controllers: {msg}")) + G.host.errback(failure_, title=_("discovery error"), + message=_("can't check remote controllers: {msg}")) found.insert(0, []) if len(found) == 2: self.show_devices(found) @@ -236,8 +236,8 @@ self.show_devices(found) def _discoFindByFeaturesEb(self, failure_, found): - G.host.errback(failure_, title=_(u"discovery error"), - message=_(u"can't check devices: {msg}")) + G.host.errback(failure_, title=_("discovery error"), + message=_("can't check devices: {msg}")) found.append(({}, {}, {})) if len(found) == 2: self.show_devices(found) @@ -247,9 +247,9 @@ try: namespace = self.host.ns_map['commands'] except KeyError: - msg = _(u"can't find ad-hoc commands namespace, is the plugin running?") + msg = _("can't find ad-hoc commands namespace, is the plugin running?") log.warning(msg) - G.host.addNote(_(u"missing plugin"), msg, C.XMLUI_DATA_LVL_ERROR) + G.host.addNote(_("missing plugin"), msg, C.XMLUI_DATA_LVL_ERROR) return self.host.bridge.discoFindByFeatures( [namespace], [], False, True, True, True, False, self.profile, @@ -259,7 +259,7 @@ def show_devices(self, found): remotes_data, (entities_services, entities_own, entities_roster) = found if remotes_data: - title = _(u"media players remote controls") + title = _("media players remote controls") self.stack_layout.add_widget(CategorySeparator(text=title)) for remote_data in remotes_data: @@ -268,14 +268,14 @@ self.stack_layout.add_widget(wid) for entities_map, title in ((entities_services, - _(u'services')), + _('services')), (entities_own, - _(u'your devices')), + _('your devices')), (entities_roster, - _(u'your contacts devices'))): + _('your contacts devices'))): if entities_map: self.stack_layout.add_widget(CategorySeparator(text=title)) - for entity_str, entity_ids in entities_map.iteritems(): + for entity_str, entity_ids in entities_map.items(): entity_jid = jid.JID(entity_str) item = RemoteDeviceWidget( self, entity_jid, Identities(entity_ids)) @@ -286,4 +286,4 @@ size_hint=(1, 1), halign='center', text_size=self.size, - text=_(u"No sharing device found"))) + text=_("No sharing device found"))) diff -r a0d978d3ce84 -r 772c170b47a9 cagou/plugins/plugin_wid_settings.py --- a/cagou/plugins/plugin_wid_settings.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/plugins/plugin_wid_settings.py Tue Aug 13 19:14:22 2019 +0200 @@ -30,10 +30,10 @@ PLUGIN_INFO = { - "name": _(u"settings"), + "name": _("settings"), "main": "CagouSettings", - "description": _(u"Cagou/SàT settings"), - "icon_symbol": u"wrench", + "description": _("Cagou/SàT settings"), + "icon_symbol": "wrench", } @@ -60,7 +60,7 @@ def getParamsUIEb(self, failure): self.changeWidget(Label( - text=_(u"Can't load parameters!"), + text=_("Can't load parameters!"), bold=True, color=(1,0,0,1))) - G.host.showDialog(u"Can't load params UI", failure, "error") + G.host.showDialog("Can't load params UI", failure, "error") diff -r a0d978d3ce84 -r 772c170b47a9 cagou/plugins/plugin_wid_widget_selector.py --- a/cagou/plugins/plugin_wid_widget_selector.py Mon Aug 05 11:21:54 2019 +0200 +++ b/cagou/plugins/plugin_wid_widget_selector.py Tue Aug 13 19:14:22 2019 +0200 @@ -31,11 +31,11 @@ PLUGIN_INFO = { - "name": _(u"widget selector"), + "name": _("widget selector"), "import_name": C.WID_SELECTOR, "main": "WidgetSelector", - "description": _(u"show available widgets and allow to select one"), - "icon_medium": u"{media}/icons/muchoslava/png/selector_no_border_blue_44.png" + "description": _("show available widgets and allow to select one"), + "icon_medium": "{media}/icons/muchoslava/png/selector_no_border_blue_44.png" } @@ -44,7 +44,7 @@ item = properties.ObjectProperty() def on_release(self, *args): - log.debug(u"widget selection: {}".format(self.plugin_info["name"])) + log.debug("widget selection: {}".format(self.plugin_info["name"])) factory = self.plugin_info["factory"] G.host.switchWidget(self, factory(self.plugin_info, None, profiles=iter(G.host.profiles))) diff -r a0d978d3ce84 -r 772c170b47a9 setup.py --- a/setup.py Mon Aug 05 11:21:54 2019 +0200 +++ b/setup.py Tue Aug 13 19:14:22 2019 +0200 @@ -52,7 +52,7 @@ setup(name=NAME, version=VERSION, - description=u'Desktop/Android frontend for Salut à Toi XMPP client', + description='Desktop/Android frontend for Salut à Toi XMPP client', long_description=textwrap.dedent("""\ Cagou is a desktop/Android frontend for Salut à Toi. It provides native graphical interface with a modern user interface,