This commit is contained in:
vabene1111
2021-02-20 23:42:44 +01:00
parent 58c6077925
commit beb4aa634f
7 changed files with 107 additions and 48 deletions

View File

@ -6,7 +6,7 @@ from emoji_picker.widgets import EmojiPickerTextInput
from .models import (Comment, Food, InviteLink, Keyword, MealPlan, Recipe, from .models import (Comment, Food, InviteLink, Keyword, MealPlan, Recipe,
RecipeBook, RecipeBookEntry, Storage, Sync, Unit, User, RecipeBook, RecipeBookEntry, Storage, Sync, Unit, User,
UserPreference) UserPreference, SupermarketCategory, MealType)
class SelectWidget(widgets.Select): class SelectWidget(widgets.Select):
@ -77,11 +77,16 @@ class ExternalRecipeForm(forms.ModelForm):
file_path = forms.CharField(disabled=True, required=False) file_path = forms.CharField(disabled=True, required=False)
file_uid = forms.CharField(disabled=True, required=False) file_uid = forms.CharField(disabled=True, required=False)
def __init__(self, *args, **kwargs):
space = kwargs.pop('space')
super().__init__(*args, **kwargs)
self.fields['keywords'].queryset = Keyword.objects.filter(space=space).all()
class Meta: class Meta:
model = Recipe model = Recipe
fields = ( fields = (
'name', 'description', 'servings', 'working_time', 'waiting_time', 'name', 'description', 'servings', 'working_time', 'waiting_time',
'file_path', 'file_uid' 'file_path', 'file_uid', 'keywords'
) )
labels = { labels = {
@ -92,7 +97,10 @@ class ExternalRecipeForm(forms.ModelForm):
'file_path': _('Path'), 'file_path': _('Path'),
'file_uid': _('Storage UID'), 'file_uid': _('Storage UID'),
} }
# widgets = {'keywords': MultiSelectWidget} widgets = {'keywords': MultiSelectWidget}
field_classes = {
'keywords': SafeModelMultipleChoiceField,
}
class ImportExportBase(forms.Form): class ImportExportBase(forms.Form):
@ -114,12 +122,12 @@ class ImportForm(ImportExportBase):
class ExportForm(ImportExportBase): class ExportForm(ImportExportBase):
recipes = forms.ModelMultipleChoiceField(widget=MultiSelectWidget, queryset=None) recipes = forms.ModelMultipleChoiceField(widget=MultiSelectWidget, queryset=Recipe.objects.none())
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__() space = kwargs.pop('space')
user = kwargs.pop('user') super().__init__(*args, **kwargs)
self.fields['recipes'].queryset = Recipe.objects.filter(internal=True).filter(space=user.userpreference.space).all() self.fields['recipes'].queryset = Recipe.objects.filter(space=space).all()
class UnitMergeForm(forms.Form): class UnitMergeForm(forms.Form):
@ -138,8 +146,12 @@ class UnitMergeForm(forms.Form):
help_text=_('Unit that should be replaced.'), help_text=_('Unit that should be replaced.'),
) )
def __init__(self, *args, **kwargs):
space = kwargs.pop('space')
super().__init__(*args, **kwargs)
self.fields['new_unit'].queryset = Unit.objects.filter(space=space).all()
self.fields['old_unit'].queryset = Unit.objects.filter(space=space).all()
# todo spaces form here on
class FoodMergeForm(forms.Form): class FoodMergeForm(forms.Form):
prefix = 'food' prefix = 'food'
@ -157,6 +169,12 @@ class FoodMergeForm(forms.Form):
help_text=_('Food that should be replaced.'), help_text=_('Food that should be replaced.'),
) )
def __init__(self, *args, **kwargs):
space = kwargs.pop('space')
super().__init__(*args, **kwargs)
self.fields['new_food'].queryset = Food.objects.filter(space=space).all()
self.fields['old_food'].queryset = Food.objects.filter(space=space).all()
class CommentForm(forms.ModelForm): class CommentForm(forms.ModelForm):
prefix = 'comment' prefix = 'comment'
@ -181,6 +199,13 @@ class KeywordForm(forms.ModelForm):
class FoodForm(forms.ModelForm): class FoodForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
space = kwargs.pop('space')
super().__init__(*args, **kwargs)
self.fields['recipe'].queryset = Recipe.objects.filter(space=space).all()
self.fields['supermarket_category'].queryset = SupermarketCategory.objects.filter(space=space).all()
class Meta: class Meta:
model = Food model = Food
fields = ('name', 'description', 'ignore_shopping', 'recipe', 'supermarket_category') fields = ('name', 'description', 'ignore_shopping', 'recipe', 'supermarket_category')
@ -198,18 +223,16 @@ class StorageForm(forms.ModelForm):
required=False required=False
) )
password = forms.CharField( password = forms.CharField(
widget=forms.TextInput( widget=forms.TextInput(attrs={'autocomplete': 'new-password', 'type': 'password'}),
attrs={'autocomplete': 'new-password', 'type': 'password'}
),
required=False, required=False,
help_text=_('Leave empty for dropbox and enter app password for nextcloud.') # noqa: E501 help_text=_('Leave empty for dropbox and enter app password for nextcloud.')
) )
token = forms.CharField( token = forms.CharField(
widget=forms.TextInput( widget=forms.TextInput(
attrs={'autocomplete': 'new-password', 'type': 'password'} attrs={'autocomplete': 'new-password', 'type': 'password'}
), ),
required=False, required=False,
help_text=_('Leave empty for nextcloud and enter api token for dropbox.') # noqa: E501 help_text=_('Leave empty for nextcloud and enter api token for dropbox.')
) )
class Meta: class Meta:
@ -217,13 +240,18 @@ class StorageForm(forms.ModelForm):
fields = ('name', 'method', 'username', 'password', 'token', 'url', 'path') fields = ('name', 'method', 'username', 'password', 'token', 'url', 'path')
help_texts = { help_texts = {
'url': _('Leave empty for dropbox and enter only base url for nextcloud (<code>/remote.php/webdav/</code> is added automatically)'), # noqa: E501 'url': _('Leave empty for dropbox and enter only base url for nextcloud (<code>/remote.php/webdav/</code> is added automatically)'),
} }
class RecipeBookEntryForm(forms.ModelForm): class RecipeBookEntryForm(forms.ModelForm):
prefix = 'bookmark' prefix = 'bookmark'
def __init__(self, *args, **kwargs):
space = kwargs.pop('space')
super().__init__(*args, **kwargs)
self.fields['book'].queryset = RecipeBook.objects.filter(space=space).all()
class Meta: class Meta:
model = RecipeBookEntry model = RecipeBookEntry
fields = ('book',) fields = ('book',)
@ -234,6 +262,12 @@ class RecipeBookEntryForm(forms.ModelForm):
class SyncForm(forms.ModelForm): class SyncForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
space = kwargs.pop('space')
super().__init__(*args, **kwargs)
self.fields['book'].queryset = Storage.objects.filter(space=space).all()
class Meta: class Meta:
model = Sync model = Sync
fields = ('storage', 'path', 'active') fields = ('storage', 'path', 'active')
@ -246,13 +280,23 @@ class SyncForm(forms.ModelForm):
class BatchEditForm(forms.Form): class BatchEditForm(forms.Form):
search = forms.CharField(label=_('Search String')) search = forms.CharField(label=_('Search String'))
keywords = forms.ModelMultipleChoiceField( keywords = forms.ModelMultipleChoiceField(
queryset=Keyword.objects.none().order_by('id'), queryset=Keyword.objects.none(),
required=False, required=False,
widget=MultiSelectWidget widget=MultiSelectWidget
) )
def __init__(self, *args, **kwargs):
space = kwargs.pop('space')
super().__init__(*args, **kwargs)
self.fields['keywords'].queryset = Keyword.objects.filter(space=space).all().order_by('id')
class ImportRecipeForm(forms.ModelForm): class ImportRecipeForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
space = kwargs.pop('space')
super().__init__(*args, **kwargs)
self.fields['keywords'].queryset = Keyword.objects.filter(space=space).all()
class Meta: class Meta:
model = Recipe model = Recipe
fields = ('name', 'keywords', 'file_path', 'file_uid') fields = ('name', 'keywords', 'file_path', 'file_uid')
@ -270,6 +314,11 @@ class ImportRecipeForm(forms.ModelForm):
class RecipeBookForm(forms.ModelForm): class RecipeBookForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
space = kwargs.pop('space')
super().__init__(*args, **kwargs)
self.fields['shared'].queryset = User.objects.filter(userpreference__space=space).all()
class Meta: class Meta:
model = RecipeBook model = RecipeBook
fields = ('name', 'icon', 'description', 'shared') fields = ('name', 'icon', 'description', 'shared')
@ -280,6 +329,12 @@ class RecipeBookForm(forms.ModelForm):
class MealPlanForm(forms.ModelForm): class MealPlanForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
space = kwargs.pop('space')
super().__init__(*args, **kwargs)
self.fields['recipe'].queryset = Recipe.objects.filter(space=space).all()
self.fields['meal_type'].queryset = MealType.objects.filter(space=space).all()
self.fields['shared'].queryset = User.objects.filter(userpreference__space=space).all()
def clean(self): def clean(self):
cleaned_data = super(MealPlanForm, self).clean() cleaned_data = super(MealPlanForm, self).clean()

