Coverage for cookbook/integration/chowdown.py: 12%

96 statements  

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

1import re 

2from io import BytesIO 

3from zipfile import ZipFile 

4 

5from cookbook.helper.image_processing import get_filetype 

6from cookbook.helper.ingredient_parser import IngredientParser 

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

8from cookbook.integration.integration import Integration 

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

10 

11 

12class Chowdown(Integration): 

13 

14 def import_file_name_filter(self, zip_info_object): 

15 print("testing", zip_info_object.filename) 

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

17 

18 def get_recipe_from_file(self, file): 

19 ingredient_mode = False 

20 direction_mode = False 

21 description_mode = False 

22 

23 description = None 

24 prep_time = None 

25 serving = None 

26 

27 ingredients = [] 

28 directions = [] 

29 descriptions = [] 

30 for fl in file.readlines(): 

31 line = fl.decode("utf-8") 

32 if 'title:' in line: 

33 title = line.replace('title:', '').replace('"', '').strip() 

34 if 'description:' in line: 

35 description = line.replace('description:', '').replace('"', '').strip() 

36 if 'prep_time:' in line: 

37 prep_time = line.replace('prep_time:', '').replace('"', '').strip() 

38 if 'yield:' in line: 

39 serving = line.replace('yield:', '').replace('"', '').strip() 

40 if 'image:' in line: 

41 image = line.replace('image:', '').strip() 

42 if 'tags:' in line: 

43 tags = line.replace('tags:', '').strip() 

44 if ingredient_mode: 

45 if len(line) > 2 and 'directions:' not in line: 

46 ingredients.append(line[2:]) 

47 if '---' in line and direction_mode: 

48 direction_mode = False 

49 description_mode = True 

50 if direction_mode: 

51 if len(line) > 2: 

52 directions.append(line[2:]) 

53 if 'ingredients:' in line: 

54 ingredient_mode = True 

55 if 'directions:' in line: 

56 ingredient_mode = False 

57 direction_mode = True 

58 if description_mode and len(line) > 3 and '---' not in line: 

59 descriptions.append(line) 

60 

61 recipe = Recipe.objects.create(name=title, created_by=self.request.user, internal=True, space=self.request.space) 

62 if description: 

63 recipe.description = description 

64 

65 for k in tags.split(','): 

66 keyword, created = Keyword.objects.get_or_create(name=k.strip(), space=self.request.space) 

67 recipe.keywords.add(keyword) 

68 

69 ingredients_added = False 

70 for direction in directions: 

71 if len(direction.strip()) > 0: 

72 step = Step.objects.create( 

73 instruction=direction, name='', space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients, 

74 ) 

75 else: 

76 step = Step.objects.create( 

77 instruction=direction, space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients, 

78 ) 

79 if not ingredients_added: 

80 ingredients_added = True 

81 

82 ingredient_parser = IngredientParser(self.request, True) 

83 for ingredient in ingredients: 

84 if len(ingredient.strip()) > 0: 

85 amount, unit, food, note = ingredient_parser.parse(ingredient) 

86 f = ingredient_parser.get_food(food) 

87 u = ingredient_parser.get_unit(unit) 

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

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

90 )) 

91 recipe.steps.add(step) 

92 

93 if serving: 

94 recipe.servings = parse_servings(serving) 

95 recipe.servings_text = 'servings' 

96 

97 if prep_time: 

98 recipe.working_time = parse_time(prep_time) 

99 

100 ingredient_parser = IngredientParser(self.request, True) 

101 for ingredient in ingredients: 

102 if len(ingredient.strip()) > 0: 

103 amount, unit, food, note = ingredient_parser.parse(ingredient) 

104 f = ingredient_parser.get_food(food) 

105 u = ingredient_parser.get_unit(unit) 

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

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

108 )) 

109 recipe.steps.add(step) 

110 

111 for f in self.files: 

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

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

114 for z in import_zip.filelist: 

115 if re.match(f'^images/{image}$', z.filename): 

116 self.import_recipe_image(recipe, BytesIO(import_zip.read(z.filename)), filetype=get_filetype(z.filename)) 

117 

118 recipe.save() 

119 return recipe 

120 

121 def get_file_from_recipe(self, recipe): 

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