Merge branch 'develop' into feature/custom_filters

# Conflicts:
#	cookbook/serializer.py
#	cookbook/views/api.py
#	vue/src/utils/openapi/api.ts
This commit is contained in:
vabene1111
2022-02-07 18:56:19 +01:00
45 changed files with 1538 additions and 320 deletions

View File

@@ -48,11 +48,13 @@ from cookbook.models import (Automation, BookmarkletImport, CookLog, CustomFilte
ShoppingListEntry, ShoppingListRecipe, Step, Storage, Supermarket,
SupermarketCategory, SupermarketCategoryRelation, Sync, SyncLog, Unit,
UserFile, UserPreference, ViewLog)
from cookbook.models import (ExportLog)
from cookbook.provider.dropbox import Dropbox
from cookbook.provider.local import Local
from cookbook.provider.nextcloud import Nextcloud
from cookbook.schemas import FilterSchema, QueryParam, QueryParamAutoSchema, TreeSchema
from cookbook.serializer import (AutomationSerializer, BookmarkletImportSerializer,
ExportLogSerializer,
CookLogSerializer, CustomFilterSerializer,
FoodInheritFieldSerializer, FoodSerializer,
FoodShoppingUpdateSerializer, ImportLogSerializer,
@@ -660,11 +662,13 @@ class RecipeViewSet(viewsets.ModelViewSet):
schema = QueryParamAutoSchema()
def get_queryset(self):
share = self.request.query_params.get('share', None)
if self.detail:
self.queryset = self.queryset.filter(space=self.request.space)
if not share:
self.queryset = self.queryset.filter(space=self.request.space)
return super().get_queryset()
share = self.request.query_params.get('share', None)
if not (share and self.detail):
self.queryset = self.queryset.filter(space=self.request.space)
@@ -872,6 +876,17 @@ class ImportLogViewSet(viewsets.ModelViewSet):
return self.queryset.filter(space=self.request.space)
class ExportLogViewSet(viewsets.ModelViewSet):
queryset = ExportLog.objects
serializer_class = ExportLogSerializer
permission_classes = [CustomIsUser]
pagination_class = DefaultPagination
def get_queryset(self):
return self.queryset.filter(space=self.request.space)
class BookmarkletImportViewSet(viewsets.ModelViewSet):
queryset = BookmarkletImport.objects
serializer_class = BookmarkletImportSerializer

View File

@@ -1,10 +1,11 @@
import re
import threading
from io import BytesIO
from django.core.cache import cache
from django.contrib import messages
from django.http import HttpResponseRedirect, JsonResponse
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
from django.shortcuts import render, get_object_or_404
from django.urls import reverse
from django.utils.translation import gettext as _
@@ -29,7 +30,7 @@ from cookbook.integration.recipesage import RecipeSage
from cookbook.integration.rezkonv import RezKonv
from cookbook.integration.saffron import Saffron
from cookbook.integration.pdfexport import PDFexport
from cookbook.models import Recipe, ImportLog, UserPreference
from cookbook.models import Recipe, ImportLog, ExportLog, UserPreference
from recipes import settings
@@ -123,25 +124,57 @@ def export_recipe(request):
if form.cleaned_data['all']:
recipes = Recipe.objects.filter(space=request.space, internal=True).all()
if form.cleaned_data['type'] == ImportExportBase.PDF and not settings.ENABLE_PDF_EXPORT:
messages.add_message(request, messages.ERROR, _('The PDF Exporter is not enabled on this instance as it is still in an experimental state.'))
return render(request, 'export.html', {'form': form})
integration = get_integration(request, form.cleaned_data['type'])
return integration.do_export(recipes)
except NotImplementedError:
messages.add_message(request, messages.ERROR, _('Exporting is not implemented for this provider'))
if form.cleaned_data['type'] == ImportExportBase.PDF and not settings.ENABLE_PDF_EXPORT:
return JsonResponse({'error': _('The PDF Exporter is not enabled on this instance as it is still in an experimental state.')})
el = ExportLog.objects.create(type=form.cleaned_data['type'], created_by=request.user, space=request.space)
t = threading.Thread(target=integration.do_export, args=[recipes, el])
t.setDaemon(True)
t.start()
return JsonResponse({'export_id': el.pk})
except NotImplementedError:
return JsonResponse(
{
'error': True,
'msg': _('Importing is not implemented for this provider')
},
status=400
)
else:
form = ExportForm(space=request.space)
pk = ''
recipe = request.GET.get('r')
if recipe:
if re.match(r'^([0-9])+$', recipe):
if recipe := Recipe.objects.filter(pk=int(recipe), space=request.space).first():
form = ExportForm(initial={'recipes': recipe}, space=request.space)
pk = Recipe.objects.filter(pk=int(recipe), space=request.space).first().pk
return render(request, 'export.html', {'form': form})
return render(request, 'export.html', {'pk': pk})
@group_required('user')
def import_response(request, pk):
return render(request, 'import_response.html', {'pk': pk})
@group_required('user')
def export_response(request, pk):
return render(request, 'export_response.html', {'pk': pk})
@group_required('user')
def export_file(request, pk):
el = get_object_or_404(ExportLog, pk=pk, space=request.space)
cacheData = cache.get(f'export_file_{el.pk}')
if cacheData is None:
el.possibly_not_expired = False
el.save()
return render(request, 'export_response.html', {'pk': pk})
response = HttpResponse(cacheData['file'], content_type='application/force-download')
response['Content-Disposition'] = 'attachment; filename="' + cacheData['filename'] + '"'
return response

View File

@@ -446,6 +446,9 @@ def history(request):
@group_required('admin')
def system(request):
if not request.user.is_superuser:
return HttpResponseRedirect(reverse('index'))
postgres = False if (
settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql_psycopg2' # noqa: E501
or settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql' # noqa: E501