2021-02-07 23:24:33 +01:00
|
|
|
import re
|
2021-02-07 18:23:24 +01:00
|
|
|
import unicodedata
|
2017-04-13 13:35:48 +02:00
|
|
|
|
2021-02-07 23:24:33 +01:00
|
|
|
from simple_email_confirmation.models import EmailAddress
|
|
|
|
|
2017-04-13 13:35:48 +02:00
|
|
|
from django import forms
|
2021-02-07 18:23:24 +01:00
|
|
|
from django.contrib.auth.forms import PasswordResetForm
|
2017-04-20 03:00:19 +02:00
|
|
|
from django.utils import timezone
|
|
|
|
|
2021-02-08 02:27:37 +01:00
|
|
|
from .models import AvisLieu, AvisStage, Lieu, Stage, User
|
2017-05-02 23:23:26 +02:00
|
|
|
from .widgets import LatLonField
|
|
|
|
|
2021-02-07 23:24:33 +01:00
|
|
|
|
2017-05-02 23:23:26 +02:00
|
|
|
# Sur-classe utile
|
2017-04-15 20:03:08 +02:00
|
|
|
class HTMLTrimmerForm(forms.ModelForm):
|
|
|
|
def clean(self):
|
2017-05-02 23:23:26 +02:00
|
|
|
# Suppression des espaces blanc avant et après le texte pour les champs html
|
2021-02-07 23:15:47 +01:00
|
|
|
leading_white = re.compile(
|
|
|
|
r"^( \t\n)*(<p>( |[ \n\t]|<br[ /]*>)*</p>( \t\n)*)+?", re.IGNORECASE
|
|
|
|
)
|
|
|
|
trailing_white = re.compile(
|
|
|
|
r"(( \t\n)*<p>( |[ \n\t]|<br[ /]*>)*</p>)+?( \t\n)*$", re.IGNORECASE
|
|
|
|
)
|
2017-04-15 20:03:08 +02:00
|
|
|
cleaned_data = super(HTMLTrimmerForm, self).clean()
|
2021-02-07 23:15:47 +01:00
|
|
|
|
2017-04-15 20:03:08 +02:00
|
|
|
for (fname, fval) in cleaned_data.items():
|
2017-05-02 23:23:26 +02:00
|
|
|
# Heuristique : les champs commençant par "avis_" sont des champs html
|
2017-04-15 20:03:08 +02:00
|
|
|
if fname[:5] == "avis_":
|
2021-02-07 23:15:47 +01:00
|
|
|
cleaned_data[fname] = leading_white.sub(
|
|
|
|
"", trailing_white.sub("", fval)
|
|
|
|
)
|
|
|
|
|
2017-04-15 20:03:08 +02:00
|
|
|
return cleaned_data
|
|
|
|
|
2021-02-07 23:15:47 +01:00
|
|
|
|
2017-05-02 23:23:26 +02:00
|
|
|
# Infos sur un stage
|
|
|
|
class StageForm(forms.ModelForm):
|
2021-02-07 23:15:47 +01:00
|
|
|
date_widget = forms.DateInput(
|
|
|
|
attrs={"class": "datepicker", "placeholder": "JJ/MM/AAAA"}
|
|
|
|
)
|
|
|
|
date_debut = forms.DateField(
|
2021-02-07 23:50:15 +01:00
|
|
|
label="Date de début", input_formats=["%d/%m/%Y"], widget=date_widget
|
2021-02-07 23:15:47 +01:00
|
|
|
)
|
|
|
|
date_fin = forms.DateField(
|
2021-02-07 23:50:15 +01:00
|
|
|
label="Date de fin", input_formats=["%d/%m/%Y"], widget=date_widget
|
2021-02-07 23:15:47 +01:00
|
|
|
)
|
2017-05-02 23:23:26 +02:00
|
|
|
|
|
|
|
class Meta:
|
|
|
|
model = Stage
|
2021-02-07 23:15:47 +01:00
|
|
|
fields = [
|
|
|
|
"sujet",
|
|
|
|
"date_debut",
|
|
|
|
"date_fin",
|
|
|
|
"type_stage",
|
|
|
|
"niveau_scol",
|
|
|
|
"thematiques",
|
|
|
|
"matieres",
|
|
|
|
"structure",
|
|
|
|
"encadrants",
|
|
|
|
]
|
2017-05-02 23:23:26 +02:00
|
|
|
help_texts = {
|
2021-02-08 02:27:37 +01:00
|
|
|
"thematiques": "Mettez une virgule pour valider votre thématique si la suggestion ne "
|
|
|
|
"correspond pas ou si elle n'existe pas encore",
|
|
|
|
"structure": "Nom de l'équipe, du laboratoire, de la startup... (si le lieu ne suffit "
|
|
|
|
"pas)",
|
2017-05-02 23:23:26 +02:00
|
|
|
}
|
|
|
|
labels = {
|
2021-02-07 23:50:15 +01:00
|
|
|
"date_debut": "Date de début",
|
2017-05-02 23:23:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
# Sauvegarde de la request pour avoir l'user
|
|
|
|
if "request" in kwargs:
|
|
|
|
self.request = kwargs.pop("request")
|
|
|
|
super(StageForm, self).__init__(*args, **kwargs)
|
2021-02-07 23:15:47 +01:00
|
|
|
|
2017-05-02 23:23:26 +02:00
|
|
|
def save(self, commit=True):
|
|
|
|
# Lors de la création : attribution à l'utilisateur connecté
|
2021-02-07 23:15:47 +01:00
|
|
|
if self.instance.id is None and hasattr(self, "request"):
|
2017-05-02 23:23:26 +02:00
|
|
|
self.instance.auteur = self.request.user.profil
|
2021-02-07 23:15:47 +01:00
|
|
|
|
2017-05-02 23:23:26 +02:00
|
|
|
# Date de modification
|
|
|
|
self.instance.date_maj = timezone.now()
|
2017-10-02 23:59:20 +02:00
|
|
|
|
|
|
|
self.instance.update_stats(False)
|
2021-02-07 23:15:47 +01:00
|
|
|
|
2017-05-02 23:23:26 +02:00
|
|
|
stage = super(StageForm, self).save(commit=commit)
|
|
|
|
return stage
|
|
|
|
|
2021-02-07 23:15:47 +01:00
|
|
|
|
2017-05-02 23:23:26 +02:00
|
|
|
# Sous-formulaire des avis sur le stage
|
2017-04-15 20:03:08 +02:00
|
|
|
class AvisStageForm(HTMLTrimmerForm):
|
2017-04-13 22:50:00 +02:00
|
|
|
class Meta:
|
|
|
|
model = AvisStage
|
2021-02-07 23:15:47 +01:00
|
|
|
fields = [
|
|
|
|
"chapo",
|
|
|
|
"avis_sujet",
|
|
|
|
"avis_ambiance",
|
|
|
|
"avis_admin",
|
|
|
|
"avis_prestage",
|
|
|
|
"les_plus",
|
|
|
|
"les_moins",
|
|
|
|
]
|
2017-04-15 20:03:08 +02:00
|
|
|
help_texts = {
|
2021-06-29 00:11:18 +02:00
|
|
|
"chapo": (
|
|
|
|
'"Trop long, pas lu" : une accroche résumant ce que vous avez pensé de ce séjour'
|
|
|
|
),
|
|
|
|
"avis_ambiance": (
|
|
|
|
"Avez-vous passé un bon moment à ce travail ? Étiez-vous assez guidé·e ? "
|
|
|
|
"Aviez-vous un bon contact avec vos encadrant·e·s ? Y avait-il une bonne "
|
|
|
|
"ambiance dans l'équipe ?"
|
|
|
|
),
|
|
|
|
"avis_sujet": (
|
|
|
|
"Quelle était votre mission ? Qu'en avez-vous retiré ? Le travail "
|
|
|
|
"correspondait-il à vos attentes ? Était-ce à votre niveau, trop dur, "
|
|
|
|
"trop facile ?"
|
|
|
|
),
|
|
|
|
"avis_admin": (
|
|
|
|
"Avez-vous commencé votre travail à la date prévue ? Était-ce compliqué "
|
|
|
|
"d'obtenir les documents nécessaires (visa, contrats, etc) ? L'administration "
|
|
|
|
"de l'établissement vous a-t-elle aidé·e ? Étiez-vous rémunéré·e ?"
|
|
|
|
),
|
|
|
|
"avis_prestage": (
|
|
|
|
"Comment avez-vous trouvé où aller pour cette expérience ? À quel moment "
|
|
|
|
"avez-vous commencé à chercher ? Avez-vous eu des entretiens pour obtenir "
|
|
|
|
"votre place ? Avez-vous eu d'autres pistes, pourquoi avez-vous choisi "
|
|
|
|
"cette option ?"
|
|
|
|
),
|
2021-02-07 23:50:15 +01:00
|
|
|
"les_plus": "Les principaux points positifs de cette expérience",
|
|
|
|
"les_moins": "Ce qui aurait pu être mieux",
|
2017-04-15 20:03:08 +02:00
|
|
|
}
|
2017-04-13 22:50:00 +02:00
|
|
|
|
2021-02-07 23:15:47 +01:00
|
|
|
|
2017-04-15 20:03:08 +02:00
|
|
|
class AvisLieuForm(HTMLTrimmerForm):
|
2017-04-13 22:50:00 +02:00
|
|
|
class Meta:
|
|
|
|
model = AvisLieu
|
2021-02-07 23:15:47 +01:00
|
|
|
fields = [
|
|
|
|
"lieu",
|
|
|
|
"chapo",
|
|
|
|
"avis_lieustage",
|
|
|
|
"avis_pratique",
|
|
|
|
"avis_tourisme",
|
|
|
|
"les_plus",
|
|
|
|
"les_moins",
|
|
|
|
]
|
2017-04-15 20:03:08 +02:00
|
|
|
help_texts = {
|
2021-06-29 00:11:18 +02:00
|
|
|
"chapo": (
|
|
|
|
'"Trop long, pas lu" : une accroche résumant ce que vous avez pensé de cet endroit'
|
|
|
|
),
|
|
|
|
"avis_lieustage": (
|
|
|
|
"Qu'avez-vous pensé des lieux où vous travailliez ? Les bâtiments "
|
|
|
|
"étaient-ils modernes ? Était-il agréable d'y travailler ?"
|
|
|
|
),
|
|
|
|
"avis_pratique": (
|
|
|
|
"Avez-vous eu du mal à trouver un logement ? Y-a-t-il des choses que vous avez "
|
|
|
|
"apprises sur place qu'il vous aurait été utile de savoir avant de partir ?"
|
|
|
|
),
|
|
|
|
"avis_tourisme": (
|
|
|
|
"Y-a-t-il des lieux à visiter dans cette zone ? Avez-vous pratiqué "
|
|
|
|
"des activités sportives ? Est-il facile de faire des rencontres ?"
|
|
|
|
),
|
2021-02-07 23:50:15 +01:00
|
|
|
"les_plus": "Les meilleures raisons de partir à cet endroit",
|
|
|
|
"les_moins": "Ce qui vous a gêné ou manqué là-bas",
|
2017-04-15 20:03:08 +02:00
|
|
|
}
|
2021-02-07 23:15:47 +01:00
|
|
|
widgets = {"lieu": forms.HiddenInput(attrs={"class": "lieu-hidden"})}
|
|
|
|
|
2017-04-13 22:50:00 +02:00
|
|
|
|
2017-05-02 23:23:26 +02:00
|
|
|
# Création d'un nouveau lieu
|
2017-04-13 13:35:48 +02:00
|
|
|
class LieuForm(forms.ModelForm):
|
|
|
|
coord = LatLonField()
|
2017-05-16 00:22:59 +02:00
|
|
|
id = forms.IntegerField(widget=forms.widgets.HiddenInput(), required=False)
|
2021-02-07 23:15:47 +01:00
|
|
|
|
2017-04-13 13:35:48 +02:00
|
|
|
class Meta:
|
|
|
|
model = Lieu
|
2021-02-07 23:15:47 +01:00
|
|
|
fields = ["id", "nom", "type_lieu", "ville", "pays", "coord"]
|
|
|
|
|
2017-04-13 13:35:48 +02:00
|
|
|
|
2017-05-02 23:23:26 +02:00
|
|
|
# Widget de feedback
|
2017-04-20 23:04:07 +02:00
|
|
|
class FeedbackForm(forms.Form):
|
|
|
|
objet = forms.CharField(label="Objet", required=True)
|
2021-02-07 23:15:47 +01:00
|
|
|
message = forms.CharField(
|
|
|
|
label="Message", required=True, widget=forms.widgets.Textarea()
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2021-02-07 18:23:24 +01:00
|
|
|
# Nouvelle adresse mail
|
|
|
|
class AdresseEmailForm(forms.Form):
|
|
|
|
def __init__(self, _user, **kwargs):
|
|
|
|
self._user = _user
|
|
|
|
super().__init__(**kwargs)
|
2021-02-07 23:15:47 +01:00
|
|
|
|
|
|
|
email = forms.EmailField(
|
|
|
|
widget=forms.widgets.EmailInput(attrs={"placeholder": "Nouvelle adresse"})
|
|
|
|
)
|
2021-02-07 18:23:24 +01:00
|
|
|
|
|
|
|
def clean_email(self):
|
|
|
|
email = self.cleaned_data["email"]
|
|
|
|
if EmailAddress.objects.filter(user=self._user, email=email).exists():
|
2021-02-07 23:15:47 +01:00
|
|
|
raise forms.ValidationError("Cette adresse est déjà associée à ce compte")
|
2021-02-07 18:23:24 +01:00
|
|
|
return email
|
|
|
|
|
|
|
|
|
|
|
|
def _unicode_ci_compare(s1, s2):
|
|
|
|
"""
|
|
|
|
Perform case-insensitive comparison of two identifiers, using the
|
|
|
|
recommended algorithm from Unicode Technical Report 36, section
|
|
|
|
2.11.2(B)(2).
|
|
|
|
"""
|
2021-02-07 23:15:47 +01:00
|
|
|
return (
|
|
|
|
unicodedata.normalize("NFKC", s1).casefold()
|
|
|
|
== unicodedata.normalize("NFKC", s2).casefold()
|
|
|
|
)
|
|
|
|
|
2021-02-07 18:23:24 +01:00
|
|
|
|
|
|
|
# (Ré)initialisation du mot de passe
|
|
|
|
class ReinitMdpForm(PasswordResetForm):
|
|
|
|
def get_users(self, email):
|
|
|
|
"""Override default method to allow unusable passwords"""
|
|
|
|
email_field_name = User.get_email_field_name()
|
2021-02-07 23:15:47 +01:00
|
|
|
active_users = User._default_manager.filter(
|
|
|
|
**{
|
|
|
|
"%s__iexact" % email_field_name: email,
|
|
|
|
"is_active": True,
|
|
|
|
}
|
|
|
|
)
|
2021-02-07 18:23:24 +01:00
|
|
|
return (
|
2021-02-07 23:15:47 +01:00
|
|
|
u
|
|
|
|
for u in active_users
|
2021-02-07 18:23:24 +01:00
|
|
|
if _unicode_ci_compare(email, getattr(u, email_field_name))
|
|
|
|
)
|