# coding: utf-8
from collections import OrderedDict
from captcha.fields import CaptchaField, CaptchaTextInput
from django import forms
from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import (
PasswordResetForm,
UserChangeForm,
UserCreationForm,
)
from django.contrib.auth.models import User
from django.core.validators import RegexValidator
from django.forms import BooleanField, ChoiceField
from django.forms import ChoiceField
from django.utils.translation import gettext_lazy as _
from registration.forms import RegistrationForm
from oioioi.base.models import Consents, PreferencesSaved
from oioioi.base.preferences import PreferencesFactory, ensure_preferences_exist_for_user
from oioioi.base.utils.user import UNICODE_CATEGORY_LIST, USERNAME_REGEX
from oioioi.base.utils.validators import UnicodeValidator, ValidationError
[docs]def adjust_username_field(form):
help_text = _("This value may contain only letters, numbers and underscore.")
form.fields['username'].error_messages['invalid'] = _("Invalid username")
form.fields['username'].help_text = help_text
form.fields['username'].validators += [RegexValidator(regex=USERNAME_REGEX)]
[docs]def adjust_name_fields(form):
help_text = _("This value may contain only letters, numbers and punctuation marks.")
adjust_unicode_field(form, 'first_name', help_text, _("Invalid first name"))
adjust_unicode_field(form, 'last_name', help_text, _("Invalid last name"))
[docs]def adjust_unicode_field(
form,
field_name,
help_text,
invalid_message,
unicode_categories=None,
allow_spaces=True,
):
if unicode_categories is None:
unicode_categories = UNICODE_CATEGORY_LIST
form.fields[field_name].error_messages['invalid'] = invalid_message
form.fields[field_name].help_text = help_text
form.fields[field_name].validators += [
UnicodeValidator(
unicode_categories=unicode_categories, allow_spaces=allow_spaces
)
]
[docs]def get_consent(field_name, user):
if hasattr(user, 'consents'):
return getattr(user.consents, field_name)
else:
return False
[docs]def _maybe_add_field(label, *args, **kwargs):
if label:
kwargs.setdefault('label', label)
PreferencesFactory.add_field(*args, **kwargs)
[docs]def adjust_preferences_factory_fields():
choices_not_translated = [("", "None")] + list(settings.LANGUAGES)
choices = [(k, _(v)) for k, v in choices_not_translated]
def handle_preferred_language(user):
if user is None:
return "None"
ensure_preferences_exist_for_user(user)
return user.userpreferences.language
PreferencesFactory.add_field(
"preferred_language",
ChoiceField,
lambda name, user: handle_preferred_language(user),
label=_("Preferred language"),
choices=choices,
required=False
)
def handle_enable_editor(user):
if user is None:
return False
ensure_preferences_exist_for_user(user)
return user.userpreferences.enable_editor
if settings.USE_ACE_EDITOR:
PreferencesFactory.add_field(
"enable_editor",
BooleanField,
lambda name, user: handle_enable_editor(user),
label=_("Enable editor"),
order=0,
required=False
)
[docs]def handle_new_preference_fields(request, user):
changed = False
ensure_preferences_exist_for_user(user)
if "preferred_language" in request.POST:
pref_lang = request.POST["preferred_language"]
if pref_lang in ([k for k, _ in settings.LANGUAGES] + [""]):
ensure_preferences_exist_for_user(user)
if pref_lang != "":
request.COOKIES[settings.LANGUAGE_COOKIE_NAME] = pref_lang
user.userpreferences.language = pref_lang
changed = True
if settings.USE_ACE_EDITOR:
if "enable_editor" in request.POST:
user.userpreferences.enable_editor = True
else:
user.userpreferences.enable_editor = False
changed = True
if changed:
user.userpreferences.save()
_maybe_add_field(
settings.REGISTRATION_RULES_CONSENT,
'terms_accepted',
forms.BooleanField,
get_consent,
required=True,
)
_maybe_add_field(
settings.REGISTRATION_MARKETING_CONSENT,
'marketing_consent',
forms.BooleanField,
get_consent,
required=False,
)
_maybe_add_field(
settings.REGISTRATION_PARTNER_CONSENT,
'partner_consent',
forms.BooleanField,
get_consent,
required=False,
)
adjust_preferences_factory_fields()
[docs]def save_consents(sender, user, **kwargs):
form = sender
consents = None
if hasattr(user, 'consents'):
consents = user.consents
else:
consents = Consents(user=user)
if 'terms_accepted' in form.cleaned_data:
consents.terms_accepted = form.cleaned_data['terms_accepted']
if 'marketing_consent' in form.cleaned_data:
consents.marketing_consent = form.cleaned_data['marketing_consent']
if 'partner_consent' in form.cleaned_data:
consents.partner_consent = form.cleaned_data['partner_consent']
consents.save()
PreferencesSaved.connect(save_consents)
[docs]class CustomCaptchaTextInput(CaptchaTextInput):
[docs] template_name = 'captcha/custom_field.html'
# http://stackoverflow.com/questions/3657709/how-to-force-save-an-empty-unchanged-django-admin-inline