#!/usr/bin/env python3 # # Copyright (C) 2022 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 . import argparse import glob import json import multiprocessing import os from importlib import import_module from i18n_helper import L10N_FOLDER_NAME, PROJECT_ROOT_DIRECTORY from i18n_helper.catalog import Catalog messages_filename = "messages.json" def warn_about_untouched_mods(): """Warn about mods that are not properly configured to get their messages extracted.""" mods_root_folder = os.path.join(PROJECT_ROOT_DIRECTORY, "binaries", "data", "mods") untouched_mods = {} for mod_folder in os.listdir(mods_root_folder): if mod_folder.startswith(("_", ".")): continue if not os.path.exists(os.path.join(mods_root_folder, mod_folder, L10N_FOLDER_NAME)): untouched_mods[mod_folder] = ( f"There is no '{L10N_FOLDER_NAME}' folder in the root folder of this mod." ) elif not os.path.exists( os.path.join(mods_root_folder, mod_folder, L10N_FOLDER_NAME, messages_filename) ): untouched_mods[mod_folder] = ( f"There is no '{messages_filename}' file within the '{L10N_FOLDER_NAME}' " f"folder in the root folder of this mod." ) if untouched_mods: print("Warning: No messages were extracted from the following mods:") for mod in untouched_mods: print(f"• {mod}: {untouched_mods[mod]}") print( "" f"For this script to extract messages from a mod folder, this mod folder must contain " f"a '{L10N_FOLDER_NAME}' folder, and this folder must contain a '{messages_filename}' " f"file that describes how to extract messages for the mod. See the folder of the main " f"mod ('public') for an example, and see the documentation for more information." ) def generate_pot(template_settings, root_path): if "skip" in template_settings and template_settings["skip"] == "yes": return input_root_path = root_path if "inputRoot" in template_settings: input_root_path = os.path.join(root_path, template_settings["inputRoot"]) template = Catalog( project=template_settings["project"], copyright_holder=template_settings["copyrightHolder"], locale="en", ) for rule in template_settings["rules"]: if "skip" in rule and rule["skip"] == "yes": return options = rule.get("options", {}) extractor_class = getattr( import_module("i18n_helper.extractors"), f'{rule["extractor"].title()}Extractor' ) extractor = extractor_class(input_root_path, rule["filemasks"], options) format_flag = None if "format" in options: format_flag = 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=[format_flag] if format_flag and message.find("%") != -1 else [], ) saved_message.locations.append(location) saved_message.flags.discard("python-format") template.write_to(os.path.join(root_path, template_settings["output"])) print('Generated "{}" with {} messages.'.format(template_settings["output"], len(template))) def generate_templates_for_messages_file(messages_file_path): with open(messages_file_path, encoding="utf-8") as file_object: settings = json.load(file_object) for template_settings in settings: multiprocessing.Process( target=generate_pot, args=(template_settings, os.path.dirname(messages_file_path)) ).start() def main(): 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() dir_to_scan = args.scandir or PROJECT_ROOT_DIRECTORY for messages_file_path in glob.glob( f"**/{L10N_FOLDER_NAME}/{messages_filename}", root_dir=dir_to_scan, recursive=True ): generate_templates_for_messages_file( os.path.abspath(f"{dir_to_scan}/{messages_file_path}") ) warn_about_untouched_mods() if __name__ == "__main__": main()