Example #1
0
    def test_translate_messages_l10n(self, tmpdir):
        source = [
            join(self.dir, 'i18n/code.py'),
            join(self.dir, 'i18n/template.html'),
        ]
        args = [
            '--verbose',
            'translate-messages',
            '--translations-dir', str(tmpdir),
            '--mapping', join(self.dir, 'i18n/babel.cfg'),
            '--sources', ",".join(source),
            '--extract-update',
            '--compile',
        ]
        i18n_tool.I18NTool().main(args)
        messages_file = join(str(tmpdir), 'messages.pot')
        assert exists(messages_file)
        with io.open(messages_file, 'rb') as fobj:
            pot = fobj.read()
            assert b'code hello i18n' in pot
            assert b'template hello i18n' in pot

        locale = 'en_US'
        locale_dir = join(str(tmpdir), locale)
        pybabel('init', '-i', messages_file, '-d', str(tmpdir), '-l', locale)
        mo_file = join(locale_dir, 'LC_MESSAGES/messages.mo')
        assert not exists(mo_file)
        i18n_tool.I18NTool().main(args)
        assert exists(mo_file)
        with io.open(mo_file, mode='rb') as fobj:
            mo = fobj.read()
            assert b'code hello i18n' in mo
            assert b'template hello i18n' in mo
Example #2
0
    def test_translate_messages_compile_arg(self, tmpdir):
        args = [
            '--verbose',
            'translate-messages',
            '--translations-dir', str(tmpdir),
            '--mapping', join(self.dir, 'i18n/babel.cfg'),
        ]
        i18n_tool.I18NTool().main(args + [
            '--sources', join(self.dir, 'i18n/code.py'),
            '--extract-update',
        ])
        messages_file = join(str(tmpdir), 'messages.pot')
        assert exists(messages_file)
        with io.open(messages_file) as fobj:
            pot = fobj.read()
            assert 'code hello i18n' in pot

        locale = 'en_US'
        locale_dir = join(str(tmpdir), locale)
        po_file = join(locale_dir, 'LC_MESSAGES/messages.po')
        pybabel(['init', '-i', messages_file, '-d', str(tmpdir), '-l', locale])
        assert exists(po_file)
        # pretend this happened a few seconds ago
        few_seconds_ago = time.time() - 60
        os.utime(po_file, (few_seconds_ago, few_seconds_ago))

        mo_file = join(locale_dir, 'LC_MESSAGES/messages.mo')

        #
        # Extract+update but do not compile
        #
        old_po_mtime = getmtime(po_file)
        assert not exists(mo_file)
        i18n_tool.I18NTool().main(args + [
            '--sources', join(self.dir, 'i18n/code.py'),
            '--extract-update',
        ])
        assert not exists(mo_file)
        current_po_mtime = getmtime(po_file)
        assert old_po_mtime < current_po_mtime

        #
        # Compile but do not extract+update
        #
        source = [
            join(self.dir, 'i18n/code.py'),
            join(self.dir, 'i18n/template.html'),
        ]
        old_po_mtime = current_po_mtime
        i18n_tool.I18NTool().main(args + [
            '--sources', ",".join(source),
            '--compile',
        ])
        assert old_po_mtime == getmtime(po_file)
        with io.open(mo_file, mode='rb') as fobj:
            mo = fobj.read()
            assert b'code hello i18n' in mo
            assert b'template hello i18n' not in mo
