diff --git a/apps/participation/forms.py b/apps/participation/forms.py index 4d7704b..1d619d0 100644 --- a/apps/participation/forms.py +++ b/apps/participation/forms.py @@ -3,6 +3,7 @@ import re +from PyPDF3 import PdfFileReader from bootstrap_datepicker_plus import DatePickerInput, DateTimePickerInput from django import forms from django.core.exceptions import ValidationError @@ -115,6 +116,19 @@ class TournamentForm(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): """ Don't save a solution with this way. Use a view instead diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index 7b48edd..f4a41b8 100644 --- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: TFJM\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" "Last-Translator: Yohann D'ANELLO \n" "Language-Team: LANGUAGE \n" @@ -104,27 +104,39 @@ msgstr "Changelog de type \"{action}\" pour le modèle {model} le {timestamp}" msgid "valid" 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." 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." 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²." 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:" 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." 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." msgstr "Ce défenseur ne travaille pas sur ce problème." @@ -784,7 +796,7 @@ msgid "Update team" msgstr "Modifier l'équipe" #: apps/participation/templates/participation/team_detail.html:152 -#: apps/participation/views.py:359 +#: apps/participation/views.py:360 msgid "Leave team" msgstr "Quitter l'équipe" @@ -872,49 +884,49 @@ msgstr "Tous les tournois" msgid "Add tournament" 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 msgid "Create team" 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." 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." 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 msgid "Join team" msgstr "Rejoindre une équipe" -#: apps/participation/views.py:146 apps/participation/views.py:365 -#: apps/participation/views.py:398 +#: apps/participation/views.py:147 apps/participation/views.py:366 +#: apps/participation/views.py:399 msgid "You are not in a team." 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." 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 msgid "Detail of team {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." msgstr "" "Vous ne participez pas, vous ne pouvez pas demander la validation de " "l'équipe." -#: apps/participation/views.py:207 +#: apps/participation/views.py:208 msgid "The validation of the team is already done or pending." msgstr "La validation de l'équipe est déjà faite ou en cours." -#: apps/participation/views.py:210 +#: apps/participation/views.py:211 msgid "" "The team can't be validated: missing email address confirmations, " "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 " "n'a pas été choisi." -#: apps/participation/views.py:229 +#: apps/participation/views.py:230 msgid "You are not an administrator." msgstr "Vous n'êtes pas administrateur." -#: apps/participation/views.py:232 +#: apps/participation/views.py:233 msgid "This team has no pending validation." 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." 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 msgid "Update team {trigram}" msgstr "Mise à jour de l'équipe {trigram}" -#: apps/participation/views.py:332 +#: apps/participation/views.py:333 #, python-brace-format msgid "Photo authorization of {participant}.{ext}" msgstr "Autorisation de droit à l'image de {participant}.{ext}" -#: apps/participation/views.py:338 +#: apps/participation/views.py:339 #, python-brace-format msgid "Parental authorization of {participant}.{ext}" msgstr "Autorisation parentale de {participant}.{ext}" -#: apps/participation/views.py:345 +#: apps/participation/views.py:346 #, python-brace-format msgid "Health sheet of {participant}.{ext}" msgstr "Fiche sanitaire de {participant}.{ext}" -#: apps/participation/views.py:349 +#: apps/participation/views.py:350 #, python-brace-format msgid "Photo authorizations of team {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." 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." msgstr "L'équipe n'est pas encore validée." -#: apps/participation/views.py:425 +#: apps/participation/views.py:426 #, python-brace-format msgid "Participation of team {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 msgid "role" 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:19 #: apps/registration/templates/registration/user_list.html:8 -#: apps/registration/views.py:85 +#: apps/registration/views.py:86 msgid "Add organizer" msgstr "Ajouter un organisateur" @@ -1389,7 +1409,7 @@ msgstr "" #: apps/registration/templates/registration/signup.html:5 #: apps/registration/templates/registration/signup.html:12 #: apps/registration/templates/registration/signup.html:19 -#: apps/registration/views.py:41 +#: apps/registration/views.py:42 msgid "Sign up" msgstr "Inscription" @@ -1502,13 +1522,13 @@ msgid "Responsible email address:" msgstr "Adresse e-mail du responsable légal :" #: apps/registration/templates/registration/user_detail.html:102 -msgid "Profesional activity:" -msgstr "Activité professionnelle :" - -#: apps/registration/templates/registration/user_detail.html:105 msgid "Role:" 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 msgid "Grant Animath to contact me in the future about other actions:" msgstr "Autorise Animath à recontacter à propos d'autres actions :" @@ -1544,71 +1564,71 @@ msgid "Update user" msgstr "Modifier l'utilisateur" #: apps/registration/templates/registration/user_detail.html:161 -#: apps/registration/views.py:312 +#: apps/registration/views.py:313 msgid "Upload photo authorization" msgstr "Téléverser l'autorisation de droit à l'image" #: apps/registration/templates/registration/user_detail.html:166 -#: apps/registration/views.py:338 +#: apps/registration/views.py:339 msgid "Upload health sheet" msgstr "Téléverser la fiche sanitaire" #: apps/registration/templates/registration/user_detail.html:171 #: apps/registration/templates/registration/user_detail.html:176 -#: apps/registration/views.py:364 +#: apps/registration/views.py:365 msgid "Upload parental authorization" msgstr "Téléverser l'autorisation parentale" -#: apps/registration/views.py:124 +#: apps/registration/views.py:125 msgid "New TFJM² organizer account" msgstr "Nouveau compte organisateur pour le TFJM²" -#: apps/registration/views.py:146 +#: apps/registration/views.py:147 msgid "Email validation" msgstr "Validation de l'adresse mail" -#: apps/registration/views.py:148 +#: apps/registration/views.py:149 msgid "Validate email" msgstr "Valider l'adresse mail" -#: apps/registration/views.py:187 +#: apps/registration/views.py:188 msgid "Email validation unsuccessful" msgstr "Échec de la validation de l'adresse mail" -#: apps/registration/views.py:198 +#: apps/registration/views.py:199 msgid "Email validation email sent" msgstr "Mail de confirmation de l'adresse mail envoyé" -#: apps/registration/views.py:206 +#: apps/registration/views.py:207 msgid "Resend email validation link" msgstr "Renvoyé le lien de validation de l'adresse mail" -#: apps/registration/views.py:246 +#: apps/registration/views.py:247 #, python-brace-format msgid "Detail of user {user}" msgstr "Détails de l'utilisateur {user}" -#: apps/registration/views.py:276 +#: apps/registration/views.py:277 #, python-brace-format msgid "Update user {user}" msgstr "Mise à jour de l'utilisateur {user}" -#: apps/registration/views.py:427 +#: apps/registration/views.py:428 #, python-brace-format msgid "Photo authorization of {student}.{ext}" msgstr "Autorisation de droit à l'image de {student}.{ext}" -#: apps/registration/views.py:450 +#: apps/registration/views.py:451 #, python-brace-format msgid "Health sheet of {student}.{ext}" msgstr "Fiche sanitaire de {student}.{ext}" -#: apps/registration/views.py:473 +#: apps/registration/views.py:474 #, python-brace-format msgid "Parental authorization of {student}.{ext}" msgstr "Autorisation parentale de {student}.{ext}" -#: apps/registration/views.py:495 +#: apps/registration/views.py:496 #, python-brace-format msgid "Scholarship attestation of {user}.{ext}" msgstr "Notification de bourse de {user}.{ext}" diff --git a/requirements.txt b/requirements.txt index 003fd46..48ed2f3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,6 +17,7 @@ gunicorn~=20.0 matrix-nio~=0.15 phonenumbers~=8.9.10 psycopg2-binary~=2.8 +PyPDF3~=1.0.2 ipython~=7.19.0 python-magic==0.4.18 requests~=2.25.0