def test_ingredient_nutrition_info_recalculation_from_different_unit(self): """Recalculate IngredientNutritionInfo with different units on save. """ pancakes = Recipe.objects.get(name='Pancakes') # A food that we don't have nutrition info for yet nuts, created = Food.objects.get_or_create(name='nuts') tablespoon = Unit.objects.get(name='tablespoon') teaspoon = Unit.objects.get(name='teaspoon') # NutritionInfo in terms of a different unit nuts_NI, created = FoodNutritionInfo.objects.get_or_create( food=nuts, quantity=1, unit=teaspoon, calories=50) # Create an ingredient tablespoon_nuts = Ingredient(recipe=pancakes, quantity=1, unit=tablespoon, food=nuts) tablespoon_nuts.save() # Ensure correct nutrition was calculated self.assertTrue(tablespoon_nuts.nutrition_info.is_equal(nuts_NI * 3.0))
def test_ingredient_string(self): """Format Ingredient as a string. """ pancakes = Recipe.objects.get(name='Pancakes') egg = Food.objects.get(name='egg') butter = Food.objects.get(name='butter') ounce = Unit.objects.get(name='ounce') beaten, created = Preparation.objects.get_or_create(name='beaten') melted, created = Preparation.objects.get_or_create(name='melted') # quantity == 1 eggs = Ingredient(recipe=pancakes, quantity=1, food=egg) self.assertEqual(str(eggs), '1 egg') # quantity > 1 eggs.quantity = 2 self.assertEqual(str(eggs), '2 eggs') # with preparation eggs.preparation = beaten self.assertEqual(str(eggs), '2 eggs, beaten') # with preparation, and optional eggs.optional = True self.assertEqual(str(eggs), '2 eggs, beaten (optional)') # Ingredient with units # quantity == 1 ounces_butter = Ingredient(recipe=pancakes, quantity=1, unit=ounce, food=butter) self.assertEqual(str(ounces_butter), '1 ounce butter') # quantity > 1 ounces_butter.quantity = 8 self.assertEqual(str(ounces_butter), '8 ounces butter') # optional ounces_butter.optional = True self.assertEqual(str(ounces_butter), '8 ounces butter (optional)') # optional, with preparation ounces_butter.preparation = melted self.assertEqual(str(ounces_butter), '8 ounces butter, melted (optional)')
def test_ingredient_nutrition_info_recalculation(self): """Recalculate IngredientNutritionInfo on save. """ egg = Food.objects.get(name='egg') pancakes = Recipe.objects.get(name='Pancakes') # Create an ingredient eggs = Ingredient(recipe=pancakes, quantity=2, food=egg) eggs.save() egg_NI = FoodNutritionInfo.objects.get(food=egg, quantity=1, unit=None) # Nutrition info should equal 2 eggs total_NI = egg_NI * 2.0 self.assertTrue(eggs.nutrition_info.is_equal(total_NI)) # Make it 3 eggs eggs.quantity = 3 eggs.save() # Ensure nutrition reflects 3 eggs now total_NI = egg_NI * 3.0 self.assertTrue(eggs.nutrition_info.is_equal(total_NI))
def internal_recipe_update(request, pk): recipe_instance = get_object_or_404(Recipe, pk=pk) status = 200 if request.method == "POST": form = InternalRecipeForm(request.POST, request.FILES) form.instance = recipe_instance if form.is_valid(): recipe = recipe_instance recipe.name = form.cleaned_data['name'] recipe.instructions = form.cleaned_data['instructions'] recipe.working_time = form.cleaned_data['working_time'] recipe.waiting_time = form.cleaned_data['waiting_time'] if form.cleaned_data['image']: recipe.image = form.cleaned_data['image'] img = Image.open(recipe.image) basewidth = 720 wpercent = (basewidth / float(img.size[0])) hsize = int((float(img.size[1]) * float(wpercent))) img = img.resize((basewidth, hsize), Image.ANTIALIAS) im_io = BytesIO() img.save(im_io, 'PNG', quality=70) recipe.image = File(im_io, name=f'{uuid.uuid4()}_{recipe.pk}.png') elif 'image' in form.changed_data and form.cleaned_data[ 'image'] is False: recipe.image = None recipe.save() try: form_ingredients = json.loads(form.cleaned_data['ingredients']) except simplejson.errors.JSONDecodeError: form_ingredients = [] RecipeIngredient.objects.filter(recipe=recipe_instance).delete() for i in form_ingredients: recipe_ingredient = RecipeIngredient() recipe_ingredient.recipe = recipe_instance if 'note' in i: recipe_ingredient.note = i['note'] if Ingredient.objects.filter( name=i['ingredient__name']).exists(): recipe_ingredient.ingredient = Ingredient.objects.get( name=i['ingredient__name']) else: ingredient = Ingredient() ingredient.name = i['ingredient__name'] ingredient.save() recipe_ingredient.ingredient = ingredient if isinstance(i['amount'], str): try: recipe_ingredient.amount = float(i['amount'].replace( ',', '.')) except ValueError: form.add_error( "ingredients", _('There was an error converting your ingredients amount to a number: ' ) + i['unit__name']) else: recipe_ingredient.amount = i['amount'] if Unit.objects.filter(name=i['unit__name']).exists(): recipe_ingredient.unit = Unit.objects.get( name=i['unit__name']) else: unit = Unit() unit.name = i['unit__name'] unit.save() recipe_ingredient.unit = unit recipe_ingredient.save() recipe.keywords.set(form.cleaned_data['keywords']) messages.add_message(request, messages.SUCCESS, _('Recipe saved!')) else: messages.add_message(request, messages.ERROR, _('There was an error saving this recipe!')) status = 403 else: form = InternalRecipeForm(instance=recipe_instance) ingredients = RecipeIngredient.objects.select_related( 'unit__name', 'ingredient__name').filter(recipe=recipe_instance).values( 'ingredient__name', 'unit__name', 'amount', 'note').order_by('id') return render(request, 'forms/edit_internal_recipe.html', { 'form': form, 'ingredients': json.dumps(list(ingredients)), 'view_url': reverse('view_recipe', args=[pk]) }, status=status)
def test_create(self): before = len(Ingredient.query.all()) i = Ingredient(name='carrots') db.session.add(i) db.session.commit()
step = Step.objects.create( instruction=data['recipeInstructions'], ) recipe.steps.add(step) for kw in data['keywords']: if k := Keyword.objects.filter(name=kw['text']).first(): recipe.keywords.add(k) elif data['all_keywords']: k = Keyword.objects.create(name=kw['text']) recipe.keywords.add(k) for ing in data['recipeIngredient']: ingredient = Ingredient() if ing['ingredient']['text'] != '': ingredient.food, f_created = Food.objects.get_or_create( name=ing['ingredient']['text'] ) if ing['unit'] and ing['unit']['text'] != '': ingredient.unit, u_created = Unit.objects.get_or_create( name=ing['unit']['text'] ) # TODO properly handle no_amount recipes if isinstance(ing['amount'], str): try: ingredient.amount = float(ing['amount'].replace(',', '.'))
def handle(self, *args, **options): default_categories = [ 'Pizza', 'Asian', 'Burgers', 'Barbecue', 'Desserts', 'Thai', 'Sushi', 'Others', ] for category in default_categories: try: c = FoodCategory(name=category) c.save() except Exception as e: raise CommandError('Error when trying to seed \n %s' % e.msg) default_ingredients = [ { 'name': 'Mozzarella Cheese', 'article_number': '15O1A0351K', 'unit': 'G', 'amount': 500, 'cost': 12, }, { 'name': 'Flour', 'article_number': 'K1595SDF', 'unit': 'KG', 'amount': 1, 'cost': 3, }, { 'name': 'Tomato', 'article_number': 'G19D1HO', 'unit': 'KG', 'amount': 1, 'cost': 7, }, { 'name': 'Basil', 'article_number': 'OA91UIVD', 'unit': 'G', 'amount': 50, 'cost': 0.4, }, ] for ingredient in default_ingredients: try: i = Ingredient(name=ingredient['name'], article_number=ingredient['article_number'], unit=ingredient['unit'], amount=ingredient['amount'], cost=ingredient['cost']) i.save() except Exception as e: raise CommandError('Error when trying to seed \n %s' % e.msg) default_recipe = { 'name': 'Marguerita', 'image': 'https://imagesvc.meredithcorp.io/v3/mm/image?url=https%3A%2F%2Fcdn-image.myrecipes.com%2Fsites%2Fdefault%2Ffiles%2Fstyles%2Fmedium_2x%2Fpublic%2Fimage%2Frecipes%2Foh%2F12%2Fmozzarella-and-basil-pizza-oh-x.jpg%3Fitok%3D3jn_M-VX&w=450&c=sc&poi=face&q=85', 'description': 'An easy pizza recipe with unbeatable flavor!', 'instructions': 'This margherita pizza recipe begins with homemade pizza dough. Top with fresh mozzarella and tomatoes, then finish it off with garden-fresh basil.', 'servings': 4, 'difficulty': 1, 'time': 2, 'category': FoodCategory.objects.get(name='Pizza'), } try: r = Recipe( name=default_recipe['name'], image=default_recipe['image'], description=default_recipe['description'], instructions=default_recipe['instructions'], servings=default_recipe['servings'], difficulty=default_recipe['difficulty'], time=default_recipe['time'], category=default_recipe['category'], ) r.save() ingredients = Ingredient.objects.all() for ingredient in ingredients: amount_used = 0 if ingredient.unit == 'KG' or ingredient.unit == 'L': amount_used = random.randint(1, 5) else: amount_used = random.randint(100, 1000) ri = RecipeIngredient(ingredient=ingredient, recipe=r, amount_used=amount_used) ri.save() except Exception as e: raise CommandError('Error when trying to seed \n %s' % e.msg) self.stdout.write( self.style.SUCCESS('Successfully seeded the database'))
def addDishData(request): new_ingredients_response = [] new_categories_response = [] data = json.loads(request.body.decode("utf-8")) # print(json.dumps(data, indent=4, sort_keys=True)) ### TO BE REMOVED general_data = data["general"] ingredients_data = data["ingredients"] recipe_data = data["recipe"] categories_data = data["categories"] # check if password is correct if general_data["password"] != password: return JsonResponse({"result": "invalid pssword"}) # validate data if not general_data["name"]: return JsonResponse({"result": "missing dish name"}) if not ingredients_data["selected"]: return JsonResponse({"result": "ingredients weren't defined"}) # create new dish dish = Dish( name=general_data["name"], type=general_data["type"], recipe=json.dumps(recipe_data), last_done_date=date(2000, 1, 1), ) dish.save() # process new ingredients definitions if ingredients_data["added"]: all_ingredients = Ingredient.objects.values_list("name", flat=True) all_ingredient_names_set = set(all_ingredients) new_ingredients = ingredients_data["added"] new_ingredient_names_set = {i[0] for i in new_ingredients} new_ingredient_names_set -= all_ingredient_names_set if new_ingredient_names_set: for i in new_ingredients: if i[0] not in new_ingredient_names_set: continue # find ingredient type try: ingredient_type = IngredientType.objects.get(pk=i[1]) except ObjectDoesNotExist: continue # find ingredient unit try: ingredient_unit = IngredientUnit.objects.get(pk=i[3]) except ObjectDoesNotExist: continue ingredient = Ingredient( name=i[0], category_type=ingredient_type, default_quantity=i[2], default_unit=ingredient_unit ) ingredient.save() new_ingredients_response.append({"id": ingredient.id, "name": ingredient.name}) # add all dish ingredients order_index = 0 for i in ingredients_data["selected"]: # find ingredient record try: ingredient = Ingredient.objects.get(name__iexact=i[0]) except ObjectDoesNotExist: message = "missing {0} dish ingredient".format(i[0]) return JsonResponse({"result": message}) # find ingredient unit record try: ingredient_unit = IngredientUnit.objects.get(pk__iexact=i[2]) except ObjectDoesNotExist: message = "missing {0} ingredient unit".format(i[2]) return JsonResponse({"result": message}) # add dish ingredient dish_ingredient = DishIngredient( dish=dish, ingredient=ingredient, quantity=i[1], unit=ingredient_unit, sequential_number=chr(order_index) ) order_index += 1 dish_ingredient.save() # process new category definitions if categories_data["added"]: all_categories = Category.objects.values_list("name", flat=True) all_categories_names_set = set(all_categories) new_categories_names_set = set(categories_data["added"]) new_categories_names_set -= all_categories_names_set for category_name in new_categories_names_set: category = Category(name=category_name) category.save() new_categories_response.append({"id": category.id, "name": category.name}) # add all dish categories if categories_data["selected"]: order_index = 0 for category_name in categories_data["selected"]: # find category record try: category = Category.objects.get(name__iexact=category_name) except ObjectDoesNotExist: continue dish_category = DishCategory(dish=dish, category=category, sequential_number=chr(order_index)) order_index += 1 return JsonResponse( {"result": "ok", "new_ingredients": new_ingredients_response, "new_categories": new_categories_response} )
def import_url(request): if request.space.max_recipes != 0 and Recipe.objects.filter( space=request.space ).count( ) >= request.space.max_recipes: # TODO move to central helper function messages.add_message( request, messages.WARNING, _('You have reached the maximum number of recipes for your space.') ) return HttpResponseRedirect(reverse('index')) if request.space.max_users != 0 and UserPreference.objects.filter( space=request.space).count() > request.space.max_users: messages.add_message( request, messages.WARNING, _('You have more users than allowed in your space.')) return HttpResponseRedirect(reverse('index')) if request.method == 'POST': data = json.loads(request.body) data['cookTime'] = parse_cooktime(data.get('cookTime', '')) data['prepTime'] = parse_cooktime(data.get('prepTime', '')) recipe = Recipe.objects.create( name=data['name'], description=data['description'], waiting_time=data['cookTime'], working_time=data['prepTime'], servings=data['servings'], internal=True, created_by=request.user, space=request.space, ) step = Step.objects.create( instruction=data['recipeInstructions'], space=request.space, ) recipe.steps.add(step) for kw in data['keywords']: if data['all_keywords']: # do not remove this check :) https://github.com/vabene1111/recipes/issues/645 k, created = Keyword.objects.get_or_create(name=kw['text'], space=request.space) recipe.keywords.add(k) else: try: k = Keyword.objects.get(name=kw['text'], space=request.space) recipe.keywords.add(k) except ObjectDoesNotExist: pass ingredient_parser = IngredientParser(request, True) for ing in data['recipeIngredient']: ingredient = Ingredient(space=request.space, ) if food_text := ing['ingredient']['text'].strip(): ingredient.food = ingredient_parser.get_food(food_text) if ing['unit']: if unit_text := ing['unit']['text'].strip(): ingredient.unit = ingredient_parser.get_unit(unit_text) # TODO properly handle no_amount recipes if isinstance(ing['amount'], str): try: ingredient.amount = float(ing['amount'].replace(',', '.')) except ValueError: ingredient.no_amount = True pass elif isinstance(ing['amount'], float) \ or isinstance(ing['amount'], int): ingredient.amount = ing['amount'] ingredient.note = ing['note'].strip() if 'note' in ing else '' ingredient.save() step.ingredients.add(ingredient)