Example #1
0
 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))
Example #2
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)')
Example #3
0
    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))
Example #4
0
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()
Example #6
0
        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(',', '.'))
Example #7
0
    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'))
Example #8
0
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}
    )
Example #9
0
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)