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

1import enum 1a

2from pathlib import Path 1a

3from zipfile import ZipFile 1a

4 

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

8 

9 

10class TemplateType(str, enum.Enum): 1a

11 json = "json" 1a

12 zip = "zip" 1a

13 

14 

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

25 

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 } 

35 

36 def __check_temp(self, method) -> None: 1a

37 """ 

38 Checks if the temporary directory was provided on initialization 

39 """ 

40 

41 if self.temp is None: 

42 raise ValueError(f"Temporary directory must be provided for method {method.__name__}") 

43 

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 

51 

52 if t_type is None: 

53 raise ValueError(f"Template '{template}' not found.") 

54 

55 return TemplateType(t_type) 

56 

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. 

60 

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) 

67 

68 if t_type == TemplateType.json: 

69 return self._render_json(recipe) 

70 

71 if t_type == TemplateType.zip: 

72 return self._render_zip(recipe) 

73 

74 raise ValueError(f"Template Type '{t_type}' not found.") 

75 

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) 

82 

83 if self.temp is None: 

84 raise ValueError("Temporary directory must be provided for method _render_json") 

85 

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)) 

89 

90 return save_path 

91 

92 def _render_zip(self, recipe: Recipe) -> Path: 1a

93 self.__check_temp(self._render_zip) 

94 

95 image_asset = recipe.image_dir.joinpath(RecipeImageTypes.original.value) 

96 

97 if self.temp is None: 

98 raise ValueError("Temporary directory must be provided for method _render_zip") 

99 

100 zip_temp = self.temp.joinpath(f"{recipe.slug}.zip") 

101 

102 with ZipFile(zip_temp, "w") as myzip: 

103 myzip.writestr(f"{recipe.slug}.json", recipe.model_dump_json()) 

104 

105 if image_asset.is_file(): 

106 myzip.write(image_asset, arcname=image_asset.name) 

107 

108 return zip_temp