Example #3
0
def test_i18n(journalist_app, config):
    # Then delete it because using it won't test what we want
    del journalist_app

    sources = [
        os.path.join(TESTS_DIR, "i18n/code.py"),
        os.path.join(TESTS_DIR, "i18n/template.html"),
    ]

    i18n_tool.I18NTool().main([
        "--verbose",
        "translate-messages",
        "--mapping",
        os.path.join(TESTS_DIR, "i18n/babel.cfg"),
        "--translations-dir",
        config.TEMP_DIR,
        "--sources",
        ",".join(sources),
        "--extract-update",
    ])

    pot = os.path.join(config.TEMP_DIR, "messages.pot")
    pybabel("init", "-i", pot, "-d", config.TEMP_DIR, "-l", "en_US")

    for (l, s) in (
        ("fr_FR", "code bonjour"),
        ("zh_Hans", "code chinese"),
        ("ar", "code arabic"),
        ("nb_NO", "code norwegian"),
        ("es_ES", "code spanish"),
    ):
        pybabel("init", "-i", pot, "-d", config.TEMP_DIR, "-l", l)
        po = os.path.join(config.TEMP_DIR, l, "LC_MESSAGES/messages.po")
        sed("-i", "-e",
            '/code hello i18n/,+1s/msgstr ""/msgstr "{}"/'.format(s), po)

    i18n_tool.I18NTool().main([
        "--verbose",
        "translate-messages",
        "--translations-dir",
        config.TEMP_DIR,
        "--compile",
    ])

    fake_config = SDConfig()
    fake_config.SUPPORTED_LOCALES = [
        "ar", "en_US", "fr_FR", "nb_NO", "zh_Hans"
    ]
    fake_config.TRANSLATION_DIRS = Path(config.TEMP_DIR)

    # Use our config (and not an app fixture) because the i18n module
    # grabs values at init time and we can't inject them later.
    for app in (journalist_app_module.create_app(fake_config),
                source_app.create_app(fake_config)):
        with app.app_context():
            db.create_all()
        assert list(i18n.LOCALES.keys()) == fake_config.SUPPORTED_LOCALES
        verify_i18n(app)
Example #4
0
    def test_main(self, tmpdir, caplog):
        with pytest.raises(SystemExit):
            i18n_tool.I18NTool().main(['--help'])

        tool = i18n_tool.I18NTool()
        with patch.object(tool,
                          'setup_verbosity',
                          side_effect=KeyboardInterrupt):
            assert tool.main(
                ['translate-messages', '--translations-dir',
                 str(tmpdir)]) == signal.SIGINT
Example #5
0
def test_i18n(journalist_app, config):
    # Then delete it because using it won't test what we want
    del journalist_app

    sources = [
        os.path.join(TESTS_DIR, 'i18n/code.py'),
        os.path.join(TESTS_DIR, 'i18n/template.html'),
    ]

    i18n_tool.I18NTool().main([
        '--verbose',
        'translate-messages',
        '--mapping',
        os.path.join(TESTS_DIR, 'i18n/babel.cfg'),
        '--translations-dir',
        config.TEMP_DIR,
        '--sources',
        ",".join(sources),
        '--extract-update',
    ])

    pot = os.path.join(config.TEMP_DIR, 'messages.pot')
    pybabel('init', '-i', pot, '-d', config.TEMP_DIR, '-l', 'en_US')

    for (l, s) in (('fr_FR', 'code bonjour'), ('zh_Hans_CN', 'code chinese'),
                   ('ar', 'code arabic'), ('nb_NO', 'code norwegian'),
                   ('es_ES', 'code spanish')):
        pybabel('init', '-i', pot, '-d', config.TEMP_DIR, '-l', l)
        po = os.path.join(config.TEMP_DIR, l, 'LC_MESSAGES/messages.po')
        sed('-i', '-e',
            '/code hello i18n/,+1s/msgstr ""/msgstr "{}"/'.format(s), po)

    i18n_tool.I18NTool().main([
        '--verbose',
        'translate-messages',
        '--translations-dir',
        config.TEMP_DIR,
        '--compile',
    ])

    fake_config = SDConfig()
    fake_config.SUPPORTED_LOCALES = [
        'en_US', 'fr_FR', 'zh_Hans_CN', 'ar', 'nb_NO'
    ]
    fake_config.TRANSLATION_DIRS = config.TEMP_DIR

    # Use our config (and not an app fixture) because the i18n module
    # grabs values at init time and we can't inject them later.
    for app in (journalist_app_module.create_app(fake_config),
                source_app.create_app(fake_config)):
        with app.app_context():
            db.create_all()
        assert i18n.LOCALES == fake_config.SUPPORTED_LOCALES
        verify_i18n(app)
