mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-04 21:58:54 -05:00
more abstract import/export interface
This commit is contained in:
@@ -1,14 +1,7 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
from io import BytesIO
|
||||||
import uuid
|
|
||||||
from io import StringIO, BytesIO
|
|
||||||
from os.path import basename
|
|
||||||
from zipfile import ZipFile
|
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 rest_framework.renderers import JSONRenderer
|
||||||
|
|
||||||
from cookbook.integration.integration import Integration
|
from cookbook.integration.integration import Integration
|
||||||
@@ -17,51 +10,16 @@ from cookbook.serializer import RecipeExportSerializer
|
|||||||
|
|
||||||
class Default(Integration):
|
class Default(Integration):
|
||||||
|
|
||||||
def do_export(self, recipes):
|
def get_recipe_from_file(self, file):
|
||||||
export_zip_stream = BytesIO()
|
recipe_zip = ZipFile(file)
|
||||||
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_string = recipe_zip.read('recipe.json').decode("utf-8")
|
||||||
recipe = self.get_recipe(recipe_string)
|
recipe = self.decode_recipe(recipe_string)
|
||||||
if 'image.png' in recipe_zip.namelist():
|
if 'image.png' in recipe_zip.namelist():
|
||||||
recipe.image = File(BytesIO(recipe_zip.read('image.png')), name=f'{uuid.uuid4()}_{recipe.pk}.png')
|
self.import_recipe_image(recipe, BytesIO(recipe_zip.read('image.png')))
|
||||||
recipe.save()
|
return recipe
|
||||||
recipe.keywords.add(self.keyword)
|
|
||||||
|
|
||||||
def get_recipe(self, string):
|
def decode_recipe(self, string):
|
||||||
data = json.loads(string)
|
data = json.loads(string)
|
||||||
serialized_recipe = RecipeExportSerializer(data=data, context={'request': self.request})
|
serialized_recipe = RecipeExportSerializer(data=data, context={'request': self.request})
|
||||||
if serialized_recipe.is_valid():
|
if serialized_recipe.is_valid():
|
||||||
@@ -70,7 +28,7 @@ class Default(Integration):
|
|||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_export(self, recipe):
|
def get_file_from_recipe(self, recipe):
|
||||||
export = RecipeExportSerializer(recipe).data
|
export = RecipeExportSerializer(recipe).data
|
||||||
|
|
||||||
return JSONRenderer().render(export).decode("utf-8")
|
return 'recipe.json', JSONRenderer().render(export).decode("utf-8")
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
import datetime
|
import datetime
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
from io import BytesIO, StringIO
|
||||||
|
from zipfile import ZipFile
|
||||||
|
|
||||||
|
from django.core.files import File
|
||||||
|
from django.http import HttpResponseRedirect, HttpResponse
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
from cookbook.models import Keyword
|
from cookbook.models import Keyword
|
||||||
|
|
||||||
@@ -16,20 +24,50 @@ class Integration:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def do_export(self, recipes):
|
def do_export(self, recipes):
|
||||||
raise Exception('Method not implemented in storage integration')
|
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_stream = StringIO()
|
||||||
|
filename, data = self.get_file_from_recipe(r)
|
||||||
|
recipe_stream.write(data)
|
||||||
|
recipe_zip_obj.writestr(filename, recipe_stream.getvalue())
|
||||||
|
recipe_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):
|
def do_import(self, files):
|
||||||
|
for f in files:
|
||||||
|
import_zip = ZipFile(f.file)
|
||||||
|
for z in import_zip.namelist():
|
||||||
|
recipe = self.get_recipe_from_file(BytesIO(import_zip.read(z)))
|
||||||
|
recipe.keywords.add(self.keyword)
|
||||||
|
|
||||||
|
return HttpResponseRedirect(reverse('view_search') + '?keywords=' + str(self.keyword.pk))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def import_recipe_image(recipe, image_file):
|
||||||
|
recipe.image = File(image_file, name=f'{uuid.uuid4()}_{recipe.pk}.png')
|
||||||
|
recipe.save()
|
||||||
|
|
||||||
|
def get_recipe_from_file(self, file):
|
||||||
raise Exception('Method not implemented in storage integration')
|
raise Exception('Method not implemented in storage integration')
|
||||||
|
|
||||||
def get_recipe(self, string):
|
def get_file_from_recipe(self, recipe):
|
||||||
raise Exception('Method not implemented in storage integration')
|
raise Exception('Method not implemented in storage integration')
|
||||||
|
|
||||||
def get_export(self, recipe):
|
|
||||||
raise Exception('Method not implemented in storage integration')
|
|
||||||
|
|
||||||
def get_export_file(self, recipe):
|
|
||||||
try:
|
|
||||||
with open(recipe.image.path, 'rb') as img_f:
|
|
||||||
return img_f
|
|
||||||
except:
|
|
||||||
return None
|
|
||||||
|
|||||||
Reference in New Issue
Block a user