retain original text when parsing ingredients

This commit is contained in:
smilerz 2022-02-21 09:47:27 -06:00
parent c1605454dd
commit e52054e732
No known key found for this signature in database
GPG Key ID: 39444C7606D47126
27 changed files with 300 additions and 319 deletions

View File

@ -6,13 +6,12 @@ from unicodedata import decomposition
from django.utils.dateparse import parse_duration
from isodate import parse_duration as iso_parse_duration
from isodate.isoerror import ISO8601Error
from recipe_scrapers._utils import get_minutes
from cookbook.helper import recipe_url_import as helper
from cookbook.helper.ingredient_parser import IngredientParser
from cookbook.models import Keyword
# from recipe_scrapers._utils import get_minutes ## temporary until/unless upstream incorporates get_minutes() PR
def get_from_scraper(scrape, request):
# converting the scrape_me object to the existing json format based on ld+json
@ -118,7 +117,7 @@ def get_from_scraper(scrape, request):
'id': random.randrange(10000, 99999)
},
'note': note,
'original': x
'original_text': x
}
)
except Exception:
@ -134,7 +133,7 @@ def get_from_scraper(scrape, request):
'id': random.randrange(10000, 99999)
},
'note': '',
'original': x
'original_text': x
}
)
recipe_json['recipeIngredient'] = ingredients
@ -200,7 +199,7 @@ def parse_ingredients(ingredients):
'id': random.randrange(10000, 99999)
},
'note': note,
'original': x
'original_text': x
}
)
except Exception:
@ -216,7 +215,7 @@ def parse_ingredients(ingredients):
'id': random.randrange(10000, 99999)
},
'note': '',
'original': x
'original_text': x
}
)
@ -367,55 +366,6 @@ def normalize_string(string):
unescaped_string = unescaped_string.replace("\xa0", " ").replace("\t", " ").strip()
return unescaped_string
# TODO deprecate when merged into recipe_scapers
def get_minutes(time_text):
if time_text is None:
return 0
TIME_REGEX = re.compile(
r"(\D*(?P<hours>\d*.?(\s\d)?\/?\d+)\s*(hours|hrs|hr|h|óra))?(\D*(?P<minutes>\d+)\s*(minutes|mins|min|m|perc))?",
re.IGNORECASE,
)
try:
return int(time_text)
except Exception:
pass
if time_text.startswith("P") and "T" in time_text:
time_text = time_text.split("T", 2)[1]
if "-" in time_text:
time_text = time_text.split("-", 2)[
1
] # sometimes formats are like this: '12-15 minutes'
if " to " in time_text:
time_text = time_text.split("to", 2)[
1
] # sometimes formats are like this: '12 to 15 minutes'
empty = ''
for x in time_text:
if 'fraction' in decomposition(x):
f = decomposition(x[-1:]).split()
empty += f" {f[1].replace('003', '')}/{f[3].replace('003', '')}"
else:
empty += x
time_text = empty
matched = TIME_REGEX.search(time_text)
minutes = int(matched.groupdict().get("minutes") or 0)
if "/" in (hours := matched.groupdict().get("hours") or ''):
number = hours.split(" ")
if len(number) == 2:
minutes += 60*int(number[0])
fraction = number[-1:][0].split("/")
minutes += 60 * float(int(fraction[0])/int(fraction[1]))
else:
minutes += 60 * float(hours)
return int(minutes)
def iso_duration_to_minutes(string):
match = re.match(

View File

@ -2,7 +2,7 @@ import re
from cookbook.helper.ingredient_parser import IngredientParser
from cookbook.integration.integration import Integration
from cookbook.models import Recipe, Step, Ingredient
from cookbook.models import Ingredient, Recipe, Step
class ChefTap(Integration):
@ -45,11 +45,11 @@ class ChefTap(Integration):
ingredient_parser = IngredientParser(self.request, True)
for ingredient in ingredients:
if len(ingredient.strip()) > 0:
amount, unit, ingredient, note = ingredient_parser.parse(ingredient)
f = ingredient_parser.get_food(ingredient)
amount, unit, food, note = ingredient_parser.parse(ingredient)
f = ingredient_parser.get_food(food)
u = ingredient_parser.get_unit(unit)
step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=amount, note=note, space=self.request.space,
food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space,
))
recipe.steps.add(step)

View File