def do_test(config, create_app):
    config.SUPPORTED_LOCALES = ['en_US', 'fr_FR']
    config.TRANSLATION_DIRS = Path(config.TEMP_DIR)
    i18n_tool.I18NTool().main([
        '--verbose',
        'translate-messages',
        '--mapping',
        os.path.join(TESTS_DIR, 'i18n/babel.cfg'),
        '--translations-dir',
        config.TEMP_DIR,
        '--sources',
        os.path.join(TESTS_DIR, 'i18n/code.py'),
        '--extract-update',
        '--compile',
    ])

    for l in ('en_US', 'fr_FR'):
        pot = os.path.join(config.TEMP_DIR, 'messages.pot')
        pybabel('init', '-i', pot, '-d', config.TEMP_DIR, '-l', l)

    app = create_app(config)
    with app.app_context():
        db.create_all()

    assert list(i18n.LOCALES.keys()) == config.SUPPORTED_LOCALES
    verify_filesizeformat(app)
    verify_rel_datetime_format(app)
Example #7
0
def do_test(config, create_app):
    config.SUPPORTED_LOCALES = ["en_US", "fr_FR"]
    config.TRANSLATION_DIRS = Path(config.TEMP_DIR)
    i18n_tool.I18NTool().main([
        "--verbose",
        "translate-messages",
        "--mapping",
        os.path.join(TESTS_DIR, "i18n/babel.cfg"),
        "--translations-dir",
        config.TEMP_DIR,
        "--sources",
        os.path.join(TESTS_DIR, "i18n/code.py"),
        "--extract-update",
        "--compile",
    ])

    for l in ("en_US", "fr_FR"):
        pot = os.path.join(config.TEMP_DIR, "messages.pot")
        pybabel("init", "-i", pot, "-d", config.TEMP_DIR, "-l", l)

    app = create_app(config)
    with app.app_context():
        db.create_all()

    assert list(i18n.LOCALES.keys()) == config.SUPPORTED_LOCALES
    verify_filesizeformat(app)
    verify_rel_datetime_format(app)
Example #8
0
    def test_update_docs(self, tmpdir, caplog):
        k = {'_cwd': str(tmpdir)}
        git.init(**k)
        git.config('user.email', "*****@*****.**", **k)
        git.config('user.name', "Your Name", **k)
        os.mkdir(join(str(tmpdir), 'includes'))
        touch('includes/l10n.txt', **k)
        git.add('includes/l10n.txt', **k)
        git.commit('-m', 'init', **k)

        i18n_tool.I18NTool().main(
            ['--verbose', 'update-docs', '--documentation-dir',
             str(tmpdir)])
        assert 'l10n.txt updated' in caplog.text
        caplog.clear()
        i18n_tool.I18NTool().main(
            ['--verbose', 'update-docs', '--documentation-dir',
             str(tmpdir)])
        assert 'l10n.txt already up to date' in caplog.text
Example #9
0
    def test_update_docs(self, tmpdir, caplog):
        k = {"_cwd": str(tmpdir)}
        git.init(**k)
        git.config("user.email", "*****@*****.**", **k)
        git.config("user.name", "Your Name", **k)
        os.makedirs(join(str(tmpdir), "docs/includes"))
        touch("docs/includes/l10n.txt", **k)
        git.add("docs/includes/l10n.txt", **k)
        git.commit("-m", "init", **k)

        i18n_tool.I18NTool().main(
            ["--verbose", "update-docs", "--docs-repo-dir",
             str(tmpdir)])
        assert "l10n.txt updated" in caplog.text
        caplog.clear()
        i18n_tool.I18NTool().main(
            ["--verbose", "update-docs", "--docs-repo-dir",
             str(tmpdir)])
        assert "l10n.txt already up to date" in caplog.text
Example #10
0
    def test_translate_messages_l10n(self, tmpdir):
        source = [
            join(self.dir, "i18n/code.py"),
            join(self.dir, "i18n/template.html"),
        ]
        args = [
            "--verbose",
            "translate-messages",
            "--translations-dir",
            str(tmpdir),
            "--mapping",
            join(self.dir, "i18n/babel.cfg"),
            "--sources",
            ",".join(source),
            "--extract-update",
            "--compile",
        ]
        i18n_tool.I18NTool().main(args)
        messages_file = join(str(tmpdir), "messages.pot")
        assert exists(messages_file)
        with io.open(messages_file, "rb") as fobj:
            pot = fobj.read()
            assert b"code hello i18n" in pot
            assert b"template hello i18n" in pot

        locale = "en_US"
        locale_dir = join(str(tmpdir), locale)
        pybabel("init", "-i", messages_file, "-d", str(tmpdir), "-l", locale)

        po_file = join(locale_dir, "LC_MESSAGES/messages.po")
        dummy_translate(po_file)

        mo_file = join(locale_dir, "LC_MESSAGES/messages.mo")
        assert not exists(mo_file)
        i18n_tool.I18NTool().main(args)
        assert exists(mo_file)
        with io.open(mo_file, mode="rb") as fobj:
            mo = fobj.read()
            assert b"code hello i18n" in mo
            assert b"template hello i18n" in mo
