mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2025-12-24 02:39:20 -05:00
182 lines
6.9 KiB
Python
182 lines
6.9 KiB
Python
from datetime import datetime
|
|
|
|
from allauth.account.forms import ResetPasswordForm, SignupForm
|
|
from allauth.socialaccount.forms import SignupForm as SocialSignupForm
|
|
from django import forms
|
|
from django.conf import settings
|
|
from django.core.exceptions import ValidationError
|
|
from django.forms import NumberInput, widgets
|
|
from django.utils.translation import gettext_lazy as _
|
|
from django_scopes import scopes_disabled
|
|
from django_scopes.forms import SafeModelChoiceField, SafeModelMultipleChoiceField
|
|
from hcaptcha.fields import hCaptchaField
|
|
|
|
from .models import Comment, InviteLink, Keyword, Recipe, SearchPreference, Space, Storage, Sync, User, UserPreference, ConnectorConfig
|
|
|
|
class SelectWidget(widgets.Select):
|
|
class Media:
|
|
js = ('custom/js/form_select.js',)
|
|
|
|
|
|
class MultiSelectWidget(widgets.SelectMultiple):
|
|
class Media:
|
|
js = ('custom/js/form_multiselect.js',)
|
|
class ImportExportBase(forms.Form):
|
|
DEFAULT = 'DEFAULT'
|
|
PAPRIKA = 'PAPRIKA'
|
|
NEXTCLOUD = 'NEXTCLOUD'
|
|
MEALIE = 'MEALIE'
|
|
MEALIE1 = 'MEALIE1'
|
|
CHOWDOWN = 'CHOWDOWN'
|
|
SAFFRON = 'SAFFRON'
|
|
CHEFTAP = 'CHEFTAP'
|
|
PEPPERPLATE = 'PEPPERPLATE'
|
|
RECIPEKEEPER = 'RECIPEKEEPER'
|
|
RECETTETEK = 'RECETTETEK'
|
|
RECIPESAGE = 'RECIPESAGE'
|
|
DOMESTICA = 'DOMESTICA'
|
|
MEALMASTER = 'MEALMASTER'
|
|
MELARECIPES = 'MELARECIPES'
|
|
REZKONV = 'REZKONV'
|
|
OPENEATS = 'OPENEATS'
|
|
PLANTOEAT = 'PLANTOEAT'
|
|
COOKBOOKAPP = 'COOKBOOKAPP'
|
|
COPYMETHAT = 'COPYMETHAT'
|
|
COOKMATE = 'COOKMATE'
|
|
REZEPTSUITEDE = 'REZEPTSUITEDE'
|
|
PDF = 'PDF'
|
|
GOURMET = 'GOURMET'
|
|
|
|
type = forms.ChoiceField(choices=((DEFAULT, _('Default')), (PAPRIKA, 'Paprika'), (NEXTCLOUD, 'Nextcloud Cookbook'), (MEALIE, 'Mealie'), (MEALIE1, 'Mealie1'), (CHOWDOWN, 'Chowdown'),
|
|
(SAFFRON, 'Saffron'), (CHEFTAP, 'ChefTap'), (PEPPERPLATE, 'Pepperplate'), (RECETTETEK, 'RecetteTek'), (RECIPESAGE, 'Recipe Sage'),
|
|
(DOMESTICA, 'Domestica'), (MEALMASTER, 'MealMaster'), (REZKONV, 'RezKonv'), (OPENEATS, 'Openeats'), (RECIPEKEEPER, 'Recipe Keeper'),
|
|
(PLANTOEAT, 'Plantoeat'), (COOKBOOKAPP, 'CookBookApp'), (COPYMETHAT, 'CopyMeThat'), (PDF, 'PDF'), (MELARECIPES, 'Melarecipes'),
|
|
(COOKMATE, 'Cookmate'), (REZEPTSUITEDE, 'Recipesuite.de'), (GOURMET, 'Gourmet')))
|
|
|
|
class MultipleFileInput(forms.ClearableFileInput):
|
|
allow_multiple_selected = True
|
|
|
|
|
|
class MultipleFileField(forms.FileField):
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
kwargs.setdefault("widget", MultipleFileInput())
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def clean(self, data, initial=None):
|
|
single_file_clean = super().clean
|
|
if isinstance(data, (list, tuple)):
|
|
result = [single_file_clean(d, initial) for d in data]
|
|
else:
|
|
result = single_file_clean(data, initial)
|
|
return result
|
|
|
|
|
|
class ImportForm(ImportExportBase):
|
|
files = MultipleFileField(required=True)
|
|
duplicates = forms.BooleanField(help_text=_('To prevent duplicates recipes with the same name as existing ones are ignored. Check this box to import everything.'),
|
|
required=False)
|
|
meal_plans = forms.BooleanField(required=False)
|
|
shopping_lists = forms.BooleanField(required=False)
|
|
nutrition_per_serving = forms.BooleanField(required=False) # some managers (e.g. mealie) do not specify what the nutrition's relate to so we let the user choose
|
|
|
|
|
|
class ExportForm(ImportExportBase):
|
|
recipes = forms.ModelMultipleChoiceField(widget=MultiSelectWidget, queryset=Recipe.objects.none(), required=False)
|
|
all = forms.BooleanField(required=False)
|
|
custom_filter = forms.IntegerField(required=False)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
space = kwargs.pop('space')
|
|
super().__init__(*args, **kwargs)
|
|
self.fields['recipes'].queryset = Recipe.objects.filter(space=space).all()
|
|
|
|
from .models import InviteLink, SearchPreference, Space, User, UserPreference
|
|
|
|
|
|
class InviteLinkForm(forms.ModelForm):
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
user = kwargs.pop('user')
|
|
super().__init__(*args, **kwargs)
|
|
self.fields['space'].queryset = Space.objects.filter(created_by=user).all()
|
|
|
|
def clean(self):
|
|
space = self.cleaned_data['space']
|
|
if space.max_users != 0 and (UserPreference.objects.filter(space=space).count()
|
|
+ InviteLink.objects.filter(valid_until__gte=datetime.today(), used_by=None, space=space).count()) >= space.max_users:
|
|
raise ValidationError(_('Maximum number of users for this space reached.'))
|
|
|
|
def clean_email(self):
|
|
email = self.cleaned_data['email']
|
|
with scopes_disabled():
|
|
if email != '' and User.objects.filter(email=email).exists():
|
|
raise ValidationError(_('Email address already taken!'))
|
|
|
|
return email
|
|
|
|
class Meta:
|
|
model = InviteLink
|
|
fields = ('email', 'group', 'valid_until', 'space')
|
|
help_texts = {'email': _('An email address is not required but if present the invite link will be sent to the user.'), }
|
|
field_classes = {'space': SafeModelChoiceField, }
|
|
|
|
|
|
class SpaceCreateForm(forms.Form):
|
|
prefix = 'create'
|
|
name = forms.CharField()
|
|
|
|
def clean_name(self):
|
|
name = self.cleaned_data['name']
|
|
with scopes_disabled():
|
|
if Space.objects.filter(name=name).exists():
|
|
raise ValidationError(_('Name already taken.'))
|
|
return name
|
|
|
|
|
|
class SpaceJoinForm(forms.Form):
|
|
prefix = 'join'
|
|
token = forms.CharField()
|
|
|
|
|
|
class AllAuthSignupForm(SignupForm):
|
|
captcha = hCaptchaField()
|
|
terms = forms.BooleanField(label=_('Accept Terms and Privacy'))
|
|
|
|
def __init__(self, **kwargs):
|
|
super().__init__(**kwargs)
|
|
if settings.PRIVACY_URL == '' and settings.TERMS_URL == '':
|
|
self.fields.pop('terms')
|
|
if settings.HCAPTCHA_SECRET == '':
|
|
self.fields.pop('captcha')
|
|
|
|
def signup(self, request, user):
|
|
pass
|
|
|
|
|
|
class AllAuthSocialSignupForm(SocialSignupForm):
|
|
terms = forms.BooleanField(label=_('Accept Terms and Privacy'))
|
|
|
|
def __init__(self, **kwargs):
|
|
super().__init__(**kwargs)
|
|
if settings.PRIVACY_URL == '' and settings.TERMS_URL == '':
|
|
self.fields.pop('terms')
|
|
|
|
def signup(self, request, user):
|
|
pass
|
|
|
|
|
|
class CustomPasswordResetForm(ResetPasswordForm):
|
|
captcha = hCaptchaField()
|
|
|
|
def __init__(self, **kwargs):
|
|
super(CustomPasswordResetForm, self).__init__(**kwargs)
|
|
if settings.HCAPTCHA_SECRET == '':
|
|
self.fields.pop('captcha')
|
|
|
|
|
|
class UserCreateForm(forms.Form):
|
|
name = forms.CharField(label='Username')
|
|
password = forms.CharField(widget=forms.TextInput(attrs={'autocomplete': 'new-password', 'type': 'password'}))
|
|
password_confirm = forms.CharField(widget=forms.TextInput(attrs={'autocomplete': 'new-password', 'type': 'password'}))
|