Coverage for cookbook/integration/mealie.py: 19%

70 statements  

« prev     ^ index     » next       coverage.py v7.4.0, created at 2023-12-29 00:47 +0100

1import json 

2import re 

3from io import BytesIO 

4from zipfile import ZipFile 

5 

6from cookbook.helper.image_processing import get_filetype 

7from cookbook.helper.ingredient_parser import IngredientParser 

8from cookbook.helper.recipe_url_import import parse_servings, parse_servings_text, parse_time 

9from cookbook.integration.integration import Integration 

10from cookbook.models import Ingredient, Keyword, Recipe, Step 

11 

12 

13class Mealie(Integration): 

14 

15 def import_file_name_filter(self, zip_info_object): 

16 return re.match(r'^recipes/([A-Za-z\d\s\-_()\[\]\u00C0-\u017F])+/([A-Za-z\d\s\-_()\[\]\u00C0-\u017F])+.json$', zip_info_object.filename) 

17 

18 def get_recipe_from_file(self, file): 

19 recipe_json = json.loads(file.getvalue().decode("utf-8")) 

20 

21 description = '' if len(recipe_json['description'].strip()) > 500 else recipe_json['description'].strip() 

22 

23 recipe = Recipe.objects.create( 

24 name=recipe_json['name'].strip(), description=description, 

25 created_by=self.request.user, internal=True, space=self.request.space) 

26 

27 for s in recipe_json['recipe_instructions']: 

28 step = Step.objects.create(instruction=s['text'], space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients, ) 

29 recipe.steps.add(step) 

30 

31 step = recipe.steps.first() 

32 if not step: # if there is no step in the exported data 

33 step = Step.objects.create(instruction='', space=self.request.space, ) 

34 recipe.steps.add(step) 

35 

36 if len(recipe_json['description'].strip()) > 500: 

37 step.instruction = recipe_json['description'].strip() + '\n\n' + step.instruction 

38 

39 ingredient_parser = IngredientParser(self.request, True) 

40 for ingredient in recipe_json['recipe_ingredient']: 

41 try: 

42 if ingredient['food']: 

43 f = ingredient_parser.get_food(ingredient['food']) 

44 u = ingredient_parser.get_unit(ingredient['unit']) 

45 amount = ingredient['quantity'] 

46 note = ingredient['note'] 

47 original_text = None 

48 else: 

49 amount, unit, food, note = ingredient_parser.parse(ingredient['note']) 

50 f = ingredient_parser.get_food(food) 

51 u = ingredient_parser.get_unit(unit) 

52 original_text = ingredient['note'] 

53 step.ingredients.add(Ingredient.objects.create( 

54 food=f, unit=u, amount=amount, note=note, original_text=original_text, space=self.request.space, 

55 )) 

56 except Exception: 

57 pass 

58 

59 if 'tags' in recipe_json and len(recipe_json['tags']) > 0: 

60 for k in recipe_json['tags']: 

61 if 'name' in k: 

62 keyword, created = Keyword.objects.get_or_create(name=k['name'].strip(), space=self.request.space) 

63 recipe.keywords.add(keyword) 

64 

65 if 'notes' in recipe_json and len(recipe_json['notes']) > 0: 

66 notes_text = "#### Notes \n\n" 

67 for n in recipe_json['notes']: 

68 notes_text += f'{n["text"]} \n' 

69 

70 step = Step.objects.create( 

71 instruction=notes_text, space=self.request.space, 

72 ) 

73 recipe.steps.add(step) 

74 

75 if 'recipe_yield' in recipe_json: 

76 recipe.servings = parse_servings(recipe_json['recipe_yield']) 

77 recipe.servings_text = parse_servings_text(recipe_json['recipe_yield']) 

78 

79 if 'total_time' in recipe_json and recipe_json['total_time'] is not None: 

80 recipe.working_time = parse_time(recipe_json['total_time']) 

81 

82 if 'org_url' in recipe_json: 

83 recipe.source_url = recipe_json['org_url'] 

84 

85 recipe.save() 

86 

87 for f in self.files: 

88 if '.zip' in f['name']: 

89 import_zip = ZipFile(f['file']) 

90 try: 

91 self.import_recipe_image(recipe, BytesIO(import_zip.read(f'recipes/{recipe_json["slug"]}/images/min-original.webp')), 

92 filetype=get_filetype(f'recipes/{recipe_json["slug"]}/images/original')) 

93 except Exception: 

94 pass 

95 

96 return recipe 

97 

98 def get_file_from_recipe(self, recipe): 

99 raise NotImplementedError('Method not implemented in storage integration')