diff --git a/cookbook/helper/ingredient_parser.py b/cookbook/helper/ingredient_parser.py index 7c4041f75..61d2a9db2 100644 --- a/cookbook/helper/ingredient_parser.py +++ b/cookbook/helper/ingredient_parser.py @@ -1,6 +1,8 @@ import string import unicodedata +from cookbook.models import Unit, Food + def parse_fraction(x): if len(x) == 1 and 'fraction' in unicodedata.decomposition(x): @@ -157,3 +159,18 @@ def parse(x): except ValueError: ingredient = ' '.join(tokens[1:]) return amount, unit.strip(), ingredient.strip(), note.strip() + + +# small utility functions to prevent emtpy unit/food creation +def get_unit(unit, space): + if len(unit) > 0: + u, created = Unit.objects.get_or_create(name=unit, space=space) + return u + return None + + +def get_food(food, space): + if len(food) > 0: + f, created = Food.objects.get_or_create(name=food, space=space) + return f + return None diff --git a/cookbook/integration/chowdown.py b/cookbook/integration/chowdown.py index b00663271..05e283556 100644 --- a/cookbook/integration/chowdown.py +++ b/cookbook/integration/chowdown.py @@ -3,7 +3,7 @@ import re from io import BytesIO from zipfile import ZipFile -from cookbook.helper.ingredient_parser import parse +from cookbook.helper.ingredient_parser import parse, get_food, get_unit from cookbook.integration.integration import Integration from cookbook.models import Recipe, Step, Food, Unit, Ingredient, Keyword @@ -59,8 +59,8 @@ class Chowdown(Integration): for ingredient in ingredients: amount, unit, ingredient, note = parse(ingredient) - f, created = Food.objects.get_or_create(name=ingredient, space=self.request.space) - u, created = Unit.objects.get_or_create(name=unit, space=self.request.space) + f = get_food(ingredient, self.request.space) + u = get_unit(unit, self.request.space) step.ingredients.add(Ingredient.objects.create( food=f, unit=u, amount=amount, note=note )) diff --git a/cookbook/integration/integration.py b/cookbook/integration/integration.py index 39d08c2b8..95cfbafb4 100644 --- a/cookbook/integration/integration.py +++ b/cookbook/integration/integration.py @@ -28,7 +28,7 @@ class Integration: self.request = request self.keyword = Keyword.objects.create( name=f'Import {export_type} {date_format(datetime.datetime.now(), "DATETIME_FORMAT")}.{datetime.datetime.now().strftime("%S")}', - description=f'Imported by {request.user.get_user_name()} at {date_format(datetime.datetime.now(), "DATETIME_FORMAT")}', + description=f'Imported by {request.user.get_user_name()} at {date_format(datetime.datetime.now(), "DATETIME_FORMAT")}. Type: {export_type}', icon='📥', space=request.space ) @@ -85,6 +85,9 @@ class Integration: :return: HttpResponseRedirect to the recipe search showing all imported recipes """ with scope(space=self.request.space): + self.keyword.name = _('Import') + ' ' + str(il.pk) + self.keyword.save() + ignored_recipes = [] try: self.files = files diff --git a/cookbook/integration/mealie.py b/cookbook/integration/mealie.py index 207e130a2..198883c88 100644 --- a/cookbook/integration/mealie.py +++ b/cookbook/integration/mealie.py @@ -3,7 +3,7 @@ import re from io import BytesIO from zipfile import ZipFile -from cookbook.helper.ingredient_parser import parse +from cookbook.helper.ingredient_parser import parse, get_food, get_unit from cookbook.integration.integration import Integration from cookbook.models import Recipe, Step, Food, Unit, Ingredient @@ -32,8 +32,8 @@ class Mealie(Integration): for ingredient in recipe_json['recipeIngredient']: amount, unit, ingredient, note = parse(ingredient) - f, created = Food.objects.get_or_create(name=ingredient, space=self.request.space) - u, created = Unit.objects.get_or_create(name=unit, space=self.request.space) + f = get_food(ingredient, self.request.space) + u = get_unit(unit, self.request.space) step.ingredients.add(Ingredient.objects.create( food=f, unit=u, amount=amount, note=note )) diff --git a/cookbook/integration/nextcloud_cookbook.py b/cookbook/integration/nextcloud_cookbook.py index 24d1d998e..6857032ad 100644 --- a/cookbook/integration/nextcloud_cookbook.py +++ b/cookbook/integration/nextcloud_cookbook.py @@ -3,7 +3,7 @@ import re from io import BytesIO from zipfile import ZipFile -from cookbook.helper.ingredient_parser import parse +from cookbook.helper.ingredient_parser import parse, get_food, get_unit from cookbook.integration.integration import Integration from cookbook.models import Recipe, Step, Food, Unit, Ingredient @@ -34,8 +34,8 @@ class NextcloudCookbook(Integration): for ingredient in recipe_json['recipeIngredient']: amount, unit, ingredient, note = parse(ingredient) - f, created = Food.objects.get_or_create(name=ingredient, space=self.request.space) - u, created = Unit.objects.get_or_create(name=unit, space=self.request.space) + f = get_food(ingredient, self.request.space) + u = get_unit(unit, self.request.space) step.ingredients.add(Ingredient.objects.create( food=f, unit=u, amount=amount, note=note )) diff --git a/cookbook/integration/paprika.py b/cookbook/integration/paprika.py index 26fd6b86d..b9dab1055 100644 --- a/cookbook/integration/paprika.py +++ b/cookbook/integration/paprika.py @@ -7,7 +7,7 @@ from zipfile import ZipFile import microdata from bs4 import BeautifulSoup -from cookbook.helper.ingredient_parser import parse +from cookbook.helper.ingredient_parser import parse, get_food, get_unit from cookbook.helper.recipe_url_import import find_recipe_json from cookbook.integration.integration import Integration from cookbook.models import Recipe, Step, Food, Ingredient, Unit @@ -33,8 +33,8 @@ class Paprika(Integration): for ingredient in recipe_json['ingredients'].split('\n'): amount, unit, ingredient, note = parse(ingredient) - f, created = Food.objects.get_or_create(name=ingredient, space=self.request.space) - u, created = Unit.objects.get_or_create(name=unit, space=self.request.space) + f = get_food(ingredient, self.request.space) + u = get_unit(unit, self.request.space) step.ingredients.add(Ingredient.objects.create( food=f, unit=u, amount=amount, note=note )) diff --git a/cookbook/integration/safron.py b/cookbook/integration/safron.py index c2cb90aaa..f3c439a38 100644 --- a/cookbook/integration/safron.py +++ b/cookbook/integration/safron.py @@ -1,6 +1,6 @@ from django.utils.translation import gettext as _ -from cookbook.helper.ingredient_parser import parse +from cookbook.helper.ingredient_parser import parse, get_food, get_unit from cookbook.integration.integration import Integration from cookbook.models import Recipe, Step, Food, Unit, Ingredient @@ -47,8 +47,8 @@ class Safron(Integration): for ingredient in ingredients: amount, unit, ingredient, note = parse(ingredient) - f, created = Food.objects.get_or_create(name=ingredient, space=self.request.space) - u, created = Unit.objects.get_or_create(name=unit, space=self.request.space) + f = get_food(ingredient, self.request.space) + u = get_unit(unit, self.request.space) step.ingredients.add(Ingredient.objects.create( food=f, unit=u, amount=amount, note=note )) diff --git a/cookbook/migrations/0116_auto_20210319_0012.py b/cookbook/migrations/0116_auto_20210319_0012.py new file mode 100644 index 000000000..898a1fc2c --- /dev/null +++ b/cookbook/migrations/0116_auto_20210319_0012.py @@ -0,0 +1,40 @@ +# Generated by Django 3.1.7 on 2021-03-18 23:12 + +from django.db import migrations +from django_scopes import scopes_disabled + + +def remove_empty_food_unit(apps, schema_editor): + with scopes_disabled(): + Ingredient = apps.get_model('cookbook', 'Ingredient') + ShoppingListEntry = apps.get_model('cookbook', 'ShoppingListEntry') + + Food = apps.get_model('cookbook', 'Food') + Unit = apps.get_model('cookbook', 'Unit') + + for f in Food.objects.filter(name='').all(): + for o in Ingredient.objects.filter(food=f): + o.food = None + o.save() + + for o in ShoppingListEntry.objects.filter(food=f): + o.delete() + + for u in Unit.objects.filter(name='').all(): + for o in Ingredient.objects.filter(unit=u): + o.unit = None + o.save() + + for o in ShoppingListEntry.objects.filter(unit=u): + o.unit = None + o.save() + + +class Migration(migrations.Migration): + dependencies = [ + ('cookbook', '0115_telegrambot'), + ] + + operations = [ + migrations.RunPython(remove_empty_food_unit), + ] diff --git a/cookbook/views/telegram.py b/cookbook/views/telegram.py index 03410c953..25ea3ee91 100644 --- a/cookbook/views/telegram.py +++ b/cookbook/views/telegram.py @@ -6,7 +6,7 @@ from django.http import JsonResponse from django.shortcuts import render, get_object_or_404 from django.views.decorators.csrf import csrf_exempt -from cookbook.helper.ingredient_parser import parse +from cookbook.helper.ingredient_parser import parse, get_unit, get_food from cookbook.helper.permission_helper import group_required from cookbook.models import TelegramBot, ShoppingList, ShoppingListEntry, Food, Unit @@ -50,8 +50,8 @@ def hook(request, token): sl = ShoppingList.objects.create(created_by=tb.created_by, space=tb.space) amount, unit, ingredient, note = parse(data['message']['text']) - f, created = Food.objects.get_or_create(name=ingredient, space=tb.space) - u, created = Unit.objects.get_or_create(name=unit, space=tb.space) + f = get_food(ingredient, tb.space) + u = get_unit(unit, tb.space) sl.entries.add( ShoppingListEntry.objects.create( food=f, unit=u, amount=amount