python gettext - 找不到消息ID时产生错误

问题描述 投票:0回答:2

我正在使用python2.7 gettext。对于翻译,我使用以下代码:

t = gettext.translation(
            domain,
            path,
            fallback=False,
            languages=[self._lang, 'en']
        )
_ = t.ugettext
translated = _('foo')

默认行为是,如果目录中没有消息标识的条目,则返回消息标识。

有没有办法产生错误呢?一个简单的代码示例将不胜感激。

python python-2.7 gettext
2个回答
1
投票

如果不破解gettext的源代码,这是不可能的。你可以在翻译函数周围编写一个包装器,如果检索到的翻译等于消息id,则会产生错误,但这通常会导致误报,因为正确的字符串翻译就是字符串本身。

如果您遵循正常的翻译工作流程,则不需要此类功能。使用.po编译msgfmt文件时,可以传递--statistics选项,该选项将报告缺少的翻译。那么在运行时检查它有什么意义呢?


0
投票

正如Guido Flohr建议的那样,我编写了自己的脚本来检查翻译,但是在使用polib的python中。

翻译文件夹树如下:

enter image description here

locale.json包含支持的语言列表(这使我可以选择放置草稿而不测试它们)

{"supported":["en","he"]}

这些是2个脚本(对于糟糕的缩进感到抱歉,我不能让它在StackOverflow上运行):

import polib
def test_po_files_msgid_different_from_mgsstr():
errors_list = list()
msg_count = 0
po_files_count = 0
locale_path = os.path.join(BASE_PROJECT_PATH, 'locale')
for root, dirs, files in os.walk(locale_path):
    for f in files:
        if f.endswith('.po'):
            po_file_path = os.path.join(root, f)
            po = polib.pofile(po_file_path)
            po_files_count += 1
            for entry in po:
                msg_count += 1
                if entry.msgid == entry.msgstr or entry.msgstr == '' or entry.msgstr is None:
                    errors_list.append(
                        "Error in {}: msgid '{}' equals its msgstr, empty or None".format(po_file_path, entry.msgid))
if po_files_count == 0:
    raise Exception('No po files found in {} and its subdirectories'.format(locale_path))

print('{} messages checked, in {} files'.format(msg_count, po_files_count))
if errors_list:
    errors_list_str = '\n'.join(errors_list)
    raise Exception(errors_list_str)


def test_po_files_on_secondary_lang_maches_en():
    """
    Compares supported languages consistency with the default language
    checks all domain (files) and msgids on the default language exists on the secondary one
    """
default_lang = 'en'

def get_supported_languages():
    file_path = os.path.join(BASE_PROJECT_PATH, 'locale', 'locale.json')
    with open(file_path) as json_data:
        dict_data = json.load(json_data)
        return dict_data['supported']

def validate_language(en_tree, curr_lang, curr_lang_tree):
    errors_list = list()
    for file in en_tree:
        if curr_lang_tree.get(file) == None:
            errors_list.append("Error in '{}': file '{}' doesn't exist".format(curr_lang, file))
            continue

        # if file == 'test_msgid_exist_only_in_en.po':
        for msgid in en_tree[file]:
            if not curr_lang_tree[file].get(msgid):
                errors_list.append(
                    "Error in '{}': msgid '{}' doesn't exist in file '{}', ".format(curr_lang, msgid, file))
    return errors_list

def create_lang_tree(locale_path):
    lang_tree = dict()
    for root, dirs, files in os.walk(locale_path):
        for f in files:
            if f.endswith('.po'):
                lang = root.split('/')[-2]
                if not lang_tree.get(lang):
                    lang_tree[lang] = dict()
                lang_tree[lang][f] = dict()
                po_file_path = os.path.join(root, f)
                po = polib.pofile(po_file_path)
                for entry in po:
                    lang_tree[lang][f][entry.msgid] = entry.msgstr
    return lang_tree

locale_path = os.path.join(BASE_PROJECT_PATH, 'locale')
errors_list = list()
supported_languages = get_supported_languages()
lang_tree = create_lang_tree(locale_path)

if not lang_tree:
    raise Exception('No po files found in {} and its subdirectories'.format(locale_path))

en_tree = lang_tree[default_lang]
for curr_lang in supported_languages:
    if curr_lang == default_lang:
        continue
    curr_lang_errors = validate_language(en_tree, curr_lang, lang_tree[curr_lang])
    errors_list.extend(curr_lang_errors)

if errors_list:
    errors_list_str = '\n'.join(errors_list)
    raise Exception(errors_list_str)

print("{} secondary languages compared to 'en', no errors found".format(len(supported_languages) - 1))
© www.soinside.com 2019 - 2024. All rights reserved.