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-07 23:24:33 +01:00
from . models import AvisLieu , AvisStage , Lieu , Normalien , 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 (
label = u " Date de début " , input_formats = [ " %d / % m/ % Y " ] , widget = date_widget
)
date_fin = forms . DateField (
label = u " Date de fin " , input_formats = [ " %d / % m/ % Y " ] , widget = date_widget
)
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 = {
" thematiques " : u " Mettez une virgule pour valider votre thématique si la suggestion ne correspond pas ou si elle n ' existe pas encore " ,
2021-02-07 23:15:47 +01:00
" structure " : u " Nom de l ' équipe, du laboratoire, de la startup... (si le lieu ne suffit pas) " ,
2017-05-02 23:23:26 +02:00
}
labels = {
" date_debut " : u " Date de début " ,
}
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-02-07 23:15:47 +01:00
" chapo " : u ' " Trop long, pas lu " : une accroche résumant ce que vous avez pensé de ce séjour ' ,
2017-05-02 03:11:34 +02:00
" avis_ambiance " : u " 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 ? " ,
2017-05-13 00:57:54 +02:00
" avis_sujet " : u " 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 " : u " 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 ? " ,
2017-10-02 23:59:20 +02:00
" avis_prestage " : u " 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 ? " ,
2017-05-02 03:11:34 +02:00
" les_plus " : u " Les principaux points positifs de cette expérience " ,
2017-04-15 20:03:08 +02:00
" les_moins " : u " Ce qui aurait pu être mieux " ,
}
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-02-07 23:15:47 +01:00
" chapo " : u ' " Trop long, pas lu " : une accroche résumant ce que vous avez pensé de cet endroit ' ,
2017-05-02 03:11:34 +02:00
" avis_lieustage " : u " Qu ' avez-vous pensé des lieux où vous travailliez ? Les bâtiments étaient-ils modernes ? Était-il agréable d ' y travailler ? " ,
2017-04-15 20:03:08 +02:00
" avis_pratique " : u " 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 " : u " Y-a-t-il des lieux à visiter dans cette zone ? Avez-vous pratiqué des activités sportives ? Est-il facile de faire des rencontres ? " ,
" les_plus " : u " Les meilleures raisons de partir à cet endroit " ,
" les_moins " : u " Ce qui vous a gêné ou manqué là-bas " ,
}
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 ) )
)