From da3271f33ffae9a96b31b075a5adff4069785cab Mon Sep 17 00:00:00 2001 From: Hayden <64056131+hay-kot@users.noreply.github.com> Date: Fri, 4 Jul 2025 19:45:56 -0500 Subject: [PATCH] chore: remove unused jinja export option (#5631) --- dev/data/templates/recipes.md | 24 ---------- mealie/assets/templates/__init__.py | 5 --- mealie/assets/templates/recipes.md | 24 ---------- mealie/core/settings/directories.py | 9 ---- mealie/lang/providers.py | 2 +- mealie/routes/recipe/_base.py | 1 - mealie/routes/users/images.py | 6 ++- mealie/services/recipe/template_service.py | 44 +------------------ .../test_recipe_export_as.py | 29 ------------ tests/unit_tests/test_recipe_export_types.py | 1 - 10 files changed, 8 insertions(+), 137 deletions(-) delete mode 100644 dev/data/templates/recipes.md delete mode 100644 mealie/assets/templates/__init__.py delete mode 100644 mealie/assets/templates/recipes.md diff --git a/dev/data/templates/recipes.md b/dev/data/templates/recipes.md deleted file mode 100644 index eda4c6e14..000000000 --- a/dev/data/templates/recipes.md +++ /dev/null @@ -1,24 +0,0 @@ - - -![Recipe Image](../../images/{{ recipe.slug }}/original.jpg) - -# {{ recipe.name }} -{{ recipe.description }} - -## Ingredients -{% for ingredient in recipe.recipeIngredient %} -- [ ] {{ ingredient }} {% endfor %} - -## Instructions -{% for step in recipe.recipeInstructions %} -- [ ] {{ step.text }} {% endfor %} - -{% for note in recipe.notes %} -**{{ note.title }}:** {{ note.text }} -{% endfor %} - ---- - -Tags: {{ recipe.tags }} -Categories: {{ recipe.categories }} -Original URL: {{ recipe.orgURL }} diff --git a/mealie/assets/templates/__init__.py b/mealie/assets/templates/__init__.py deleted file mode 100644 index 7c3db204f..000000000 --- a/mealie/assets/templates/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from pathlib import Path - -CWD = Path(__file__).parent - -recipes_markdown = CWD / "recipes.md" diff --git a/mealie/assets/templates/recipes.md b/mealie/assets/templates/recipes.md deleted file mode 100644 index eda4c6e14..000000000 --- a/mealie/assets/templates/recipes.md +++ /dev/null @@ -1,24 +0,0 @@ - - -![Recipe Image](../../images/{{ recipe.slug }}/original.jpg) - -# {{ recipe.name }} -{{ recipe.description }} - -## Ingredients -{% for ingredient in recipe.recipeIngredient %} -- [ ] {{ ingredient }} {% endfor %} - -## Instructions -{% for step in recipe.recipeInstructions %} -- [ ] {{ step.text }} {% endfor %} - -{% for note in recipe.notes %} -**{{ note.title }}:** {{ note.text }} -{% endfor %} - ---- - -Tags: {{ recipe.tags }} -Categories: {{ recipe.categories }} -Original URL: {{ recipe.orgURL }} diff --git a/mealie/core/settings/directories.py b/mealie/core/settings/directories.py index f55032444..86a4dc1dc 100644 --- a/mealie/core/settings/directories.py +++ b/mealie/core/settings/directories.py @@ -1,8 +1,5 @@ -import shutil from pathlib import Path -from mealie.assets import templates - class AppDirectories: def __init__(self, data_dir: Path) -> None: @@ -38,9 +35,3 @@ class AppDirectories: for dir in required_dirs: dir.mkdir(parents=True, exist_ok=True) - - # Bootstrap Templates - markdown_template = self.TEMPLATE_DIR.joinpath("recipes.md") - - if not markdown_template.exists(): - shutil.copyfile(templates.recipes_markdown, markdown_template) diff --git a/mealie/lang/providers.py b/mealie/lang/providers.py index 106a89403..67d1471f7 100644 --- a/mealie/lang/providers.py +++ b/mealie/lang/providers.py @@ -13,7 +13,7 @@ TRANSLATIONS = CWD / "messages" class Translator(Protocol): @abstractmethod - def t(self, key, default=None, **kwargs): + def t(self, key, default=None, **kwargs) -> str: pass diff --git a/mealie/routes/recipe/_base.py b/mealie/routes/recipe/_base.py index 146cbe2bb..8a48a8744 100644 --- a/mealie/routes/recipe/_base.py +++ b/mealie/routes/recipe/_base.py @@ -32,7 +32,6 @@ class JSONBytes(JSONResponse): class FormatResponse(BaseModel): jjson: list[str] = Field(..., alias="json") zip: list[str] - jinja2: list[str] class BaseRecipeController(BaseCrudController): diff --git a/mealie/routes/users/images.py b/mealie/routes/users/images.py index b472e4b1f..c2606c6f6 100644 --- a/mealie/routes/users/images.py +++ b/mealie/routes/users/images.py @@ -1,4 +1,5 @@ import shutil +from uuid import uuid4 from fastapi import File, HTTPException, UploadFile, status from pydantic import UUID4 @@ -24,7 +25,10 @@ class UserImageController(BaseUserController): """Updates a User Image""" with get_temporary_path() as temp_path: assert_user_change_allowed(id, self.user, self.user) - temp_img = temp_path.joinpath(profile.filename) + + # use a generated uuid and ignore the filename so we don't + # need to worry about sanitizing user inputs. + temp_img = temp_path.joinpath(str(uuid4())) with temp_img.open("wb") as buffer: shutil.copyfileobj(profile.file, buffer) diff --git a/mealie/services/recipe/template_service.py b/mealie/services/recipe/template_service.py index 9038ca2f1..504adeb23 100644 --- a/mealie/services/recipe/template_service.py +++ b/mealie/services/recipe/template_service.py @@ -2,8 +2,6 @@ import enum from pathlib import Path from zipfile import ZipFile -from jinja2 import Template - from mealie.schema.recipe import Recipe from mealie.schema.recipe.recipe_image_types import RecipeImageTypes from mealie.services._base_service import BaseService @@ -11,7 +9,6 @@ from mealie.services._base_service import BaseService class TemplateType(str, enum.Enum): json = "json" - jinja2 = "jinja2" zip = "zip" @@ -32,7 +29,6 @@ class TemplateService(BaseService): Returns a list of all templates available to render. """ return { - TemplateType.jinja2.value: [x.name for x in self.directories.TEMPLATE_DIR.iterdir() if x.is_file()], TemplateType.json.value: ["raw"], TemplateType.zip.value: ["zip"], } @@ -65,16 +61,13 @@ class TemplateService(BaseService): Args: t_type (TemplateType): The type of template to render recipe (Recipe): The recipe to render - template (str): The template to render **Required for Jinja2 Templates** + template (str): The template to render """ t_type = self.template_type(template) if t_type == TemplateType.json: return self._render_json(recipe) - if t_type == TemplateType.jinja2: - return self._render_jinja2(recipe, template) - if t_type == TemplateType.zip: return self._render_zip(recipe) @@ -96,41 +89,8 @@ class TemplateService(BaseService): return save_path - def _render_jinja2(self, recipe: Recipe, j2_template: str | None = None) -> Path: - """ - Renders a Jinja2 Template in a temporary directory and returns - the path to the file. - """ - self.__check_temp(self._render_jinja2) - - if j2_template is None: - raise ValueError("Template must be provided for method _render_jinja2") - - j2_path: Path = self.directories.TEMPLATE_DIR / j2_template - - if not j2_path.is_file(): - raise FileNotFoundError(f"Template '{j2_path}' not found.") - - with open(j2_path) as f: - template_text = f.read() - - template = Template(template_text) - rendered_text = template.render(recipe=recipe.model_dump(by_alias=True)) - - save_name = f"{recipe.slug}{j2_path.suffix}" - - if self.temp is None: - raise ValueError("Temporary directory must be provided for method _render_jinja2") - - save_path = self.temp.joinpath(save_name) - - with open(save_path, "w") as f: - f.write(rendered_text) - - return save_path - def _render_zip(self, recipe: Recipe) -> Path: - self.__check_temp(self._render_jinja2) + self.__check_temp(self._render_zip) image_asset = recipe.image_dir.joinpath(RecipeImageTypes.original.value) diff --git a/tests/integration_tests/user_recipe_tests/test_recipe_export_as.py b/tests/integration_tests/user_recipe_tests/test_recipe_export_as.py index 7729a437e..37e25d44a 100644 --- a/tests/integration_tests/user_recipe_tests/test_recipe_export_as.py +++ b/tests/integration_tests/user_recipe_tests/test_recipe_export_as.py @@ -18,28 +18,9 @@ def test_get_available_exports(api_client: TestClient, unique_user: TestUser) -> as_json = response.json() - assert "recipes.md" in as_json["jinja2"] assert "raw" in as_json["json"] -def test_render_jinja_template(api_client: TestClient, unique_user: TestUser) -> None: - # Create Recipe - recipe_name = random_string() - response = api_client.post(api_routes.recipes, json={"name": recipe_name}, headers=unique_user.token) - assert response.status_code == 201 - slug = response.json() - - # Render Template - response = api_client.get( - api_routes.recipes_slug_exports(slug) + "?template_name=recipes.md", headers=unique_user.token - ) - assert response.status_code == 200 - - # Assert Template is Rendered Correctly - # TODO: More robust test - assert f"# {recipe_name}" in response.text - - def test_get_recipe_as_zip(api_client: TestClient, unique_user: TestUser) -> None: # Create Recipe recipe_name = random_string() @@ -61,13 +42,3 @@ def test_get_recipe_as_zip(api_client: TestClient, unique_user: TestUser) -> Non with zipfile.ZipFile(zip_file, "r") as zip_fp: with zip_fp.open(f"{slug}.json") as json_fp: assert json.loads(json_fp.read())["name"] == recipe_name - - -# TODO: Allow users to upload templates to their own directory -# def test_upload_template(api_client: TestClient, unique_user: TestUser) -> None: -# assert False - - -# # TODO: Allow users to upload templates to their own directory -# def test_delete_template(api_client: TestClient, unique_user: TestUser) -> None: -# assert False diff --git a/tests/unit_tests/test_recipe_export_types.py b/tests/unit_tests/test_recipe_export_types.py index 5c4003147..475c5d6f0 100644 --- a/tests/unit_tests/test_recipe_export_types.py +++ b/tests/unit_tests/test_recipe_export_types.py @@ -3,6 +3,5 @@ from mealie.services.recipe.template_service import TemplateService, TemplateTyp def test_recipe_export_types() -> None: ts = TemplateService() - assert ts.template_type("recipes.md") == TemplateType.jinja2.value assert ts.template_type("raw") == TemplateType.json.value assert ts.template_type("zip") == TemplateType.zip.value