diff --git a/cookbook/forms.py b/cookbook/forms.py index d905d768..a622eb7d 100644 --- a/cookbook/forms.py +++ b/cookbook/forms.py @@ -130,13 +130,14 @@ class ImportExportBase(forms.Form): REZKONV = 'REZKONV' OPENEATS = 'OPENEATS' PLANTOEAT = 'PLANTOEAT' + COOKBOOKAPP = 'COOKBOOKAPP' type = forms.ChoiceField(choices=( (DEFAULT, _('Default')), (PAPRIKA, 'Paprika'), (NEXTCLOUD, 'Nextcloud Cookbook'), (MEALIE, 'Mealie'), (CHOWDOWN, 'Chowdown'), (SAFRON, 'Safron'), (CHEFTAP, 'ChefTap'), (PEPPERPLATE, 'Pepperplate'), (RECETTETEK, 'RecetteTek'), (RECIPESAGE, 'Recipe Sage'), (DOMESTICA, 'Domestica'), (MEALMASTER, 'MealMaster'), (REZKONV, 'RezKonv'), (OPENEATS, 'Openeats'), (RECIPEKEEPER, 'Recipe Keeper'), - (PLANTOEAT, 'Plantoeat'), + (PLANTOEAT, 'Plantoeat'), (COOKBOOKAPP, 'CookBookApp'), )) diff --git a/cookbook/integration/cookbookapp.py b/cookbook/integration/cookbookapp.py new file mode 100644 index 00000000..f5225f77 --- /dev/null +++ b/cookbook/integration/cookbookapp.py @@ -0,0 +1,66 @@ +import base64 +import gzip +import json +import re +from io import BytesIO + +import yaml + +from cookbook.helper.ingredient_parser import parse, get_food, get_unit +from cookbook.integration.integration import Integration +from cookbook.models import Recipe, Step, Ingredient, Keyword +from gettext import gettext as _ + + +class CookBookApp(Integration): + + def import_file_name_filter(self, zip_info_object): + return zip_info_object.filename.endswith('.yml') + + def get_recipe_from_file(self, file): + recipe_yml = yaml.safe_load(file.getvalue().decode("utf-8")) + + recipe = Recipe.objects.create( + name=recipe_yml['name'].strip(), + created_by=self.request.user, internal=True, + space=self.request.space) + + try: + recipe.servings = re.findall('([0-9])+', recipe_yml['recipeYield'])[0] + except Exception as e: + pass + + try: + recipe.working_time = recipe_yml['prep_time'].replace(' minutes', '') + recipe.waiting_time = recipe_yml['cook_time'].replace(' minutes', '') + except Exception: + pass + + if recipe_yml['on_favorites']: + recipe.keywords.add(Keyword.objects.get_or_create(name=_('Favorites'), space=self.request.space)) + + step = Step.objects.create(instruction=recipe_yml['directions'], space=self.request.space, ) + + if 'notes' in recipe_yml and recipe_yml['notes'].strip() != '': + step.instruction = step.instruction + '\n\n' + recipe_yml['notes'] + + if 'nutritional_info' in recipe_yml: + step.instruction = step.instruction + '\n\n' + recipe_yml['nutritional_info'] + + if 'source' in recipe_yml and recipe_yml['source'].strip() != '': + step.instruction = step.instruction + '\n\n' + recipe_yml['source'] + + step.save() + recipe.steps.add(step) + + for ingredient in recipe_yml['ingredients'].split('\n'): + if ingredient.strip() != '': + amount, unit, ingredient, note = parse(ingredient) + 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, space=self.request.space, + )) + + recipe.save() + return recipe diff --git a/cookbook/integration/Pepperplate.py b/cookbook/integration/pepperplate.py similarity index 100% rename from cookbook/integration/Pepperplate.py rename to cookbook/integration/pepperplate.py diff --git a/cookbook/templates/url_import.html b/cookbook/templates/url_import.html index da180f34..94490978 100644 --- a/cookbook/templates/url_import.html +++ b/cookbook/templates/url_import.html @@ -70,21 +70,22 @@ diff --git a/cookbook/views/import_export.py b/cookbook/views/import_export.py index 26135d54..0a8e83e1 100644 --- a/cookbook/views/import_export.py +++ b/cookbook/views/import_export.py @@ -10,7 +10,8 @@ from django.utils.translation import gettext as _ from cookbook.forms import ExportForm, ImportForm, ImportExportBase from cookbook.helper.permission_helper import group_required -from cookbook.integration.Pepperplate import Pepperplate +from cookbook.integration.cookbookapp import CookBookApp +from cookbook.integration.pepperplate import Pepperplate from cookbook.integration.cheftap import ChefTap from cookbook.integration.chowdown import Chowdown from cookbook.integration.default import Default @@ -62,6 +63,8 @@ def get_integration(request, export_type): return OpenEats(request, export_type) if export_type == ImportExportBase.PLANTOEAT: return Plantoeat(request, export_type) + if export_type == ImportExportBase.COOKBOOKAPP: + return CookBookApp(request, export_type) @group_required('user') diff --git a/docs/features/import_export.md b/docs/features/import_export.md index 576f964a..9155ba91 100644 --- a/docs/features/import_export.md +++ b/docs/features/import_export.md @@ -36,6 +36,7 @@ Overview of the capabilities of the different integrations. | RezKonv | ✔️ | ❌ | ❌ | | OpenEats | ✔️ | ❌ | ⌚ | | Plantoeat | ✔️ | ❌ | ✔ | +| CookBookApp | ✔️ | ⌚ | ❌ | ✔ = implemented, ❌ = not implemented and not possible/planned, ⌚ = not yet implemented @@ -208,4 +209,12 @@ Store the outputted json string in a `.json` file and simply import it using the } ] -``` \ No newline at end of file +``` + +## Plantoeat + +Plan to eat allow to export a text file containing all your recipes. Simply upload that text file to Tandoor to import all recipes + +## CookBookApp + +CookBookApp can export .zip files containing .yml files. Upload the entire ZIP to Tandoor to import all conluded recipes. \ No newline at end of file