Example #11
0
    def test_translate_desktop_l10n(self, tmpdir):
        in_files = {}
        for what in ('source', 'journalist'):
            in_files[what] = join(str(tmpdir), what + '.desktop.in')
            shutil.copy(join(self.dir, 'i18n/' + what + '.desktop.in'),
                        in_files[what])
        i18n_tool.I18NTool().main([
            '--verbose',
            'translate-desktop',
            '--translations-dir', str(tmpdir),
            '--sources', in_files['source'],
            '--extract-update',
        ])
        messages_file = join(str(tmpdir), 'desktop.pot')
        assert exists(messages_file)
        with io.open(messages_file) as fobj:
            pot = fobj.read()
            assert 'SecureDrop Source Interfaces' in pot
        # pretend this happened a few seconds ago
        few_seconds_ago = time.time() - 60
        os.utime(messages_file, (few_seconds_ago, few_seconds_ago))

        i18n_file = join(str(tmpdir), 'source.desktop')

        #
        # Extract+update but do not compile
        #
        old_messages_mtime = getmtime(messages_file)
        assert not exists(i18n_file)
        i18n_tool.I18NTool().main([
            '--verbose',
            'translate-desktop',
            '--translations-dir', str(tmpdir),
            '--sources', ",".join(list(in_files.values())),
            '--extract-update',
        ])
        assert not exists(i18n_file)
        current_messages_mtime = getmtime(messages_file)
        assert old_messages_mtime < current_messages_mtime

        locale = 'fr_FR'
        po_file = join(str(tmpdir), locale + ".po")
        msginit(
            '--no-translator',
            '--locale', locale,
            '--output', po_file,
            '--input', messages_file)
        source = 'SecureDrop Source Interfaces'
        sed('-i', '-e',
            '/{}/,+1s/msgstr ""/msgstr "SOURCE FR"/'.format(source),
            po_file)
        assert exists(po_file)

        # Regression test to trigger bug introduced when adding
        # Romanian as an accepted language.
        locale = 'ro'
        po_file = join(str(tmpdir), locale + ".po")
        msginit(
            '--no-translator',
            '--locale', locale,
            '--output', po_file,
            '--input', messages_file)
        source = 'SecureDrop Source Interfaces'
        sed('-i', '-e',
            '/{}/,+1s/msgstr ""/msgstr "SOURCE RO"/'.format(source),
            po_file)
        assert exists(po_file)

        #
        # Compile but do not extract+update
        #
        old_messages_mtime = current_messages_mtime
        i18n_tool.I18NTool().main([
            '--verbose',
            'translate-desktop',
            '--translations-dir', str(tmpdir),
            '--sources', ",".join(list(in_files.values()) + ['BOOM']),
            '--compile',
        ])
        assert old_messages_mtime == getmtime(messages_file)
        with io.open(po_file) as fobj:
            po = fobj.read()
            assert 'SecureDrop Source Interfaces' in po
            assert 'SecureDrop Journalist Interfaces' not in po
        with io.open(i18n_file) as fobj:
            i18n = fobj.read()
            assert 'SOURCE FR' in i18n
