Coverage for opt/mealie/lib/python3.12/site-packages/mealie/services/recipe/template_service.py: 30%
55 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-11-25 15:32 +0000
« prev ^ index » next coverage.py v7.10.6, created at 2025-11-25 15:32 +0000
1import enum 1a
2from pathlib import Path 1a
3from zipfile import ZipFile 1a
5from mealie.schema.recipe import Recipe 1a
6from mealie.schema.recipe.recipe_image_types import RecipeImageTypes 1a
7from mealie.services._base_service import BaseService 1a
10class TemplateType(str, enum.Enum): 1a
11 json = "json" 1a
12 zip = "zip" 1a
15class TemplateService(BaseService): 1a
16 def __init__(self, temp: Path | None = None) -> None: 1a
17 """Creates a template service that can be used for multiple template generations
18 A temporary directory must be provided as a place holder for where to render all templates
19 Args:
20 temp (Path): [description]
21 """
22 self.temp = temp 1b
23 self.types = TemplateType 1b
24 super().__init__() 1b
26 @property 1a
27 def templates(self) -> dict[str, list[str]]: 1a
28 """
29 Returns a list of all templates available to render.
30 """
31 return { 1b
32 TemplateType.json.value: ["raw"],
33 TemplateType.zip.value: ["zip"],
34 }
36 def __check_temp(self, method) -> None: 1a
37 """
38 Checks if the temporary directory was provided on initialization
39 """
41 if self.temp is None:
42 raise ValueError(f"Temporary directory must be provided for method {method.__name__}")
44 def template_type(self, template: str) -> TemplateType: 1a
45 # Determine Type:
46 t_type = None
47 for key, value in self.templates.items():
48 if template in value:
49 t_type = key
50 break
52 if t_type is None:
53 raise ValueError(f"Template '{template}' not found.")
55 return TemplateType(t_type)
57 def render(self, recipe: Recipe, template: str) -> Path: 1a
58 """
59 Renders a TemplateType in a temporary directory and returns the path to the file.
61 Args:
62 t_type (TemplateType): The type of template to render
63 recipe (Recipe): The recipe to render
64 template (str): The template to render
65 """
66 t_type = self.template_type(template)
68 if t_type == TemplateType.json:
69 return self._render_json(recipe)
71 if t_type == TemplateType.zip:
72 return self._render_zip(recipe)
74 raise ValueError(f"Template Type '{t_type}' not found.")
76 def _render_json(self, recipe: Recipe) -> Path: 1a
77 """
78 Renders a JSON file in a temporary directory and returns
79 the path to the file.
80 """
81 self.__check_temp(self._render_json)
83 if self.temp is None:
84 raise ValueError("Temporary directory must be provided for method _render_json")
86 save_path = self.temp.joinpath(f"{recipe.slug}.json")
87 with open(save_path, "w") as f:
88 f.write(recipe.model_dump_json(indent=4, by_alias=True))
90 return save_path
92 def _render_zip(self, recipe: Recipe) -> Path: 1a
93 self.__check_temp(self._render_zip)
95 image_asset = recipe.image_dir.joinpath(RecipeImageTypes.original.value)
97 if self.temp is None:
98 raise ValueError("Temporary directory must be provided for method _render_zip")
100 zip_temp = self.temp.joinpath(f"{recipe.slug}.zip")
102 with ZipFile(zip_temp, "w") as myzip:
103 myzip.writestr(f"{recipe.slug}.json", recipe.model_dump_json())
105 if image_asset.is_file():
106 myzip.write(image_asset, arcname=image_asset.name)
108 return zip_temp