Merge branch 'develop' into feature/allauth

# Conflicts:
#	requirements.txt
This commit is contained in:
vabene1111
2021-01-28 12:07:30 +01:00
31 changed files with 837 additions and 205 deletions

View File

@@ -36,8 +36,9 @@ from cookbook.models import (CookLog, Food, Ingredient, Keyword, MealPlan,
MealType, Recipe, RecipeBook, ShoppingList,
ShoppingListEntry, ShoppingListRecipe, Step,
Storage, Sync, SyncLog, Unit, UserPreference,
ViewLog, RecipeBookEntry)
ViewLog, RecipeBookEntry, Supermarket)
from cookbook.provider.dropbox import Dropbox
from cookbook.provider.local import Local
from cookbook.provider.nextcloud import Nextcloud
from cookbook.serializer import (FoodSerializer, IngredientSerializer,
KeywordSerializer, MealPlanSerializer,
@@ -50,10 +51,35 @@ from cookbook.serializer import (FoodSerializer, IngredientSerializer,
StorageSerializer, SyncLogSerializer,
SyncSerializer, UnitSerializer,
UserNameSerializer, UserPreferenceSerializer,
ViewLogSerializer, CookLogSerializer, RecipeBookEntrySerializer, RecipeOverviewSerializer)
ViewLogSerializer, CookLogSerializer, RecipeBookEntrySerializer, RecipeOverviewSerializer, SupermarketSerializer)
from recipes.settings import DEMO
class StandardFilterMixin(ViewSetMixin):
def get_queryset(self):
queryset = self.queryset
query = self.request.query_params.get('query', None)
if query is not None:
queryset = queryset.filter(name__icontains=query)
updated_at = self.request.query_params.get('updated_at', None)
if updated_at is not None:
try:
queryset = queryset.filter(updated_at__gte=updated_at)
except FieldError:
pass
limit = self.request.query_params.get('limit', None)
random = self.request.query_params.get('random', False)
if limit is not None:
if random:
queryset = queryset.random(int(limit))
else:
queryset = queryset[:int(limit)]
return queryset
class UserNameViewSet(viewsets.ReadOnlyModelViewSet):
"""
list:
@@ -115,29 +141,10 @@ class SyncLogViewSet(viewsets.ReadOnlyModelViewSet):
permission_classes = [CustomIsAdmin, ]
class StandardFilterMixin(ViewSetMixin):
def get_queryset(self):
queryset = self.queryset
query = self.request.query_params.get('query', None)
if query is not None:
queryset = queryset.filter(name__icontains=query)
updated_at = self.request.query_params.get('updated_at', None)
if updated_at is not None:
try:
queryset = queryset.filter(updated_at__gte=updated_at)
except FieldError:
pass
limit = self.request.query_params.get('limit', None)
random = self.request.query_params.get('random', False)
if limit is not None:
if random:
queryset = queryset.random(int(limit))
else:
queryset = queryset[:int(limit)]
return queryset
class SupermarketViewSet(viewsets.ModelViewSet, StandardFilterMixin):
queryset = Supermarket.objects.all()
serializer_class = SupermarketSerializer
permission_classes = [CustomIsUser]
class KeywordViewSet(viewsets.ModelViewSet, StandardFilterMixin):
@@ -169,7 +176,7 @@ class FoodViewSet(viewsets.ModelViewSet, StandardFilterMixin):
class RecipeBookViewSet(viewsets.ModelViewSet, StandardFilterMixin):
queryset = RecipeBook.objects.all()
serializer_class = RecipeBookSerializer
permission_classes = [CustomIsOwner, CustomIsAdmin]
permission_classes = [CustomIsOwner]
def get_queryset(self):
self.queryset = super(RecipeBookViewSet, self).get_queryset()
@@ -181,7 +188,7 @@ class RecipeBookViewSet(viewsets.ModelViewSet, StandardFilterMixin):
class RecipeBookEntryViewSet(viewsets.ModelViewSet, viewsets.GenericViewSet):
queryset = RecipeBookEntry.objects.all()
serializer_class = RecipeBookEntrySerializer
permission_classes = [CustomIsOwner, CustomIsAdmin]
permission_classes = [CustomIsOwner]
def get_queryset(self):
if self.request.user.is_superuser:
@@ -200,7 +207,7 @@ class MealPlanViewSet(viewsets.ModelViewSet):
"""
queryset = MealPlan.objects.all()
serializer_class = MealPlanSerializer
permission_classes = [permissions.IsAuthenticated] # TODO fix permissions
permission_classes = [CustomIsOwner]
def get_queryset(self):
queryset = MealPlan.objects.filter(
@@ -225,11 +232,10 @@ class MealTypeViewSet(viewsets.ModelViewSet):
"""
queryset = MealType.objects.order_by('order').all()
serializer_class = MealTypeSerializer
permission_classes = [permissions.IsAuthenticated]
permission_classes = [CustomIsOwner]
def get_queryset(self):
queryset = MealType.objects.order_by('order', 'id') \
.filter(created_by=self.request.user).all()
queryset = MealType.objects.order_by('order', 'id').filter(created_by=self.request.user).all()
return queryset
@@ -310,17 +316,19 @@ class RecipeViewSet(viewsets.ModelViewSet, StandardFilterMixin):
class ShoppingListRecipeViewSet(viewsets.ModelViewSet):
queryset = ShoppingListRecipe.objects.all()
serializer_class = ShoppingListRecipeSerializer
permission_classes = [CustomIsUser, ] # TODO add custom validation
permission_classes = [CustomIsOwner, ]
# TODO custom get qs
def get_queryset(self):
return self.queryset.filter(shoppinglist__created_by=self.request.user).all()
class ShoppingListEntryViewSet(viewsets.ModelViewSet):
queryset = ShoppingListEntry.objects.all()
serializer_class = ShoppingListEntrySerializer
permission_classes = [CustomIsOwner, ] # TODO add custom validation
permission_classes = [CustomIsOwner, ]
# TODO custom get qs
def get_queryset(self):
return self.queryset.filter(shoppinglist__created_by=self.request.user).all()
class ShoppingListViewSet(viewsets.ModelViewSet):
@@ -345,12 +353,10 @@ class ShoppingListViewSet(viewsets.ModelViewSet):
class ViewLogViewSet(viewsets.ModelViewSet):
queryset = ViewLog.objects.all()
serializer_class = ViewLogSerializer
permission_classes = [permissions.IsAuthenticated]
permission_classes = [CustomIsOwner]
def get_queryset(self):
queryset = ViewLog.objects \
.filter(created_by=self.request.user).all()[:5]
return queryset
return CookLog.objects.filter(created_by=self.request.user).all()[:5]
class CookLogViewSet(viewsets.ModelViewSet):
@@ -359,7 +365,7 @@ class CookLogViewSet(viewsets.ModelViewSet):
permission_classes = [CustomIsOwner]
def get_queryset(self):
queryset = ViewLog.objects.filter(created_by=self.request.user).all()[:5]
queryset = CookLog.objects.filter(created_by=self.request.user).all()[:5]
return queryset
@@ -370,6 +376,8 @@ def get_recipe_provider(recipe):
return Dropbox
elif recipe.storage.method == Storage.NEXTCLOUD:
return Nextcloud
elif recipe.storage.method == Storage.LOCAL:
return Local
else:
raise Exception('Provider not implemented')
@@ -394,15 +402,15 @@ def get_external_file_link(request, recipe_id):
@group_required('user')
def get_recipe_file(request, recipe_id):
recipe = Recipe.objects.get(id=recipe_id)
if not recipe.cors_link:
update_recipe_links(recipe)
# if not recipe.cors_link:
# update_recipe_links(recipe)
return FileResponse(get_recipe_provider(recipe).get_file(recipe))
@group_required('user')
def sync_all(request):
if DEMO or True:
if DEMO:
messages.add_message(
request, messages.ERROR, _('This feature is not available in the demo version!')
)
@@ -420,6 +428,10 @@ def sync_all(request):
ret = Nextcloud.import_all(monitor)
if not ret:
error = True
if monitor.storage.method == Storage.LOCAL:
ret = Local.import_all(monitor)
if not ret:
error = True
if not error:
messages.add_message(

View File

@@ -13,6 +13,7 @@ from cookbook.models import (Comment, InviteLink, Keyword, MealPlan, Recipe,
RecipeBook, RecipeBookEntry, RecipeImport,
Storage, Sync)
from cookbook.provider.dropbox import Dropbox
from cookbook.provider.local import Local
from cookbook.provider.nextcloud import Nextcloud
@@ -37,6 +38,8 @@ def delete_recipe_source(request, pk):
Dropbox.delete_file(recipe)
if recipe.storage.method == Storage.NEXTCLOUD:
Nextcloud.delete_file(recipe)
if recipe.storage.method == Storage.LOCAL:
Local.delete_file(recipe)
recipe.storage = None
recipe.file_path = ''

View File

@@ -18,6 +18,7 @@ from cookbook.models import (Comment, Food, Ingredient, Keyword, MealPlan,
MealType, Recipe, RecipeBook, RecipeImport,
Storage, Sync)
from cookbook.provider.dropbox import Dropbox
from cookbook.provider.local import Local
from cookbook.provider.nextcloud import Nextcloud
@@ -231,6 +232,8 @@ class ExternalRecipeUpdate(GroupRequiredMixin, UpdateView):
Dropbox.rename_file(old_recipe, self.object.name)
if self.object.storage.method == Storage.NEXTCLOUD:
Nextcloud.rename_file(old_recipe, self.object.name)
if self.object.storage.method == Storage.LOCAL:
Local.rename_file(old_recipe, self.object.name)
self.object.file_path = "%s/%s%s" % (
os.path.dirname(self.object.file_path),

View File

@@ -12,7 +12,7 @@ from django.core.exceptions import ValidationError
from django.db import IntegrityError
from django.db.models import Avg, Q
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.shortcuts import get_object_or_404, render, redirect
from django.urls import reverse, reverse_lazy
from django.utils import timezone
from django.utils.translation import gettext as _
@@ -28,6 +28,7 @@ from cookbook.models import (Comment, CookLog, InviteLink, MealPlan,
RecipeBook, RecipeBookEntry, ViewLog)
from cookbook.tables import (CookLogTable, RecipeTable, RecipeTableSmall,
ViewLogTable)
from recipes.settings import DEMO
from recipes.version import BUILD_REF, VERSION_NUMBER
@@ -263,6 +264,10 @@ def shopping_list(request, pk=None):
@group_required('guest')
def user_settings(request):
if DEMO:
messages.add_message(request, messages.ERROR, _('This feature is not available in the demo version!'))
return redirect('index')
up = request.user.userpreference
user_name_form = UserNameForm(instance=request.user)