mirror of
https://github.com/mealie-recipes/mealie.git
synced 2026-04-18 19:05:34 -04:00
109 lines
3.4 KiB
Python
109 lines
3.4 KiB
Python
import enum
|
|
from pathlib import Path
|
|
from zipfile import ZipFile
|
|
|
|
from mealie.schema.recipe import Recipe
|
|
from mealie.schema.recipe.recipe_image_types import RecipeImageTypes
|
|
from mealie.services._base_service import BaseService
|
|
|
|
|
|
class TemplateType(enum.StrEnum):
|
|
json = "json"
|
|
zip = "zip"
|
|
|
|
|
|
class TemplateService(BaseService):
|
|
def __init__(self, temp: Path | None = None) -> None:
|
|
"""Creates a template service that can be used for multiple template generations
|
|
A temporary directory must be provided as a place holder for where to render all templates
|
|
Args:
|
|
temp (Path): [description]
|
|
"""
|
|
self.temp = temp
|
|
self.types = TemplateType
|
|
super().__init__()
|
|
|
|
@property
|
|
def templates(self) -> dict[str, list[str]]:
|
|
"""
|
|
Returns a list of all templates available to render.
|
|
"""
|
|
return {
|
|
TemplateType.json.value: ["raw"],
|
|
TemplateType.zip.value: ["zip"],
|
|
}
|
|
|
|
def __check_temp(self, method) -> None:
|
|
"""
|
|
Checks if the temporary directory was provided on initialization
|
|
"""
|
|
|
|
if self.temp is None:
|
|
raise ValueError(f"Temporary directory must be provided for method {method.__name__}")
|
|
|
|
def template_type(self, template: str) -> TemplateType:
|
|
# Determine Type:
|
|
t_type = None
|
|
for key, value in self.templates.items():
|
|
if template in value:
|
|
t_type = key
|
|
break
|
|
|
|
if t_type is None:
|
|
raise ValueError(f"Template '{template}' not found.")
|
|
|
|
return TemplateType(t_type)
|
|
|
|
def render(self, recipe: Recipe, template: str) -> Path:
|
|
"""
|
|
Renders a TemplateType in a temporary directory and returns the path to the file.
|
|
|
|
Args:
|
|
t_type (TemplateType): The type of template to render
|
|
recipe (Recipe): The recipe to render
|
|
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.zip:
|
|
return self._render_zip(recipe)
|
|
|
|
raise ValueError(f"Template Type '{t_type}' not found.")
|
|
|
|
def _render_json(self, recipe: Recipe) -> Path:
|
|
"""
|
|
Renders a JSON file in a temporary directory and returns
|
|
the path to the file.
|
|
"""
|
|
self.__check_temp(self._render_json)
|
|
|
|
if self.temp is None:
|
|
raise ValueError("Temporary directory must be provided for method _render_json")
|
|
|
|
save_path = self.temp.joinpath(f"{recipe.slug}.json")
|
|
with open(save_path, "w") as f:
|
|
f.write(recipe.model_dump_json(indent=4, by_alias=True))
|
|
|
|
return save_path
|
|
|
|
def _render_zip(self, recipe: Recipe) -> Path:
|
|
self.__check_temp(self._render_zip)
|
|
|
|
image_asset = recipe.image_dir.joinpath(RecipeImageTypes.original.value)
|
|
|
|
if self.temp is None:
|
|
raise ValueError("Temporary directory must be provided for method _render_zip")
|
|
|
|
zip_temp = self.temp.joinpath(f"{recipe.slug}.zip")
|
|
|
|
with ZipFile(zip_temp, "w") as myzip:
|
|
myzip.writestr(f"{recipe.slug}.json", recipe.model_dump_json())
|
|
|
|
if image_asset.is_file():
|
|
myzip.write(image_asset, arcname=image_asset.name)
|
|
|
|
return zip_temp
|