From 46a9d1937415c351ab7aab23f07e6b5ba4068625 Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Tue, 9 Feb 2021 17:34:38 +0100 Subject: [PATCH] safron import --- .idea/dictionaries/vabene1111_PC.xml | 1 + cookbook/forms.py | 6 ++- cookbook/integration/chowdown.py | 5 +-- cookbook/integration/safron.py | 60 ++++++++++++++++++++++++++++ cookbook/views/import_export.py | 3 ++ docs/features/import_export.md | 7 ++++ 6 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 cookbook/integration/safron.py diff --git a/.idea/dictionaries/vabene1111_PC.xml b/.idea/dictionaries/vabene1111_PC.xml index 49ae2f94..da49b1e4 100644 --- a/.idea/dictionaries/vabene1111_PC.xml +++ b/.idea/dictionaries/vabene1111_PC.xml @@ -7,6 +7,7 @@ gunicorn ical mealie + safron traefik diff --git a/cookbook/forms.py b/cookbook/forms.py index e7ee014b..1d6d0d79 100644 --- a/cookbook/forms.py +++ b/cookbook/forms.py @@ -137,8 +137,12 @@ class ImportExportBase(forms.Form): NEXTCLOUD = 'NEXTCLOUD' MEALIE = 'MEALIE' CHOWDOWN = 'CHOWDOWN' + SAFRON = 'SAFRON' - type = forms.ChoiceField(choices=((DEFAULT, _('Default')), (PAPRIKA, _('Paprika')), (NEXTCLOUD, _('Nextcloud Cookbook')), (MEALIE, _('Mealie')), (CHOWDOWN, _('Chowdown')),)) + type = forms.ChoiceField(choices=( + (DEFAULT, _('Default')), (PAPRIKA, 'Paprika'), (NEXTCLOUD, 'Nextcloud Cookbook'), + (MEALIE, 'Mealie'), (CHOWDOWN, 'Chowdown'), (SAFRON, 'Safron'), + )) class ImportForm(ImportExportBase): diff --git a/cookbook/integration/chowdown.py b/cookbook/integration/chowdown.py index 424c57d1..ecd2c45e 100644 --- a/cookbook/integration/chowdown.py +++ b/cookbook/integration/chowdown.py @@ -75,6 +75,5 @@ class Chowdown(Integration): return recipe - -def get_file_from_recipe(self, recipe): - raise NotImplementedError('Method not implemented in storage integration') + def get_file_from_recipe(self, recipe): + raise NotImplementedError('Method not implemented in storage integration') diff --git a/cookbook/integration/safron.py b/cookbook/integration/safron.py new file mode 100644 index 00000000..77277950 --- /dev/null +++ b/cookbook/integration/safron.py @@ -0,0 +1,60 @@ +from django.utils.translation import gettext as _ + +from cookbook.helper.ingredient_parser import parse +from cookbook.integration.integration import Integration +from cookbook.models import Recipe, Step, Food, Unit, Ingredient + + +class Safron(Integration): + + def get_recipe_from_file(self, file): + ingredient_mode = False + direction_mode = False + + ingredients = [] + directions = [] + for fl in file.readlines(): + line = fl.decode("utf-8") + if 'Title:' in line: + title = line.replace('Title:', '').strip() + if 'Description:' in line: + description = line.replace('Description:', '').strip() + if 'Yield:' in line: + directions.append(_('Servings') + ' ' + line.replace('Yield:', '').strip() + '\n') + if 'Cook:' in line: + directions.append(_('Waiting time') + ' ' + line.replace('Cook:', '').strip() + '\n') + if 'Prep:' in line: + directions.append(_('Preparation Time') + ' ' + line.replace('Prep:', '').strip() + '\n') + if 'Cookbook:' in line: + directions.append(_('Cookbook') + ' ' + line.replace('Cookbook:', '').strip() + '\n') + if 'Section:' in line: + directions.append(_('Section') + ' ' + line.replace('Section:', '').strip() + '\n') + if ingredient_mode: + if len(line) > 2 and 'Instructions:' not in line: + ingredients.append(line.strip()) + if direction_mode: + if len(line) > 2: + directions.append(line.strip()) + if 'Ingredients:' in line: + ingredient_mode = True + if 'Instructions:' in line: + ingredient_mode = False + direction_mode = True + + recipe = Recipe.objects.create(name=title, description=description, created_by=self.request.user, internal=True, ) + + step = Step.objects.create(instruction='\n'.join(directions)) + + for ingredient in ingredients: + amount, unit, ingredient, note = parse(ingredient) + f, created = Food.objects.get_or_create(name=ingredient) + u, created = Unit.objects.get_or_create(name=unit) + step.ingredients.add(Ingredient.objects.create( + food=f, unit=u, amount=amount, note=note + )) + recipe.steps.add(step) + + return recipe + + def get_file_from_recipe(self, recipe): + raise NotImplementedError('Method not implemented in storage integration') diff --git a/cookbook/views/import_export.py b/cookbook/views/import_export.py index cef46694..02361c15 100644 --- a/cookbook/views/import_export.py +++ b/cookbook/views/import_export.py @@ -11,6 +11,7 @@ from cookbook.integration.default import Default from cookbook.integration.mealie import Mealie from cookbook.integration.nextcloud_cookbook import NextcloudCookbook from cookbook.integration.paprika import Paprika +from cookbook.integration.safron import Safron from cookbook.models import Recipe @@ -25,6 +26,8 @@ def get_integration(request, export_type): return Mealie(request) if export_type == ImportExportBase.CHOWDOWN: return Chowdown(request) + if export_type == ImportExportBase.SAFRON: + return Safron(request) @group_required('user') diff --git a/docs/features/import_export.md b/docs/features/import_export.md index 11ebedfe..258eb562 100644 --- a/docs/features/import_export.md +++ b/docs/features/import_export.md @@ -75,6 +75,13 @@ Recipes.zip/ └── ... ``` +## Safron +Go to you safron settings page and export your recipes. +Then simply upload the entire `.zip` file to the importer. + +!!! warning "Images" + Safron exports do not contain any images. They will be lost during import. + ## Paprika Paprika can create two types of export. The first is a proprietary `.paprikarecipes` file in some kind of binarized format. The second one is HTML files containing at least a bit of microdata.