TandoorRecipes/cookbook/integration/default.py

77 lines
2.6 KiB
Python

import json
import os
import uuid
from io import StringIO, BytesIO
from os.path import basename
from zipfile import ZipFile
from PIL import Image
from django.core.files import File
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
from rest_framework.renderers import JSONRenderer
from cookbook.integration.integration import Integration
from cookbook.serializer import RecipeExportSerializer
class Default(Integration):
def do_export(self, recipes):
export_zip_stream = BytesIO()
export_zip_obj = ZipFile(export_zip_stream, 'w')
for r in recipes:
if r.internal:
recipe_zip_stream = BytesIO()
recipe_zip_obj = ZipFile(recipe_zip_stream, 'w')
recipe_json_stream = StringIO()
recipe_json_stream.write(self.get_export(r))
recipe_zip_obj.writestr('recipe.json', recipe_json_stream.getvalue())
recipe_json_stream.close()
try:
recipe_zip_obj.write(r.image.path, 'image.png')
except ValueError:
pass
recipe_zip_obj.close()
export_zip_obj.writestr(str(r.pk) + '.zip', recipe_zip_stream.getvalue())
export_zip_obj.close()
response = HttpResponse(export_zip_stream.getvalue(), content_type='application/force-download')
response['Content-Disposition'] = 'attachment; filename="export.zip"'
return response
def do_import(self, files):
for f in files:
zip = ZipFile(f.file)
for z in zip.namelist():
self.get_recipe_from_zip(ZipFile(BytesIO(zip.read(z))))
return HttpResponseRedirect(reverse('view_search') + '?keywords=' + str(self.keyword.pk))
def get_recipe_from_zip(self, recipe_zip):
recipe_string = recipe_zip.read('recipe.json').decode("utf-8")
recipe = self.get_recipe(recipe_string)
if 'image.png' in recipe_zip.namelist():
recipe.image = File(BytesIO(recipe_zip.read('image.png')), name=f'{uuid.uuid4()}_{recipe.pk}.png')
recipe.save()
recipe.keywords.add(self.keyword)
def get_recipe(self, string):
data = json.loads(string)
serialized_recipe = RecipeExportSerializer(data=data, context={'request': self.request})
if serialized_recipe.is_valid():
recipe = serialized_recipe.save()
return recipe
return None
def get_export(self, recipe):
export = RecipeExportSerializer(recipe).data
return JSONRenderer().render(export).decode("utf-8")