retain original text when parsing ingredients
This commit is contained in:
parent
c1605454dd
commit
e52054e732
@ -6,13 +6,12 @@ from unicodedata import decomposition
|
|||||||
from django.utils.dateparse import parse_duration
|
from django.utils.dateparse import parse_duration
|
||||||
from isodate import parse_duration as iso_parse_duration
|
from isodate import parse_duration as iso_parse_duration
|
||||||
from isodate.isoerror import ISO8601Error
|
from isodate.isoerror import ISO8601Error
|
||||||
|
from recipe_scrapers._utils import get_minutes
|
||||||
|
|
||||||
from cookbook.helper import recipe_url_import as helper
|
from cookbook.helper import recipe_url_import as helper
|
||||||
from cookbook.helper.ingredient_parser import IngredientParser
|
from cookbook.helper.ingredient_parser import IngredientParser
|
||||||
from cookbook.models import Keyword
|
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):
|
def get_from_scraper(scrape, request):
|
||||||
# converting the scrape_me object to the existing json format based on ld+json
|
# 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)
|
'id': random.randrange(10000, 99999)
|
||||||
},
|
},
|
||||||
'note': note,
|
'note': note,
|
||||||
'original': x
|
'original_text': x
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
@ -134,7 +133,7 @@ def get_from_scraper(scrape, request):
|
|||||||
'id': random.randrange(10000, 99999)
|
'id': random.randrange(10000, 99999)
|
||||||
},
|
},
|
||||||
'note': '',
|
'note': '',
|
||||||
'original': x
|
'original_text': x
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
recipe_json['recipeIngredient'] = ingredients
|
recipe_json['recipeIngredient'] = ingredients
|
||||||
@ -200,7 +199,7 @@ def parse_ingredients(ingredients):
|
|||||||
'id': random.randrange(10000, 99999)
|
'id': random.randrange(10000, 99999)
|
||||||
},
|
},
|
||||||
'note': note,
|
'note': note,
|
||||||
'original': x
|
'original_text': x
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
@ -216,7 +215,7 @@ def parse_ingredients(ingredients):
|
|||||||
'id': random.randrange(10000, 99999)
|
'id': random.randrange(10000, 99999)
|
||||||
},
|
},
|
||||||
'note': '',
|
'note': '',
|
||||||
'original': x
|
'original_text': x
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -367,55 +366,6 @@ def normalize_string(string):
|
|||||||
unescaped_string = unescaped_string.replace("\xa0", " ").replace("\t", " ").strip()
|
unescaped_string = unescaped_string.replace("\xa0", " ").replace("\t", " ").strip()
|
||||||
return unescaped_string
|
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):
|
def iso_duration_to_minutes(string):
|
||||||
match = re.match(
|
match = re.match(
|
||||||
|
@ -2,7 +2,7 @@ import re
|
|||||||
|
|
||||||
from cookbook.helper.ingredient_parser import IngredientParser
|
from cookbook.helper.ingredient_parser import IngredientParser
|
||||||
from cookbook.integration.integration import Integration
|
from cookbook.integration.integration import Integration
|
||||||
from cookbook.models import Recipe, Step, Ingredient
|
from cookbook.models import Ingredient, Recipe, Step
|
||||||
|
|
||||||
|
|
||||||
class ChefTap(Integration):
|
class ChefTap(Integration):
|
||||||
@ -45,11 +45,11 @@ class ChefTap(Integration):
|
|||||||
ingredient_parser = IngredientParser(self.request, True)
|
ingredient_parser = IngredientParser(self.request, True)
|
||||||
for ingredient in ingredients:
|
for ingredient in ingredients:
|
||||||
if len(ingredient.strip()) > 0:
|
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)
|
f = ingredient_parser.get_food(food)
|
||||||
u = ingredient_parser.get_unit(unit)
|
u = ingredient_parser.get_unit(unit)
|
||||||
step.ingredients.add(Ingredient.objects.create(
|
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)
|
recipe.steps.add(step)
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ from zipfile import ZipFile
|
|||||||
from cookbook.helper.image_processing import get_filetype
|
from cookbook.helper.image_processing import get_filetype
|
||||||
from cookbook.helper.ingredient_parser import IngredientParser
|
from cookbook.helper.ingredient_parser import IngredientParser
|
||||||
from cookbook.integration.integration import Integration
|
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):
|
class Chowdown(Integration):
|
||||||
@ -60,11 +60,12 @@ class Chowdown(Integration):
|
|||||||
|
|
||||||
ingredient_parser = IngredientParser(self.request, True)
|
ingredient_parser = IngredientParser(self.request, True)
|
||||||
for ingredient in ingredients:
|
for ingredient in ingredients:
|
||||||
amount, unit, ingredient, note = ingredient_parser.parse(ingredient)
|
if len(ingredient.strip()) > 0:
|
||||||
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)
|
u = ingredient_parser.get_unit(unit)
|
||||||
step.ingredients.add(Ingredient.objects.create(
|
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)
|
recipe.steps.add(step)
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ import base64
|
|||||||
import gzip
|
import gzip
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
|
from gettext import gettext as _
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
import requests
|
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_html_import import get_recipe_from_source
|
||||||
from cookbook.helper.recipe_url_import import iso_duration_to_minutes
|
from cookbook.helper.recipe_url_import import iso_duration_to_minutes
|
||||||
from cookbook.integration.integration import Integration
|
from cookbook.integration.integration import Integration
|
||||||
from cookbook.models import Recipe, Step, Ingredient, Keyword
|
from cookbook.models import Ingredient, Keyword, Recipe, Step
|
||||||
from gettext import gettext as _
|
|
||||||
|
|
||||||
|
|
||||||
class CookBookApp(Integration):
|
class CookBookApp(Integration):
|
||||||
|
@ -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_html_import import get_recipe_from_source
|
||||||
from cookbook.helper.recipe_url_import import iso_duration_to_minutes, parse_servings
|
from cookbook.helper.recipe_url_import import iso_duration_to_minutes, parse_servings
|
||||||
from cookbook.integration.integration import Integration
|
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
|
from recipes.settings import DEBUG
|
||||||
|
|
||||||
|
|
||||||
@ -41,11 +41,11 @@ class CopyMeThat(Integration):
|
|||||||
for ingredient in file.find_all("li", {"class": "recipeIngredient"}):
|
for ingredient in file.find_all("li", {"class": "recipeIngredient"}):
|
||||||
if ingredient.text == "":
|
if ingredient.text == "":
|
||||||
continue
|
continue
|
||||||
amount, unit, ingredient, note = ingredient_parser.parse(ingredient.text.strip())
|
amount, unit, food, note = ingredient_parser.parse(ingredient.text.strip())
|
||||||
f = ingredient_parser.get_food(ingredient)
|
f = ingredient_parser.get_food(food)
|
||||||
u = ingredient_parser.get_unit(unit)
|
u = ingredient_parser.get_unit(unit)
|
||||||
step.ingredients.add(Ingredient.objects.create(
|
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"}):
|
for s in file.find_all("li", {"class": "instruction"}):
|
||||||
|
@ -4,7 +4,7 @@ from io import BytesIO
|
|||||||
|
|
||||||
from cookbook.helper.ingredient_parser import IngredientParser
|
from cookbook.helper.ingredient_parser import IngredientParser
|
||||||
from cookbook.integration.integration import Integration
|
from cookbook.integration.integration import Integration
|
||||||
from cookbook.models import Recipe, Step, Ingredient
|
from cookbook.models import Ingredient, Recipe, Step
|
||||||
|
|
||||||
|
|
||||||
class Domestica(Integration):
|
class Domestica(Integration):
|
||||||
@ -37,11 +37,11 @@ class Domestica(Integration):
|
|||||||
ingredient_parser = IngredientParser(self.request, True)
|
ingredient_parser = IngredientParser(self.request, True)
|
||||||
for ingredient in file['ingredients'].split('\n'):
|
for ingredient in file['ingredients'].split('\n'):
|
||||||
if len(ingredient.strip()) > 0:
|
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)
|
f = ingredient_parser.get_food(food)
|
||||||
u = ingredient_parser.get_unit(unit)
|
u = ingredient_parser.get_unit(unit)
|
||||||
step.ingredients.add(Ingredient.objects.create(
|
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)
|
recipe.steps.add(step)
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ from zipfile import ZipFile
|
|||||||
from cookbook.helper.image_processing import get_filetype
|
from cookbook.helper.image_processing import get_filetype
|
||||||
from cookbook.helper.ingredient_parser import IngredientParser
|
from cookbook.helper.ingredient_parser import IngredientParser
|
||||||
from cookbook.integration.integration import Integration
|
from cookbook.integration.integration import Integration
|
||||||
from cookbook.models import Recipe, Step, Ingredient
|
from cookbook.models import Ingredient, Recipe, Step
|
||||||
|
|
||||||
|
|
||||||
class Mealie(Integration):
|
class Mealie(Integration):
|
||||||
@ -45,12 +45,14 @@ class Mealie(Integration):
|
|||||||
u = ingredient_parser.get_unit(ingredient['unit'])
|
u = ingredient_parser.get_unit(ingredient['unit'])
|
||||||
amount = ingredient['quantity']
|
amount = ingredient['quantity']
|
||||||
note = ingredient['note']
|
note = ingredient['note']
|
||||||
|
original_text = None
|
||||||
else:
|
else:
|
||||||
amount, unit, ingredient, note = ingredient_parser.parse(ingredient['note'])
|
amount, unit, food, note = ingredient_parser.parse(ingredient['note'])
|
||||||
f = ingredient_parser.get_food(ingredient)
|
f = ingredient_parser.get_food(food)
|
||||||
u = ingredient_parser.get_unit(unit)
|
u = ingredient_parser.get_unit(unit)
|
||||||
|
original_text = ingredient['note']
|
||||||
step.ingredients.add(Ingredient.objects.create(
|
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:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
@ -60,7 +62,8 @@ class Mealie(Integration):
|
|||||||
if '.zip' in f['name']:
|
if '.zip' in f['name']:
|
||||||
import_zip = ZipFile(f['file'])
|
import_zip = ZipFile(f['file'])
|
||||||
try:
|
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:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import re
|
|||||||
|
|
||||||
from cookbook.helper.ingredient_parser import IngredientParser
|
from cookbook.helper.ingredient_parser import IngredientParser
|
||||||
from cookbook.integration.integration import Integration
|
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):
|
class MealMaster(Integration):
|
||||||
@ -45,11 +45,11 @@ class MealMaster(Integration):
|
|||||||
ingredient_parser = IngredientParser(self.request, True)
|
ingredient_parser = IngredientParser(self.request, True)
|
||||||
for ingredient in ingredients:
|
for ingredient in ingredients:
|
||||||
if len(ingredient.strip()) > 0:
|
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)
|
f = ingredient_parser.get_food(ingredient)
|
||||||
u = ingredient_parser.get_unit(unit)
|
u = ingredient_parser.get_unit(unit)
|
||||||
step.ingredients.add(Ingredient.objects.create(
|
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)
|
recipe.steps.add(step)
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ from cookbook.helper.image_processing import get_filetype
|
|||||||
from cookbook.helper.ingredient_parser import IngredientParser
|
from cookbook.helper.ingredient_parser import IngredientParser
|
||||||
from cookbook.helper.recipe_url_import import iso_duration_to_minutes
|
from cookbook.helper.recipe_url_import import iso_duration_to_minutes
|
||||||
from cookbook.integration.integration import Integration
|
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):
|
class NextcloudCookbook(Integration):
|
||||||
@ -57,11 +57,11 @@ class NextcloudCookbook(Integration):
|
|||||||
|
|
||||||
ingredient_parser = IngredientParser(self.request, True)
|
ingredient_parser = IngredientParser(self.request, True)
|
||||||
for ingredient in recipe_json['recipeIngredient']:
|
for ingredient in recipe_json['recipeIngredient']:
|
||||||
amount, unit, ingredient, note = ingredient_parser.parse(ingredient)
|
amount, unit, food, note = ingredient_parser.parse(ingredient)
|
||||||
f = ingredient_parser.get_food(ingredient)
|
f = ingredient_parser.get_food(food)
|
||||||
u = ingredient_parser.get_unit(unit)
|
u = ingredient_parser.get_unit(unit)
|
||||||
step.ingredients.add(Ingredient.objects.create(
|
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)
|
recipe.steps.add(step)
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import json
|
|||||||
|
|
||||||
from cookbook.helper.ingredient_parser import IngredientParser
|
from cookbook.helper.ingredient_parser import IngredientParser
|
||||||
from cookbook.integration.integration import Integration
|
from cookbook.integration.integration import Integration
|
||||||
from cookbook.models import Recipe, Step, Ingredient
|
from cookbook.models import Ingredient, Recipe, Step
|
||||||
|
|
||||||
|
|
||||||
class OpenEats(Integration):
|
class OpenEats(Integration):
|
||||||
|
@ -2,12 +2,12 @@ import base64
|
|||||||
import gzip
|
import gzip
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
|
from gettext import gettext as _
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
from cookbook.helper.ingredient_parser import IngredientParser
|
from cookbook.helper.ingredient_parser import IngredientParser
|
||||||
from cookbook.integration.integration import Integration
|
from cookbook.integration.integration import Integration
|
||||||
from cookbook.models import Recipe, Step, Ingredient, Keyword
|
from cookbook.models import Ingredient, Keyword, Recipe, Step
|
||||||
from gettext import gettext as _
|
|
||||||
|
|
||||||
|
|
||||||
class Paprika(Integration):
|
class Paprika(Integration):
|
||||||
@ -70,11 +70,11 @@ class Paprika(Integration):
|
|||||||
try:
|
try:
|
||||||
for ingredient in recipe_json['ingredients'].split('\n'):
|
for ingredient in recipe_json['ingredients'].split('\n'):
|
||||||
if len(ingredient.strip()) > 0:
|
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)
|
f = ingredient_parser.get_food(food)
|
||||||
u = ingredient_parser.get_unit(unit)
|
u = ingredient_parser.get_unit(unit)
|
||||||
step.ingredients.add(Ingredient.objects.create(
|
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:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from cookbook.helper.ingredient_parser import IngredientParser
|
from cookbook.helper.ingredient_parser import IngredientParser
|
||||||
from cookbook.integration.integration import Integration
|
from cookbook.integration.integration import Integration
|
||||||
from cookbook.models import Recipe, Step, Ingredient
|
from cookbook.models import Ingredient, Recipe, Step
|
||||||
|
|
||||||
|
|
||||||
class Pepperplate(Integration):
|
class Pepperplate(Integration):
|
||||||
@ -41,11 +41,11 @@ class Pepperplate(Integration):
|
|||||||
ingredient_parser = IngredientParser(self.request, True)
|
ingredient_parser = IngredientParser(self.request, True)
|
||||||
for ingredient in ingredients:
|
for ingredient in ingredients:
|
||||||
if len(ingredient.strip()) > 0:
|
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)
|
f = ingredient_parser.get_food(food)
|
||||||
u = ingredient_parser.get_unit(unit)
|
u = ingredient_parser.get_unit(unit)
|
||||||
step.ingredients.add(Ingredient.objects.create(
|
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)
|
recipe.steps.add(step)
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import requests
|
|||||||
|
|
||||||
from cookbook.helper.ingredient_parser import IngredientParser
|
from cookbook.helper.ingredient_parser import IngredientParser
|
||||||
from cookbook.integration.integration import Integration
|
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):
|
class Plantoeat(Integration):
|
||||||
@ -56,11 +56,11 @@ class Plantoeat(Integration):
|
|||||||
ingredient_parser = IngredientParser(self.request, True)
|
ingredient_parser = IngredientParser(self.request, True)
|
||||||
for ingredient in ingredients:
|
for ingredient in ingredients:
|
||||||
if len(ingredient.strip()) > 0:
|
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)
|
f = ingredient_parser.get_food(food)
|
||||||
u = ingredient_parser.get_unit(unit)
|
u = ingredient_parser.get_unit(unit)
|
||||||
step.ingredients.add(Ingredient.objects.create(
|
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)
|
recipe.steps.add(step)
|
||||||
|
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
import re
|
import imghdr
|
||||||
import json
|
import json
|
||||||
import requests
|
import re
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
import imghdr
|
|
||||||
|
import requests
|
||||||
|
|
||||||
from cookbook.helper.image_processing import get_filetype
|
from cookbook.helper.image_processing import get_filetype
|
||||||
from cookbook.helper.ingredient_parser import IngredientParser
|
from cookbook.helper.ingredient_parser import IngredientParser
|
||||||
from cookbook.integration.integration import Integration
|
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):
|
class RecetteTek(Integration):
|
||||||
@ -58,11 +59,11 @@ class RecetteTek(Integration):
|
|||||||
ingredient_parser = IngredientParser(self.request, True)
|
ingredient_parser = IngredientParser(self.request, True)
|
||||||
for ingredient in file['ingredients'].split('\n'):
|
for ingredient in file['ingredients'].split('\n'):
|
||||||
if len(ingredient.strip()) > 0:
|
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)
|
f = ingredient_parser.get_food(ingredient)
|
||||||
u = ingredient_parser.get_unit(unit)
|
u = ingredient_parser.get_unit(unit)
|
||||||
step.ingredients.add(Ingredient.objects.create(
|
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:
|
except Exception as e:
|
||||||
print(recipe.name, ': failed to parse recipe ingredients ', str(e))
|
print(recipe.name, ': failed to parse recipe ingredients ', str(e))
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import re
|
import re
|
||||||
from bs4 import BeautifulSoup
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
|
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
from cookbook.helper.ingredient_parser import IngredientParser
|
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.integration.integration import Integration
|
||||||
from cookbook.models import Recipe, Step, Ingredient, Keyword
|
from cookbook.models import Ingredient, Keyword, Recipe, Step
|
||||||
|
|
||||||
|
|
||||||
class RecipeKeeper(Integration):
|
class RecipeKeeper(Integration):
|
||||||
@ -45,11 +46,11 @@ class RecipeKeeper(Integration):
|
|||||||
for ingredient in file.find("div", {"itemprop": "recipeIngredients"}).findChildren("p"):
|
for ingredient in file.find("div", {"itemprop": "recipeIngredients"}).findChildren("p"):
|
||||||
if ingredient.text == "":
|
if ingredient.text == "":
|
||||||
continue
|
continue
|
||||||
amount, unit, ingredient, note = ingredient_parser.parse(ingredient.text.strip())
|
amount, unit, food, note = ingredient_parser.parse(ingredient.text.strip())
|
||||||
f = ingredient_parser.get_food(ingredient)
|
f = ingredient_parser.get_food(food)
|
||||||
u = ingredient_parser.get_unit(unit)
|
u = ingredient_parser.get_unit(unit)
|
||||||
step.ingredients.add(Ingredient.objects.create(
|
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"):
|
for s in file.find("div", {"itemprop": "recipeDirections"}).find_all("p"):
|
||||||
|
@ -5,7 +5,7 @@ import requests
|
|||||||
|
|
||||||
from cookbook.helper.ingredient_parser import IngredientParser
|
from cookbook.helper.ingredient_parser import IngredientParser
|
||||||
from cookbook.integration.integration import Integration
|
from cookbook.integration.integration import Integration
|
||||||
from cookbook.models import Recipe, Step, Ingredient
|
from cookbook.models import Ingredient, Recipe, Step
|
||||||
|
|
||||||
|
|
||||||
class RecipeSage(Integration):
|
class RecipeSage(Integration):
|
||||||
@ -41,11 +41,11 @@ class RecipeSage(Integration):
|
|||||||
ingredients_added = True
|
ingredients_added = True
|
||||||
|
|
||||||
for ingredient in file['recipeIngredient']:
|
for ingredient in file['recipeIngredient']:
|
||||||
amount, unit, ingredient, note = ingredient_parser.parse(ingredient)
|
amount, unit, food, note = ingredient_parser.parse(ingredient)
|
||||||
f = ingredient_parser.get_food(ingredient)
|
f = ingredient_parser.get_food(food)
|
||||||
u = ingredient_parser.get_unit(unit)
|
u = ingredient_parser.get_unit(unit)
|
||||||
step.ingredients.add(Ingredient.objects.create(
|
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)
|
recipe.steps.add(step)
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from cookbook.helper.ingredient_parser import IngredientParser
|
from cookbook.helper.ingredient_parser import IngredientParser
|
||||||
from cookbook.integration.integration import Integration
|
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):
|
class RezKonv(Integration):
|
||||||
@ -44,11 +44,11 @@ class RezKonv(Integration):
|
|||||||
ingredient_parser = IngredientParser(self.request, True)
|
ingredient_parser = IngredientParser(self.request, True)
|
||||||
for ingredient in ingredients:
|
for ingredient in ingredients:
|
||||||
if len(ingredient.strip()) > 0:
|
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)
|
f = ingredient_parser.get_food(food)
|
||||||
u = ingredient_parser.get_unit(unit)
|
u = ingredient_parser.get_unit(unit)
|
||||||
step.ingredients.add(Ingredient.objects.create(
|
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)
|
recipe.steps.add(step)
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ from django.utils.translation import gettext as _
|
|||||||
|
|
||||||
from cookbook.helper.ingredient_parser import IngredientParser
|
from cookbook.helper.ingredient_parser import IngredientParser
|
||||||
from cookbook.integration.integration import Integration
|
from cookbook.integration.integration import Integration
|
||||||
from cookbook.models import Recipe, Step, Ingredient
|
from cookbook.models import Ingredient, Recipe, Step
|
||||||
|
|
||||||
|
|
||||||
class Saffron(Integration):
|
class Saffron(Integration):
|
||||||
@ -47,11 +47,11 @@ class Saffron(Integration):
|
|||||||
|
|
||||||
ingredient_parser = IngredientParser(self.request, True)
|
ingredient_parser = IngredientParser(self.request, True)
|
||||||
for ingredient in ingredients:
|
for ingredient in ingredients:
|
||||||
amount, unit, ingredient, note = ingredient_parser.parse(ingredient)
|
amount, unit, food, note = ingredient_parser.parse(ingredient)
|
||||||
f = ingredient_parser.get_food(ingredient)
|
f = ingredient_parser.get_food(food)
|
||||||
u = ingredient_parser.get_unit(unit)
|
u = ingredient_parser.get_unit(unit)
|
||||||
step.ingredients.add(Ingredient.objects.create(
|
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)
|
recipe.steps.add(step)
|
||||||
|
|
||||||
|
18
cookbook/migrations/0172_ingredient_original_text.py
Normal file
18
cookbook/migrations/0172_ingredient_original_text.py
Normal 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),
|
||||||
|
),
|
||||||
|
]
|
@ -590,6 +590,7 @@ class Ingredient(ExportModelOperationsMixin('ingredient'), models.Model, Permiss
|
|||||||
is_header = models.BooleanField(default=False)
|
is_header = models.BooleanField(default=False)
|
||||||
no_amount = models.BooleanField(default=False)
|
no_amount = models.BooleanField(default=False)
|
||||||
order = models.IntegerField(default=0)
|
order = models.IntegerField(default=0)
|
||||||
|
original_text = models.CharField(max_length=256, null=True, blank=True)
|
||||||
|
|
||||||
space = models.ForeignKey(Space, on_delete=models.CASCADE)
|
space = models.ForeignKey(Space, on_delete=models.CASCADE)
|
||||||
objects = ScopedManager(space='space')
|
objects = ScopedManager(space='space')
|
||||||
|
@ -479,11 +479,15 @@ class IngredientSerializer(WritableNestedModelSerializer):
|
|||||||
validated_data['space'] = self.context['request'].space
|
validated_data['space'] = self.context['request'].space
|
||||||
return super().create(validated_data)
|
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:
|
class Meta:
|
||||||
model = Ingredient
|
model = Ingredient
|
||||||
fields = (
|
fields = (
|
||||||
'id', 'food', 'unit', 'amount', 'note', 'order',
|
'id', 'food', 'unit', 'amount', 'note', 'order',
|
||||||
'is_header', 'no_amount'
|
'is_header', 'no_amount', 'original_text'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -473,9 +473,9 @@
|
|||||||
|
|
||||||
<div class="card" style="margin-top: 4px">
|
<div class="card" style="margin-top: 4px">
|
||||||
<div class="card-body">
|
<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">
|
<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>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -1024,7 +1024,7 @@
|
|||||||
amount: String(response.body.amount),
|
amount: String(response.body.amount),
|
||||||
ingredient: {id: Math.random() * 1000, text: response.body.food},
|
ingredient: {id: Math.random() * 1000, text: response.body.food},
|
||||||
note: response.body.note,
|
note: response.body.note,
|
||||||
original: v
|
original_text: v
|
||||||
}
|
}
|
||||||
this.recipe_json.recipeIngredient.push(new_ingredient)
|
this.recipe_json.recipeIngredient.push(new_ingredient)
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -168,7 +168,8 @@ def import_url(request):
|
|||||||
|
|
||||||
ingredient_parser = IngredientParser(request, True)
|
ingredient_parser = IngredientParser(request, True)
|
||||||
for ing in data['recipeIngredient']:
|
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():
|
if food_text := ing['ingredient']['text'].strip():
|
||||||
ingredient.food = ingredient_parser.get_food(food_text)
|
ingredient.food = ingredient_parser.get_food(food_text)
|
||||||
|
@ -48,11 +48,11 @@ def hook(request, token):
|
|||||||
request.space = tb.space # TODO this is likely a bad idea. Verify and test
|
request.space = tb.space # TODO this is likely a bad idea. Verify and test
|
||||||
request.user = tb.created_by
|
request.user = tb.created_by
|
||||||
ingredient_parser = IngredientParser(request, False)
|
ingredient_parser = IngredientParser(request, False)
|
||||||
amount, unit, ingredient, note = ingredient_parser.parse(data['message']['text'])
|
amount, unit, food, note = ingredient_parser.parse(data['message']['text'])
|
||||||
f = ingredient_parser.get_food(ingredient)
|
f = ingredient_parser.get_food(food)
|
||||||
u = ingredient_parser.get_unit(unit)
|
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']})
|
return JsonResponse({'data': data['message']['text']})
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@ -30,7 +30,7 @@ Jinja2==3.0.3
|
|||||||
django-webpack-loader==1.4.1
|
django-webpack-loader==1.4.1
|
||||||
django-js-reverse==0.9.1
|
django-js-reverse==0.9.1
|
||||||
django-allauth==0.47.0
|
django-allauth==0.47.0
|
||||||
recipe-scrapers==13.16.0
|
recipe-scrapers==13.18.0
|
||||||
django-scopes==1.2.0
|
django-scopes==1.2.0
|
||||||
pytest==6.2.5
|
pytest==6.2.5
|
||||||
pytest-django==4.5.2
|
pytest-django==4.5.2
|
||||||
|
@ -983,6 +983,7 @@ export default {
|
|||||||
unit: unit,
|
unit: unit,
|
||||||
food: { name: result.data.food },
|
food: { name: result.data.food },
|
||||||
note: result.data.note,
|
note: result.data.note,
|
||||||
|
original_text: ing,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
order++
|
order++
|
||||||
|
Loading…
Reference in New Issue
Block a user