Example #12
0
    def test_update_from_weblate(self, tmpdir, caplog):
        d = str(tmpdir)
        for repo in ('i18n', 'securedrop'):
            os.mkdir(join(d, repo))
            k = {'_cwd': join(d, repo)}
            git.init(**k)
            git.config('user.email', '*****@*****.**', **k)
            git.config('user.name',  'Loïc Nordhøy', **k)
            touch('README.md', **k)
            git.add('README.md', **k)
            git.commit('-m', 'README', 'README.md', **k)
        for o in os.listdir(join(self.dir, 'i18n')):
            f = join(self.dir, 'i18n', o)
            if os.path.isfile(f):
                shutil.copyfile(f, join(d, 'i18n', o))
            else:
                shutil.copytree(f, join(d, 'i18n', o))
        k = {'_cwd': join(d, 'i18n')}
        git.add('securedrop', 'install_files', **k)
        git.commit('-m', 'init', '-a', **k)
        git.checkout('-b', 'i18n', 'master', **k)

        def r():
            return "".join([str(l) for l in caplog.records])

        #
        # de_DE is not amount the supported languages, it is not taken
        # into account despite the fact that it exists in weblate.
        #
        caplog.clear()
        i18n_tool.I18NTool().main([
            '--verbose',
            'update-from-weblate',
            '--root', join(str(tmpdir), 'securedrop'),
            '--url', join(str(tmpdir), 'i18n'),
            '--supported-languages', 'nl',
        ])
        assert 'l10n: updated Dutch (nl)' in r()
        assert 'l10n: updated German (de_DE)' not in r()

        #
        # de_DE is added but there is no change in the nl translation
        # therefore nothing is done for nl
        #
        caplog.clear()
        i18n_tool.I18NTool().main([
            '--verbose',
            'update-from-weblate',
            '--root', join(str(tmpdir), 'securedrop'),
            '--url', join(str(tmpdir), 'i18n'),
            '--supported-languages', 'nl,de_DE',
        ])
        assert 'l10n: updated Dutch (nl)' not in r()
        assert 'l10n: updated German (de_DE)' in r()

        #
        # nothing new for nl or de_DE: nothing is done
        #
        caplog.clear()
        i18n_tool.I18NTool().main([
            '--verbose',
            'update-from-weblate',
            '--root', join(str(tmpdir), 'securedrop'),
            '--url', join(str(tmpdir), 'i18n'),
            '--supported-languages', 'nl,de_DE',
        ])
        assert 'l10n: updated Dutch (nl)' not in r()
        assert 'l10n: updated German (de_DE)' not in r()
        message = str(git('--no-pager', '-C', 'securedrop', 'show',
                          _cwd=d, _encoding='utf-8'))
        assert "Loïc" in message

        #
        # an update is done to nl in weblate
        #
        k = {'_cwd': join(d, 'i18n')}
        f = 'securedrop/translations/nl/LC_MESSAGES/messages.po'
        sed('-i', '-e', 's/inactiviteit/INACTIVITEIT/', f, **k)
        git.add(f, **k)
        git.config('user.email', '*****@*****.**', **k)
        git.config('user.name', 'Someone Else', **k)
        git.commit('-m', 'translation change', f, **k)

        k = {'_cwd': join(d, 'securedrop')}
        git.config('user.email', '*****@*****.**', **k)
        git.config('user.name', 'Someone Else', **k)

        #
        # the nl translation update from weblate is copied
        # over.
        #
        caplog.clear()
        i18n_tool.I18NTool().main([
            '--verbose',
            'update-from-weblate',
            '--root', join(str(tmpdir), 'securedrop'),
            '--url', join(str(tmpdir), 'i18n'),
            '--supported-languages', 'nl,de_DE',
        ])
        assert 'l10n: updated Dutch (nl)' in r()
        assert 'l10n: updated German (de_DE)' not in r()
        message = str(git('--no-pager', '-C', 'securedrop', 'show',
                          _cwd=d))
        assert "Someone Else" in message
        assert "Loïc" not in message
