fixed importer threading stuff
This commit is contained in:
@ -67,8 +67,8 @@ class Chowdown(Integration):
|
|||||||
recipe.steps.add(step)
|
recipe.steps.add(step)
|
||||||
|
|
||||||
for f in self.files:
|
for f in self.files:
|
||||||
if '.zip' in f.name:
|
if '.zip' in f['name']:
|
||||||
import_zip = ZipFile(f.file)
|
import_zip = ZipFile(f['file'])
|
||||||
for z in import_zip.filelist:
|
for z in import_zip.filelist:
|
||||||
if re.match(f'^images/{image}$', z.filename):
|
if re.match(f'^images/{image}$', z.filename):
|
||||||
self.import_recipe_image(recipe, BytesIO(import_zip.read(z.filename)))
|
self.import_recipe_image(recipe, BytesIO(import_zip.read(z.filename)))
|
||||||
|
@ -10,6 +10,8 @@ from django.http import HttpResponseRedirect, HttpResponse
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.formats import date_format
|
from django.utils.formats import date_format
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
from django_scopes import scope
|
||||||
|
|
||||||
from cookbook.models import Keyword, Recipe
|
from cookbook.models import Keyword, Recipe
|
||||||
|
|
||||||
|
|
||||||
@ -81,37 +83,38 @@ class Integration:
|
|||||||
:param files: List of in memory files
|
:param files: List of in memory files
|
||||||
:return: HttpResponseRedirect to the recipe search showing all imported recipes
|
:return: HttpResponseRedirect to the recipe search showing all imported recipes
|
||||||
"""
|
"""
|
||||||
ignored_recipes = []
|
with scope(space=self.request.space):
|
||||||
try:
|
ignored_recipes = []
|
||||||
self.files = files
|
try:
|
||||||
for f in files:
|
self.files = files
|
||||||
if '.zip' in f.name or '.paprikarecipes' in f.name:
|
for f in files:
|
||||||
import_zip = ZipFile(f.file)
|
if '.zip' in f['name'] or '.paprikarecipes' in f['name']:
|
||||||
for z in import_zip.filelist:
|
import_zip = ZipFile(f['file'])
|
||||||
if self.import_file_name_filter(z):
|
for z in import_zip.filelist:
|
||||||
recipe = self.get_recipe_from_file(BytesIO(import_zip.read(z.filename)))
|
if self.import_file_name_filter(z):
|
||||||
recipe.keywords.add(self.keyword)
|
recipe = self.get_recipe_from_file(BytesIO(import_zip.read(z.filename)))
|
||||||
if duplicate := self.is_duplicate(recipe):
|
recipe.keywords.add(self.keyword)
|
||||||
ignored_recipes.append(duplicate)
|
if duplicate := self.is_duplicate(recipe):
|
||||||
import_zip.close()
|
ignored_recipes.append(duplicate)
|
||||||
else:
|
import_zip.close()
|
||||||
recipe = self.get_recipe_from_file(f.file)
|
else:
|
||||||
recipe.keywords.add(self.keyword)
|
recipe = self.get_recipe_from_file(f['file'])
|
||||||
if duplicate := self.is_duplicate(recipe):
|
recipe.keywords.add(self.keyword)
|
||||||
ignored_recipes.append(duplicate)
|
if duplicate := self.is_duplicate(recipe):
|
||||||
except BadZipFile:
|
ignored_recipes.append(duplicate)
|
||||||
messages.add_message(self.request, messages.ERROR, _('Importer expected a .zip file. Did you choose the correct importer type for your data ?'))
|
except BadZipFile:
|
||||||
|
messages.add_message(self.request, messages.ERROR, _('Importer expected a .zip file. Did you choose the correct importer type for your data ?'))
|
||||||
|
|
||||||
if len(ignored_recipes) > 0:
|
if len(ignored_recipes) > 0:
|
||||||
messages.add_message(self.request, messages.WARNING, _('The following recipes were ignored because they already existed:') + ' ' + ', '.join(ignored_recipes))
|
messages.add_message(self.request, messages.WARNING, _('The following recipes were ignored because they already existed:') + ' ' + ', '.join(ignored_recipes))
|
||||||
return HttpResponseRedirect(reverse('view_search') + '?keywords=' + str(self.keyword.pk))
|
return HttpResponseRedirect(reverse('view_search') + '?keywords=' + str(self.keyword.pk))
|
||||||
|
|
||||||
def is_duplicate(self, recipe):
|
def is_duplicate(self, recipe):
|
||||||
"""
|
"""
|
||||||
Checks if a recipe is already present, if so deletes it
|
Checks if a recipe is already present, if so deletes it
|
||||||
:param recipe: Recipe object
|
:param recipe: Recipe object
|
||||||
"""
|
"""
|
||||||
if Recipe.objects.filter(space=self.request.space, name=recipe.name).exists():
|
if Recipe.objects.filter(space=self.request.space, name=recipe.name).count() > 1:
|
||||||
recipe.delete()
|
recipe.delete()
|
||||||
return recipe.name
|
return recipe.name
|
||||||
else:
|
else:
|
||||||
|
@ -40,8 +40,8 @@ class Mealie(Integration):
|
|||||||
recipe.steps.add(step)
|
recipe.steps.add(step)
|
||||||
|
|
||||||
for f in self.files:
|
for f in self.files:
|
||||||
if '.zip' in f.name:
|
if '.zip' in f['name']:
|
||||||
import_zip = ZipFile(f.file)
|
import_zip = ZipFile(f['file'])
|
||||||
for z in import_zip.filelist:
|
for z in import_zip.filelist:
|
||||||
if re.match(f'^images/{recipe_json["slug"]}.jpg$', z.filename):
|
if re.match(f'^images/{recipe_json["slug"]}.jpg$', z.filename):
|
||||||
self.import_recipe_image(recipe, BytesIO(import_zip.read(z.filename)))
|
self.import_recipe_image(recipe, BytesIO(import_zip.read(z.filename)))
|
||||||
|
@ -42,8 +42,8 @@ class NextcloudCookbook(Integration):
|
|||||||
recipe.steps.add(step)
|
recipe.steps.add(step)
|
||||||
|
|
||||||
for f in self.files:
|
for f in self.files:
|
||||||
if '.zip' in f.name:
|
if '.zip' in f['name']:
|
||||||
import_zip = ZipFile(f.file)
|
import_zip = ZipFile(f['file'])
|
||||||
for z in import_zip.filelist:
|
for z in import_zip.filelist:
|
||||||
if re.match(f'^Recipes/{recipe.name}/full.jpg$', z.filename):
|
if re.match(f'^Recipes/{recipe.name}/full.jpg$', z.filename):
|
||||||
self.import_recipe_image(recipe, BytesIO(import_zip.read(z.filename)))
|
self.import_recipe_image(recipe, BytesIO(import_zip.read(z.filename)))
|
||||||
|
@ -241,6 +241,20 @@ class SyncLog(models.Model, PermissionModelMixin):
|
|||||||
return f"{self.created_at}:{self.sync} - {self.status}"
|
return f"{self.created_at}:{self.sync} - {self.status}"
|
||||||
|
|
||||||
|
|
||||||
|
class ImportLog(models.Model, PermissionModelMixin):
|
||||||
|
type = models.CharField(max_length=32)
|
||||||
|
running = models.BooleanField(default=True)
|
||||||
|
msg = models.TextField(default="")
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
objects = ScopedManager(space='space')
|
||||||
|
space = models.ForeignKey(Space, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.created_at}:{self.type} - {self.msg}"
|
||||||
|
|
||||||
|
|
||||||
class Keyword(models.Model, PermissionModelMixin):
|
class Keyword(models.Model, PermissionModelMixin):
|
||||||
name = models.CharField(max_length=64)
|
name = models.CharField(max_length=64)
|
||||||
icon = models.CharField(max_length=16, blank=True, null=True)
|
icon = models.CharField(max_length=16, blank=True, null=True)
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import re
|
import re
|
||||||
|
import threading
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
@ -37,7 +39,15 @@ def import_recipe(request):
|
|||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
try:
|
try:
|
||||||
integration = get_integration(request, form.cleaned_data['type'])
|
integration = get_integration(request, form.cleaned_data['type'])
|
||||||
return integration.do_import(request.FILES.getlist('files'))
|
files = []
|
||||||
|
for f in request.FILES.getlist('files'):
|
||||||
|
files.append({'file': BytesIO(f.read()), 'name': f.name})
|
||||||
|
t = threading.Thread(target=integration.do_import, args=[files])
|
||||||
|
t.setDaemon(True)
|
||||||
|
t.start()
|
||||||
|
|
||||||
|
messages.add_message(request, messages.SUCCESS, 'Import started')
|
||||||
|
return render(request, 'import.html', {'form': form})
|
||||||
except NotImplementedError:
|
except NotImplementedError:
|
||||||
messages.add_message(request, messages.ERROR, _('Importing is not implemented for this provider'))
|
messages.add_message(request, messages.ERROR, _('Importing is not implemented for this provider'))
|
||||||
else:
|
else:
|
||||||
|
Reference in New Issue
Block a user