Detect when a solution has more than 30 pages

This commit is contained in:
Yohann D'ANELLO 2021-01-19 00:32:34 +01:00
parent 8515153be7
commit d5e7295981
Signed by: ynerant
GPG Key ID: 3A75C55819C8CF85
3 changed files with 86 additions and 51 deletions

View File

@ -3,6 +3,7 @@
import re import re
from PyPDF3 import PdfFileReader
from bootstrap_datepicker_plus import DatePickerInput, DateTimePickerInput from bootstrap_datepicker_plus import DatePickerInput, DateTimePickerInput
from django import forms from django import forms
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
@ -115,6 +116,19 @@ class TournamentForm(forms.ModelForm):
class SolutionForm(forms.ModelForm): class SolutionForm(forms.ModelForm):
def clean_file(self):
if "file" in self.files:
file = self.files["file"]
if file.size > 2e6:
raise ValidationError(_("The uploaded file size must be under 5 Mo."))
if file.content_type != "application/pdf":
raise ValidationError(_("The uploaded file must be a PDF file."))
pdf_reader = PdfFileReader(file)
pages = len(pdf_reader.pages)
if pages > 30:
raise ValidationError(_("The PDF file must not have more than 30 pages."))
return self.cleaned_data["photo_authorization"]
def save(self, commit=True): def save(self, commit=True):
""" """
Don't save a solution with this way. Use a view instead Don't save a solution with this way. Use a view instead

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: TFJM\n" "Project-Id-Version: TFJM\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-01-18 23:37+0100\n" "POT-Creation-Date: 2021-01-19 00:29+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Yohann D'ANELLO <yohann.danello@animath.fr>\n" "Last-Translator: Yohann D'ANELLO <yohann.danello@animath.fr>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -104,27 +104,39 @@ msgstr "Changelog de type \"{action}\" pour le modèle {model} le {timestamp}"
msgid "valid" msgid "valid"
msgstr "valide" msgstr "valide"
#: apps/participation/forms.py:22 apps/participation/models.py:37 #: apps/participation/forms.py:23 apps/participation/models.py:37
msgid "The trigram must be composed of three uppercase letters." msgid "The trigram must be composed of three uppercase letters."
msgstr "Le trigramme doit être composé de trois lettres majuscules." msgstr "Le trigramme doit être composé de trois lettres majuscules."
#: apps/participation/forms.py:37 #: apps/participation/forms.py:38
msgid "No team was found with this access code." msgid "No team was found with this access code."
msgstr "Aucune équipe n'a été trouvée avec ce code d'accès." msgstr "Aucune équipe n'a été trouvée avec ce code d'accès."
#: apps/participation/forms.py:71 #: apps/participation/forms.py:72
msgid "I engage myself to participate to the whole TFJM²." msgid "I engage myself to participate to the whole TFJM²."
msgstr "Je m'engage à participer à l'intégralité du TFJM²." msgstr "Je m'engage à participer à l'intégralité du TFJM²."
#: apps/participation/forms.py:86 #: apps/participation/forms.py:87
msgid "Message to address to the team:" msgid "Message to address to the team:"
msgstr "Message à adresser à l'équipe :" msgstr "Message à adresser à l'équipe :"
#: apps/participation/forms.py:155 #: apps/participation/forms.py:123
msgid "The uploaded file size must be under 5 Mo."
msgstr "Le fichier envoyé doit peser moins de 5 Mo."
#: apps/participation/forms.py:125
msgid "The uploaded file must be a PDF file."
msgstr "Le fichier envoyé doit être au format PDF."
#: apps/participation/forms.py:129
msgid "The PDF file must not have more than 30 pages."
msgstr "Le fichier PDF ne doit pas avoir plus de 30 pages."
#: apps/participation/forms.py:169
msgid "The defender, the opponent and the reporter must be different." msgid "The defender, the opponent and the reporter must be different."
msgstr "Le défenseur, l'opposant et le rapporteur doivent être différents." msgstr "Le défenseur, l'opposant et le rapporteur doivent être différents."
#: apps/participation/forms.py:159 #: apps/participation/forms.py:173
msgid "This defender did not work on this problem." msgid "This defender did not work on this problem."
msgstr "Ce défenseur ne travaille pas sur ce problème." msgstr "Ce défenseur ne travaille pas sur ce problème."
@ -784,7 +796,7 @@ msgid "Update team"
msgstr "Modifier l'équipe" msgstr "Modifier l'équipe"
#: apps/participation/templates/participation/team_detail.html:152 #: apps/participation/templates/participation/team_detail.html:152
#: apps/participation/views.py:359 #: apps/participation/views.py:360
msgid "Leave team" msgid "Leave team"
msgstr "Quitter l'équipe" msgstr "Quitter l'équipe"
@ -872,49 +884,49 @@ msgstr "Tous les tournois"
msgid "Add tournament" msgid "Add tournament"
msgstr "Ajouter un tournoi" msgstr "Ajouter un tournoi"
#: apps/participation/views.py:39 tfjm/templates/base.html:74 #: apps/participation/views.py:40 tfjm/templates/base.html:74
#: tfjm/templates/base.html:233 #: tfjm/templates/base.html:233
msgid "Create team" msgid "Create team"
msgstr "Créer une équipe" msgstr "Créer une équipe"
#: apps/participation/views.py:48 apps/participation/views.py:93 #: apps/participation/views.py:49 apps/participation/views.py:94
msgid "You don't participate, so you can't create a team." msgid "You don't participate, so you can't create a team."
msgstr "Vous ne participez pas, vous ne pouvez pas créer d'équipe." msgstr "Vous ne participez pas, vous ne pouvez pas créer d'équipe."
#: apps/participation/views.py:50 apps/participation/views.py:95 #: apps/participation/views.py:51 apps/participation/views.py:96
msgid "You are already in a team." msgid "You are already in a team."
msgstr "Vous êtes déjà dans une équipe." msgstr "Vous êtes déjà dans une équipe."
#: apps/participation/views.py:84 tfjm/templates/base.html:79 #: apps/participation/views.py:85 tfjm/templates/base.html:79
#: tfjm/templates/base.html:228 #: tfjm/templates/base.html:228
msgid "Join team" msgid "Join team"
msgstr "Rejoindre une équipe" msgstr "Rejoindre une équipe"
#: apps/participation/views.py:146 apps/participation/views.py:365 #: apps/participation/views.py:147 apps/participation/views.py:366
#: apps/participation/views.py:398 #: apps/participation/views.py:399
msgid "You are not in a team." msgid "You are not in a team."
msgstr "Vous n'êtes pas dans une équipe." msgstr "Vous n'êtes pas dans une équipe."
#: apps/participation/views.py:147 apps/participation/views.py:399 #: apps/participation/views.py:148 apps/participation/views.py:400
msgid "You don't participate, so you don't have any team." msgid "You don't participate, so you don't have any team."
msgstr "Vous ne participez pas, vous n'avez donc pas d'équipe." msgstr "Vous ne participez pas, vous n'avez donc pas d'équipe."
#: apps/participation/views.py:171 #: apps/participation/views.py:172
#, python-brace-format #, python-brace-format
msgid "Detail of team {trigram}" msgid "Detail of team {trigram}"
msgstr "Détails de l'équipe {trigram}" msgstr "Détails de l'équipe {trigram}"
#: apps/participation/views.py:204 #: apps/participation/views.py:205
msgid "You don't participate, so you can't request the validation of the team." msgid "You don't participate, so you can't request the validation of the team."
msgstr "" msgstr ""
"Vous ne participez pas, vous ne pouvez pas demander la validation de " "Vous ne participez pas, vous ne pouvez pas demander la validation de "
"l'équipe." "l'équipe."
#: apps/participation/views.py:207 #: apps/participation/views.py:208
msgid "The validation of the team is already done or pending." msgid "The validation of the team is already done or pending."
msgstr "La validation de l'équipe est déjà faite ou en cours." msgstr "La validation de l'équipe est déjà faite ou en cours."
#: apps/participation/views.py:210 #: apps/participation/views.py:211
msgid "" msgid ""
"The team can't be validated: missing email address confirmations, " "The team can't be validated: missing email address confirmations, "
"authorizations, people or the chosen problem is not set." "authorizations, people or the chosen problem is not set."
@ -923,56 +935,64 @@ msgstr ""
"d'adresse e-mail, soit une autorisation, soit des personnes soit le problème " "d'adresse e-mail, soit une autorisation, soit des personnes soit le problème "
"n'a pas été choisi." "n'a pas été choisi."
#: apps/participation/views.py:229 #: apps/participation/views.py:230
msgid "You are not an administrator." msgid "You are not an administrator."
msgstr "Vous n'êtes pas administrateur." msgstr "Vous n'êtes pas administrateur."
#: apps/participation/views.py:232 #: apps/participation/views.py:233
msgid "This team has no pending validation." msgid "This team has no pending validation."
msgstr "L'équipe n'a pas de validation en attente." msgstr "L'équipe n'a pas de validation en attente."
#: apps/participation/views.py:262 #: apps/participation/views.py:263
msgid "You must specify if you validate the registration or not." msgid "You must specify if you validate the registration or not."
msgstr "Vous devez spécifier si vous validez l'inscription ou non." msgstr "Vous devez spécifier si vous validez l'inscription ou non."
#: apps/participation/views.py:293 #: apps/participation/views.py:294
#, python-brace-format #, python-brace-format
msgid "Update team {trigram}" msgid "Update team {trigram}"
msgstr "Mise à jour de l'équipe {trigram}" msgstr "Mise à jour de l'équipe {trigram}"
#: apps/participation/views.py:332 #: apps/participation/views.py:333
#, python-brace-format #, python-brace-format
msgid "Photo authorization of {participant}.{ext}" msgid "Photo authorization of {participant}.{ext}"
msgstr "Autorisation de droit à l'image de {participant}.{ext}" msgstr "Autorisation de droit à l'image de {participant}.{ext}"
#: apps/participation/views.py:338 #: apps/participation/views.py:339
#, python-brace-format #, python-brace-format
msgid "Parental authorization of {participant}.{ext}" msgid "Parental authorization of {participant}.{ext}"
msgstr "Autorisation parentale de {participant}.{ext}" msgstr "Autorisation parentale de {participant}.{ext}"
#: apps/participation/views.py:345 #: apps/participation/views.py:346
#, python-brace-format #, python-brace-format
msgid "Health sheet of {participant}.{ext}" msgid "Health sheet of {participant}.{ext}"
msgstr "Fiche sanitaire de {participant}.{ext}" msgstr "Fiche sanitaire de {participant}.{ext}"
#: apps/participation/views.py:349 #: apps/participation/views.py:350
#, python-brace-format #, python-brace-format
msgid "Photo authorizations of team {trigram}.zip" msgid "Photo authorizations of team {trigram}.zip"
msgstr "Autorisations de droit à l'image de l'équipe {trigram}.zip" msgstr "Autorisations de droit à l'image de l'équipe {trigram}.zip"
#: apps/participation/views.py:367 #: apps/participation/views.py:368
msgid "The team is already validated or the validation is pending." msgid "The team is already validated or the validation is pending."
msgstr "La validation de l'équipe est déjà faite ou en cours." msgstr "La validation de l'équipe est déjà faite ou en cours."
#: apps/participation/views.py:413 #: apps/participation/views.py:414
msgid "The team is not validated yet." msgid "The team is not validated yet."
msgstr "L'équipe n'est pas encore validée." msgstr "L'équipe n'est pas encore validée."
#: apps/participation/views.py:425 #: apps/participation/views.py:426
#, python-brace-format #, python-brace-format
msgid "Participation of team {trigram}" msgid "Participation of team {trigram}"
msgstr "Participation de l'équipe {trigram}" msgstr "Participation de l'équipe {trigram}"
#: apps/participation/views.py:515
msgid "You can't upload a solution after the deadline."
msgstr "Vous ne pouvez pas envoyer de solution après la date limite."
#: apps/participation/views.py:695
msgid "You can't upload a synthesis after the deadline."
msgstr "Vous ne pouvez pas envoyer de note de synthèse après la date limite."
#: apps/registration/forms.py:21 apps/registration/forms.py:53 #: apps/registration/forms.py:21 apps/registration/forms.py:53
msgid "role" msgid "role"
msgstr "rôle" msgstr "rôle"
@ -1185,7 +1205,7 @@ msgstr "nom de famille"
#: apps/registration/templates/registration/add_organizer.html:12 #: apps/registration/templates/registration/add_organizer.html:12
#: apps/registration/templates/registration/add_organizer.html:19 #: apps/registration/templates/registration/add_organizer.html:19
#: apps/registration/templates/registration/user_list.html:8 #: apps/registration/templates/registration/user_list.html:8
#: apps/registration/views.py:85 #: apps/registration/views.py:86
msgid "Add organizer" msgid "Add organizer"
msgstr "Ajouter un organisateur" msgstr "Ajouter un organisateur"
@ -1389,7 +1409,7 @@ msgstr ""
#: apps/registration/templates/registration/signup.html:5 #: apps/registration/templates/registration/signup.html:5
#: apps/registration/templates/registration/signup.html:12 #: apps/registration/templates/registration/signup.html:12
#: apps/registration/templates/registration/signup.html:19 #: apps/registration/templates/registration/signup.html:19
#: apps/registration/views.py:41 #: apps/registration/views.py:42
msgid "Sign up" msgid "Sign up"
msgstr "Inscription" msgstr "Inscription"
@ -1502,13 +1522,13 @@ msgid "Responsible email address:"
msgstr "Adresse e-mail du responsable légal :" msgstr "Adresse e-mail du responsable légal :"
#: apps/registration/templates/registration/user_detail.html:102 #: apps/registration/templates/registration/user_detail.html:102
msgid "Profesional activity:"
msgstr "Activité professionnelle :"
#: apps/registration/templates/registration/user_detail.html:105
msgid "Role:" msgid "Role:"
msgstr "Rôle :" msgstr "Rôle :"
#: apps/registration/templates/registration/user_detail.html:105
msgid "Profesional activity:"
msgstr "Activité professionnelle :"
#: apps/registration/templates/registration/user_detail.html:109 #: apps/registration/templates/registration/user_detail.html:109
msgid "Grant Animath to contact me in the future about other actions:" msgid "Grant Animath to contact me in the future about other actions:"
msgstr "Autorise Animath à recontacter à propos d'autres actions :" msgstr "Autorise Animath à recontacter à propos d'autres actions :"
@ -1544,71 +1564,71 @@ msgid "Update user"
msgstr "Modifier l'utilisateur" msgstr "Modifier l'utilisateur"
#: apps/registration/templates/registration/user_detail.html:161 #: apps/registration/templates/registration/user_detail.html:161
#: apps/registration/views.py:312 #: apps/registration/views.py:313
msgid "Upload photo authorization" msgid "Upload photo authorization"
msgstr "Téléverser l'autorisation de droit à l'image" msgstr "Téléverser l'autorisation de droit à l'image"
#: apps/registration/templates/registration/user_detail.html:166 #: apps/registration/templates/registration/user_detail.html:166
#: apps/registration/views.py:338 #: apps/registration/views.py:339
msgid "Upload health sheet" msgid "Upload health sheet"
msgstr "Téléverser la fiche sanitaire" msgstr "Téléverser la fiche sanitaire"
#: apps/registration/templates/registration/user_detail.html:171 #: apps/registration/templates/registration/user_detail.html:171
#: apps/registration/templates/registration/user_detail.html:176 #: apps/registration/templates/registration/user_detail.html:176
#: apps/registration/views.py:364 #: apps/registration/views.py:365
msgid "Upload parental authorization" msgid "Upload parental authorization"
msgstr "Téléverser l'autorisation parentale" msgstr "Téléverser l'autorisation parentale"
#: apps/registration/views.py:124 #: apps/registration/views.py:125
msgid "New TFJM² organizer account" msgid "New TFJM² organizer account"
msgstr "Nouveau compte organisateur pour le TFJM²" msgstr "Nouveau compte organisateur pour le TFJM²"
#: apps/registration/views.py:146 #: apps/registration/views.py:147
msgid "Email validation" msgid "Email validation"
msgstr "Validation de l'adresse mail" msgstr "Validation de l'adresse mail"
#: apps/registration/views.py:148 #: apps/registration/views.py:149
msgid "Validate email" msgid "Validate email"
msgstr "Valider l'adresse mail" msgstr "Valider l'adresse mail"
#: apps/registration/views.py:187 #: apps/registration/views.py:188
msgid "Email validation unsuccessful" msgid "Email validation unsuccessful"
msgstr "Échec de la validation de l'adresse mail" msgstr "Échec de la validation de l'adresse mail"
#: apps/registration/views.py:198 #: apps/registration/views.py:199
msgid "Email validation email sent" msgid "Email validation email sent"
msgstr "Mail de confirmation de l'adresse mail envoyé" msgstr "Mail de confirmation de l'adresse mail envoyé"
#: apps/registration/views.py:206 #: apps/registration/views.py:207
msgid "Resend email validation link" msgid "Resend email validation link"
msgstr "Renvoyé le lien de validation de l'adresse mail" msgstr "Renvoyé le lien de validation de l'adresse mail"
#: apps/registration/views.py:246 #: apps/registration/views.py:247
#, python-brace-format #, python-brace-format
msgid "Detail of user {user}" msgid "Detail of user {user}"
msgstr "Détails de l'utilisateur {user}" msgstr "Détails de l'utilisateur {user}"
#: apps/registration/views.py:276 #: apps/registration/views.py:277
#, python-brace-format #, python-brace-format
msgid "Update user {user}" msgid "Update user {user}"
msgstr "Mise à jour de l'utilisateur {user}" msgstr "Mise à jour de l'utilisateur {user}"
#: apps/registration/views.py:427 #: apps/registration/views.py:428
#, python-brace-format #, python-brace-format
msgid "Photo authorization of {student}.{ext}" msgid "Photo authorization of {student}.{ext}"
msgstr "Autorisation de droit à l'image de {student}.{ext}" msgstr "Autorisation de droit à l'image de {student}.{ext}"
#: apps/registration/views.py:450 #: apps/registration/views.py:451
#, python-brace-format #, python-brace-format
msgid "Health sheet of {student}.{ext}" msgid "Health sheet of {student}.{ext}"
msgstr "Fiche sanitaire de {student}.{ext}" msgstr "Fiche sanitaire de {student}.{ext}"
#: apps/registration/views.py:473 #: apps/registration/views.py:474
#, python-brace-format #, python-brace-format
msgid "Parental authorization of {student}.{ext}" msgid "Parental authorization of {student}.{ext}"
msgstr "Autorisation parentale de {student}.{ext}" msgstr "Autorisation parentale de {student}.{ext}"
#: apps/registration/views.py:495 #: apps/registration/views.py:496
#, python-brace-format #, python-brace-format
msgid "Scholarship attestation of {user}.{ext}" msgid "Scholarship attestation of {user}.{ext}"
msgstr "Notification de bourse de {user}.{ext}" msgstr "Notification de bourse de {user}.{ext}"

View File

@ -17,6 +17,7 @@ gunicorn~=20.0
matrix-nio~=0.15 matrix-nio~=0.15
phonenumbers~=8.9.10 phonenumbers~=8.9.10
psycopg2-binary~=2.8 psycopg2-binary~=2.8
PyPDF3~=1.0.2
ipython~=7.19.0 ipython~=7.19.0
python-magic==0.4.18 python-magic==0.4.18
requests~=2.25.0 requests~=2.25.0