diff --git a/securedrop_client/__init__.py b/securedrop_client/__init__.py index dc7b12a144..fa9c4ec2bc 100644 --- a/securedrop_client/__init__.py +++ b/securedrop_client/__init__.py @@ -1,25 +1 @@ -import gettext -import locale -import os - - -# Configure locale and language. -# Define where the translation assets are to be found. -localedir = os.path.abspath(os.path.join(os.path.dirname(__file__), 'locale')) -try: - # Use the operating system's locale. - current_locale, encoding = locale.getdefaultlocale() - # Get the language code. - if current_locale is None: - language_code = 'en' - else: - language_code = current_locale[:2] -except ValueError: # pragma: no cover - language_code = 'en' # pragma: no cover -# DEBUG/TRANSLATE: override the language code here (e.g. to Chinese). -# language_code = 'zh' -gettext.translation('securedrop_client', localedir=localedir, - languages=[language_code], fallback=True).install() - - __version__ = '0.0.6' diff --git a/securedrop_client/app.py b/securedrop_client/app.py index efb06cdc7f..c5c1044be5 100644 --- a/securedrop_client/app.py +++ b/securedrop_client/app.py @@ -18,6 +18,8 @@ """ import logging import os +import gettext +import locale import platform import signal import sys @@ -54,6 +56,27 @@ def excepthook(*exc_args): sys.exit(1) +def configure_locale_and_language() -> str: + # Configure locale and language. + # Define where the translation assets are to be found. + localedir = os.path.abspath(os.path.join(os.path.dirname(__file__), 'locale')) + try: + # Use the operating system's locale. + current_locale, encoding = locale.getdefaultlocale() + # Get the language code. + if current_locale is None: + language_code = 'en' + else: + language_code = current_locale[:2] + except ValueError: # pragma: no cover + language_code = 'en' # pragma: no cover + # DEBUG/TRANSLATE: override the language code here (e.g. to Chinese). + # language_code = 'zh' + gettext.translation('securedrop_client', localedir=localedir, + languages=[language_code], fallback=True).install() + return language_code + + def configure_logging(sdc_home: str) -> None: """ All logging related settings are set up by this function. @@ -140,6 +163,7 @@ def start_app(args, qt_args) -> None: Create all the top-level assets for the application, set things up and run the application. Specific tasks include: + - set up locale and language. - set up logging. - create an application object. - create a window for the app. @@ -148,6 +172,7 @@ def start_app(args, qt_args) -> None: - configure the client (logic) object. - ensure the application is setup in the default safe starting state. """ + configure_locale_and_language() init(args.sdc_home) configure_logging(args.sdc_home) logging.info('Starting SecureDrop Client {}'.format(__version__)) diff --git a/tests/conftest.py b/tests/conftest.py index cc3b439aad..da95a4d8b7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,6 +6,7 @@ from configparser import ConfigParser from datetime import datetime from securedrop_client.config import Config +from securedrop_client.app import configure_locale_and_language from securedrop_client.db import Base, make_engine, Source from sqlalchemy.orm import sessionmaker from uuid import uuid4 @@ -26,6 +27,7 @@ def homedir(): ''' tmpdir = tempfile.mkdtemp(prefix='sdc-') + configure_locale_and_language() os.chmod(tmpdir, 0o0700) data_dir = os.path.join(tmpdir, 'data') diff --git a/tests/test_app.py b/tests/test_app.py index e604ce9c0d..26a3d996f6 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -8,11 +8,17 @@ from PyQt5.QtWidgets import QApplication from securedrop_client.app import ENCODING, excepthook, configure_logging, \ start_app, arg_parser, DEFAULT_SDC_HOME, run, configure_signal_handlers, \ - prevent_second_instance + prevent_second_instance, configure_locale_and_language app = QApplication([]) +def test_application_sets_en_as_default_language_code(mocker): + mocker.patch('locale.getdefaultlocale', return_value=(None, None)) + language_code = configure_locale_and_language() + assert language_code == 'en' + + def test_excepthook(mocker): """ Ensure the custom excepthook logs the error and calls sys.exit.