Example #13
0
    def test_translate_desktop_l10n(self, tmpdir):
        in_files = {}
        for what in ("source", "journalist"):
            in_files[what] = join(str(tmpdir), what + ".desktop.in")
            shutil.copy(join(self.dir, "i18n/" + what + ".desktop.in"),
                        in_files[what])
        i18n_tool.I18NTool().main([
            "--verbose",
            "translate-desktop",
            "--translations-dir",
            str(tmpdir),
            "--sources",
            in_files["source"],
            "--extract-update",
        ])
        messages_file = join(str(tmpdir), "desktop.pot")
        assert exists(messages_file)
        with io.open(messages_file) as fobj:
            pot = fobj.read()
            assert "SecureDrop Source Interfaces" in pot
        # pretend this happened a few seconds ago
        few_seconds_ago = time.time() - 60
        os.utime(messages_file, (few_seconds_ago, few_seconds_ago))

        i18n_file = join(str(tmpdir), "source.desktop")

        #
        # Extract+update but do not compile
        #
        old_messages_mtime = getmtime(messages_file)
        assert not exists(i18n_file)
        i18n_tool.I18NTool().main([
            "--verbose",
            "translate-desktop",
            "--translations-dir",
            str(tmpdir),
            "--sources",
            ",".join(list(in_files.values())),
            "--extract-update",
        ])
        assert not exists(i18n_file)
        current_messages_mtime = getmtime(messages_file)
        assert old_messages_mtime < current_messages_mtime

        locale = "fr_FR"
        po_file = join(str(tmpdir), locale + ".po")
        msginit("--no-translator", "--locale", locale, "--output", po_file,
                "--input", messages_file)
        source = "SecureDrop Source Interfaces"
        sed("-i", "-e",
            '/{}/,+1s/msgstr ""/msgstr "SOURCE FR"/'.format(source), po_file)
        assert exists(po_file)

        # Regression test to trigger bug introduced when adding
        # Romanian as an accepted language.
        locale = "ro"
        po_file = join(str(tmpdir), locale + ".po")
        msginit("--no-translator", "--locale", locale, "--output", po_file,
                "--input", messages_file)
        source = "SecureDrop Source Interfaces"
        sed("-i", "-e",
            '/{}/,+1s/msgstr ""/msgstr "SOURCE RO"/'.format(source), po_file)
        assert exists(po_file)

        #
        # Compile but do not extract+update
        #
        old_messages_mtime = current_messages_mtime
        i18n_tool.I18NTool().main([
            "--verbose",
            "translate-desktop",
            "--translations-dir",
            str(tmpdir),
            "--sources",
            ",".join(list(in_files.values()) + ["BOOM"]),
            "--compile",
        ])
        assert old_messages_mtime == getmtime(messages_file)
        with io.open(po_file) as fobj:
            po = fobj.read()
            assert "SecureDrop Source Interfaces" in po
            assert "SecureDrop Journalist Interfaces" not in po
        with io.open(i18n_file) as fobj:
            i18n = fobj.read()
            assert "SOURCE FR" in i18n
