plan to eat importer

This commit is contained in:
vabene1111 2021-09-14 22:47:26 +02:00
parent cbb2c0460c
commit 70f96d3fe6
6 changed files with 100 additions and 3 deletions

View File

@ -129,13 +129,14 @@ class ImportExportBase(forms.Form):
MEALMASTER = 'MEALMASTER' MEALMASTER = 'MEALMASTER'
REZKONV = 'REZKONV' REZKONV = 'REZKONV'
OPENEATS = 'OPENEATS' OPENEATS = 'OPENEATS'
PLANTOEAT = 'PLANTOEAT'
type = forms.ChoiceField(choices=( type = forms.ChoiceField(choices=(
(DEFAULT, _('Default')), (PAPRIKA, 'Paprika'), (NEXTCLOUD, 'Nextcloud Cookbook'), (DEFAULT, _('Default')), (PAPRIKA, 'Paprika'), (NEXTCLOUD, 'Nextcloud Cookbook'),
(MEALIE, 'Mealie'), (CHOWDOWN, 'Chowdown'), (SAFRON, 'Safron'), (CHEFTAP, 'ChefTap'), (MEALIE, 'Mealie'), (CHOWDOWN, 'Chowdown'), (SAFRON, 'Safron'), (CHEFTAP, 'ChefTap'),
(PEPPERPLATE, 'Pepperplate'), (RECETTETEK, 'RecetteTek'), (RECIPESAGE, 'Recipe Sage'), (DOMESTICA, 'Domestica'), (PEPPERPLATE, 'Pepperplate'), (RECETTETEK, 'RecetteTek'), (RECIPESAGE, 'Recipe Sage'), (DOMESTICA, 'Domestica'),
(MEALMASTER, 'MealMaster'), (REZKONV, 'RezKonv'), (OPENEATS, 'Openeats'), (RECIPEKEEPER, 'Recipe Keeper'), (MEALMASTER, 'MealMaster'), (REZKONV, 'RezKonv'), (OPENEATS, 'Openeats'), (RECIPEKEEPER, 'Recipe Keeper'),
(PLANTOEAT, 'Plantoeat'),
)) ))

View File

@ -0,0 +1,93 @@
from io import BytesIO
import requests
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
class Plantoeat(Integration):
def get_recipe_from_file(self, file):
ingredient_mode = False
direction_mode = False
image_url = None
tags = None
ingredients = []
directions = []
description = ''
for line in file.replace('\r', '').split('\n'):
if line.strip() != '':
if 'Title:' in line:
title = line.replace('Title:', '').replace('"', '').strip()
if 'Description:' in line:
description = line.replace('Description:', '').strip()
if 'Source:' in line or 'Serves:' in line or 'Prep Time:' in line or 'Cook Time:' in line:
directions.append(line.strip() + '\n')
if 'Photo Url:' in line:
image_url = line.replace('Photo Url:', '').strip()
if 'Tags:' in line:
tags = line.replace('Tags:', '').strip()
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() + '\n')
if 'Ingredients:' in line:
ingredient_mode = True
if 'Directions:' in line:
ingredient_mode = False
direction_mode = True
recipe = Recipe.objects.create(name=title, description=description, created_by=self.request.user, internal=True, space=self.request.space)
step = Step.objects.create(
instruction='\n'.join(directions) + '\n\n', space=self.request.space,
)
if tags:
for k in tags.split(','):
keyword, created = Keyword.objects.get_or_create(name=k.strip(), space=self.request.space)
recipe.keywords.add(keyword)
for ingredient in ingredients:
if len(ingredient.strip()) > 0:
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.steps.add(step)
if image_url:
try:
response = requests.get(image_url)
self.import_recipe_image(recipe, BytesIO(response.content))
except Exception as e:
print('failed to import image ', str(e))
return recipe
def split_recipe_file(self, file):
recipe_list = []
current_recipe = ''
for fl in file.readlines():
line = fl.decode("ANSI")
if line.startswith('--------------'):
if current_recipe != '':
recipe_list.append(current_recipe)
current_recipe = ''
else:
current_recipe = ''
else:
current_recipe += line + '\n'
if current_recipe != '':
recipe_list.append(current_recipe)
return recipe_list

View File

@ -41,7 +41,6 @@ class TreeManager(MP_NodeManager):
def get_or_create(self, **kwargs): def get_or_create(self, **kwargs):
kwargs['name'] = kwargs['name'].strip() kwargs['name'] = kwargs['name'].strip()
try: try:
print(f'checking name {kwargs["name"]}')
return self.get(name__exact=kwargs['name'], space=kwargs['space']), False return self.get(name__exact=kwargs['name'], space=kwargs['space']), False
except self.model.DoesNotExist: except self.model.DoesNotExist:
with scopes_disabled(): with scopes_disabled():

View File

@ -84,6 +84,7 @@
<option value="MEALMASTER">Mealmaster</option> <option value="MEALMASTER">Mealmaster</option>
<option value="REZKONV">Rezkonv</option> <option value="REZKONV">Rezkonv</option>
<option value="RECETTETEK">RecetteTek</option> <option value="RECETTETEK">RecetteTek</option>
<option value="PLANTOEAT">Plantoeat</option>
</select> </select>
<b-form-checkbox v-model="import_duplicates" name="check-button" switch style="margin-top: 1vh"> <b-form-checkbox v-model="import_duplicates" name="check-button" switch style="margin-top: 1vh">

View File

@ -20,6 +20,7 @@ from cookbook.integration.mealmaster import MealMaster
from cookbook.integration.nextcloud_cookbook import NextcloudCookbook from cookbook.integration.nextcloud_cookbook import NextcloudCookbook
from cookbook.integration.openeats import OpenEats from cookbook.integration.openeats import OpenEats
from cookbook.integration.paprika import Paprika from cookbook.integration.paprika import Paprika
from cookbook.integration.plantoeat import Plantoeat
from cookbook.integration.recipekeeper import RecipeKeeper from cookbook.integration.recipekeeper import RecipeKeeper
from cookbook.integration.recettetek import RecetteTek from cookbook.integration.recettetek import RecetteTek
from cookbook.integration.recipesage import RecipeSage from cookbook.integration.recipesage import RecipeSage
@ -59,6 +60,8 @@ def get_integration(request, export_type):
return MealMaster(request, export_type) return MealMaster(request, export_type)
if export_type == ImportExportBase.OPENEATS: if export_type == ImportExportBase.OPENEATS:
return OpenEats(request, export_type) return OpenEats(request, export_type)
if export_type == ImportExportBase.PLANTOEAT:
return Plantoeat(request, export_type)
@group_required('user') @group_required('user')

View File

@ -35,7 +35,7 @@ Overview of the capabilities of the different integrations.
| MealMaster | ✔️ | ❌ | ❌ | | MealMaster | ✔️ | ❌ | ❌ |
| RezKonv | ✔️ | ❌ | ❌ | | RezKonv | ✔️ | ❌ | ❌ |
| OpenEats | ✔️ | ❌ | ⌚ | | OpenEats | ✔️ | ❌ | ⌚ |
| OpenEats | ✔️ | ❌ | ✔ | | Plantoeat | ✔️ | ❌ | ✔ |
✔ = implemented, ❌ = not implemented and not possible/planned, ⌚ = not yet implemented ✔ = implemented, ❌ = not implemented and not possible/planned, ⌚ = not yet implemented