@ -5,7 +5,7 @@ from zipfile import ZipFile
from cookbook.helper.image_processing import get_filetype
from cookbook.helper.ingredient_parser import IngredientParser
from cookbook.integration.integration import Integration
from cookbook.models import Recipe, Step, Ingredient, Keyword
from cookbook.models import Ingredient, Keyword, Recipe, Step
class Chowdown(Integration):
@ -60,12 +60,13 @@ class Chowdown(Integration):
ingredient_parser = IngredientParser(self.request, True)
for ingredient in ingredients:
amount, unit, ingredient, note = ingredient_parser.parse(ingredient)
f = ingredient_parser.get_food(ingredient)
u = ingredient_parser.get_unit(unit)
step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=amount, note=note, space=self.request.space,
))
if len(ingredient.strip()) > 0:
amount, unit, food, note = ingredient_parser.parse(ingredient)
f = ingredient_parser.get_food(food)
u = ingredient_parser.get_unit(unit)
step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space,
))
recipe.steps.add(step)
for f in self.files:

View File

@ -2,6 +2,7 @@ import base64
import gzip
import json
import re
from gettext import gettext as _
from io import BytesIO
import requests
@ -11,8 +12,7 @@ from cookbook.helper.ingredient_parser import IngredientParser
from cookbook.helper.recipe_html_import import get_recipe_from_source
from cookbook.helper.recipe_url_import import iso_duration_to_minutes
from cookbook.integration.integration import Integration
from cookbook.models import Recipe, Step, Ingredient, Keyword
from gettext import gettext as _
from cookbook.models import Ingredient, Keyword, Recipe, Step
class CookBookApp(Integration):
@ -51,11 +51,11 @@ class CookBookApp(Integration):
ingredient_parser = IngredientParser(self.request, True)
for ingredient in recipe_json['recipeIngredient']:
f = ingredient_parser.get_food(ingredient['ingredient']['text'])
u = ingredient_parser.get_unit(ingredient['unit']['text'])
step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=ingredient['amount'], note=ingredient['note'], space=self.request.space,
))
f = ingredient_parser.get_food(ingredient['ingredient']['text'])
u = ingredient_parser.get_unit(ingredient['unit']['text'])
step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=ingredient['amount'], note=ingredient['note'], space=self.request.space,
))
if len(images) > 0:
try:

View File

@ -8,7 +8,7 @@ from cookbook.helper.ingredient_parser import IngredientParser
from cookbook.helper.recipe_html_import import get_recipe_from_source
from cookbook.helper.recipe_url_import import iso_duration_to_minutes, parse_servings
from cookbook.integration.integration import Integration
from cookbook.models import Recipe, Step, Ingredient, Keyword
from cookbook.models import Ingredient, Keyword, Recipe, Step
from recipes.settings import DEBUG
@ -41,11 +41,11 @@ class CopyMeThat(Integration):
for ingredient in file.find_all("li", {"class": "recipeIngredient"}):
if ingredient.text == "":
continue
amount, unit, ingredient, note = ingredient_parser.parse(ingredient.text.strip())
f = ingredient_parser.get_food(ingredient)
amount, unit, food, note = ingredient_parser.parse(ingredient.text.strip())
f = ingredient_parser.get_food(food)
u = ingredient_parser.get_unit(unit)
step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=amount, note=note, space=self.request.space,
food=f, unit=u, amount=amount, note=note, original_text=ingredient.text.strip(), space=self.request.space,
))
for s in file.find_all("li", {"class": "instruction"}):

View File

@ -4,7 +4,7 @@ from io import BytesIO
from cookbook.helper.ingredient_parser import IngredientParser
from cookbook.integration.integration import Integration
from cookbook.models import Recipe, Step, Ingredient
from cookbook.models import Ingredient, Recipe, Step
class Domestica(Integration):
@ -37,11 +37,11 @@ class Domestica(Integration):
ingredient_parser = IngredientParser(self.request, True)
for ingredient in file['ingredients'].split('\n'):
if len(ingredient.strip()) > 0:
amount, unit, ingredient, note = ingredient_parser.parse(ingredient)
f = ingredient_parser.get_food(ingredient)
amount, unit, food, note = ingredient_parser.parse(ingredient)
f = ingredient_parser.get_food(food)
u = ingredient_parser.get_unit(unit)
step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=amount, note=note, space=self.request.space,
food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space,
))
recipe.steps.add(step)

View File