View File

@ -9,8 +9,8 @@ class ScopeMiddleware:
if request.user.is_authenticated: if request.user.is_authenticated:
request.space = request.user.userpreference.space request.space = request.user.userpreference.space
#with scopes_disabled(): with scopes_disabled():
with scope(space=request.space): #with scope(space=request.space):
return self.get_response(request) return self.get_response(request)
else: else:
return self.get_response(request) return self.get_response(request)

View File

@ -73,7 +73,7 @@ def batch_import(request):
@group_required('user') @group_required('user')
def batch_edit(request): def batch_edit(request):
if request.method == "POST": if request.method == "POST":
form = BatchEditForm(request.POST) form = BatchEditForm(request.POST, space=request.space)
if form.is_valid(): if form.is_valid():
word = form.cleaned_data['search'] word = form.cleaned_data['search']
keywords = form.cleaned_data['keywords'] keywords = form.cleaned_data['keywords']
@ -100,7 +100,7 @@ def batch_edit(request):
return redirect('data_batch_edit') return redirect('data_batch_edit')
else: else:
form = BatchEditForm() form = BatchEditForm(space=request.space)
return render(request, 'batch/edit.html', {'form': form}) return render(request, 'batch/edit.html', {'form': form})

View File

@ -6,6 +6,7 @@ from django.shortcuts import get_object_or_404, render
from django.urls import reverse, reverse_lazy from django.urls import reverse, reverse_lazy
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.views.generic import UpdateView from django.views.generic import UpdateView
from django.views.generic.edit import FormMixin
from django_scopes import scopes_disabled from django_scopes import scopes_disabled
from cookbook.forms import (CommentForm, ExternalRecipeForm, FoodForm, from cookbook.forms import (CommentForm, ExternalRecipeForm, FoodForm,
@ -51,7 +52,15 @@ def internal_recipe_update(request, pk):
) )
class SyncUpdate(GroupRequiredMixin, UpdateView): class SpaceFormMixing(FormMixin):
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs.update({'space': self.request.space})
return kwargs
class SyncUpdate(GroupRequiredMixin, UpdateView, SpaceFormMixing):
groups_required = ['admin'] groups_required = ['admin']
template_name = "generic/edit_template.html" template_name = "generic/edit_template.html"
model = Sync model = Sync
@ -85,7 +94,7 @@ class KeywordUpdate(GroupRequiredMixin, UpdateView):
return context return context
class FoodUpdate(GroupRequiredMixin, UpdateView): class FoodUpdate(GroupRequiredMixin, UpdateView, SpaceFormMixing):
groups_required = ['user'] groups_required = ['user']
template_name = "generic/edit_template.html" template_name = "generic/edit_template.html"
model = Food model = Food
@ -182,7 +191,7 @@ class ImportUpdate(GroupRequiredMixin, UpdateView):
return context return context
class RecipeBookUpdate(OwnerRequiredMixin, UpdateView): class RecipeBookUpdate(OwnerRequiredMixin, UpdateView, SpaceFormMixing):
template_name = "generic/edit_template.html" template_name = "generic/edit_template.html"
model = RecipeBook model = RecipeBook
form_class = RecipeBookForm form_class = RecipeBookForm
@ -196,7 +205,7 @@ class RecipeBookUpdate(OwnerRequiredMixin, UpdateView):
return context return context
class MealPlanUpdate(OwnerRequiredMixin, UpdateView): class MealPlanUpdate(OwnerRequiredMixin, UpdateView, SpaceFormMixing):
template_name = "generic/edit_template.html" template_name = "generic/edit_template.html"
model = MealPlan model = MealPlan
form_class = MealPlanForm form_class = MealPlanForm
@ -216,7 +225,7 @@ class MealPlanUpdate(OwnerRequiredMixin, UpdateView):
return context return context
class ExternalRecipeUpdate(GroupRequiredMixin, UpdateView): class ExternalRecipeUpdate(GroupRequiredMixin, UpdateView, SpaceFormMixing):
groups_required = ['user'] groups_required = ['user']
model = Recipe model = Recipe
form_class = ExternalRecipeForm form_class = ExternalRecipeForm
@ -226,8 +235,8 @@ class ExternalRecipeUpdate(GroupRequiredMixin, UpdateView):
self.object = form.save(commit=False) self.object = form.save(commit=False)
old_recipe = Recipe.objects.get(pk=self.object.pk, space=self.request.space) old_recipe = Recipe.objects.get(pk=self.object.pk, space=self.request.space)
if not old_recipe.name == self.object.name: if not old_recipe.name == self.object.name:
if self.object.storage.method == Storage.DROPBOX:
# TODO central location to handle storage type switches # TODO central location to handle storage type switches
if self.object.storage.method == Storage.DROPBOX:
Dropbox.rename_file(old_recipe, self.object.name) Dropbox.rename_file(old_recipe, self.object.name)
if self.object.storage.method == Storage.NEXTCLOUD: if self.object.storage.method == Storage.NEXTCLOUD:
Nextcloud.rename_file(old_recipe, self.object.name) Nextcloud.rename_file(old_recipe, self.object.name)
@ -240,24 +249,18 @@ class ExternalRecipeUpdate(GroupRequiredMixin, UpdateView):
os.path.splitext(self.object.file_path)[1] os.path.splitext(self.object.file_path)[1]
) )
messages.add_message( messages.add_message(self.request, messages.SUCCESS, _('Changes saved!'))
self.request, messages.SUCCESS, _('Changes saved!')
)
return super(ExternalRecipeUpdate, self).form_valid(form) return super(ExternalRecipeUpdate, self).form_valid(form)
def form_invalid(self, form): def form_invalid(self, form):
messages.add_message( messages.add_message(self.request, messages.ERROR, _('Error saving changes!'))
self.request,
messages.ERROR,
_('Error saving changes!')
)
return super(ExternalRecipeUpdate, self).form_valid(form) return super(ExternalRecipeUpdate, self).form_valid(form)
def get_success_url(self): def get_success_url(self):
return reverse('edit_recipe', kwargs={'pk': self.object.pk}) return reverse('edit_recipe', kwargs={'pk': self.object.pk})
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(ExternalRecipeUpdate, self).get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context['title'] = _("Recipe") context['title'] = _("Recipe")
context['view_url'] = reverse('view_recipe', args=[self.object.pk]) context['view_url'] = reverse('view_recipe', args=[self.object.pk])
if self.object.storage: if self.object.storage:
@ -271,7 +274,7 @@ class ExternalRecipeUpdate(GroupRequiredMixin, UpdateView):
def edit_ingredients(request): def edit_ingredients(request):
if request.method == "POST": if request.method == "POST":
success = False success = False
units_form = UnitMergeForm(request.POST, prefix=UnitMergeForm.prefix) units_form = UnitMergeForm(request.POST, prefix=UnitMergeForm.prefix, space=request.space)
if units_form.is_valid(): if units_form.is_valid():
new_unit = units_form.cleaned_data['new_unit'] new_unit = units_form.cleaned_data['new_unit']
old_unit = units_form.cleaned_data['old_unit'] old_unit = units_form.cleaned_data['old_unit']
@ -287,7 +290,7 @@ def edit_ingredients(request):
else: else:
messages.add_message(request, messages.ERROR, _('Cannot merge with the same object!')) messages.add_message(request, messages.ERROR, _('Cannot merge with the same object!'))
food_form = FoodMergeForm(request.POST, prefix=FoodMergeForm.prefix) food_form = FoodMergeForm(request.POST, prefix=FoodMergeForm.prefix, space=request.space)
if food_form.is_valid(): if food_form.is_valid():
new_food = food_form.cleaned_data['new_food'] new_food = food_form.cleaned_data['new_food']
old_food = food_form.cleaned_data['old_food'] old_food = food_form.cleaned_data['old_food']
@ -304,10 +307,10 @@ def edit_ingredients(request):
messages.add_message(request, messages.ERROR, _('Cannot merge with the same object!')) messages.add_message(request, messages.ERROR, _('Cannot merge with the same object!'))
if success: if success:
units_form = UnitMergeForm() units_form = UnitMergeForm(space=request.space)
food_form = FoodMergeForm() food_form = FoodMergeForm(space=request.space)
else: else:
units_form = UnitMergeForm() units_form = UnitMergeForm(space=request.space)
food_form = FoodMergeForm() food_form = FoodMergeForm(space=request.space)
return render(request, 'forms/ingredients.html', {'units_form': units_form, 'food_form': food_form}) return render(request, 'forms/ingredients.html', {'units_form': units_form, 'food_form': food_form})

