diff --git a/dev/code-generation/_gen_utils.py b/dev/code-generation/_gen_utils.py index 8c6c6e2b3a0b..8d2af8f5e577 100644 --- a/dev/code-generation/_gen_utils.py +++ b/dev/code-generation/_gen_utils.py @@ -1,3 +1,4 @@ +import logging import re from dataclasses import dataclass from pathlib import Path @@ -5,9 +6,15 @@ from pathlib import Path import black import isort from jinja2 import Template +from rich.logging import RichHandler + +FORMAT = "%(message)s" +logging.basicConfig(level=logging.INFO, format=FORMAT, datefmt="[%X]", handlers=[RichHandler()]) + +log = logging.getLogger("rich") -def render_python_template(template_file: Path | str, dest: Path, data: dict) -> str: +def render_python_template(template_file: Path | str, dest: Path, data: dict): """Render and Format a Jinja2 Template for Python Code""" if isinstance(template_file, Path): tplt = Template(template_file.read_text()) @@ -37,7 +44,6 @@ class CodeSlicer: def push_line(self, string: str) -> None: self._next_line = self._next_line or self.start + 1 - print(self.indentation) self.text.insert(self._next_line, self.indentation + string + "\n") self._next_line += 1 diff --git a/dev/code-generation/gen_frontend_types.py b/dev/code-generation/gen_frontend_types.py index 1ac4744bcf96..a4a6693f48d5 100644 --- a/dev/code-generation/gen_frontend_types.py +++ b/dev/code-generation/gen_frontend_types.py @@ -1,8 +1,8 @@ from pathlib import Path +from _gen_utils import log from jinja2 import Template from pydantic2ts import generate_typescript_defs -from rich import print # ============================================================ # Global Compoenents Generator @@ -99,26 +99,24 @@ def generate_typescript_types() -> None: generate_typescript_defs(path_as_module, str(out_path), exclude=("MealieModel")) # type: ignore except Exception as e: failed_modules.append(module) - print("\nModule Errors:", module, "-----------------") # noqa - print(e) # noqa - print("Finished Module Errors:", module, "-----------------\n") # noqa + log.error(f"Module Error: {e}") # noqa - print("\n📁 Skipped Directories:") # noqa + log.info("\n📁 Skipped Directories:") # noqa for skipped_dir in skipped_dirs: - print(" 📁", skipped_dir.name) # noqa + log.info(" 📁", skipped_dir.name) # noqa - print("📄 Skipped Files:") # noqa + log.info("📄 Skipped Files:") # noqa for f in skipped_files: - print(" 📄", f.name) # noqa + log.info(" 📄", f.name) # noqa - print("❌ Failed Modules:") # noqa + log.error("❌ Failed Modules:") # noqa for f in failed_modules: - print(" ❌", f.name) # noqa + log.error(" ❌", f.name) # noqa if __name__ == "__main__": - print("\n-- Starting Global Components Generator --") # noqa + log.info("\n-- Starting Global Components Generator --") # noqa generate_global_components_types() - print("\n-- Starting Pydantic To Typescript Generator --") # noqa + log.info("\n-- Starting Pydantic To Typescript Generator --") # noqa generate_typescript_types() diff --git a/dev/code-generation/gen_locales.py b/dev/code-generation/gen_locales.py index cb3d3a19d68d..785c1c2cf2f0 100644 --- a/dev/code-generation/gen_locales.py +++ b/dev/code-generation/gen_locales.py @@ -3,9 +3,9 @@ import pathlib import _static import dotenv import requests +from _gen_utils import log from jinja2 import Template from requests import Response -from rich import print from mealie.schema._mealie import MealieModel @@ -13,6 +13,10 @@ BASE = pathlib.Path(__file__).parent.parent.parent API_KEY = dotenv.get_key(BASE / ".env", "CROWDIN_API_KEY") +if API_KEY is None or API_KEY == "": + log.info("CROWDIN_API_KEY is not set") + exit(1) + NAMES = { "en-US": "American English", "en-GB": "British English", @@ -55,6 +59,7 @@ export const LOCALES = [{% for locale in locales %} progress: {{ locale.progress }}, },{% endfor %} ] + """ @@ -122,22 +127,57 @@ class CrowdinApi: return response.json() -def main(): - print("Starting...") # noqa +from pathlib import Path - if API_KEY is None: - print("CROWDIN_API_KEY is not set") # noqa - return +from _gen_utils import inject_inline +from _static import CodeKeys +PROJECT_DIR = Path(__file__).parent.parent.parent + + +datetime_dir = PROJECT_DIR / "frontend" / "lang" / "dateTimeFormats" +locales_dir = PROJECT_DIR / "frontend" / "lang" / "messages" +nuxt_config = PROJECT_DIR / "frontend" / "nuxt.config.js" + +""" +This snippet walks the message and dat locales directories and generates the import information +for the nuxt.config.js file and automatically injects it into the nuxt.config.js file. Note that +the code generation ID is hardcoded into the script and required in the nuxt config. +""" + + +def inject_nuxt_values(): + all_date_locales = [ + f'"{match.stem}": require("./lang/dateTimeFormats/{match.name}"),' for match in datetime_dir.glob("*.json") + ] + + all_langs = [] + for match in locales_dir.glob("*.json"): + lang_string = f'{{ code: "{match.stem}", file: "{match.name}" }},' + all_langs.append(lang_string) + + log.info(f"injecting locales into nuxt config -> {nuxt_config}") + inject_inline(nuxt_config, CodeKeys.nuxt_local_messages, all_langs) + inject_inline(nuxt_config, CodeKeys.nuxt_local_dates, all_date_locales) + + +def generate_locales_ts_file(): api = CrowdinApi("") models = api.get_languages() tmpl = Template(LOCALE_TEMPLATE) rendered = tmpl.render(locales=models) + log.info(f"generating locales ts file -> {_static.CodeDest.use_locales}") with open(_static.CodeDest.use_locales, "w") as f: f.write(rendered) # type:ignore - print("Finished...") # noqa + +def main(): + generate_locales_ts_file() + + inject_nuxt_values() + + log.info("finished code generation") if __name__ == "__main__": diff --git a/dev/code-generation/gen_nuxt_locales.py b/dev/code-generation/gen_nuxt_locales.py deleted file mode 100644 index 71d0ff4602ce..000000000000 --- a/dev/code-generation/gen_nuxt_locales.py +++ /dev/null @@ -1,39 +0,0 @@ -from pathlib import Path - -from _gen_utils import inject_inline -from _static import CodeKeys - -PROJECT_DIR = Path(__file__).parent.parent.parent - - -datetime_dir = PROJECT_DIR / "frontend" / "lang" / "dateTimeFormats" -locales_dir = PROJECT_DIR / "frontend" / "lang" / "messages" -nuxt_config = PROJECT_DIR / "frontend" / "nuxt.config.js" - -""" -This snippet walks the message and dat locales directories and generates the import information -for the nuxt.config.js file and automatically injects it into the nuxt.config.js file. Note that -the code generation ID is hardcoded into the script and required in the nuxt config. -""" - - -def main(): # sourcery skip: list-comprehension - print("Starting...") - - all_date_locales = [] - for match in datetime_dir.glob("*.json"): - all_date_locales.append(f'"{match.stem}": require("./lang/dateTimeFormats/{match.name}"),') - - all_langs = [] - for match in locales_dir.glob("*.json"): - lang_string = f'{{ code: "{match.stem}", file: "{match.name}" }},' - all_langs.append(lang_string) - - inject_inline(nuxt_config, CodeKeys.nuxt_local_messages, all_langs) - inject_inline(nuxt_config, CodeKeys.nuxt_local_dates, all_date_locales) - - print("Finished...") - - -if __name__ == "__main__": - main() diff --git a/dev/code-generation/gen_schema_exports.py b/dev/code-generation/gen_schema_exports.py index 063e4d340401..33ad1f33b72c 100644 --- a/dev/code-generation/gen_schema_exports.py +++ b/dev/code-generation/gen_schema_exports.py @@ -1,4 +1,4 @@ -from _gen_utils import render_python_template +from _gen_utils import log, render_python_template from _static import PROJECT_DIR template = """# GENERATED CODE - DO NOT MODIFY BY HAND @@ -10,13 +10,12 @@ SCHEMA_PATH = PROJECT_DIR / "mealie" / "schema" def generate_init_files() -> None: - for schema in SCHEMA_PATH.iterdir(): if not schema.is_dir(): - print(f"Skipping {schema}") + log.info(f"Skipping {schema}") continue - print(f"Generating {schema}") + log.info(f"Generating {schema}") init_file = schema.joinpath("__init__.py") module_files = [ @@ -26,9 +25,9 @@ def generate_init_files() -> None: def main(): - print("Starting...") + log.info("Starting...") generate_init_files() - print("Finished...") + log.info("Finished...") if __name__ == "__main__": diff --git a/dev/code-generation/gen_test_data_paths.py b/dev/code-generation/gen_test_data_paths.py index c9e2d641e949..ed357966bcee 100644 --- a/dev/code-generation/gen_test_data_paths.py +++ b/dev/code-generation/gen_test_data_paths.py @@ -1,15 +1,13 @@ from dataclasses import dataclass from pathlib import Path -from _gen_utils import render_python_template +from _gen_utils import log, render_python_template from slugify import slugify CWD = Path(__file__).parent TEMPLATE = CWD / "templates" / "test_data.py.j2" - TEST_DATA = CWD.parent.parent / "tests" / "data" - GENERATED = CWD / "generated" @@ -99,7 +97,7 @@ def rename_non_compliant_paths(): def main(): - print("Starting Template Generation") + log.info("Starting Template Generation") rename_non_compliant_paths() @@ -117,7 +115,7 @@ def main(): {"children": all_children}, ) - print("Finished Template Generation") + log.info("Finished Template Generation") if __name__ == "__main__": diff --git a/frontend/composables/use-locales/available-locales.ts b/frontend/composables/use-locales/available-locales.ts index 7162dafb7031..7e334d0ae7b6 100644 --- a/frontend/composables/use-locales/available-locales.ts +++ b/frontend/composables/use-locales/available-locales.ts @@ -3,12 +3,12 @@ export const LOCALES = [ { name: "繁體中文 (Chinese traditional)", value: "zh-TW", - progress: 90, + progress: 77, }, { name: "简体中文 (Chinese simplified)", value: "zh-CN", - progress: 74, + progress: 64, }, { name: "Tiếng Việt (Vietnamese)", @@ -28,52 +28,62 @@ export const LOCALES = [ { name: "Svenska (Swedish)", value: "sv-SE", - progress: 92, + progress: 93, }, { name: "српски (Serbian)", value: "sr-SP", - progress: 0, + progress: 12, + }, + { + name: "Slovenian", + value: "sl-SI", + progress: 100, }, { name: "Slovak", value: "sk-SK", - progress: 74, + progress: 78, }, { name: "Pусский (Russian)", value: "ru-RU", - progress: 74, + progress: 64, }, { name: "Română (Romanian)", value: "ro-RO", - progress: 0, + progress: 4, }, { name: "Português (Portugese)", value: "pt-PT", - progress: 11, + progress: 10, }, { name: "Português do Brasil (Brazilian Portuguese)", value: "pt-BR", - progress: 47, + progress: 44, }, { name: "Polski (Polish)", value: "pl-PL", - progress: 100, + progress: 99, }, { name: "Norsk (Norwegian)", value: "no-NO", - progress: 74, + progress: 64, }, { name: "Nederlands (Dutch)", value: "nl-NL", - progress: 98, + progress: 85, + }, + { + name: "Lithuanian", + value: "lt-LT", + progress: 0, }, { name: "한국어 (Korean)", @@ -88,12 +98,12 @@ export const LOCALES = [ { name: "Italiano (Italian)", value: "it-IT", - progress: 96, + progress: 93, }, { name: "Magyar (Hungarian)", value: "hu-HU", - progress: 100, + progress: 88, }, { name: "עברית (Hebrew)", @@ -103,12 +113,12 @@ export const LOCALES = [ { name: "Français (French)", value: "fr-FR", - progress: 99, + progress: 100, }, { name: "French, Canada", value: "fr-CA", - progress: 88, + progress: 85, }, { name: "Suomi (Finnish)", @@ -118,7 +128,7 @@ export const LOCALES = [ { name: "Español (Spanish)", value: "es-ES", - progress: 74, + progress: 64, }, { name: "American English", @@ -128,12 +138,12 @@ export const LOCALES = [ { name: "British English", value: "en-GB", - progress: 74, + progress: 35, }, { name: "Ελληνικά (Greek)", value: "el-GR", - progress: 86, + progress: 79, }, { name: "Deutsch (German)", @@ -143,22 +153,27 @@ export const LOCALES = [ { name: "Dansk (Danish)", value: "da-DK", - progress: 83, + progress: 100, }, { name: "Čeština (Czech)", value: "cs-CZ", - progress: 0, + progress: 55, }, { name: "Català (Catalan)", value: "ca-ES", - progress: 74, + progress: 64, + }, + { + name: "Bulgarian", + value: "bg-BG", + progress: 0, }, { name: "العربية (Arabic)", value: "ar-SA", - progress: 4, + progress: 11, }, { name: "Afrikaans (Afrikaans)", diff --git a/frontend/nuxt.config.js b/frontend/nuxt.config.js index 8be8864e025b..e197a6775226 100644 --- a/frontend/nuxt.config.js +++ b/frontend/nuxt.config.js @@ -141,6 +141,7 @@ export default { { code: "ko-KR", file: "ko-KR.json" }, { code: "es-ES", file: "es-ES.json" }, { code: "ja-JP", file: "ja-JP.json" }, + { code: "bg-BG", file: "bg-BG.json" }, { code: "zh-CN", file: "zh-CN.json" }, { code: "tr-TR", file: "tr-TR.json" }, { code: "ar-SA", file: "ar-SA.json" }, @@ -149,7 +150,10 @@ export default { { code: "no-NO", file: "no-NO.json" }, { code: "sv-SE", file: "sv-SE.json" }, { code: "ro-RO", file: "ro-RO.json" }, + { code: "sk-SK", file: "sk-SK.json" }, { code: "uk-UA", file: "uk-UA.json" }, + { code: "lt-LT", file: "lt-LT.json" }, + { code: "fr-CA", file: "fr-CA.json" }, { code: "pl-PL", file: "pl-PL.json" }, { code: "da-DK", file: "da-DK.json" }, { code: "pt-BR", file: "pt-BR.json" }, @@ -160,6 +164,7 @@ export default { { code: "fr-FR", file: "fr-FR.json" }, { code: "zh-TW", file: "zh-TW.json" }, { code: "af-ZA", file: "af-ZA.json" }, + { code: "sl-SI", file: "sl-SI.json" }, { code: "ru-RU", file: "ru-RU.json" }, { code: "he-IL", file: "he-IL.json" }, { code: "nl-NL", file: "nl-NL.json" }, @@ -185,6 +190,7 @@ export default { "ko-KR": require("./lang/dateTimeFormats/ko-KR.json"), "es-ES": require("./lang/dateTimeFormats/es-ES.json"), "ja-JP": require("./lang/dateTimeFormats/ja-JP.json"), + "bg-BG": require("./lang/dateTimeFormats/bg-BG.json"), "zh-CN": require("./lang/dateTimeFormats/zh-CN.json"), "tr-TR": require("./lang/dateTimeFormats/tr-TR.json"), "ar-SA": require("./lang/dateTimeFormats/ar-SA.json"), @@ -193,7 +199,9 @@ export default { "no-NO": require("./lang/dateTimeFormats/no-NO.json"), "sv-SE": require("./lang/dateTimeFormats/sv-SE.json"), "ro-RO": require("./lang/dateTimeFormats/ro-RO.json"), + "sk-SK": require("./lang/dateTimeFormats/sk-SK.json"), "uk-UA": require("./lang/dateTimeFormats/uk-UA.json"), + "fr-CA": require("./lang/dateTimeFormats/fr-CA.json"), "pl-PL": require("./lang/dateTimeFormats/pl-PL.json"), "da-DK": require("./lang/dateTimeFormats/da-DK.json"), "pt-BR": require("./lang/dateTimeFormats/pt-BR.json"),