@ -6,7 +6,7 @@ from zipfile import ZipFile
from cookbook.helper.image_processing import get_filetype
from cookbook.helper.ingredient_parser import IngredientParser
from cookbook.integration.integration import Integration
from cookbook.models import Recipe, Step, Ingredient
from cookbook.models import Ingredient, Recipe, Step
class Mealie(Integration):
@ -45,12 +45,14 @@ class Mealie(Integration):
u = ingredient_parser.get_unit(ingredient['unit'])
amount = ingredient['quantity']
note = ingredient['note']
original_text = None
else:
amount, unit, ingredient, note = ingredient_parser.parse(ingredient['note'])
f = ingredient_parser.get_food(ingredient)
amount, unit, food, note = ingredient_parser.parse(ingredient['note'])
f = ingredient_parser.get_food(food)
u = ingredient_parser.get_unit(unit)
original_text = ingredient['note']
step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=amount, note=note, space=self.request.space,
food=f, unit=u, amount=amount, note=note, original_text=original_text, space=self.request.space,
))
except Exception:
pass
@ -60,7 +62,8 @@ class Mealie(Integration):
if '.zip' in f['name']:
import_zip = ZipFile(f['file'])
try:
self.import_recipe_image(recipe, BytesIO(import_zip.read(f'recipes/{recipe_json["slug"]}/images/min-original.webp')), filetype=get_filetype(f'recipes/{recipe_json["slug"]}/images/original'))
self.import_recipe_image(recipe, BytesIO(import_zip.read(f'recipes/{recipe_json["slug"]}/images/min-original.webp')),
filetype=get_filetype(f'recipes/{recipe_json["slug"]}/images/original'))
except Exception:
pass

View File

@ -2,7 +2,7 @@ import re
from cookbook.helper.ingredient_parser import IngredientParser
from cookbook.integration.integration import Integration
from cookbook.models import Recipe, Step, Ingredient, Keyword
from cookbook.models import Ingredient, Keyword, Recipe, Step
class MealMaster(Integration):
@ -45,11 +45,11 @@ class MealMaster(Integration):
ingredient_parser = IngredientParser(self.request, True)
for ingredient in ingredients:
if len(ingredient.strip()) > 0:
amount, unit, ingredient, note = ingredient_parser.parse(ingredient)
amount, unit, food, note = ingredient_parser.parse(ingredient)
f = ingredient_parser.get_food(ingredient)
u = ingredient_parser.get_unit(unit)
step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=amount, note=note, space=self.request.space,
food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space,
))
recipe.steps.add(step)

View File

@ -7,7 +7,7 @@ from cookbook.helper.image_processing import get_filetype
from cookbook.helper.ingredient_parser import IngredientParser
from cookbook.helper.recipe_url_import import iso_duration_to_minutes
from cookbook.integration.integration import Integration
from cookbook.models import Recipe, Step, Ingredient, Keyword
from cookbook.models import Ingredient, Keyword, Recipe, Step
class NextcloudCookbook(Integration):
@ -57,11 +57,11 @@ class NextcloudCookbook(Integration):
ingredient_parser = IngredientParser(self.request, True)
for ingredient in recipe_json['recipeIngredient']:
amount, unit, ingredient, note = ingredient_parser.parse(ingredient)
f = ingredient_parser.get_food(ingredient)
amount, unit, food, note = ingredient_parser.parse(ingredient)
f = ingredient_parser.get_food(food)
u = ingredient_parser.get_unit(unit)
step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=amount, note=note, space=self.request.space,
food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space,
))
recipe.steps.add(step)

View File

@ -2,7 +2,7 @@ import json
from cookbook.helper.ingredient_parser import IngredientParser
from cookbook.integration.integration import Integration
from cookbook.models import Recipe, Step, Ingredient
from cookbook.models import Ingredient, Recipe, Step
class OpenEats(Integration):

View File

@ -2,12 +2,12 @@ import base64
import gzip
import json
import re
from gettext import gettext as _
from io import BytesIO
from cookbook.helper.ingredient_parser import IngredientParser
from cookbook.integration.integration import Integration
from cookbook.models import Recipe, Step, Ingredient, Keyword
from gettext import gettext as _
from cookbook.models import Ingredient, Keyword, Recipe, Step
class Paprika(Integration):
@ -70,11 +70,11 @@ class Paprika(Integration):
try:
for ingredient in recipe_json['ingredients'].split('\n'):
if len(ingredient.strip()) > 0:
amount, unit, ingredient, note = ingredient_parser.parse(ingredient)
f = ingredient_parser.get_food(ingredient)
amount, unit, food, note = ingredient_parser.parse(ingredient)
f = ingredient_parser.get_food(food)
u = ingredient_parser.get_unit(unit)
step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=amount, note=note, space=self.request.space,
food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space,
))
except AttributeError:
pass

