improvements to recipekeeper importer

This commit is contained in:
vabene1111 2021-06-09 17:23:14 +02:00
parent 46db6d4186
commit f7d85bb4b8
5 changed files with 45 additions and 28 deletions

View File

@ -358,3 +358,11 @@ def normalize_string(string):
unescaped_string = re.sub(r'\n\s*\n', '\n\n', unescaped_string) unescaped_string = re.sub(r'\n\s*\n', '\n\n', unescaped_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
def iso_duration_to_minutes(string):
match = re.match(
r'P((?P<years>\d+)Y)?((?P<months>\d+)M)?((?P<weeks>\d+)W)?((?P<days>\d+)D)?T((?P<hours>\d+)H)?((?P<minutes>\d+)M)?((?P<seconds>\d+)S)?',
string
).groupdict()
return int(match['days'] or 0) * 24 * 60 + int(match['hours'] or 0) * 60 + int(match['minutes'] or 0)

View File

@ -1,5 +1,6 @@
import datetime import datetime
import json import json
import re
import uuid import uuid
from io import BytesIO, StringIO from io import BytesIO, StringIO
from zipfile import ZipFile, BadZipFile from zipfile import ZipFile, BadZipFile
@ -216,3 +217,4 @@ class Integration:
- data - string content for file to get created in export zip - data - string content for file to get created in export zip
""" """
raise NotImplementedError('Method not implemented in integration') raise NotImplementedError('Method not implemented in integration')

View File

@ -6,6 +6,7 @@ from zipfile import ZipFile
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from cookbook.helper.ingredient_parser import parse, get_food, get_unit from cookbook.helper.ingredient_parser import parse, get_food, get_unit
from cookbook.helper.recipe_url_import import parse_servings, iso_duration_to_minutes
from cookbook.integration.integration import Integration from cookbook.integration.integration import Integration
from cookbook.models import Recipe, Step, Food, Unit, Ingredient, Keyword from cookbook.models import Recipe, Step, Food, Unit, Ingredient, Keyword
@ -32,29 +33,16 @@ class RecipeKeeper(Integration):
keyword, created = Keyword.objects.get_or_create(name=category.get("content"), space=self.request.space) keyword, created = Keyword.objects.get_or_create(name=category.get("content"), space=self.request.space)
recipe.keywords.add(keyword) recipe.keywords.add(keyword)
# TODO: import prep and cook times try:
# Recipe Keeper uses ISO 8601 format for its duration periods. recipe.servings = parse_servings(file.find("span", {"itemprop": "recipeYield"}).text.strip())
recipe.working_time = iso_duration_to_minutes(file.find("span", {"meta": "prepTime"}).text.strip())
recipe.waiting_time = iso_duration_to_minutes(file.find("span", {"meta": "cookTime"}).text.strip())
recipe.save()
except AttributeError:
pass
source_url_added = False step = Step.objects.create(instruction='')
ingredients_added = False
for s in file.find("div", {"itemprop": "recipeDirections"}).find_all("p"):
if s.text == "":
continue
step = Step.objects.create(
instruction=s.text
)
if not source_url_added:
# If there is a source URL, add it to the first step field.
if file.find("span", {"itemprop": "recipeSource"}).text != '':
step.instruction += "\n\nImported from: " + file.find("span", {"itemprop": "recipeSource"}).text
step.save()
source_url_added = True
if not ingredients_added:
ingredients_added = True
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
@ -64,6 +52,17 @@ class RecipeKeeper(Integration):
step.ingredients.add(Ingredient.objects.create( step.ingredients.add(Ingredient.objects.create(
food=f, unit=u, amount=amount, note=note food=f, unit=u, amount=amount, note=note
)) ))
for s in file.find("div", {"itemprop": "recipeDirections"}).find_all("p"):
if s.text == "":
continue
step.instruction += s.text + ' \n'
if file.find("span", {"itemprop": "recipeSource"}).text != '':
step.instruction += "\n\nImported from: " + file.find("span", {"itemprop": "recipeSource"}).text
step.save()
source_url_added = True
recipe.steps.add(step) recipe.steps.add(step)
# import the Primary recipe image that is stored in the Zip # import the Primary recipe image that is stored in the Zip

View File

@ -100,6 +100,9 @@
<label class="btn btn-outline-info btn-sm" @click="recipe_app='RECIPESAGE'"> <label class="btn btn-outline-info btn-sm" @click="recipe_app='RECIPESAGE'">
<input type="radio" autocomplete="off"> Recipesage <input type="radio" autocomplete="off"> Recipesage
</label> </label>
<label class="btn btn-outline-info btn-sm" @click="recipe_app='RECIPEKEEPER'">
<input type="radio" autocomplete="off"> Recipekeeper
</label>
<label class="btn btn-outline-info btn-sm" @click="recipe_app='DOMESTICA'"> <label class="btn btn-outline-info btn-sm" @click="recipe_app='DOMESTICA'">
<input type="radio" autocomplete="off"> Domestica <input type="radio" autocomplete="off"> Domestica
</label> </label>

View File

@ -35,6 +35,7 @@ Overview of the capabilities of the different integrations.
| MealMaster | ✔️ | ❌ | ❌ | | MealMaster | ✔️ | ❌ | ❌ |
| RezKonv | ✔️ | ❌ | ❌ | | RezKonv | ✔️ | ❌ | ❌ |
| OpenEats | ✔️ | ❌ | ⌚ | | OpenEats | ✔️ | ❌ | ⌚ |
| OpenEats | ✔️ | ❌ | ✔ |
✔ = implemented, ❌ = not implemented and not possible/planned, ⌚ = not yet implemented ✔ = implemented, ❌ = not implemented and not possible/planned, ⌚ = not yet implemented
@ -161,7 +162,11 @@ The RezKonv format is primarily used in the german recipe manager RezKonv Suite.
To migrate from RezKonv Suite to Tandoor select `Export > Gesamtes Kochbuch exportieren` (the last option in the export menu). To migrate from RezKonv Suite to Tandoor select `Export > Gesamtes Kochbuch exportieren` (the last option in the export menu).
The generated file can simply be imported into Tandoor. The generated file can simply be imported into Tandoor.
As i only had limited sample data feel free to open an issue if your RezKonv export cannot be imported. As I only had limited sample data feel free to open an issue if your RezKonv export cannot be imported.
## Recipekeeper
Recipe keeper allows to export a zip file containing recipes and images using its apps.
This zip file can simply be imported into Tandoor.
## OpenEats ## OpenEats
OpenEats does not provide any way to export the data using the interface. Luckily it is relatively easy to export it from the command line. OpenEats does not provide any way to export the data using the interface. Luckily it is relatively easy to export it from the command line.