Skip to content

Commit

Permalink
fix: sync locales in user registration validation (#3278)
Browse files Browse the repository at this point in the history
* Add ability to inject into Python files

* Update outdated references to gen_global_components.py

* Add code gen for registration locale validation

* sort validators

* update for pydantic 2

* run generator again

---------

Co-authored-by: Gasper Gril <gasper@gril.si>
Co-authored-by: Michael Genson <71845777+michael-genson@users.noreply.github.com>
  • Loading branch information
3 people committed Mar 10, 2024
1 parent 02da211 commit b54cdf6
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 84 deletions.
16 changes: 9 additions & 7 deletions dev/code-generation/gen_py_pytest_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,34 @@

from fastapi import FastAPI
from jinja2 import Template
from pydantic import BaseModel
from utils import PROJECT_DIR, CodeTemplates, HTTPRequest, RouteObject
from pydantic import BaseModel, ConfigDict
from utils import PROJECT_DIR, CodeTemplates, HTTPRequest, RouteObject, RequestType

CWD = Path(__file__).parent

OUTFILE = PROJECT_DIR / "tests" / "utils" / "api_routes" / "__init__.py"


class PathObject(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True)
route_object: RouteObject
http_verbs: list[HTTPRequest]

class Config:
arbitrary_types_allowed = True


def get_path_objects(app: FastAPI):
paths = []

for key, value in app.openapi().items():
if key == "paths":
for key, value in value.items():
for key, value2 in value.items():
verbs = []
for k, v in value2.items():
verbs.append(HTTPRequest(request_type=k, **v))

paths.append(
PathObject(
route_object=RouteObject(key),
http_verbs=[HTTPRequest(request_type=k, **v) for k, v in value.items()],
http_verbs=verbs,
)
)

Expand Down
25 changes: 19 additions & 6 deletions dev/code-generation/gen_ts_locales.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import dotenv
import requests
from jinja2 import Template
from pydantic import Extra
from pydantic import ConfigDict
from requests import Response
from utils import CodeDest, CodeKeys, inject_inline, log

Expand Down Expand Up @@ -56,7 +56,7 @@ class LocaleData:
"zh-TW": LocaleData(name="繁體中文 (Chinese traditional)"),
}

LOCALE_TEMPLATE = """// This Code is auto generated by gen_global_components.py
LOCALE_TEMPLATE = """// This Code is auto generated by gen_ts_locales.py
export const LOCALES = [{% for locale in locales %}
{
name: "{{ locale.name }}",
Expand All @@ -70,6 +70,8 @@ class LocaleData:


class TargetLanguage(MealieModel):
model_config = ConfigDict(populate_by_name=True, extra="allow")

id: str
name: str
locale: str
Expand All @@ -78,10 +80,6 @@ class TargetLanguage(MealieModel):
twoLettersCode: str
progress: float = 0.0

class Config:
extra = Extra.allow
allow_population_by_field_name = True


class CrowdinApi:
project_name = "Mealie"
Expand Down Expand Up @@ -152,6 +150,7 @@ def get_progress(self) -> dict:
datetime_dir = PROJECT_DIR / "frontend" / "lang" / "dateTimeFormats"
locales_dir = PROJECT_DIR / "frontend" / "lang" / "messages"
nuxt_config = PROJECT_DIR / "frontend" / "nuxt.config.js"
reg_valid = PROJECT_DIR / "mealie" / "schema" / "_mealie" / "validators.py"

"""
This snippet walks the message and dat locales directories and generates the import information
Expand All @@ -175,6 +174,19 @@ def inject_nuxt_values():
inject_inline(nuxt_config, CodeKeys.nuxt_local_dates, all_date_locales)


def inject_registration_validation_values():
all_langs = []
for match in locales_dir.glob("*.json"):
lang_string = f'"{match.stem}",'
all_langs.append(lang_string)

# sort
all_langs.sort()

log.debug(f"injecting locales into user registration validation -> {reg_valid}")
inject_inline(reg_valid, CodeKeys.nuxt_local_messages, all_langs)


def generate_locales_ts_file():
api = CrowdinApi("")
models = api.get_languages()
Expand All @@ -193,6 +205,7 @@ def main():

generate_locales_ts_file()
inject_nuxt_values()
inject_registration_validation_values()


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion dev/code-generation/gen_ts_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

# ============================================================

template = """// This Code is auto generated by gen_global_components.py
template = """// This Code is auto generated by gen_ts_types.py
{% for name in global %}import {{ name }} from "@/components/global/{{ name }}.vue";
{% endfor %}{% for name in layout %}import {{ name }} from "@/components/layout/{{ name }}.vue";
{% endfor %}
Expand Down
24 changes: 10 additions & 14 deletions dev/code-generation/utils/route.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import re
from enum import Enum
from typing import Optional

from humps import camelize
from pydantic import BaseModel, Extra, Field
from pydantic import BaseModel, ConfigDict, Field
from slugify import slugify


Expand Down Expand Up @@ -34,33 +33,30 @@ class ParameterIn(str, Enum):


class RouterParameter(BaseModel):
model_config = ConfigDict(extra="allow")

required: bool = False
name: str
location: ParameterIn = Field(..., alias="in")

class Config:
extra = Extra.allow


class RequestBody(BaseModel):
required: bool = False
model_config = ConfigDict(extra="allow")

class Config:
extra = Extra.allow
required: bool = False


class HTTPRequest(BaseModel):
model_config = ConfigDict(extra="allow", populate_by_name=True)

request_type: RequestType
description: str = ""
summary: str
requestBody: Optional[RequestBody]
request_body: RequestBody | None = None

parameters: list[RouterParameter] = []
tags: list[str] | None = []

class Config:
extra = Extra.allow

def list_as_js_object_string(self, parameters, braces=True):
if len(parameters) == 0:
return ""
Expand All @@ -71,11 +67,11 @@ def list_as_js_object_string(self, parameters, braces=True):
return ", ".join(parameters)

def payload(self):
return "payload" if self.requestBody else ""
return "payload" if self.request_body else ""

def function_args(self):
all_params = [p.name for p in self.parameters]
if self.requestBody:
if self.request_body:
all_params.append("payload")
return self.list_as_js_object_string(all_params)

Expand Down
2 changes: 1 addition & 1 deletion dev/code-generation/utils/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def push_line(self, string: str) -> None:
self._next_line += 1


def get_indentation_of_string(line: str, comment_char: str = "//") -> str:
def get_indentation_of_string(line: str, comment_char: str = "//|#") -> str:
return re.sub(rf"{comment_char}.*", "", line).removesuffix("\n")


Expand Down

0 comments on commit b54cdf6

Please sign in to comment.