View File

@ -1,6 +1,6 @@
from cookbook.helper.ingredient_parser import IngredientParser
from cookbook.integration.integration import Integration
from cookbook.models import Recipe, Step, Ingredient
from cookbook.models import Ingredient, Recipe, Step
class Pepperplate(Integration):
@ -41,11 +41,11 @@ class Pepperplate(Integration):
ingredient_parser = IngredientParser(self.request, True)
for ingredient in ingredients:
if len(ingredient.strip()) > 0:
amount, unit, ingredient, note = ingredient_parser.parse(ingredient)
f = ingredient_parser.get_food(ingredient)
amount, unit, food, note = ingredient_parser.parse(ingredient)
f = ingredient_parser.get_food(food)
u = ingredient_parser.get_unit(unit)
step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=amount, note=note, space=self.request.space,
food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space,
))
recipe.steps.add(step)

View File

@ -4,7 +4,7 @@ import requests
from cookbook.helper.ingredient_parser import IngredientParser
from cookbook.integration.integration import Integration
from cookbook.models import Recipe, Step, Ingredient, Keyword
from cookbook.models import Ingredient, Keyword, Recipe, Step
class Plantoeat(Integration):
@ -56,11 +56,11 @@ class Plantoeat(Integration):
ingredient_parser = IngredientParser(self.request, True)
for ingredient in ingredients:
if len(ingredient.strip()) > 0:
amount, unit, ingredient, note = ingredient_parser.parse(ingredient)
f = ingredient_parser.get_food(ingredient)
amount, unit, food, note = ingredient_parser.parse(ingredient)
f = ingredient_parser.get_food(food)
u = ingredient_parser.get_unit(unit)
step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=amount, note=note, space=self.request.space,
food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space,
))
recipe.steps.add(step)

View File

@ -1,14 +1,15 @@
import re
import imghdr
import json
import requests
import re
from io import BytesIO
from zipfile import ZipFile
import imghdr
import requests
from cookbook.helper.image_processing import get_filetype
from cookbook.helper.ingredient_parser import IngredientParser
from cookbook.integration.integration import Integration
from cookbook.models import Recipe, Step, Ingredient, Keyword
from cookbook.models import Ingredient, Keyword, Recipe, Step
class RecetteTek(Integration):
@ -58,11 +59,11 @@ class RecetteTek(Integration):
ingredient_parser = IngredientParser(self.request, True)
for ingredient in file['ingredients'].split('\n'):
if len(ingredient.strip()) > 0:
amount, unit, ingredient, note = ingredient_parser.parse(ingredient)
amount, unit, food, note = ingredient_parser.parse(food)
f = ingredient_parser.get_food(ingredient)
u = ingredient_parser.get_unit(unit)
step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=amount, note=note, space=self.request.space,
food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space,
))
except Exception as e:
print(recipe.name, ': failed to parse recipe ingredients ', str(e))

View File

@ -1,12 +1,13 @@
import re
from bs4 import BeautifulSoup
from io import BytesIO
from zipfile import ZipFile
from bs4 import BeautifulSoup
from cookbook.helper.ingredient_parser import IngredientParser
from cookbook.helper.recipe_url_import import parse_servings, iso_duration_to_minutes
from cookbook.helper.recipe_url_import import iso_duration_to_minutes, parse_servings
from cookbook.integration.integration import Integration
from cookbook.models import Recipe, Step, Ingredient, Keyword
from cookbook.models import Ingredient, Keyword, Recipe, Step
class RecipeKeeper(Integration):
@ -45,11 +46,11 @@ class RecipeKeeper(Integration):
for ingredient in file.find("div", {"itemprop": "recipeIngredients"}).findChildren("p"):
if ingredient.text == "":
continue
amount, unit, ingredient, note = ingredient_parser.parse(ingredient.text.strip())
f = ingredient_parser.get_food(ingredient)
amount, unit, food, note = ingredient_parser.parse(ingredient.text.strip())
f = ingredient_parser.get_food(food)
u = ingredient_parser.get_unit(unit)
step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=amount, note=note, space=self.request.space,
food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space,
))
for s in file.find("div", {"itemprop": "recipeDirections"}).find_all("p"):

