wraitii
1b150b303f
The `pology` library runs on Python2 and development appears stalled. It is also not available on pip. The `babel` library, BSD-licensed, provides, amongst many other things, a replacement for .POT / .PO manipulation. The `poediff` tool that we used to detect spurious i18n change is replaced with a Python script that does a simpler but good enough job (it is also much, much faster). These replacements let the i18n scripts run on Python3 entirely. Makes D506 redundant. Comments by: Itms Reviewed By: Gallaecio Refs #5694 Differential Revision: https://code.wildfiregames.com/D2757 This was SVN commit r24313.
127 lines
5.1 KiB
Python
127 lines
5.1 KiB
Python
#!/usr/bin/env python3
|
|
#
|
|
# Copyright (C) 2020 Wildfire Games.
|
|
# This file is part of 0 A.D.
|
|
#
|
|
# 0 A.D. is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# 0 A.D. is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
import json, os
|
|
import multiprocessing
|
|
from importlib import import_module
|
|
|
|
from lxml import etree
|
|
|
|
from i18n_helper import l10nToolsDirectory, projectRootDirectory
|
|
from i18n_helper.catalog import Catalog
|
|
from extractors import extractors
|
|
|
|
l10nFolderName = "l10n"
|
|
messagesFilename = "messages.json"
|
|
|
|
|
|
def warnAboutUntouchedMods():
|
|
"""
|
|
Warn about mods that are not properly configured to get their messages extracted.
|
|
"""
|
|
modsRootFolder = os.path.join(projectRootDirectory, "binaries", "data", "mods")
|
|
untouchedMods = {}
|
|
for modFolder in os.listdir(modsRootFolder):
|
|
if modFolder[0] != "_" and modFolder[0] != '.':
|
|
if not os.path.exists(os.path.join(modsRootFolder, modFolder, l10nFolderName)):
|
|
untouchedMods[modFolder] = "There is no '{folderName}' folder in the root folder of this mod.".format(folderName=l10nFolderName)
|
|
elif not os.path.exists(os.path.join(modsRootFolder, modFolder, l10nFolderName, messagesFilename)):
|
|
untouchedMods[modFolder] = "There is no '{filename}' file within the '{folderName}' folder in the root folder of this mod.".format(folderName=l10nFolderName, filename=messagesFilename)
|
|
if untouchedMods:
|
|
print(""
|
|
"Warning: No messages were extracted from the following mods:"
|
|
"")
|
|
for mod in untouchedMods:
|
|
print("• {modName}: {warningMessage}".format(modName=mod, warningMessage=untouchedMods[mod]))
|
|
print(""
|
|
f"For this script to extract messages from a mod folder, this mod folder must contain a '{l10nFolderName}' "
|
|
f"folder, and this folder must contain a '{messagesFilename}' file that describes how to extract messages for the "
|
|
f"mod. See the folder of the main mod ('public') for an example, and see the documentation for more "
|
|
f"information."
|
|
)
|
|
|
|
def generatePOT(templateSettings, rootPath):
|
|
if "skip" in templateSettings and templateSettings["skip"] == "yes":
|
|
return
|
|
|
|
inputRootPath = rootPath
|
|
if "inputRoot" in templateSettings:
|
|
inputRootPath = os.path.join(rootPath, templateSettings["inputRoot"])
|
|
|
|
template = Catalog(
|
|
project=templateSettings["project"],
|
|
copyright_holder=templateSettings["copyrightHolder"],
|
|
locale='en',
|
|
)
|
|
|
|
for rule in templateSettings["rules"]:
|
|
if "skip" in rule and rule["skip"] == "yes":
|
|
return
|
|
|
|
options = rule.get("options", {})
|
|
extractorClass = getattr(import_module("extractors.extractors"), rule['extractor'])
|
|
extractor = extractorClass(inputRootPath, rule["filemasks"], options)
|
|
formatFlag = None
|
|
if "format" in options:
|
|
formatFlag = options["format"]
|
|
for message, plural, context, location, comments in extractor.run():
|
|
message_id = (message, plural) if plural else message
|
|
|
|
saved_message = template.get(message_id, context) or template.add(
|
|
id=message_id,
|
|
context=context,
|
|
auto_comments=comments,
|
|
flags=[formatFlag] if formatFlag and message.find("%") != -1 else []
|
|
)
|
|
saved_message.locations.append(location)
|
|
saved_message.flags.discard('python-format')
|
|
|
|
template.writeTo(os.path.join(rootPath, templateSettings["output"]))
|
|
print(u"Generated \"{}\" with {} messages.".format(templateSettings["output"], len(template)))
|
|
|
|
def generateTemplatesForMessagesFile(messagesFilePath):
|
|
|
|
with open(messagesFilePath, 'r') as fileObject:
|
|
settings = json.load(fileObject)
|
|
|
|
for templateSettings in settings:
|
|
multiprocessing.Process(
|
|
target=generatePOT,
|
|
args=(templateSettings, os.path.dirname(messagesFilePath))
|
|
).start()
|
|
|
|
|
|
def main():
|
|
import argparse
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--scandir", help="Directory to start scanning for l10n folders in. "
|
|
"Type '.' for current working directory")
|
|
args = parser.parse_args()
|
|
for root, folders, filenames in os.walk(args.scandir or projectRootDirectory):
|
|
for folder in folders:
|
|
if folder == l10nFolderName:
|
|
messagesFilePath = os.path.join(root, folder, messagesFilename)
|
|
if os.path.exists(messagesFilePath):
|
|
generateTemplatesForMessagesFile(messagesFilePath)
|
|
|
|
warnAboutUntouchedMods()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|