View File

@ -49,7 +49,7 @@ def import_recipe(request):
@group_required('user') @group_required('user')
def export_recipe(request): def export_recipe(request):
if request.method == "POST": if request.method == "POST":
form = ExportForm(request.POST, user=request.user) form = ExportForm(request.POST, space=request.space)
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'])
@ -58,11 +58,11 @@ def export_recipe(request):
messages.add_message(request, messages.ERROR, _('Exporting is not implemented for this provider')) messages.add_message(request, messages.ERROR, _('Exporting is not implemented for this provider'))
else: else:
form = ExportForm(user=request.user) form = ExportForm(space=request.space)
recipe = request.GET.get('r') recipe = request.GET.get('r')
if recipe: if recipe:
if re.match(r'^([0-9])+$', recipe): if re.match(r'^([0-9])+$', recipe):
if recipe := Recipe.objects.filter(pk=int(recipe), space=request.space).first(): if recipe := Recipe.objects.filter(pk=int(recipe), space=request.space).first():
form = ExportForm(initial={'recipes': recipe}, user=request.user) form = ExportForm(initial={'recipes': recipe}, space=request.space)
return render(request, 'export.html', {'form': form}) return render(request, 'export.html', {'form': form})

View File

@ -14,6 +14,7 @@ from cookbook.helper.permission_helper import (GroupRequiredMixin,
group_required) group_required)
from cookbook.models import (InviteLink, Keyword, MealPlan, MealType, Recipe, from cookbook.models import (InviteLink, Keyword, MealPlan, MealType, Recipe,
RecipeBook, RecipeImport, ShareLink, Step) RecipeBook, RecipeImport, ShareLink, Step)
from cookbook.views.edit import SpaceFormMixing
class RecipeCreate(GroupRequiredMixin, CreateView): class RecipeCreate(GroupRequiredMixin, CreateView):
@ -89,7 +90,7 @@ class StorageCreate(GroupRequiredMixin, CreateView):
@group_required('user') @group_required('user')
def create_new_external_recipe(request, import_id): def create_new_external_recipe(request, import_id):
if request.method == "POST": if request.method == "POST":
form = ImportRecipeForm(request.POST) form = ImportRecipeForm(request.POST, space=request.space)
if form.is_valid(): if form.is_valid():
new_recipe = get_object_or_404(RecipeImport, pk=import_id, space=request.space) new_recipe = get_object_or_404(RecipeImport, pk=import_id, space=request.space)
recipe = Recipe() recipe = Recipe()
@ -117,13 +118,13 @@ def create_new_external_recipe(request, import_id):
'file_path': new_recipe.file_path, 'file_path': new_recipe.file_path,
'name': new_recipe.name, 'name': new_recipe.name,
'file_uid': new_recipe.file_uid 'file_uid': new_recipe.file_uid
} }, space=request.space
) )
return render(request, 'forms/edit_import_recipe.html', {'form': form}) return render(request, 'forms/edit_import_recipe.html', {'form': form})
class RecipeBookCreate(GroupRequiredMixin, CreateView): class RecipeBookCreate(GroupRequiredMixin, CreateView, SpaceFormMixing):
groups_required = ['user'] groups_required = ['user']
template_name = "generic/new_template.html" template_name = "generic/new_template.html"
model = RecipeBook model = RecipeBook
@ -143,7 +144,7 @@ class RecipeBookCreate(GroupRequiredMixin, CreateView):
return context return context
class MealPlanCreate(GroupRequiredMixin, CreateView): class MealPlanCreate(GroupRequiredMixin, CreateView, SpaceFormMixing):
groups_required = ['user'] groups_required = ['user']
template_name = "generic/new_template.html" template_name = "generic/new_template.html"
model = MealPlan model = MealPlan

View File

@ -129,7 +129,7 @@ def recipe_view(request, pk, share=None):
request, messages.SUCCESS, _('Comment saved!') request, messages.SUCCESS, _('Comment saved!')
) )
bookmark_form = RecipeBookEntryForm(request.POST, prefix='bookmark') bookmark_form = RecipeBookEntryForm(request.POST, prefix='bookmark', space=request.space)
if bookmark_form.is_valid(): if bookmark_form.is_valid():
bookmark = RecipeBookEntry() bookmark = RecipeBookEntry()
bookmark.recipe = recipe bookmark.recipe = recipe