Example #14
0
    def test_update_from_weblate(self, tmpdir, caplog):
        d = str(tmpdir)
        for repo in ("i18n", "securedrop"):
            os.mkdir(join(d, repo))
            k = {"_cwd": join(d, repo)}
            git.init(**k)
            git.config("user.email", "*****@*****.**", **k)
            git.config("user.name", "Loïc Nordhøy", **k)
            touch("README.md", **k)
            git.add("README.md", **k)
            git.commit("-m", "README", "README.md", **k)
        for o in os.listdir(join(self.dir, "i18n")):
            f = join(self.dir, "i18n", o)
            if os.path.isfile(f):
                shutil.copyfile(f, join(d, "i18n", o))
            else:
                shutil.copytree(f, join(d, "i18n", o))
        k = {"_cwd": join(d, "i18n")}
        git.add("securedrop", "install_files", **k)
        git.commit("-m", "init", "-a", **k)
        git.checkout("-b", "i18n", "master", **k)

        def r():
            return "".join([str(l) for l in caplog.records])

        #
        # de_DE is not amount the supported languages, it is not taken
        # into account despite the fact that it exists in weblate.
        #
        caplog.clear()
        i18n_tool.I18NTool().main([
            "--verbose",
            "update-from-weblate",
            "--root",
            join(str(tmpdir), "securedrop"),
            "--url",
            join(str(tmpdir), "i18n"),
            "--supported-languages",
            "nl",
        ])
        assert "l10n: updated Dutch (nl)" in r()
        assert "l10n: updated German (de_DE)" not in r()

        #
        # de_DE is added but there is no change in the nl translation
        # therefore nothing is done for nl
        #
        caplog.clear()
        i18n_tool.I18NTool().main([
            "--verbose",
            "update-from-weblate",
            "--root",
            join(str(tmpdir), "securedrop"),
            "--url",
            join(str(tmpdir), "i18n"),
            "--supported-languages",
            "nl,de_DE",
        ])
        assert "l10n: updated Dutch (nl)" not in r()
        assert "l10n: updated German (de_DE)" in r()

        #
        # nothing new for nl or de_DE: nothing is done
        #
        caplog.clear()
        i18n_tool.I18NTool().main([
            "--verbose",
            "update-from-weblate",
            "--root",
            join(str(tmpdir), "securedrop"),
            "--url",
            join(str(tmpdir), "i18n"),
            "--supported-languages",
            "nl,de_DE",
        ])
        assert "l10n: updated Dutch (nl)" not in r()
        assert "l10n: updated German (de_DE)" not in r()
        message = str(
            git("--no-pager",
                "-C",
                "securedrop",
                "show",
                _cwd=d,
                _encoding="utf-8"))
        assert "Loïc" in message

        #
        # an update is done to nl in weblate
        #
        k = {"_cwd": join(d, "i18n")}
        f = "securedrop/translations/nl/LC_MESSAGES/messages.po"
        sed("-i", "-e", "s/inactiviteit/INACTIVITEIT/", f, **k)
        git.add(f, **k)
        git.config("user.email", "*****@*****.**", **k)
        git.config("user.name", "Someone Else", **k)
        git.commit("-m", "translation change", f, **k)

        k = {"_cwd": join(d, "securedrop")}
        git.config("user.email", "*****@*****.**", **k)
        git.config("user.name", "Someone Else", **k)

        #
        # the nl translation update from weblate is copied
        # over.
        #
        caplog.clear()
        i18n_tool.I18NTool().main([
            "--verbose",
            "update-from-weblate",
            "--root",
            join(str(tmpdir), "securedrop"),
            "--url",
            join(str(tmpdir), "i18n"),
            "--supported-languages",
            "nl,de_DE",
        ])
        assert "l10n: updated Dutch (nl)" in r()
        assert "l10n: updated German (de_DE)" not in r()
        message = str(git("--no-pager", "-C", "securedrop", "show", _cwd=d))
        assert "Someone Else" in message
        assert "Loïc" not in message
Example #15
0
    def test_translate_messages_compile_arg(self, tmpdir):
        args = [
            "--verbose",
            "translate-messages",
            "--translations-dir",
            str(tmpdir),
            "--mapping",
            join(self.dir, "i18n/babel.cfg"),
        ]
        i18n_tool.I18NTool().main(args + [
            "--sources",
            join(self.dir, "i18n/code.py"),
            "--extract-update",
        ])
        messages_file = join(str(tmpdir), "messages.pot")
        assert exists(messages_file)
        with io.open(messages_file) as fobj:
            pot = fobj.read()
            assert "code hello i18n" in pot

        locale = "en_US"
        locale_dir = join(str(tmpdir), locale)
        po_file = join(locale_dir, "LC_MESSAGES/messages.po")
        pybabel(["init", "-i", messages_file, "-d", str(tmpdir), "-l", locale])
        assert exists(po_file)
        # pretend this happened a few seconds ago
        few_seconds_ago = time.time() - 60
        os.utime(po_file, (few_seconds_ago, few_seconds_ago))

        mo_file = join(locale_dir, "LC_MESSAGES/messages.mo")

        #
        # Extract+update but do not compile
        #
        old_po_mtime = getmtime(po_file)
        assert not exists(mo_file)
        i18n_tool.I18NTool().main(args + [
            "--sources",
            join(self.dir, "i18n/code.py"),
            "--extract-update",
        ])
        assert not exists(mo_file)
        current_po_mtime = getmtime(po_file)
        assert old_po_mtime < current_po_mtime

        #
        # Translation would occur here - let's fake it
        dummy_translate(po_file)

        #
        # Compile but do not extract+update
        #
        source = [
            join(self.dir, "i18n/code.py"),
            join(self.dir, "i18n/template.html"),
        ]
        current_po_mtime = getmtime(po_file)
        i18n_tool.I18NTool().main(args + [
            "--sources",
            ",".join(source),
            "--compile",
        ])
        assert current_po_mtime == getmtime(po_file)
        with io.open(mo_file, mode="rb") as fobj:
            mo = fobj.read()
            assert b"code hello i18n" in mo
            assert b"template hello i18n" not in mo