[Core] Refactor the base argparser and translation code.
- Move baseargparser out of deluge/ui since it is also used by the Daemon and could cause packaging issues if UI code is not available. - Renamed baseargparser to argparserbase to follow existing Deluge naming. - Renamed get_version to distinguish from deluge.common.get_version. - Translation code is usable by more than just the UIs so also move it to Deluge namespace and re-use i18n directory and make it a package. - Renamed setup_translations to singular as it felt more correct. - Renamed set_dummy_trans to be more descriptive. Closes: #3081
This commit is contained in:
parent
653f80eac8
commit
d417c4b0f9
|
@ -86,7 +86,7 @@ argparse.ArgumentParser.find_subcommand = find_subcommand
|
|||
argparse.ArgumentParser.set_default_subparser = set_default_subparser
|
||||
|
||||
|
||||
def get_version():
|
||||
def _get_version_detail():
|
||||
version_str = '%s\n' % (common.get_version())
|
||||
try:
|
||||
from deluge._libtorrent import LT_VERSION
|
||||
|
@ -151,7 +151,7 @@ class HelpAction(argparse._HelpAction):
|
|||
parser.exit()
|
||||
|
||||
|
||||
class BaseArgParser(argparse.ArgumentParser):
|
||||
class ArgParserBase(argparse.ArgumentParser):
|
||||
def __init__(self, *args, **kwargs):
|
||||
if 'formatter_class' not in kwargs:
|
||||
kwargs['formatter_class'] = lambda prog: DelugeTextHelpFormatter(
|
||||
|
@ -165,7 +165,7 @@ class BaseArgParser(argparse.ArgumentParser):
|
|||
self.log_stream = kwargs['log_stream']
|
||||
del kwargs['log_stream']
|
||||
|
||||
super(BaseArgParser, self).__init__(*args, **kwargs)
|
||||
super(ArgParserBase, self).__init__(*args, **kwargs)
|
||||
|
||||
self.common_setup = False
|
||||
self.process_arg_group = False
|
||||
|
@ -178,13 +178,13 @@ class BaseArgParser(argparse.ArgumentParser):
|
|||
'-V',
|
||||
'--version',
|
||||
action='version',
|
||||
version='%(prog)s ' + get_version(),
|
||||
version='%(prog)s ' + _get_version_detail(),
|
||||
help=_('Print version information'),
|
||||
)
|
||||
self.group.add_argument(
|
||||
'-v',
|
||||
action='version',
|
||||
version='%(prog)s ' + get_version(),
|
||||
version='%(prog)s ' + _get_version_detail(),
|
||||
help=argparse.SUPPRESS,
|
||||
) # Deprecated arg
|
||||
self.group.add_argument(
|
||||
|
@ -246,7 +246,7 @@ class BaseArgParser(argparse.ArgumentParser):
|
|||
argparse.Namespace: The parsed arguments.
|
||||
|
||||
"""
|
||||
options = super(BaseArgParser, self).parse_args(args=args)
|
||||
options = super(ArgParserBase, self).parse_args(args=args)
|
||||
return self._handle_ui_options(options)
|
||||
|
||||
def parse_known_ui_args(self, args, withhold=None):
|
||||
|
@ -262,7 +262,7 @@ class BaseArgParser(argparse.ArgumentParser):
|
|||
"""
|
||||
if withhold:
|
||||
args = [a for a in args if a not in withhold]
|
||||
options, remaining = super(BaseArgParser, self).parse_known_args(args=args)
|
||||
options, remaining = super(ArgParserBase, self).parse_known_args(args=args)
|
||||
options.remaining = remaining
|
||||
# Hanlde common and process group options
|
||||
return self._handle_ui_options(options)
|
|
@ -15,10 +15,10 @@ from logging import DEBUG, FileHandler, getLogger
|
|||
|
||||
from twisted.internet.error import CannotListenError
|
||||
|
||||
from deluge.argparserbase import ArgParserBase
|
||||
from deluge.common import run_profiled
|
||||
from deluge.configmanager import get_config_dir
|
||||
from deluge.ui.baseargparser import BaseArgParser
|
||||
from deluge.ui.translations_util import set_dummy_trans
|
||||
from deluge.i18n import setup_mock_translation
|
||||
|
||||
|
||||
def add_daemon_options(parser):
|
||||
|
@ -78,10 +78,10 @@ def start_daemon(skip_start=False):
|
|||
deluge.core.daemon.Daemon: A new daemon object
|
||||
|
||||
"""
|
||||
set_dummy_trans(warn_msg=True)
|
||||
setup_mock_translation(warn_msg=True)
|
||||
|
||||
# Setup the argument parser
|
||||
parser = BaseArgParser()
|
||||
parser = ArgParserBase()
|
||||
add_daemon_options(parser)
|
||||
|
||||
options = parser.parse_args()
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
from .util import (
|
||||
I18N_DOMAIN,
|
||||
get_languages,
|
||||
set_language,
|
||||
setup_mock_translation,
|
||||
setup_translation,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
'I18N_DOMAIN',
|
||||
'set_language',
|
||||
'get_languages',
|
||||
'setup_translation',
|
||||
'setup_mock_translation',
|
||||
]
|
|
@ -9,6 +9,12 @@ from __future__ import unicode_literals
|
|||
# http://www.i18nguy.com/unicode/language-identifiers.html
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
|
||||
|
||||
# Deferred translation
|
||||
def _(message):
|
||||
return message
|
||||
|
||||
|
||||
# Languages we provide translations for, out of the box.
|
||||
LANGUAGES = {
|
||||
'af': _('Afrikaans'),
|
||||
|
@ -107,3 +113,5 @@ LANGUAGES = {
|
|||
'zh-hant': _('Traditional Chinese'),
|
||||
'zh_TW': _('Chinese (Taiwan)'),
|
||||
}
|
||||
|
||||
del _
|
|
@ -20,35 +20,19 @@ from six.moves import builtins
|
|||
|
||||
import deluge.common
|
||||
|
||||
from .languages import LANGUAGES
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
log.addHandler(
|
||||
logging.NullHandler()
|
||||
) # Silence: No handlers could be found for logger "deluge.util.lang"
|
||||
|
||||
I18N_DOMAIN = 'deluge'
|
||||
|
||||
|
||||
def set_dummy_trans(warn_msg=None):
|
||||
def _func(*txt):
|
||||
if warn_msg:
|
||||
log.warning(
|
||||
'"%s" has been marked for translation, but translation is unavailable.',
|
||||
txt[0],
|
||||
)
|
||||
return txt[0]
|
||||
|
||||
builtins.__dict__['_'] = _func
|
||||
builtins.__dict__['ngettext'] = builtins.__dict__['_n'] = _func
|
||||
|
||||
|
||||
def get_translations_path():
|
||||
"""Get the absolute path to the directory containing translation files"""
|
||||
return deluge.common.resource_filename('deluge', 'i18n')
|
||||
|
||||
|
||||
def get_languages():
|
||||
from deluge.ui import languages # Import here so that gettext has been setup first
|
||||
|
||||
lang = []
|
||||
|
||||
translations_path = get_translations_path()
|
||||
|
@ -61,9 +45,9 @@ def get_languages():
|
|||
|
||||
for i, lang_code in enumerate(lang_dirs):
|
||||
name = '%s (Language name missing)' % lang_code
|
||||
if lang_code in languages.LANGUAGES:
|
||||
name = languages.LANGUAGES[lang_code]
|
||||
lang.append([lang_code, name])
|
||||
if lang_code in LANGUAGES:
|
||||
name = LANGUAGES[lang_code]
|
||||
lang.append([lang_code, _(name)])
|
||||
|
||||
lang = sorted(lang, key=lambda l: l[1])
|
||||
return lang
|
||||
|
@ -93,8 +77,21 @@ def set_language(lang):
|
|||
log.warning('IOError when loading translations: %s', ex)
|
||||
|
||||
|
||||
def setup_mock_translation(warn_msg=None):
|
||||
def _func(*txt):
|
||||
if warn_msg:
|
||||
log.warning(
|
||||
'"%s" has been marked for translation, but translation is unavailable.',
|
||||
txt[0],
|
||||
)
|
||||
return txt[0]
|
||||
|
||||
builtins.__dict__['_'] = _func
|
||||
builtins.__dict__['ngettext'] = builtins.__dict__['_n'] = _func
|
||||
|
||||
|
||||
# Initialize gettext
|
||||
def setup_translations():
|
||||
def setup_translation():
|
||||
translations_path = get_translations_path()
|
||||
log.info('Setting up translations from %s', translations_path)
|
||||
|
||||
|
@ -131,6 +128,6 @@ def setup_translations():
|
|||
except Exception as ex:
|
||||
log.error('Unable to initialize gettext/locale!')
|
||||
log.exception(ex)
|
||||
set_dummy_trans()
|
||||
setup_mock_translation()
|
||||
|
||||
deluge.common.translate_size_units()
|
|
@ -23,7 +23,7 @@ import deluge.configmanager
|
|||
import deluge.core.preferencesmanager
|
||||
import deluge.log
|
||||
from deluge.error import DelugeError
|
||||
from deluge.ui.translations_util import setup_translations
|
||||
from deluge.i18n import setup_translation
|
||||
|
||||
# This sets log level to critical, so use log.critical() to debug while running unit tests
|
||||
deluge.log.setup_logger('none')
|
||||
|
@ -75,7 +75,7 @@ def add_watchdog(deferred, timeout=0.05, message=None):
|
|||
|
||||
|
||||
# Initialize gettext
|
||||
setup_translations()
|
||||
setup_translation()
|
||||
|
||||
|
||||
class ReactorOverride(object):
|
||||
|
|
|
@ -30,7 +30,7 @@ from deluge.common import (
|
|||
is_url,
|
||||
windows_check,
|
||||
)
|
||||
from deluge.ui.translations_util import setup_translations
|
||||
from deluge.i18n import setup_translation
|
||||
|
||||
from .common import get_test_data_file, set_tmp_config_dir
|
||||
|
||||
|
@ -38,7 +38,7 @@ from .common import get_test_data_file, set_tmp_config_dir
|
|||
class CommonTestCase(unittest.TestCase):
|
||||
def setUp(self): # NOQA
|
||||
self.config_dir = set_tmp_config_dir()
|
||||
setup_translations()
|
||||
setup_translation()
|
||||
|
||||
def tearDown(self): # NOQA
|
||||
pass
|
||||
|
|
|
@ -13,7 +13,7 @@ from twisted.trial import unittest
|
|||
import deluge.component as component
|
||||
from deluge.common import windows_check
|
||||
from deluge.configmanager import ConfigManager
|
||||
from deluge.ui.translations_util import setup_translations
|
||||
from deluge.i18n import setup_translation
|
||||
|
||||
from . import common
|
||||
from .basetest import BaseTestCase
|
||||
|
@ -27,7 +27,7 @@ try:
|
|||
except ImportError:
|
||||
libs_available = False
|
||||
|
||||
setup_translations()
|
||||
setup_translation()
|
||||
|
||||
|
||||
@pytest.mark.gtkui
|
||||
|
|
|
@ -15,7 +15,7 @@ from twisted.trial import unittest
|
|||
|
||||
import deluge.component as component
|
||||
from deluge.configmanager import ConfigManager
|
||||
from deluge.ui.translations_util import setup_translations
|
||||
from deluge.i18n import setup_translation
|
||||
|
||||
from . import common
|
||||
from .basetest import BaseTestCase
|
||||
|
@ -36,7 +36,7 @@ except (ImportError, ValueError):
|
|||
else:
|
||||
libs_available = True
|
||||
|
||||
setup_translations()
|
||||
setup_translation()
|
||||
|
||||
|
||||
@pytest.mark.gtkui
|
||||
|
|
|
@ -15,7 +15,7 @@ import os
|
|||
import sys
|
||||
|
||||
import deluge.common
|
||||
from deluge.ui.baseargparser import BaseArgParser, DelugeTextHelpFormatter
|
||||
from deluge.argparserbase import ArgParserBase, DelugeTextHelpFormatter
|
||||
from deluge.ui.ui import UI
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
@ -143,7 +143,7 @@ class Console(UI):
|
|||
def start(self):
|
||||
if self.ui_args is None:
|
||||
# Started directly by deluge-console script so must find the UI args manually
|
||||
options, remaining = BaseArgParser(common_help=False).parse_known_args()
|
||||
options, remaining = ArgParserBase(common_help=False).parse_known_args()
|
||||
self.ui_args = remaining
|
||||
|
||||
i = self.console_parser.find_subcommand(args=self.ui_args)
|
||||
|
|
|
@ -13,6 +13,7 @@ import logging
|
|||
|
||||
from deluge.common import is_ip
|
||||
from deluge.decorators import overrides
|
||||
from deluge.i18n import get_languages
|
||||
from deluge.ui.client import client
|
||||
from deluge.ui.common import DISK_CACHE_KEYS
|
||||
from deluge.ui.console.widgets import BaseInputPane, BaseWindow
|
||||
|
@ -192,7 +193,6 @@ class InterfacePane(BasePreferencePane):
|
|||
_('Move selection when moving torrents in the queue'),
|
||||
console_config['torrentview']['move_selection'],
|
||||
)
|
||||
from deluge.ui.translations_util import get_languages
|
||||
|
||||
langs = get_languages()
|
||||
langs.insert(0, ('', 'System Default'))
|
||||
|
|
|
@ -13,11 +13,11 @@ import copy
|
|||
import logging
|
||||
|
||||
import deluge.common
|
||||
from deluge.i18n import setup_translation
|
||||
from deluge.ui.common import TORRENT_DATA_FIELD
|
||||
from deluge.ui.console.utils import format_utils
|
||||
from deluge.ui.translations_util import setup_translations
|
||||
|
||||
setup_translations()
|
||||
setup_translation()
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
|
|
@ -47,11 +47,11 @@ from deluge.common import (
|
|||
)
|
||||
from deluge.configmanager import ConfigManager, get_config_dir
|
||||
from deluge.error import DaemonRunningError
|
||||
from deluge.i18n import I18N_DOMAIN, set_language, setup_translation
|
||||
from deluge.ui.client import client
|
||||
from deluge.ui.hostlist import LOCALHOST
|
||||
from deluge.ui.sessionproxy import SessionProxy
|
||||
from deluge.ui.tracker_icons import TrackerIcons
|
||||
from deluge.ui.translations_util import I18N_DOMAIN, set_language, setup_translations
|
||||
|
||||
# isort:imports-localfolder
|
||||
from .addtorrentdialog import AddTorrentDialog
|
||||
|
@ -146,7 +146,7 @@ def windowing(like):
|
|||
class GtkUI(object):
|
||||
def __init__(self, args):
|
||||
# Setup gtkbuilder/glade translation
|
||||
setup_translations()
|
||||
setup_translation()
|
||||
Builder().set_translation_domain(I18N_DOMAIN)
|
||||
|
||||
# Setup signals
|
||||
|
|
|
@ -22,9 +22,9 @@ import deluge.common
|
|||
import deluge.component as component
|
||||
from deluge.configmanager import ConfigManager, get_config_dir
|
||||
from deluge.error import AuthManagerError, NotAuthorizedError
|
||||
from deluge.i18n import get_languages
|
||||
from deluge.ui.client import client
|
||||
from deluge.ui.common import DISK_CACHE_KEYS, PREFS_CATOG_TRANS
|
||||
from deluge.ui.translations_util import get_languages
|
||||
|
||||
from .common import associate_magnet_links, get_clipboard_text, get_deluge_icon
|
||||
from .dialogs import AccountDialog, ErrorDialog, InformationDialog, YesNoDialog
|
||||
|
|
|
@ -14,8 +14,8 @@ import logging
|
|||
import deluge.common
|
||||
import deluge.configmanager
|
||||
import deluge.log
|
||||
from deluge.ui.baseargparser import BaseArgParser
|
||||
from deluge.ui.translations_util import setup_translations
|
||||
from deluge.argparserbase import ArgParserBase
|
||||
from deluge.i18n import setup_translation
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -38,8 +38,8 @@ class UI(object):
|
|||
def __init__(self, name, **kwargs):
|
||||
self.__name = name
|
||||
self.ui_args = kwargs.pop('ui_args', None)
|
||||
setup_translations()
|
||||
self.__parser = BaseArgParser(**kwargs)
|
||||
setup_translation()
|
||||
self.__parser = ArgParserBase(**kwargs)
|
||||
|
||||
def parse_args(self, parser, args=None):
|
||||
options = parser.parse_args(args)
|
||||
|
|
|
@ -23,8 +23,8 @@ import pkg_resources
|
|||
|
||||
import deluge.common
|
||||
import deluge.configmanager
|
||||
from deluge.ui.baseargparser import BaseArgParser
|
||||
from deluge.ui.translations_util import setup_translations
|
||||
from deluge.argparserbase import ArgParserBase
|
||||
from deluge.i18n import setup_translation
|
||||
|
||||
DEFAULT_PREFS = {'default_ui': 'gtk'}
|
||||
|
||||
|
@ -33,7 +33,7 @@ AMBIGUOUS_CMD_ARGS = ('-h', '--help', '-v', '-V', '--version')
|
|||
|
||||
def start_ui():
|
||||
"""Entry point for ui script"""
|
||||
setup_translations()
|
||||
setup_translation()
|
||||
|
||||
# Get the registered UI entry points
|
||||
ui_entrypoints = {}
|
||||
|
@ -59,7 +59,7 @@ def start_ui():
|
|||
return _parser
|
||||
|
||||
# Setup parser with Common Options and add UI Options group.
|
||||
parser = add_ui_options_group(BaseArgParser())
|
||||
parser = add_ui_options_group(ArgParserBase())
|
||||
|
||||
# Parse and handle common/process group options
|
||||
options = parser.parse_known_ui_args(sys.argv, withhold=AMBIGUOUS_CMD_ARGS)
|
||||
|
@ -81,7 +81,7 @@ def start_ui():
|
|||
# We have parsed and got the config dir needed to get the default UI
|
||||
# Now create a parser for choosing the UI. We reuse the ui option group for
|
||||
# parsing to succeed and the text displayed to user, but result is not used.
|
||||
parser = add_ui_options_group(BaseArgParser(common_help=True))
|
||||
parser = add_ui_options_group(ArgParserBase(common_help=True))
|
||||
|
||||
# Create subparser for each registered UI. Empty title is used to remove unwanted positional text.
|
||||
subparsers = parser.add_subparsers(
|
||||
|
|
|
@ -26,12 +26,12 @@ from deluge import component, httpdownloader
|
|||
from deluge.common import AUTH_LEVEL_DEFAULT, get_magnet_info, is_magnet
|
||||
from deluge.configmanager import get_config_dir
|
||||
from deluge.error import NotAuthorizedError
|
||||
from deluge.i18n import get_languages
|
||||
from deluge.ui.client import Client, client
|
||||
from deluge.ui.common import FileTree2, TorrentInfo
|
||||
from deluge.ui.coreconfig import CoreConfig
|
||||
from deluge.ui.hostlist import HostList
|
||||
from deluge.ui.sessionproxy import SessionProxy
|
||||
from deluge.ui.translations_util import get_languages
|
||||
from deluge.ui.web.common import _
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
|
|
@ -25,8 +25,8 @@ from deluge import common, component, configmanager
|
|||
from deluge.common import is_ipv6
|
||||
from deluge.core.rpcserver import check_ssl_keys
|
||||
from deluge.crypto_utils import get_context_factory
|
||||
from deluge.i18n import set_language, setup_translation
|
||||
from deluge.ui.tracker_icons import TrackerIcons
|
||||
from deluge.ui.translations_util import set_language, setup_translations
|
||||
from deluge.ui.web.auth import Auth
|
||||
from deluge.ui.web.common import Template
|
||||
from deluge.ui.web.json_api import JSON, WebApi, WebUtils
|
||||
|
@ -687,7 +687,7 @@ class DelugeWeb(component.Component):
|
|||
# Strip away slashes and serve on the base path as well as root path
|
||||
self.top_level.putChild(self.base.strip('/'), self.top_level)
|
||||
|
||||
setup_translations()
|
||||
setup_translation()
|
||||
|
||||
# Remove twisted version number from 'server' http-header for security reasons
|
||||
server.version = 'TwistedWeb'
|
||||
|
|
Loading…
Reference in New Issue