import log working

This commit is contained in:
vabene1111
2021-03-18 18:30:12 +01:00
parent af1bc19fd8
commit 950315936e
5 changed files with 77 additions and 29 deletions

View File

@ -7,7 +7,7 @@ from .models import (Comment, CookLog, Food, Ingredient, InviteLink, Keyword,
RecipeBook, RecipeBookEntry, RecipeImport, ShareLink, RecipeBook, RecipeBookEntry, RecipeImport, ShareLink,
ShoppingList, ShoppingListEntry, ShoppingListRecipe, ShoppingList, ShoppingListEntry, ShoppingListRecipe,
Space, Step, Storage, Sync, SyncLog, Unit, UserPreference, Space, Step, Storage, Sync, SyncLog, Unit, UserPreference,
ViewLog, Supermarket, SupermarketCategory, SupermarketCategoryRelation) ViewLog, Supermarket, SupermarketCategory, SupermarketCategoryRelation, ImportLog)
class CustomUserAdmin(UserAdmin): class CustomUserAdmin(UserAdmin):
@ -213,3 +213,10 @@ class NutritionInformationAdmin(admin.ModelAdmin):
admin.site.register(NutritionInformation, NutritionInformationAdmin) admin.site.register(NutritionInformation, NutritionInformationAdmin)
class ImportLogAdmin(admin.ModelAdmin):
list_display = ('id', 'type', 'running', 'created_by', 'created_at',)
admin.site.register(ImportLog, ImportLogAdmin)

View File

@ -20,14 +20,14 @@ class Integration:
keyword = None keyword = None
files = None files = None
def __init__(self, request): def __init__(self, request, export_type):
""" """
Integration for importing and exporting recipes Integration for importing and exporting recipes
:param request: request context of import session (used to link user to created objects) :param request: request context of import session (used to link user to created objects)
""" """
self.request = request self.request = request
self.keyword = Keyword.objects.create( self.keyword = Keyword.objects.create(
name=f'Import {date_format(datetime.datetime.now(), "DATETIME_FORMAT")}.{datetime.datetime.now().strftime("%S")}', name=f'Import {export_type} {date_format(datetime.datetime.now(), "DATETIME_FORMAT")}.{datetime.datetime.now().strftime("%S")}',
description=f'Imported by {request.user.get_user_name()} at {date_format(datetime.datetime.now(), "DATETIME_FORMAT")}', description=f'Imported by {request.user.get_user_name()} at {date_format(datetime.datetime.now(), "DATETIME_FORMAT")}',
icon='📥', icon='📥',
space=request.space space=request.space
@ -77,10 +77,11 @@ class Integration:
""" """
return True return True
def do_import(self, files): def do_import(self, files, il):
""" """
Imports given files Imports given files
:param files: List of in memory files :param files: List of in memory files
:param il: Import Log object to refresh while running
:return: HttpResponseRedirect to the recipe search showing all imported recipes :return: HttpResponseRedirect to the recipe search showing all imported recipes
""" """
with scope(space=self.request.space): with scope(space=self.request.space):
@ -94,20 +95,26 @@ class Integration:
if self.import_file_name_filter(z): if self.import_file_name_filter(z):
recipe = self.get_recipe_from_file(BytesIO(import_zip.read(z.filename))) recipe = self.get_recipe_from_file(BytesIO(import_zip.read(z.filename)))
recipe.keywords.add(self.keyword) recipe.keywords.add(self.keyword)
il.msg += f'{recipe.pk} - {recipe.name} \n'
if duplicate := self.is_duplicate(recipe): if duplicate := self.is_duplicate(recipe):
ignored_recipes.append(duplicate) ignored_recipes.append(duplicate)
import_zip.close() import_zip.close()
else: else:
recipe = self.get_recipe_from_file(f['file']) recipe = self.get_recipe_from_file(f['file'])
recipe.keywords.add(self.keyword) recipe.keywords.add(self.keyword)
il.msg += f'{recipe.pk} - {recipe.name} \n'
if duplicate := self.is_duplicate(recipe): if duplicate := self.is_duplicate(recipe):
ignored_recipes.append(duplicate) ignored_recipes.append(duplicate)
except BadZipFile: except BadZipFile:
messages.add_message(self.request, messages.ERROR, _('Importer expected a .zip file. Did you choose the correct importer type for your data ?')) il.msg += 'ERROR ' + _('Importer expected a .zip file. Did you choose the correct importer type for your data ?') + '\n'
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)) il.msg += _('The following recipes were ignored because they already existed:') + ' ' + ', '.join(ignored_recipes) + '\n'
return HttpResponseRedirect(reverse('view_search') + '?keywords=' + str(self.keyword.pk))
il.keyword = self.keyword
il.msg += (_('Imported %s recipes.') % Recipe.objects.filter(keywords=self.keyword).count()) + '\n'
il.running = False
il.save()
def is_duplicate(self, recipe): def is_duplicate(self, recipe):
""" """