View File

@ -5,7 +5,7 @@ import requests
from cookbook.helper.ingredient_parser import IngredientParser
from cookbook.integration.integration import Integration
from cookbook.models import Recipe, Step, Ingredient
from cookbook.models import Ingredient, Recipe, Step
class RecipeSage(Integration):
@ -31,7 +31,7 @@ class RecipeSage(Integration):
except Exception as e:
print('failed to parse yield or time ', str(e))
ingredient_parser = IngredientParser(self.request,True)
ingredient_parser = IngredientParser(self.request, True)
ingredients_added = False
for s in file['recipeInstructions']:
step = Step.objects.create(
@ -41,11 +41,11 @@ class RecipeSage(Integration):
ingredients_added = True
for ingredient in file['recipeIngredient']:
amount, unit, ingredient, note = ingredient_parser.parse(ingredient)
f = ingredient_parser.get_food(ingredient)
amount, unit, food, note = ingredient_parser.parse(ingredient)
f = ingredient_parser.get_food(food)
u = ingredient_parser.get_unit(unit)
step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=amount, note=note, space=self.request.space,
food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space,
))
recipe.steps.add(step)

View File

@ -1,6 +1,6 @@
from cookbook.helper.ingredient_parser import IngredientParser
from cookbook.integration.integration import Integration
from cookbook.models import Recipe, Step, Ingredient, Keyword
from cookbook.models import Ingredient, Keyword, Recipe, Step
class RezKonv(Integration):
@ -44,11 +44,11 @@ class RezKonv(Integration):
ingredient_parser = IngredientParser(self.request, True)
for ingredient in ingredients:
if len(ingredient.strip()) > 0:
amount, unit, ingredient, note = ingredient_parser.parse(ingredient)
f = ingredient_parser.get_food(ingredient)
amount, unit, food, note = ingredient_parser.parse(ingredient)
f = ingredient_parser.get_food(food)
u = ingredient_parser.get_unit(unit)
step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=amount, note=note, space=self.request.space,
food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space,
))
recipe.steps.add(step)

View File

@ -2,7 +2,7 @@ from django.utils.translation import gettext as _
from cookbook.helper.ingredient_parser import IngredientParser
from cookbook.integration.integration import Integration
from cookbook.models import Recipe, Step, Ingredient
from cookbook.models import Ingredient, Recipe, Step
class Saffron(Integration):
@ -47,11 +47,11 @@ class Saffron(Integration):
ingredient_parser = IngredientParser(self.request, True)
for ingredient in ingredients:
amount, unit, ingredient, note = ingredient_parser.parse(ingredient)
f = ingredient_parser.get_food(ingredient)
amount, unit, food, note = ingredient_parser.parse(ingredient)
f = ingredient_parser.get_food(food)
u = ingredient_parser.get_unit(unit)
step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=amount, note=note, space=self.request.space,
food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space,
))
recipe.steps.add(step)
@ -76,7 +76,7 @@ class Saffron(Integration):
for i in s.ingredients.all():
recipeIngredient.append(f'{float(i.amount)} {i.unit} {i.food}')
data += "Ingredients: \n"
for ingredient in recipeIngredient:
data += ingredient+"\n"
@ -91,10 +91,10 @@ class Saffron(Integration):
files = []
for r in recipes:
filename, data = self.get_file_from_recipe(r)
files.append([ filename, data ])
files.append([filename, data])
el.exported_recipes += 1
el.msg += self.get_recipe_processed_msg(r)
el.save()
return files
return files

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.12 on 2022-02-21 15:06
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0171_alter_searchpreference_trigram_threshold'),
]
operations = [
migrations.AddField(
model_name='ingredient',
name='original_text',
field=models.CharField(blank=True, max_length=256, null=True),
),
]

View File

