| 
									
										
										
										
											2022-03-19 16:33:55 -08:00
										 |  |  |  | import pathlib | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | import _static | 
					
						
							|  |  |  |  | import dotenv | 
					
						
							|  |  |  |  | import requests | 
					
						
							| 
									
										
										
										
											2022-08-02 10:41:44 -08:00
										 |  |  |  | from _gen_utils import log | 
					
						
							| 
									
										
										
										
											2022-03-19 16:33:55 -08:00
										 |  |  |  | from jinja2 import Template | 
					
						
							|  |  |  |  | from requests import Response | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-25 10:56:49 -08:00
										 |  |  |  | from mealie.schema._mealie import MealieModel | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-19 16:33:55 -08:00
										 |  |  |  | BASE = pathlib.Path(__file__).parent.parent.parent | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | API_KEY = dotenv.get_key(BASE / ".env", "CROWDIN_API_KEY") | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-02 10:41:44 -08:00
										 |  |  |  | if API_KEY is None or API_KEY == "": | 
					
						
							|  |  |  |  |     log.info("CROWDIN_API_KEY is not set") | 
					
						
							|  |  |  |  |     exit(1) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-19 16:33:55 -08:00
										 |  |  |  | NAMES = { | 
					
						
							|  |  |  |  |     "en-US": "American English", | 
					
						
							|  |  |  |  |     "en-GB": "British English", | 
					
						
							|  |  |  |  |     "af-ZA": "Afrikaans (Afrikaans)", | 
					
						
							|  |  |  |  |     "ar-SA": "العربية (Arabic)", | 
					
						
							|  |  |  |  |     "ca-ES": "Català (Catalan)", | 
					
						
							|  |  |  |  |     "cs-CZ": "Čeština (Czech)", | 
					
						
							|  |  |  |  |     "da-DK": "Dansk (Danish)", | 
					
						
							|  |  |  |  |     "de-DE": "Deutsch (German)", | 
					
						
							|  |  |  |  |     "el-GR": "Ελληνικά (Greek)", | 
					
						
							|  |  |  |  |     "es-ES": "Español (Spanish)", | 
					
						
							|  |  |  |  |     "fi-FI": "Suomi (Finnish)", | 
					
						
							|  |  |  |  |     "fr-FR": "Français (French)", | 
					
						
							|  |  |  |  |     "he-IL": "עברית (Hebrew)", | 
					
						
							|  |  |  |  |     "hu-HU": "Magyar (Hungarian)", | 
					
						
							|  |  |  |  |     "it-IT": "Italiano (Italian)", | 
					
						
							|  |  |  |  |     "ja-JP": "日本語 (Japanese)", | 
					
						
							|  |  |  |  |     "ko-KR": "한국어 (Korean)", | 
					
						
							|  |  |  |  |     "no-NO": "Norsk (Norwegian)", | 
					
						
							|  |  |  |  |     "nl-NL": "Nederlands (Dutch)", | 
					
						
							|  |  |  |  |     "pl-PL": "Polski (Polish)", | 
					
						
							|  |  |  |  |     "pt-BR": "Português do Brasil (Brazilian Portuguese)", | 
					
						
							|  |  |  |  |     "pt-PT": "Português (Portugese)", | 
					
						
							|  |  |  |  |     "ro-RO": "Română (Romanian)", | 
					
						
							|  |  |  |  |     "ru-RU": "Pусский (Russian)", | 
					
						
							|  |  |  |  |     "sr-SP": "српски (Serbian)", | 
					
						
							|  |  |  |  |     "sv-SE": "Svenska (Swedish)", | 
					
						
							|  |  |  |  |     "tr-TR": "Türkçe (Turkish)", | 
					
						
							|  |  |  |  |     "uk-UA": "Українська (Ukrainian)", | 
					
						
							|  |  |  |  |     "vi-VN": "Tiếng Việt (Vietnamese)", | 
					
						
							|  |  |  |  |     "zh-CN": "简体中文 (Chinese simplified)", | 
					
						
							|  |  |  |  |     "zh-TW": "繁體中文 (Chinese traditional)", | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | LOCALE_TEMPLATE = """// This Code is auto generated by gen_global_components.py
 | 
					
						
							|  |  |  |  | export const LOCALES = [{% for locale in locales %} | 
					
						
							|  |  |  |  |   { | 
					
						
							|  |  |  |  |     name: "{{ locale.name }}", | 
					
						
							|  |  |  |  |     value: "{{ locale.locale }}", | 
					
						
							|  |  |  |  |     progress: {{ locale.progress }}, | 
					
						
							|  |  |  |  |   },{% endfor %} | 
					
						
							|  |  |  |  | ] | 
					
						
							| 
									
										
										
										
											2022-08-02 10:41:44 -08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-19 16:33:55 -08:00
										 |  |  |  | """
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-25 10:56:49 -08:00
										 |  |  |  | class TargetLanguage(MealieModel): | 
					
						
							| 
									
										
										
										
											2022-03-19 16:33:55 -08:00
										 |  |  |  |     id: str | 
					
						
							|  |  |  |  |     name: str | 
					
						
							|  |  |  |  |     locale: str | 
					
						
							|  |  |  |  |     threeLettersCode: str | 
					
						
							|  |  |  |  |     twoLettersCode: str | 
					
						
							|  |  |  |  |     progress: float = 0.0 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | class CrowdinApi: | 
					
						
							|  |  |  |  |     project_name = "Mealie" | 
					
						
							|  |  |  |  |     project_id = "451976" | 
					
						
							|  |  |  |  |     api_key = API_KEY | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     def __init__(self, api_key: str): | 
					
						
							|  |  |  |  |         api_key = api_key | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     @property | 
					
						
							|  |  |  |  |     def headers(self) -> dict: | 
					
						
							|  |  |  |  |         return { | 
					
						
							|  |  |  |  |             "Content-Type": "application/json", | 
					
						
							|  |  |  |  |             "Authorization": f"Bearer {self.api_key}", | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     def get_projects(self) -> Response: | 
					
						
							|  |  |  |  |         return requests.get("https://api.crowdin.com/api/v2/projects", headers=self.headers) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     def get_project(self) -> Response: | 
					
						
							|  |  |  |  |         return requests.get(f"https://api.crowdin.com/api/v2/projects/{self.project_id}", headers=self.headers) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     def get_languages(self) -> list[TargetLanguage]: | 
					
						
							|  |  |  |  |         response = self.get_project() | 
					
						
							|  |  |  |  |         tls = response.json()["data"]["targetLanguages"] | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         models = [TargetLanguage(**t) for t in tls] | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         models.insert( | 
					
						
							|  |  |  |  |             0, | 
					
						
							|  |  |  |  |             TargetLanguage( | 
					
						
							|  |  |  |  |                 id="en-US", name="English", locale="en-US", threeLettersCode="en", twoLettersCode="en", progress=100 | 
					
						
							|  |  |  |  |             ), | 
					
						
							|  |  |  |  |         ) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         progress: list[dict] = self.get_progress()["data"] | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         for model in models: | 
					
						
							|  |  |  |  |             if model.locale in NAMES: | 
					
						
							|  |  |  |  |                 model.name = NAMES[model.locale] | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             for p in progress: | 
					
						
							|  |  |  |  |                 if p["data"]["languageId"] == model.id: | 
					
						
							|  |  |  |  |                     model.progress = p["data"]["translationProgress"] | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         models.sort(key=lambda x: x.locale, reverse=True) | 
					
						
							|  |  |  |  |         return models | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     def get_progress(self) -> dict: | 
					
						
							|  |  |  |  |         response = requests.get( | 
					
						
							|  |  |  |  |             f"https://api.crowdin.com/api/v2/projects/{self.project_id}/languages/progress?limit=500", | 
					
						
							|  |  |  |  |             headers=self.headers, | 
					
						
							|  |  |  |  |         ) | 
					
						
							|  |  |  |  |         return response.json() | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-02 10:41:44 -08:00
										 |  |  |  | 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 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) | 
					
						
							| 
									
										
										
										
											2022-03-19 16:33:55 -08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-02 10:41:44 -08:00
										 |  |  |  | def generate_locales_ts_file(): | 
					
						
							| 
									
										
										
										
											2022-03-19 16:33:55 -08:00
										 |  |  |  |     api = CrowdinApi("") | 
					
						
							|  |  |  |  |     models = api.get_languages() | 
					
						
							|  |  |  |  |     tmpl = Template(LOCALE_TEMPLATE) | 
					
						
							|  |  |  |  |     rendered = tmpl.render(locales=models) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-02 10:41:44 -08:00
										 |  |  |  |     log.info(f"generating locales ts file -> {_static.CodeDest.use_locales}") | 
					
						
							| 
									
										
										
										
											2022-03-19 16:33:55 -08:00
										 |  |  |  |     with open(_static.CodeDest.use_locales, "w") as f: | 
					
						
							|  |  |  |  |         f.write(rendered)  # type:ignore | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-02 10:41:44 -08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | def main(): | 
					
						
							|  |  |  |  |     generate_locales_ts_file() | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     inject_nuxt_values() | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     log.info("finished code generation") | 
					
						
							| 
									
										
										
										
											2022-03-19 16:33:55 -08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | if __name__ == "__main__": | 
					
						
							|  |  |  |  |     main() |