python gettext - 找不到消息 ID 时产生错误
python gettext - produce an error when message id not found
我正在使用 python2.7 gettext。
对于翻译,我使用以下代码:
t = gettext.translation(
domain,
path,
fallback=False,
languages=[self._lang, 'en']
)
_ = t.ugettext
translated = _('foo')
默认行为是,如果消息 ID 的目录中没有条目,则返回消息 ID。
有没有办法产生错误?
一个简单的代码示例将不胜感激。
如果不破解 gettext 的源代码,这是不可能的。您可以围绕翻译函数编写一个包装器,如果检索到的翻译等于消息 ID,它会产生错误,但这通常会导致误报,因为碰巧字符串的正确翻译是字符串本身。
如果您遵循正常的翻译流程,则不需要此功能。当您使用 msgfmt
编译 .po
文件时,您可以传递选项 --statistics
,这将报告缺少的翻译。那么在 运行 时间检查它有什么意义呢?
如 suggested, I wrote my own script for checking the translations, but in python using polib.
翻译文件夹树如下:
locale.json
包含支持的语言列表(这让我可以选择放置草稿语言而不测试它们)
{"supported":["en","he"]}
这是 2 个脚本(抱歉缩进错误,我无法在 Whosebug 上运行):
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))
我正在使用 python2.7 gettext。 对于翻译,我使用以下代码:
t = gettext.translation(
domain,
path,
fallback=False,
languages=[self._lang, 'en']
)
_ = t.ugettext
translated = _('foo')
默认行为是,如果消息 ID 的目录中没有条目,则返回消息 ID。
有没有办法产生错误? 一个简单的代码示例将不胜感激。
如果不破解 gettext 的源代码,这是不可能的。您可以围绕翻译函数编写一个包装器,如果检索到的翻译等于消息 ID,它会产生错误,但这通常会导致误报,因为碰巧字符串的正确翻译是字符串本身。
如果您遵循正常的翻译流程,则不需要此功能。当您使用 msgfmt
编译 .po
文件时,您可以传递选项 --statistics
,这将报告缺少的翻译。那么在 运行 时间检查它有什么意义呢?
如
翻译文件夹树如下:
locale.json
包含支持的语言列表(这让我可以选择放置草稿语言而不测试它们)
{"supported":["en","he"]}
这是 2 个脚本(抱歉缩进错误,我无法在 Whosebug 上运行):
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))