@ -590,6 +590,7 @@ class Ingredient(ExportModelOperationsMixin('ingredient'), models.Model, Permiss
is_header = models.BooleanField(default=False)
no_amount = models.BooleanField(default=False)
order = models.IntegerField(default=0)
original_text = models.CharField(max_length=256, null=True, blank=True)
space = models.ForeignKey(Space, on_delete=models.CASCADE)
objects = ScopedManager(space='space')

View File

@ -479,11 +479,15 @@ class IngredientSerializer(WritableNestedModelSerializer):
validated_data['space'] = self.context['request'].space
return super().create(validated_data)
def update(self, instance, validated_data):
validated_data.pop('original_text', None)
return super().update(instance, validated_data)
class Meta:
model = Ingredient
fields = (
'id', 'food', 'unit', 'amount', 'note', 'order',
'is_header', 'no_amount'
'is_header', 'no_amount', 'original_text'
)
@ -678,7 +682,7 @@ class RecipeBookEntrySerializer(serializers.ModelSerializer):
def create(self, validated_data):
book = validated_data['book']
recipe = validated_data['recipe']
if not book.get_owner() == self.context['request'].user and not self.context['request'].user in book.get_shared():
if not book.get_owner() == self.context['request'].user and not self.context['request'].user in book.get_shared():
raise NotFound(detail=None, code=None)
obj, created = RecipeBookEntry.objects.get_or_create(book=book, recipe=recipe)
return obj
@ -733,11 +737,11 @@ class ShoppingListRecipeSerializer(serializers.ModelSerializer):
value = Decimal(value)
value = value.quantize(Decimal(1)) if value == value.to_integral() else value.normalize() # strips trailing zero
return (
obj.name
or getattr(obj.mealplan, 'title', None)
or (d := getattr(obj.mealplan, 'date', None)) and ': '.join([obj.mealplan.recipe.name, str(d)])
or obj.recipe.name
) + f' ({value:.2g})'
obj.name
or getattr(obj.mealplan, 'title', None)
or (d := getattr(obj.mealplan, 'date', None)) and ': '.join([obj.mealplan.recipe.name, str(d)])
or obj.recipe.name
) + f' ({value:.2g})'
def update(self, instance, validated_data):
# TODO remove once old shopping list

View File

@ -473,9 +473,9 @@
<div class="card" style="margin-top: 4px">
<div class="card-body">
<div class="row" v-if="i.original">
<div class="row" v-if="i.original_text">
<div class="col-md-12" style="margin-bottom: 4px">
<span class="text-muted"><i class="fas fa-globe"></i> [[i.original]]</span>
<span class="text-muted"><i class="fas fa-globe"></i> [[i.original_text]]</span>
</div>
</div>
<div class="row">
@ -1024,7 +1024,7 @@
amount: String(response.body.amount),
ingredient: {id: Math.random() * 1000, text: response.body.food},
note: response.body.note,
original: v
original_text: v
}
this.recipe_json.recipeIngredient.push(new_ingredient)
}).catch((err) => {

File diff suppressed because it is too large Load Diff

View File

@ -156,7 +156,7 @@ def import_url(request):
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
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:
@ -168,7 +168,8 @@ def import_url(request):
ingredient_parser = IngredientParser(request, True)
for ing in data['recipeIngredient']:
ingredient = Ingredient(space=request.space, )
original = ing.pop('original', None) or ing.pop('original_text', None)
ingredient = Ingredient(original_text=original, space=request.space, )
if food_text := ing['ingredient']['text'].strip():
ingredient.food = ingredient_parser.get_food(food_text)

View File

@ -48,11 +48,11 @@ def hook(request, token):
request.space = tb.space # TODO this is likely a bad idea. Verify and test
request.user = tb.created_by
ingredient_parser = IngredientParser(request, False)
amount, unit, ingredient, note = ingredient_parser.parse(data['message']['text'])
f = ingredient_parser.get_food(ingredient)
amount, unit, food, note = ingredient_parser.parse(data['message']['text'])
f = ingredient_parser.get_food(food)
u = ingredient_parser.get_unit(unit)
ShoppingListEntry.objects.create(food=f, unit=u, amount=amount, created_by=request.user, space=request.space)
ShoppingListEntry.objects.create(food=f, unit=u, amount=amount, original_text=ingredient, created_by=request.user, space=request.space)
return JsonResponse({'data': data['message']['text']})
except Exception:

View File

@ -30,7 +30,7 @@ Jinja2==3.0.3
django-webpack-loader==1.4.1
django-js-reverse==0.9.1
django-allauth==0.47.0
recipe-scrapers==13.16.0
recipe-scrapers==13.18.0
django-scopes==1.2.0
pytest==6.2.5
pytest-django==4.5.2

View File

@ -983,6 +983,7 @@ export default {
unit: unit,
food: { name: result.data.food },
note: result.data.note,
original_text: ing,
})
})
order++