Coverage for cookbook/integration/recipesage.py: 21%
61 statements
« prev ^ index » next coverage.py v7.4.0, created at 2023-12-29 00:47 +0100
« prev ^ index » next coverage.py v7.4.0, created at 2023-12-29 00:47 +0100
1import json
2from io import BytesIO
4import requests
5import validators
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, Recipe, Step
13class RecipeSage(Integration):
15 def get_recipe_from_file(self, file):
17 recipe = Recipe.objects.create(
18 name=file['name'].strip(),
19 created_by=self.request.user, internal=True,
20 space=self.request.space)
22 if file['recipeYield'] != '':
23 recipe.servings = parse_servings(file['recipeYield'])
24 recipe.servings_text = parse_servings_text(file['recipeYield'])
26 try:
27 if 'totalTime' in file and file['totalTime'] != '':
28 recipe.working_time = parse_time(file['totalTime'])
30 if 'timePrep' in file and file['prepTime'] != '':
31 recipe.working_time = parse_time(file['timePrep'])
32 recipe.waiting_time = parse_time(file['totalTime']) - parse_time(file['timePrep'])
33 except Exception as e:
34 print('failed to parse time ', str(e))
36 recipe.save()
38 ingredient_parser = IngredientParser(self.request, True)
39 ingredients_added = False
40 for s in file['recipeInstructions']:
41 step = Step.objects.create(
42 instruction=s['text'], space=self.request.space, show_ingredients_table=self.request.user.userpreference.show_step_ingredients,
43 )
44 if not ingredients_added:
45 ingredients_added = True
47 for ingredient in file['recipeIngredient']:
48 amount, unit, food, note = ingredient_parser.parse(ingredient)
49 f = ingredient_parser.get_food(food)
50 u = ingredient_parser.get_unit(unit)
51 step.ingredients.add(Ingredient.objects.create(
52 food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space,
53 ))
54 recipe.steps.add(step)
56 if len(file['image']) > 0:
57 try:
58 url = file['image'][0]
59 if validators.url(url, public=True):
60 response = requests.get(url)
61 self.import_recipe_image(recipe, BytesIO(response.content))
62 except Exception as e:
63 print('failed to import image ', str(e))
65 return recipe
67 def get_file_from_recipe(self, recipe):
68 data = {
69 '@context': 'http://schema.org',
70 '@type': 'Recipe',
71 'creditText': '',
72 'isBasedOn': '',
73 'name': recipe.name,
74 'description': recipe.description,
75 'prepTime': str(recipe.working_time),
76 'totalTime': str(recipe.waiting_time + recipe.working_time),
77 'recipeYield': str(recipe.servings),
78 'image': [],
79 'recipeCategory': [],
80 'comment': [],
81 'recipeIngredient': [],
82 'recipeInstructions': [],
83 }
85 for s in recipe.steps.all():
86 data['recipeInstructions'].append({
87 '@type': 'HowToStep',
88 'text': s.instruction
89 })
91 for i in s.ingredients.all():
92 data['recipeIngredient'].append(f'{float(i.amount)} {i.unit} {i.food}')
94 return data
96 def get_files_from_recipes(self, recipes, el, cookie):
97 json_list = []
98 for r in recipes:
99 json_list.append(self.get_file_from_recipe(r))
101 el.exported_recipes += 1
102 el.msg += self.get_recipe_processed_msg(r)
103 el.save()
105 return [[self.get_export_file_name('json'), json.dumps(json_list)]]
107 def split_recipe_file(self, file):
108 return json.loads(file.read().decode("utf-8"))