1
0
Fork 0
mirror of https://github.com/mealie-recipes/mealie.git synced 2025-07-24 15:49:42 +02:00

Feature/auto generate crowdin data (#1071)

* add translated key

* update code generation for crowdin generation

* use composition api and minor styling changes
This commit is contained in:
Hayden 2022-03-19 16:33:55 -08:00 committed by GitHub
parent 022cbd1616
commit 50a67f9301
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 391 additions and 175 deletions

View file

@ -16,6 +16,7 @@ class CodeTemplates:
class CodeDest:
interface = CWD / "generated" / "interface.js"
pytest_routes = CWD / "generated" / "test_routes.py"
use_locales = PROJECT_DIR / "frontend" / "composables" / "use-locales" / "available-locales.ts"
class CodeKeys:

View file

@ -38,9 +38,9 @@ def generate_global_components_types() -> None:
"layout": PROJECT_DIR / "frontend" / "components" / "Layout",
}
def render_template(template: str, data: dict) -> None:
template = Template(template)
return template.render(**data)
def render_template(template: str, data: dict) -> str | None:
tmpl = Template(template)
return tmpl.render(**data)
def build_data() -> dict:
data = {}
@ -54,7 +54,9 @@ def generate_global_components_types() -> None:
destination_file.write_text(text)
text = render_template(template, build_data())
write_template(text)
if text:
write_template(text)
# ============================================================
@ -63,13 +65,13 @@ def generate_global_components_types() -> None:
def generate_typescript_types() -> None:
def path_to_module(path: Path):
path: str = str(path)
str_path: str = str(path)
path = path.removeprefix(str(PROJECT_DIR))
path = path.removeprefix("/")
path = path.replace("/", ".")
str_path = str_path.removeprefix(str(PROJECT_DIR))
str_path = str_path.removeprefix("/")
str_path = str_path.replace("/", ".")
return path
return str_path
schema_path = PROJECT_DIR / "mealie" / "schema"
types_dir = PROJECT_DIR / "frontend" / "types" / "api-types"
@ -94,12 +96,12 @@ def generate_typescript_types() -> None:
try:
path_as_module = path_to_module(module)
generate_typescript_defs(path_as_module, str(out_path), exclude=("CamelModel"))
generate_typescript_defs(path_as_module, str(out_path), exclude=("CamelModel")) # type: ignore
except Exception as e:
failed_modules.append(module)
print("\nModule Errors:", module, "-----------------")
print("\nModule Errors:", module, "-----------------") # noqa
print(e) # noqa
print("Finished Module Errors:", module, "-----------------\n")
print("Finished Module Errors:", module, "-----------------\n") # noqa
print("\n📁 Skipped Directories:") # noqa
for skipped_dir in skipped_dirs:

View file

@ -0,0 +1,143 @@
import pathlib
import _static
import dotenv
import requests
from fastapi_camelcase import CamelModel
from jinja2 import Template
from requests import Response
from rich import print
BASE = pathlib.Path(__file__).parent.parent.parent
API_KEY = dotenv.get_key(BASE / ".env", "CROWDIN_API_KEY")
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 %}
]
"""
class TargetLanguage(CamelModel):
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()
def main():
print("Starting...") # noqa
if API_KEY is None:
print("CROWDIN_API_KEY is not set") # noqa
return
api = CrowdinApi("")
models = api.get_languages()
tmpl = Template(LOCALE_TEMPLATE)
rendered = tmpl.render(locales=models)
with open(_static.CodeDest.use_locales, "w") as f:
f.write(rendered) # type:ignore
print("Finished...") # noqa
if __name__ == "__main__":
main()