View File

@ -0,0 +1,31 @@
# Generated by Django 3.1.7 on 2021-03-18 17:23
import cookbook.models
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('cookbook', '0113_auto_20210317_2017'),
]
operations = [
migrations.CreateModel(
name='ImportLog',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('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(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
('keyword', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='cookbook.keyword')),
('space', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.space')),
],
bases=(models.Model, cookbook.models.PermissionModelMixin),
),
]

View File

@ -241,20 +241,6 @@ 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)
@ -655,3 +641,18 @@ class ViewLog(models.Model, PermissionModelMixin):
def __str__(self): def __str__(self):
return self.recipe.name return self.recipe.name
class ImportLog(models.Model, PermissionModelMixin):
type = models.CharField(max_length=32)
running = models.BooleanField(default=True)
msg = models.TextField(default="")
keyword = models.ForeignKey(Keyword, null=True, blank=True, on_delete=models.SET_NULL)
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}"

View File

@ -14,22 +14,22 @@ from cookbook.integration.mealie import Mealie
from cookbook.integration.nextcloud_cookbook import NextcloudCookbook from cookbook.integration.nextcloud_cookbook import NextcloudCookbook
from cookbook.integration.paprika import Paprika from cookbook.integration.paprika import Paprika
from cookbook.integration.safron import Safron from cookbook.integration.safron import Safron
from cookbook.models import Recipe from cookbook.models import Recipe, ImportLog
def get_integration(request, export_type): def get_integration(request, export_type):
if export_type == ImportExportBase.DEFAULT: if export_type == ImportExportBase.DEFAULT:
return Default(request) return Default(request, export_type)
if export_type == ImportExportBase.PAPRIKA: if export_type == ImportExportBase.PAPRIKA:
return Paprika(request) return Paprika(request, export_type)
if export_type == ImportExportBase.NEXTCLOUD: if export_type == ImportExportBase.NEXTCLOUD:
return NextcloudCookbook(request) return NextcloudCookbook(request, export_type)
if export_type == ImportExportBase.MEALIE: if export_type == ImportExportBase.MEALIE:
return Mealie(request) return Mealie(request, export_type)
if export_type == ImportExportBase.CHOWDOWN: if export_type == ImportExportBase.CHOWDOWN:
return Chowdown(request) return Chowdown(request, export_type)
if export_type == ImportExportBase.SAFRON: if export_type == ImportExportBase.SAFRON:
return Safron(request) return Safron(request, export_type)
@group_required('user') @group_required('user')
@ -39,10 +39,12 @@ 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'])
il = ImportLog.objects.create(type=form.cleaned_data['type'], created_by=request.user, space=request.space)
files = [] files = []
for f in request.FILES.getlist('files'): for f in request.FILES.getlist('files'):
files.append({'file': BytesIO(f.read()), 'name': f.name}) files.append({'file': BytesIO(f.read()), 'name': f.name})
t = threading.Thread(target=integration.do_import, args=[files]) t = threading.Thread(target=integration.do_import, args=[files, il])
t.setDaemon(True) t.setDaemon(True)
t.start() t.start()