Merge pull request #2140 from TiagoRascazzi/develop
Added nextcloud export implementation
This commit is contained in:
commit
00a59baa92
@ -1,7 +1,8 @@
|
|||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
from io import BytesIO
|
from io import BytesIO, StringIO
|
||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
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
|
||||||
@ -96,5 +97,92 @@ class NextcloudCookbook(Integration):
|
|||||||
|
|
||||||
return recipe
|
return recipe
|
||||||
|
|
||||||
|
def formatTime(self, min):
|
||||||
|
h = min//60
|
||||||
|
m = min % 60
|
||||||
|
return f'PT{h}H{m}M0S'
|
||||||
|
|
||||||
|
|
||||||
def get_file_from_recipe(self, recipe):
|
def get_file_from_recipe(self, recipe):
|
||||||
raise NotImplementedError('Method not implemented in storage integration')
|
|
||||||
|
export = {}
|
||||||
|
export['name'] = recipe.name
|
||||||
|
export['description'] = recipe.description
|
||||||
|
export['url'] = recipe.source_url
|
||||||
|
export['prepTime'] = self.formatTime(recipe.working_time)
|
||||||
|
export['cookTime'] = self.formatTime(recipe.waiting_time)
|
||||||
|
export['totalTime'] = self.formatTime(recipe.working_time+recipe.waiting_time)
|
||||||
|
export['recipeYield'] = recipe.servings
|
||||||
|
export['image'] = f'/Recipes/{recipe.name}/full.jpg'
|
||||||
|
export['imageUrl'] = f'/Recipes/{recipe.name}/full.jpg'
|
||||||
|
|
||||||
|
recipeKeyword = []
|
||||||
|
for k in recipe.keywords.all():
|
||||||
|
recipeKeyword.append(k.name)
|
||||||
|
|
||||||
|
export['keywords'] = recipeKeyword
|
||||||
|
|
||||||
|
recipeInstructions = []
|
||||||
|
recipeIngredient = []
|
||||||
|
for s in recipe.steps.all():
|
||||||
|
recipeInstructions.append(s.instruction)
|
||||||
|
|
||||||
|
for i in s.ingredients.all():
|
||||||
|
recipeIngredient.append(f'{float(i.amount)} {i.unit} {i.food}')
|
||||||
|
|
||||||
|
export['recipeIngredient'] = recipeIngredient
|
||||||
|
export['recipeInstructions'] = recipeInstructions
|
||||||
|
|
||||||
|
|
||||||
|
return "recipe.json", json.dumps(export)
|
||||||
|
|
||||||
|
def get_files_from_recipes(self, recipes, el, cookie):
|
||||||
|
export_zip_stream = BytesIO()
|
||||||
|
export_zip_obj = ZipFile(export_zip_stream, 'w')
|
||||||
|
|
||||||
|
for recipe in recipes:
|
||||||
|
if recipe.internal and recipe.space == self.request.space:
|
||||||
|
|
||||||
|
recipe_stream = StringIO()
|
||||||
|
filename, data = self.get_file_from_recipe(recipe)
|
||||||
|
recipe_stream.write(data)
|
||||||
|
export_zip_obj.writestr(f'{recipe.name}/{filename}', recipe_stream.getvalue())
|
||||||
|
recipe_stream.close()
|
||||||
|
|
||||||
|
try:
|
||||||
|
imageByte = recipe.image.file.read()
|
||||||
|
export_zip_obj.writestr(f'{recipe.name}/full.jpg', self.getJPEG(imageByte))
|
||||||
|
export_zip_obj.writestr(f'{recipe.name}/thumb.jpg', self.getThumb(171, imageByte))
|
||||||
|
export_zip_obj.writestr(f'{recipe.name}/thumb16.jpg', self.getThumb(16, imageByte))
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
el.exported_recipes += 1
|
||||||
|
el.msg += self.get_recipe_processed_msg(recipe)
|
||||||
|
el.save()
|
||||||
|
|
||||||
|
export_zip_obj.close()
|
||||||
|
|
||||||
|
return [[ self.get_export_file_name(), export_zip_stream.getvalue() ]]
|
||||||
|
|
||||||
|
def getJPEG(self, imageByte):
|
||||||
|
image = Image.open(BytesIO(imageByte))
|
||||||
|
image = image.convert('RGB')
|
||||||
|
|
||||||
|
bytes = BytesIO()
|
||||||
|
image.save(bytes, "JPEG")
|
||||||
|
return bytes.getvalue()
|
||||||
|
|
||||||
|
def getThumb(self, size, imageByte):
|
||||||
|
image = Image.open(BytesIO(imageByte))
|
||||||
|
|
||||||
|
w, h = image.size
|
||||||
|
m = min(w, h)
|
||||||
|
|
||||||
|
image = image.crop(((w-m)//2, (h-m)//2, (w+m)//2, (h+m)//2))
|
||||||
|
image = image.resize([size, size], Image.Resampling.LANCZOS)
|
||||||
|
image = image.convert('RGB')
|
||||||
|
|
||||||
|
bytes = BytesIO()
|
||||||
|
image.save(bytes, "JPEG")
|
||||||
|
return bytes.getvalue()
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
<select class="form-control" v-model="recipe_app">
|
<select class="form-control" v-model="recipe_app">
|
||||||
<option value="DEFAULT">Default</option>
|
<option value="DEFAULT">Default</option>
|
||||||
<option value="SAFFRON">Saffron</option>
|
<option value="SAFFRON">Saffron</option>
|
||||||
|
<option value="NEXTCLOUD">Nextcloud Cookbook</option>
|
||||||
<option value="RECIPESAGE">Recipe Sage</option>
|
<option value="RECIPESAGE">Recipe Sage</option>
|
||||||
<option value="PDF">PDF (experimental)</option>
|
<option value="PDF">PDF (experimental)</option>
|
||||||
</select>
|
</select>
|
||||||
|
Loading…
Reference in New Issue
Block a user