diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index 21aa517..3b49861 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: 2024-07-06 10:16+0200\n" +"POT-Creation-Date: 2024-07-06 21:27+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Emmy D'Anello \n" "Language-Team: LANGUAGE \n" @@ -79,7 +79,7 @@ msgstr "Type de permission nécessaire pour écrire un message dans un canal." #: chat/models.py:62 draw/admin.py:53 draw/admin.py:71 draw/admin.py:88 #: draw/models.py:27 participation/admin.py:79 participation/admin.py:144 #: participation/admin.py:176 participation/models.py:783 -#: participation/models.py:807 participation/models.py:1116 +#: participation/models.py:807 participation/models.py:1131 #: registration/models.py:763 #: registration/templates/registration/payment_form.html:53 msgid "tournament" @@ -95,7 +95,7 @@ msgstr "" #: chat/models.py:73 draw/models.py:446 draw/models.py:473 #: participation/admin.py:140 participation/admin.py:160 -#: participation/models.py:1651 participation/models.py:1660 +#: participation/models.py:1666 participation/models.py:1675 #: participation/tables.py:84 msgid "pool" msgstr "poule" @@ -265,7 +265,7 @@ msgid "teams" msgstr "équipes" #: draw/admin.py:92 draw/models.py:245 draw/models.py:465 -#: participation/models.py:1120 +#: participation/models.py:1135 msgid "round" msgstr "tour" @@ -634,7 +634,7 @@ msgstr "Le numéro du tour doit être entre 1 et {nb}." msgid "rounds" msgstr "tours" -#: draw/models.py:268 participation/models.py:1128 +#: draw/models.py:268 participation/models.py:1143 msgid "letter" msgstr "lettre" @@ -672,12 +672,12 @@ msgstr "L'instance complète de la poule." msgid "Pool {letter}{number}" msgstr "Poule {letter}{number}" -#: draw/models.py:447 participation/models.py:1652 +#: draw/models.py:447 participation/models.py:1667 msgid "pools" msgstr "poules" -#: draw/models.py:459 participation/models.py:1106 participation/models.py:1871 -#: participation/models.py:1901 participation/models.py:1943 +#: draw/models.py:459 participation/models.py:1121 participation/models.py:1886 +#: participation/models.py:1920 participation/models.py:1962 msgid "participation" msgstr "participation" @@ -701,9 +701,9 @@ msgid "" msgstr "" "L'ordre de choix dans la poule, entre 0 et la taille de la poule moins 1." -#: draw/models.py:496 draw/models.py:519 participation/models.py:1237 -#: participation/models.py:1674 participation/models.py:1908 -#: participation/views.py:1489 participation/views.py:1754 +#: draw/models.py:496 draw/models.py:519 participation/models.py:1252 +#: participation/models.py:1689 participation/models.py:1927 +#: participation/views.py:1492 participation/views.py:1757 #, python-brace-format msgid "Problem #{problem}" msgstr "Problème n°{problem}" @@ -919,26 +919,26 @@ msgid "selected for final" msgstr "sélectionnée pour la finale" #: participation/admin.py:124 participation/admin.py:188 -#: participation/models.py:1681 participation/tables.py:114 +#: participation/models.py:1696 participation/tables.py:114 msgid "defender" msgstr "défenseur⋅se" -#: participation/admin.py:128 participation/models.py:1688 -#: participation/models.py:1955 +#: participation/admin.py:128 participation/models.py:1703 +#: participation/models.py:1974 msgid "opponent" msgstr "opposant⋅e" -#: participation/admin.py:132 participation/models.py:1695 -#: participation/models.py:1956 +#: participation/admin.py:132 participation/models.py:1710 +#: participation/models.py:1975 msgid "reviewer" msgstr "rapporteur⋅rice" -#: participation/admin.py:136 participation/models.py:1702 -#: participation/models.py:1957 +#: participation/admin.py:136 participation/models.py:1717 +#: participation/models.py:1976 msgid "observer" msgstr "observateur⋅rice" -#: participation/admin.py:192 participation/models.py:1906 +#: participation/admin.py:192 participation/models.py:1925 msgid "problem" msgstr "numéro de problème" @@ -1239,7 +1239,7 @@ msgid "first phase date" msgstr "date du premier tour" #: participation/models.py:327 -msgid "limit date to upload the syntheses for the first phase" +msgid "limit date to upload the written reviews for the first phase" msgstr "date limite pour envoyer les notes de synthèses pour la première phase" #: participation/models.py:332 @@ -1252,7 +1252,7 @@ msgstr "" "cocher la case lorsque les solutions pour le second tour sont accessibles" #: participation/models.py:342 -msgid "limit date to upload the syntheses for the second phase" +msgid "limit date to upload the written reviews for the second phase" msgstr "date limite d'envoi des notes de synthèse pour la seconde phase" #: participation/models.py:347 @@ -1265,7 +1265,7 @@ msgstr "" "cocher la case lorsque les solutions pour le second tour sont accessibles" #: participation/models.py:357 -msgid "limit date to upload the syntheses for the third phase" +msgid "limit date to upload the written reviews for the third phase" msgstr "" "date limite pour envoyer les notes de synthèses pour la troisième phase" @@ -1294,7 +1294,7 @@ msgid "Final ranking" msgstr "Classement final" #: participation/models.py:481 participation/models.py:553 -#: participation/models.py:1312 participation/views.py:1728 +#: participation/models.py:1327 participation/views.py:1731 msgid "Team" msgstr "Équipe" @@ -1326,15 +1326,15 @@ msgstr "Scores jour 3" msgid "Tweaks day 3" msgstr "Ajustements 3" -#: participation/models.py:485 participation/models.py:1312 -#: participation/views.py:1735 +#: participation/models.py:485 participation/models.py:1327 +#: participation/views.py:1738 msgid "Total" msgstr "Total" #: participation/models.py:485 participation/models.py:553 -#: participation/models.py:1312 +#: participation/models.py:1327 #: participation/templates/participation/tournament_harmonize.html:14 -#: participation/views.py:1738 +#: participation/views.py:1741 msgid "Rank" msgstr "Rang" @@ -1346,7 +1346,7 @@ msgstr "Score" msgid "Mention" msgstr "Mention" -#: participation/models.py:698 participation/models.py:1581 +#: participation/models.py:698 participation/models.py:1596 msgid "Don't update the table structure for a better automated integration." msgstr "" "Ne pas mettre à jour la structure de la table pour une meilleure intégration " @@ -1456,47 +1456,47 @@ msgstr "" "tour, vous défendrez votre solution du problème " "{problem}.

" -#: participation/models.py:930 participation/models.py:988 -#: participation/models.py:1047 +#: participation/models.py:930 participation/models.py:993 +#: participation/models.py:1057 #, python-brace-format msgid "" "

You will oppose the solution of the team {opponent} on the problem {problem}. You can upload your synthesis " -"sheet on this page.

" +"href='{solution_url}'>problem {problem}. You can upload your written " +"review on this page.

" msgstr "" "

Vous opposerez la solution de l'équipe {opponent} sur le problème {problem}. Vous pouvez envoyer votre note " "de synthèse sur cette page.

" -#: participation/models.py:939 participation/models.py:997 -#: participation/models.py:1056 +#: participation/models.py:939 participation/models.py:1002 +#: participation/models.py:1066 #, python-brace-format msgid "" "

You will report the solution of the team {reviewer} on the problem {problem}. You can upload your synthesis sheet " -"on this page.

" +"href='{solution_url}'>problem {problem}. You can upload your written " +"review on this page.

" msgstr "" "

Vous rapporterez la solution de l'équipe {reviewer} sur le problème {problem}. Vous pouvez envoyer votre note " "de synthèse sur cette page.

" -#: participation/models.py:949 participation/models.py:1007 -#: participation/models.py:1066 +#: participation/models.py:949 participation/models.py:1012 +#: participation/models.py:1076 #, python-brace-format msgid "" "

You will observe the solution of the team {observer} on the problem {problem}. You can upload your synthesis sheet " -"on this page.

" +"href='{solution_url}'>problem {problem}. You can upload your written " +"review on this page.

" msgstr "" "

Vous observerez la solution de l'équipe {observer} sur le problème {problem}. Vous pouvez envoyer votre note " "de synthèse sur cette page.

" -#: participation/models.py:969 registration/models.py:629 +#: participation/models.py:974 registration/models.py:629 msgid "First round" msgstr "Premier tour" -#: participation/models.py:981 +#: participation/models.py:986 #, python-brace-format msgid "" "

For the second round, you will defend your " @@ -1505,12 +1505,12 @@ msgstr "" "

Pour le second tour, vous défendrez votre " "solution du problème {problem}.

" -#: participation/models.py:1027 participation/models.py:1086 +#: participation/models.py:1037 participation/models.py:1101 #: registration/models.py:640 msgid "Second round" msgstr "Second tour" -#: participation/models.py:1040 +#: participation/models.py:1050 #, python-brace-format msgid "" "

For the third round, you will defend your " @@ -1519,7 +1519,7 @@ msgstr "" "

Pour le troisième tour, vous défendrez votre " "solution du problème {problem}.

" -#: participation/models.py:1092 +#: participation/models.py:1107 #, python-brace-format msgid "" "

The tournament {tournament} is ended. You can check the results on the Le tournoi {tournament} est terminé. Vous pouvez consulter les résultats " "sur la page du tournoi.

" -#: participation/models.py:1097 +#: participation/models.py:1112 msgid "Tournament ended" msgstr "Tournoi terminé" -#: participation/models.py:1107 participation/models.py:1150 +#: participation/models.py:1122 participation/models.py:1165 msgid "participations" msgstr "participations" -#: participation/models.py:1122 participation/models.py:1123 -#: participation/models.py:1124 +#: participation/models.py:1137 participation/models.py:1138 +#: participation/models.py:1139 #, python-brace-format msgid "Round {round}" msgstr "Tour {round}" -#: participation/models.py:1138 +#: participation/models.py:1153 msgid "room" msgstr "salle" -#: participation/models.py:1140 +#: participation/models.py:1155 msgid "Room 1" msgstr "Salle 1" -#: participation/models.py:1141 +#: participation/models.py:1156 msgid "Room 2" msgstr "Salle 2" -#: participation/models.py:1144 +#: participation/models.py:1159 msgid "For 5-teams pools only" msgstr "Pour les poules de 5 équipe uniquement" -#: participation/models.py:1156 +#: participation/models.py:1171 msgid "juries" msgstr "jurys" -#: participation/models.py:1165 +#: participation/models.py:1180 msgid "president of the jury" msgstr "président⋅e du jury" -#: participation/models.py:1172 +#: participation/models.py:1187 msgid "BigBlueButton URL" msgstr "Lien BigBlueButton" -#: participation/models.py:1173 +#: participation/models.py:1188 msgid "The link of the BBB visio for this pool." msgstr "Le lien du salon BBB pour cette poule." -#: participation/models.py:1178 +#: participation/models.py:1193 msgid "results available" msgstr "résultats disponibles" -#: participation/models.py:1179 +#: participation/models.py:1194 msgid "" "Check this case when results become accessible to teams. They stay " "accessible to you. Only averages are given." @@ -1587,65 +1587,65 @@ msgstr "" "Ils restent toujours accessibles pour vous. Seules les moyennes sont " "communiquées." -#: participation/models.py:1211 +#: participation/models.py:1226 msgid "The president of the jury must be part of the jury." msgstr "Læ président⋅e du jury doit faire partie du jury." -#: participation/models.py:1238 participation/models.py:1312 -#: participation/views.py:1483 participation/views.py:1732 +#: participation/models.py:1253 participation/models.py:1327 +#: participation/views.py:1486 participation/views.py:1735 msgid "Problem" msgstr "Problème" -#: participation/models.py:1243 participation/views.py:1498 +#: participation/models.py:1258 participation/views.py:1501 msgid "Role" msgstr "Rôle" -#: participation/models.py:1248 participation/views.py:1532 -#: participation/views.py:1533 +#: participation/models.py:1263 participation/views.py:1535 +#: participation/views.py:1536 msgid "Juree" msgstr "Juré⋅e" -#: participation/models.py:1271 participation/models.py:1597 -#: participation/models.py:1619 participation/views.py:1602 +#: participation/models.py:1286 participation/models.py:1612 +#: participation/models.py:1634 participation/views.py:1605 msgid "Average" msgstr "Moyenne" -#: participation/models.py:1277 participation/views.py:1621 +#: participation/models.py:1292 participation/views.py:1624 msgid "Coefficient" msgstr "Coefficien" -#: participation/models.py:1278 participation/views.py:1664 +#: participation/models.py:1293 participation/views.py:1667 msgid "Subtotal" msgstr "Sous-total" -#: participation/models.py:1544 +#: participation/models.py:1559 #, python-brace-format msgid "Input must be a valid integer between {min_note} and {max_note}." msgstr "L'entrée doit être un entier valide entre {min_note} et {max_note}." -#: participation/models.py:1632 +#: participation/models.py:1647 #, python-brace-format msgid "The jury {jury} is not part of the jury for this pool." msgstr "{jury} ne fait pas partie du jury pour cette poule." -#: participation/models.py:1645 +#: participation/models.py:1660 #, python-brace-format msgid "Pool {code} for tournament {tournament} with teams {teams}" msgstr "Poule {code} du tournoi {tournament} avec les équipes {teams}" -#: participation/models.py:1665 +#: participation/models.py:1680 msgid "position" msgstr "position" -#: participation/models.py:1672 +#: participation/models.py:1687 msgid "defended solution" msgstr "solution défendue" -#: participation/models.py:1710 +#: participation/models.py:1725 msgid "penalties" msgstr "pénalités" -#: participation/models.py:1712 +#: participation/models.py:1727 msgid "" "Number of penalties for the defender. The defender will loose a 0.5 " "coefficient per penalty." @@ -1653,128 +1653,128 @@ msgstr "" "Nombre de pénalités pour l'équipe défenseuse. Elle perd un coefficient 0.5 " "sur sa présentation orale par pénalité." -#: participation/models.py:1838 participation/models.py:1841 -#: participation/models.py:1844 participation/models.py:1847 +#: participation/models.py:1853 participation/models.py:1856 +#: participation/models.py:1859 participation/models.py:1862 #, python-brace-format msgid "Team {trigram} is not registered in the pool." msgstr "L'équipe {trigram} n'est pas inscrite dans la poule." -#: participation/models.py:1852 +#: participation/models.py:1867 #, python-brace-format msgid "Passage of {defender} for problem {problem}" msgstr "Passage de {defender} pour le problème {problem}" -#: participation/models.py:1856 participation/models.py:1865 -#: participation/models.py:1950 participation/models.py:1993 +#: participation/models.py:1871 participation/models.py:1880 +#: participation/models.py:1969 participation/models.py:2012 msgid "passage" msgstr "passage" -#: participation/models.py:1857 +#: participation/models.py:1872 msgid "passages" msgstr "passages" -#: participation/models.py:1876 +#: participation/models.py:1891 msgid "difference" msgstr "différence" -#: participation/models.py:1877 +#: participation/models.py:1892 msgid "Score to add/remove on the final score" msgstr "Score à ajouter/retrancher au score final" -#: participation/models.py:1884 +#: participation/models.py:1899 msgid "tweak" msgstr "harmonisation" -#: participation/models.py:1885 +#: participation/models.py:1900 msgid "tweaks" msgstr "harmonisations" -#: participation/models.py:1913 +#: participation/models.py:1932 msgid "solution for the final tournament" msgstr "solution pour la finale" -#: participation/models.py:1918 participation/models.py:1962 +#: participation/models.py:1937 participation/models.py:1981 msgid "file" msgstr "fichier" -#: participation/models.py:1928 +#: participation/models.py:1947 #, python-brace-format msgid "Solution of team {team} for problem {problem}" msgstr "Solution de l'équipe {team} pour le problème {problem}" -#: participation/models.py:1930 +#: participation/models.py:1949 msgid "for final" msgstr "pour la finale" -#: participation/models.py:1933 +#: participation/models.py:1952 msgid "solution" msgstr "solution" -#: participation/models.py:1934 +#: participation/models.py:1953 msgid "solutions" msgstr "solutions" -#: participation/models.py:1968 +#: participation/models.py:1987 #, python-brace-format -msgid "Synthesis of {team} as {type} for problem {problem} of {defender}" +msgid "Written review of {team} as {type} for problem {problem} of {defender}" msgstr "" "Note de synthèse de l'équipe {team} en tant que {type} pour le problème " "{problem} de {defender}" -#: participation/models.py:1976 -msgid "synthesis" +#: participation/models.py:1995 +msgid "written review" msgstr "note de synthèse" -#: participation/models.py:1977 -msgid "syntheses" +#: participation/models.py:1996 +msgid "written reviews" msgstr "notes de synthèse" -#: participation/models.py:1986 +#: participation/models.py:2005 msgid "jury" msgstr "jury" -#: participation/models.py:1998 +#: participation/models.py:2017 msgid "defender writing note" msgstr "note d'écrit défenseur⋅se" -#: participation/models.py:2004 +#: participation/models.py:2023 msgid "defender oral note" msgstr "note d'oral défenseur⋅se" -#: participation/models.py:2010 +#: participation/models.py:2029 msgid "opponent writing note" msgstr "note d'écrit opposant⋅e" -#: participation/models.py:2016 +#: participation/models.py:2035 msgid "opponent oral note" msgstr "note d'oral opposant⋅e" -#: participation/models.py:2022 +#: participation/models.py:2041 msgid "reviewer writing note" msgstr "note d'écrit rapporteur⋅rice" -#: participation/models.py:2028 +#: participation/models.py:2047 msgid "reviewer oral note" msgstr "note d'oral du rapporteur⋅rice" -#: participation/models.py:2034 +#: participation/models.py:2053 msgid "observer writing note" msgstr "note d'écrit de l'observateur⋅rice" -#: participation/models.py:2040 +#: participation/models.py:2059 msgid "observer oral note" msgstr "note d'oral de l'observateur⋅rice" -#: participation/models.py:2105 +#: participation/models.py:2124 #, python-brace-format msgid "Notes of {jury} for {passage}" msgstr "Notes de {jury} pour le {passage}" -#: participation/models.py:2108 +#: participation/models.py:2127 msgid "note" msgstr "note" -#: participation/models.py:2109 +#: participation/models.py:2128 msgid "notes" msgstr "notes" @@ -1910,7 +1910,7 @@ msgstr "Envoyer une solution" #: participation/templates/participation/upload_motivation_letter.html:13 #: participation/templates/participation/upload_notes.html:24 #: participation/templates/participation/upload_solution.html:11 -#: participation/templates/participation/upload_synthesis.html:18 +#: participation/templates/participation/upload_written_review.html:23 #: registration/templates/registration/upload_health_sheet.html:17 #: registration/templates/registration/upload_parental_authorization.html:17 #: registration/templates/registration/upload_photo_authorization.html:18 @@ -1963,7 +1963,7 @@ msgstr "Notes de synthèse :" #: participation/templates/participation/passage_detail.html:53 #: participation/templates/participation/pool_detail.html:68 -msgid "No synthesis was uploaded yet." +msgid "No review was uploaded yet." msgstr "Aucune note de synthèse n'a encore été envoyée." #: participation/templates/participation/passage_detail.html:61 @@ -1973,8 +1973,8 @@ msgstr "Modifier les notes" #: participation/templates/participation/passage_detail.html:66 #: participation/templates/participation/passage_detail.html:187 -msgid "Upload synthesis" -msgstr "Envoyer une note de synthèse" +msgid "Upload review" +msgstr "Envoyer la note de synthèse" #: participation/templates/participation/passage_detail.html:74 msgid "Notes detail" @@ -2374,15 +2374,15 @@ msgid "date of the random draw" msgstr "date du tirage au sort" #: participation/templates/participation/tournament_detail.html:41 -msgid "date of maximal syntheses submission for the first round" +msgid "date of maximal written reviews submission for the first round" msgstr "date limite de soumission des notes de synthèse pour le premier tour" #: participation/templates/participation/tournament_detail.html:44 -msgid "date of maximal syntheses submission for the second round" +msgid "date of maximal written reviews submission for the second round" msgstr "date limite de soumission des notes de synthèse pour le second tour" #: participation/templates/participation/tournament_detail.html:48 -msgid "date of maximal syntheses submission for the third round" +msgid "date of maximal written reviews submission for the third round" msgstr "date limite de soumission des notes de synthèse pour le troisième tour" #: participation/templates/participation/tournament_detail.html:56 @@ -2462,6 +2462,42 @@ msgstr "Dépublier les notes pour le troisième tour" msgid "Files available for download" msgstr "Fichiers disponibles au téléchargement" +#: participation/templates/participation/tournament_detail.html:236 +msgid "Validated team participant data spreadsheet" +msgstr "Tableur des données des équipes validées" + +#: participation/templates/participation/tournament_detail.html:241 +msgid "All teams participant data spreadsheet" +msgstr "Tableur des données de toutes les équipes" + +#: participation/templates/participation/tournament_detail.html:246 +msgid "Archive of all authorisations sorted by team and person" +msgstr "Archive de toutes les autorisations triées par équipe et personne" + +#: participation/templates/participation/tournament_detail.html:251 +msgid "Archive of all submitted solutions sorted by team" +msgstr "Archive de toutes les solutions envoyées triées par équipe" + +#: participation/templates/participation/tournament_detail.html:256 +msgid "Archive of all sent solutions sorted by problem" +msgstr "Archive de toutes les solutions envoyées triées par problème" + +#: participation/templates/participation/tournament_detail.html:261 +msgid "Archive of all sent solutions sorted by pool" +msgstr "Archive de toutes les solutions envoyées triées par poule" + +#: participation/templates/participation/tournament_detail.html:266 +msgid "Archive of all summary notes sorted by pool and passage" +msgstr "Archive de toutes les notes de synthèse triées par poule et passage" + +#: participation/templates/participation/tournament_detail.html:272 +msgid "Note spreadsheet on Google Sheets" +msgstr "Tableur de notes sur Google Sheets" + +#: participation/templates/participation/tournament_detail.html:277 +msgid "Archive of all printable note sheets sorted by pool" +msgstr "Archive de toutes les fiches de notes imprimables triées par poule" + #: participation/templates/participation/tournament_harmonize.html:16 #: registration/models.py:655 msgid "Note" @@ -2504,11 +2540,11 @@ msgstr "" msgid "Download empty notation sheet" msgstr "Télécharger la fiche de notation vierge" -#: participation/templates/participation/upload_synthesis.html:9 +#: participation/templates/participation/upload_written_review.html:9 msgid "Templates:" msgstr "Modèles :" -#: participation/templates/participation/upload_synthesis.html:13 +#: participation/templates/participation/upload_written_review.html:14 msgid "Warning: non-free format" msgstr "Attention : format non libre" @@ -2656,96 +2692,96 @@ msgstr "Vous ne pouvez pas envoyer de solution après la date limite." msgid "Solutions of team {trigram}.zip" msgstr "Solutions de l'équipe {trigram}.zip" -#: participation/views.py:1022 +#: participation/views.py:1023 #, python-brace-format -msgid "Syntheses of team {trigram}.zip" +msgid "Written reviews of team {trigram}.zip" msgstr "Notes de synthèse de l'équipe {trigram}.zip" -#: participation/views.py:1039 participation/views.py:1054 +#: participation/views.py:1040 participation/views.py:1056 #, python-brace-format msgid "Solutions of {tournament}.zip" msgstr "Solutions de {tournament}.zip" -#: participation/views.py:1039 participation/views.py:1054 +#: participation/views.py:1041 participation/views.py:1057 #, python-brace-format -msgid "Syntheses of {tournament}.zip" +msgid "Written reviews of {tournament}.zip" msgstr "Notes de synthèse de {tournament}.zip" -#: participation/views.py:1063 +#: participation/views.py:1066 #, python-brace-format msgid "Solutions for pool {pool} of tournament {tournament}.zip" msgstr "Solutions pour la poule {pool} du tournoi {tournament}.zip" -#: participation/views.py:1064 +#: participation/views.py:1067 #, python-brace-format -msgid "Syntheses for pool {pool} of tournament {tournament}.zip" +msgid "Written reviews for pool {pool} of tournament {tournament}.zip" msgstr "Notes de synthèses pour la poule {pool} du tournoi {tournament}.zip" -#: participation/views.py:1106 +#: participation/views.py:1109 #, python-brace-format msgid "Jury of pool {pool} for {tournament} with teams {teams}" msgstr "Jury de la poule {pool} pour {tournament} avec les équipes {teams}" -#: participation/views.py:1122 +#: participation/views.py:1125 #, python-brace-format msgid "The jury {name} is already in the pool!" msgstr "{name} est déjà dans la poule !" -#: participation/views.py:1142 +#: participation/views.py:1145 msgid "New jury account" msgstr "Nouveau compte de juré⋅e" -#: participation/views.py:1163 +#: participation/views.py:1166 #, python-brace-format msgid "The jury {name} has been successfully added!" msgstr "{name} a été ajouté⋅e avec succès en tant que juré⋅e !" -#: participation/views.py:1199 +#: participation/views.py:1202 #, python-brace-format msgid "The jury {name} has been successfully removed!" msgstr "{name} a été retiré⋅e avec succès du jury !" -#: participation/views.py:1225 +#: participation/views.py:1228 #, python-brace-format msgid "The jury {name} has been successfully promoted president!" msgstr "{name} a été nommé⋅e président⋅e du jury !" -#: participation/views.py:1253 +#: participation/views.py:1256 msgid "The following user is not registered as a jury:" msgstr "L'utilisateur⋅rice suivant n'est pas inscrit⋅e en tant que juré⋅e :" -#: participation/views.py:1269 +#: participation/views.py:1272 msgid "Notes were successfully uploaded." msgstr "Les notes ont bien été envoyées." -#: participation/views.py:1504 +#: participation/views.py:1507 msgid "Defender" msgstr "Défenseur⋅se" -#: participation/views.py:1510 +#: participation/views.py:1513 msgid "Opponent" msgstr "Opposant⋅e" -#: participation/views.py:1517 +#: participation/views.py:1520 msgid "Reviewer" msgstr "Rapporteur⋅rice" -#: participation/views.py:1524 +#: participation/views.py:1527 msgid "Observer" msgstr "Observateur⋅rice" -#: participation/views.py:1895 +#: participation/views.py:1898 #, python-brace-format msgid "Notation sheets of pool {pool} of {tournament}.zip" msgstr "Feuilles de notations pour la poule {pool} du tournoi {tournament}.zip" -#: participation/views.py:1900 +#: participation/views.py:1903 #, python-brace-format msgid "Notation sheets of {tournament}.zip" msgstr "Feuilles de notation de {tournament}.zip" -#: participation/views.py:2067 -msgid "You can't upload a synthesis after the deadline." +#: participation/views.py:2070 +msgid "You can't upload a written review after the deadline." msgstr "Vous ne pouvez pas envoyer de note de synthèse après la date limite." #: registration/admin.py:53 registration/admin.py:69 registration/admin.py:85 diff --git a/participation/admin.py b/participation/admin.py index ca73ee3..a94b57e 100644 --- a/participation/admin.py +++ b/participation/admin.py @@ -4,7 +4,7 @@ from django.contrib import admin from django.utils.translation import gettext_lazy as _ -from .models import Note, Participation, Passage, Pool, Solution, Synthesis, Team, Tournament, Tweak +from .models import Note, Participation, Passage, Pool, Solution, Team, Tournament, Tweak, WrittenReview class ParticipationInline(admin.StackedInline): @@ -32,8 +32,8 @@ class SolutionInline(admin.TabularInline): show_change_link = True -class SynthesisInline(admin.TabularInline): - model = Synthesis +class WrittenReviewInline(admin.TabularInline): + model = WrittenReview extra = 0 ordering = ('passage__solution_number', 'type',) autocomplete_fields = ('passage',) @@ -95,7 +95,7 @@ class ParticipationAdmin(admin.ModelAdmin): search_fields = ('team__name', 'team__trigram',) list_filter = ('valid', 'tournament',) autocomplete_fields = ('team', 'tournament',) - inlines = (SolutionInline, SynthesisInline,) + inlines = (SolutionInline, WrittenReviewInline,) @admin.register(Pool) @@ -178,19 +178,19 @@ class SolutionAdmin(admin.ModelAdmin): return Tournament.final_tournament() if record.final_solution else record.participation.tournament -@admin.register(Synthesis) -class SynthesisAdmin(admin.ModelAdmin): +@admin.register(WrittenReview) +class WrittenReviewAdmin(admin.ModelAdmin): list_display = ('participation', 'type', 'defender', 'passage',) list_filter = ('participation__tournament', 'type', 'passage__solution_number',) search_fields = ('participation__team__name', 'participation__team__trigram',) autocomplete_fields = ('participation', 'passage',) @admin.display(description=_("defender")) - def defender(self, record: Synthesis): + def defender(self, record: WrittenReview): return record.passage.defender @admin.display(description=_("problem")) - def problem(self, record: Synthesis): + def problem(self, record: WrittenReview): return record.passage.solution_number diff --git a/participation/api/serializers.py b/participation/api/serializers.py index ce6866d..86d25ec 100644 --- a/participation/api/serializers.py +++ b/participation/api/serializers.py @@ -3,7 +3,7 @@ from rest_framework import serializers -from ..models import Note, Participation, Passage, Pool, Solution, Synthesis, Team, Tournament +from ..models import Note, Participation, Passage, Pool, Solution, Team, Tournament, WrittenReview class NoteSerializer(serializers.ModelSerializer): @@ -38,9 +38,9 @@ class SolutionSerializer(serializers.ModelSerializer): fields = '__all__' -class SynthesisSerializer(serializers.ModelSerializer): +class WrittenReviewSerializer(serializers.ModelSerializer): class Meta: - model = Synthesis + model = WrittenReview fields = '__all__' @@ -58,9 +58,9 @@ class TournamentSerializer(serializers.ModelSerializer): class Meta: model = Tournament fields = ('id', 'pk', 'name', 'date_start', 'date_end', 'place', 'max_teams', 'price', 'remote', - 'inscription_limit', 'solution_limit', 'solutions_draw', 'syntheses_first_phase_limit', - 'solutions_available_second_phase', 'syntheses_second_phase_limit', - 'solutions_available_third_phase', 'syntheses_third_phase_limit', + 'inscription_limit', 'solution_limit', 'solutions_draw', 'reviews_first_phase_limit', + 'solutions_available_second_phase', 'reviews_second_phase_limit', + 'solutions_available_third_phase', 'reviews_third_phase_limit', 'description', 'organizers', 'final', 'participations',) diff --git a/participation/api/urls.py b/participation/api/urls.py index 7034d0c..5dd5003 100644 --- a/participation/api/urls.py +++ b/participation/api/urls.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later from .views import NoteViewSet, ParticipationViewSet, PassageViewSet, PoolViewSet, \ - SolutionViewSet, SynthesisViewSet, TeamViewSet, TournamentViewSet, TweakViewSet + SolutionViewSet, TeamViewSet, TournamentViewSet, TweakViewSet, WrittenReviewViewSet def register_participation_urls(router, path): @@ -13,8 +13,8 @@ def register_participation_urls(router, path): router.register(path + "/participation", ParticipationViewSet) router.register(path + "/passage", PassageViewSet) router.register(path + "/pool", PoolViewSet) + router.register(path + "/review", WrittenReviewViewSet) router.register(path + "/solution", SolutionViewSet) - router.register(path + "/synthesis", SynthesisViewSet) router.register(path + "/team", TeamViewSet) router.register(path + "/tournament", TournamentViewSet) router.register(path + "/tweak", TweakViewSet) diff --git a/participation/api/views.py b/participation/api/views.py index 923d29d..097e739 100644 --- a/participation/api/views.py +++ b/participation/api/views.py @@ -4,8 +4,8 @@ from django_filters.rest_framework import DjangoFilterBackend from rest_framework.viewsets import ModelViewSet from .serializers import NoteSerializer, ParticipationSerializer, PassageSerializer, PoolSerializer, \ - SolutionSerializer, SynthesisSerializer, TeamSerializer, TournamentSerializer, TweakSerializer -from ..models import Note, Participation, Passage, Pool, Solution, Synthesis, Team, Tournament, Tweak + SolutionSerializer, TeamSerializer, TournamentSerializer, TweakSerializer, WrittenReviewSerializer +from ..models import Note, Participation, Passage, Pool, Solution, Team, Tournament, Tweak, WrittenReview class NoteViewSet(ModelViewSet): @@ -44,9 +44,9 @@ class SolutionViewSet(ModelViewSet): filterset_fields = ['participation', 'number', 'problem', 'final_solution', ] -class SynthesisViewSet(ModelViewSet): - queryset = Synthesis.objects.all() - serializer_class = SynthesisSerializer +class WrittenReviewViewSet(ModelViewSet): + queryset = WrittenReview.objects.all() + serializer_class = WrittenReviewSerializer filter_backends = [DjangoFilterBackend] filterset_fields = ['participation', 'number', 'passage', 'type', ] @@ -64,9 +64,9 @@ class TournamentViewSet(ModelViewSet): serializer_class = TournamentSerializer filter_backends = [DjangoFilterBackend] filterset_fields = ['name', 'date_start', 'date_end', 'place', 'max_teams', 'price', 'remote', - 'inscription_limit', 'solution_limit', 'solutions_draw', 'syntheses_first_phase_limit', - 'solutions_available_second_phase', 'syntheses_second_phase_limit', - 'solutions_available_third_phase', 'syntheses_third_phase_limit', + 'inscription_limit', 'solution_limit', 'solutions_draw', 'reviews_first_phase_limit', + 'solutions_available_second_phase', 'reviews_second_phase_limit', + 'solutions_available_third_phase', 'reviews_third_phase_limit', 'description', 'organizers', 'final', ] diff --git a/participation/forms.py b/participation/forms.py index 2178cd1..9cdd64d 100644 --- a/participation/forms.py +++ b/participation/forms.py @@ -16,7 +16,7 @@ from pypdf import PdfReader from registration.models import VolunteerRegistration from tfjm import settings -from .models import Note, Participation, Passage, Pool, Solution, Synthesis, Team, Tournament +from .models import Note, Participation, Passage, Pool, Solution, Team, Tournament, WrittenReview class TeamForm(forms.ModelForm): @@ -137,7 +137,7 @@ class TournamentForm(forms.ModelForm): if settings.NB_ROUNDS < 3: del self.fields['date_third_phase'] del self.fields['solutions_available_third_phase'] - del self.fields['syntheses_third_phase_limit'] + del self.fields['reviews_third_phase_limit'] if not settings.PAYMENT_MANAGEMENT: del self.fields['price'] @@ -151,14 +151,14 @@ class TournamentForm(forms.ModelForm): 'solution_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'}, format='%Y-%m-%d %H:%M'), 'solutions_draw': forms.DateTimeInput(attrs={'type': 'datetime-local'}, format='%Y-%m-%d %H:%M'), 'date_first_phase': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'), - 'syntheses_first_phase_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'}, - format='%Y-%m-%d %H:%M'), + 'reviews_first_phase_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'}, + format='%Y-%m-%d %H:%M'), 'date_second_phase': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'), - 'syntheses_second_phase_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'}, - format='%Y-%m-%d %H:%M'), + 'reviews_second_phase_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'}, + format='%Y-%m-%d %H:%M'), 'date_third_phase': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'), - 'syntheses_third_phase_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'}, - format='%Y-%m-%d %H:%M'), + 'reviews_third_phase_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'}, + format='%Y-%m-%d %H:%M'), 'organizers': forms.SelectMultiple(attrs={ 'class': 'selectpicker', 'data-live-search': 'true', @@ -359,7 +359,7 @@ class PassageForm(forms.ModelForm): fields = ('position', 'solution_number', 'defender', 'opponent', 'reviewer', 'opponent', 'defender_penalties',) -class SynthesisForm(forms.ModelForm): +class WrittenReviewForm(forms.ModelForm): def clean_file(self): if "file" in self.files: file = self.files["file"] @@ -375,11 +375,11 @@ class SynthesisForm(forms.ModelForm): def save(self, commit=True): """ - Don't save a synthesis with this way. Use a view instead + Don't save a written review with this way. Use a view instead """ class Meta: - model = Synthesis + model = WrittenReview fields = ('file',) diff --git a/participation/migrations/0020_rename_synthesis_writtenreview_and_more.py b/participation/migrations/0020_rename_synthesis_writtenreview_and_more.py new file mode 100644 index 0000000..e292683 --- /dev/null +++ b/participation/migrations/0020_rename_synthesis_writtenreview_and_more.py @@ -0,0 +1,75 @@ +# Generated by Django 5.0.6 on 2024-07-06 19:19 + +import django.utils.timezone +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("participation", "0019_note_observer_oral_note_observer_writing_and_more"), + ] + + operations = [ + migrations.RenameModel( + old_name="Synthesis", + new_name="WrittenReview", + ), + migrations.AlterModelOptions( + name="writtenreview", + options={ + "ordering": ("passage__pool__round", "type"), + "verbose_name": "written review", + "verbose_name_plural": "written reviews", + }, + ), + migrations.RenameField( + model_name="tournament", + old_name="syntheses_first_phase_limit", + new_name="reviews_first_phase_limit", + ), + migrations.RenameField( + model_name="tournament", + old_name="syntheses_second_phase_limit", + new_name="reviews_second_phase_limit", + ), + migrations.RenameField( + model_name="tournament", + old_name="syntheses_third_phase_limit", + new_name="reviews_third_phase_limit", + ), + migrations.AlterField( + model_name="tournament", + name="reviews_first_phase_limit", + field=models.DateTimeField( + default=django.utils.timezone.now, + verbose_name="limit date to upload the written reviews for the first phase", + ), + ), + migrations.AlterField( + model_name="tournament", + name="reviews_second_phase_limit", + field=models.DateTimeField( + default=django.utils.timezone.now, + verbose_name="limit date to upload the written reviews for the second phase", + ), + ), + migrations.AlterField( + model_name="tournament", + name="reviews_third_phase_limit", + field=models.DateTimeField( + default=django.utils.timezone.now, + verbose_name="limit date to upload the written reviews for the third phase", + ), + ), + migrations.AlterField( + model_name="writtenreview", + name="passage", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="written_reviews", + to="participation.passage", + verbose_name="passage", + ), + ), + ] diff --git a/participation/models.py b/participation/models.py index 383b9b5..2452e30 100644 --- a/participation/models.py +++ b/participation/models.py @@ -323,8 +323,8 @@ class Tournament(models.Model): default=date.today, ) - syntheses_first_phase_limit = models.DateTimeField( - verbose_name=_("limit date to upload the syntheses for the first phase"), + reviews_first_phase_limit = models.DateTimeField( + verbose_name=_("limit date to upload the written reviews for the first phase"), default=timezone.now, ) @@ -338,8 +338,8 @@ class Tournament(models.Model): default=False, ) - syntheses_second_phase_limit = models.DateTimeField( - verbose_name=_("limit date to upload the syntheses for the second phase"), + reviews_second_phase_limit = models.DateTimeField( + verbose_name=_("limit date to upload the written reviews for the second phase"), default=timezone.now, ) @@ -353,8 +353,8 @@ class Tournament(models.Model): default=False, ) - syntheses_third_phase_limit = models.DateTimeField( - verbose_name=_("limit date to upload the syntheses for the third phase"), + reviews_third_phase_limit = models.DateTimeField( + verbose_name=_("limit date to upload the written reviews for the third phase"), default=timezone.now, ) @@ -442,10 +442,10 @@ class Tournament(models.Model): return Solution.objects.filter(participation__tournament=self) @property - def syntheses(self): + def written_reviews(self): if self.final: - return Synthesis.objects.filter(final_solution=True) - return Synthesis.objects.filter(participation__tournament=self) + return WrittenReview.objects.filter(final_solution=True) + return WrittenReview.objects.filter(participation__tournament=self) @property def best_format(self): @@ -911,7 +911,7 @@ class Participation(models.Model): 'priority': 1, 'content': content, }) - elif timezone.now() <= tournament.syntheses_first_phase_limit + timedelta(hours=2): + elif timezone.now() <= tournament.reviews_first_phase_limit + timedelta(hours=2): defender_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=1, defender=self) opponent_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=1, opponent=self) reviewer_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=1, reviewer=self) @@ -929,7 +929,7 @@ class Participation(models.Model): opponent_text = _("

You will oppose the solution of the team {opponent} on the " "problem {problem}. " - "You can upload your synthesis sheet on this page.

") + "You can upload your written review on this page.

") solution_url = opponent_passage.defended_solution.file.url passage_url = reverse_lazy("participation:passage_detail", args=(opponent_passage.pk,)) opponent_content = format_lazy(opponent_text, opponent=opponent_passage.defender.team.trigram, @@ -938,7 +938,7 @@ class Participation(models.Model): reviewer_text = _("

You will report the solution of the team {reviewer} on the " "problem {problem}. " - "You can upload your synthesis sheet on this page.

") + "You can upload your written review on this page.

") solution_url = reviewer_passage.defended_solution.file.url passage_url = reverse_lazy("participation:passage_detail", args=(reviewer_passage.pk,)) reviewer_content = format_lazy(reviewer_text, reviewer=reviewer_passage.defender.team.trigram, @@ -948,7 +948,7 @@ class Participation(models.Model): if observer_passage: observer_text = _("

You will observe the solution of the team {observer} on the " "problem {problem}. " - "You can upload your synthesis sheet on this page.

") + "You can upload your written review on this page.

") solution_url = observer_passage.defended_solution.file.url passage_url = reverse_lazy("participation:passage_detail", args=(observer_passage.pk,)) observer_content = format_lazy(observer_text, @@ -959,24 +959,24 @@ class Participation(models.Model): observer_content = "" if settings.TFJM_APP == "TFJM": - syntheses_template_begin = f"{settings.STATIC_URL}tfjm/Fiche_synthèse." - syntheses_templates = " — ".join(f"{ext.upper()}" - for ext in ["pdf", "tex", "odt", "docx"]) + reviews_template_begin = f"{settings.STATIC_URL}tfjm/Fiche_synthèse." + reviews_templates = " — ".join(f"{ext.upper()}" + for ext in ["pdf", "tex", "odt", "docx"]) else: - syntheses_template_begin = f"{settings.STATIC_URL}eteam/Written_review." - syntheses_templates = " — ".join(f"{ext.upper()}" - for ext in ["pdf", "tex"]) - syntheses_templates_content = f"

{_('Templates:')} {syntheses_templates}

" + reviews_template_begin = f"{settings.STATIC_URL}eteam/Written_review." + reviews_templates = " — ".join(f"{ext.upper()}" + for ext in ["pdf", "tex"]) + reviews_templates_content = f"

{_('Templates:')} {reviews_templates}

" content = defender_content + opponent_content + reviewer_content + observer_content \ - + syntheses_templates_content + + reviews_templates_content informations.append({ 'title': _("First round"), 'type': "info", 'priority': 1, 'content': content, }) - elif timezone.now() <= tournament.syntheses_second_phase_limit + timedelta(hours=2): + elif timezone.now() <= tournament.reviews_second_phase_limit + timedelta(hours=2): defender_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=2, defender=self) opponent_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=2, opponent=self) reviewer_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=2, reviewer=self) @@ -992,7 +992,7 @@ class Participation(models.Model): opponent_text = _("

You will oppose the solution of the team {opponent} on the " "problem {problem}. " - "You can upload your synthesis sheet on this page.

") + "You can upload your written review on this page.

") solution_url = opponent_passage.defended_solution.file.url passage_url = reverse_lazy("participation:passage_detail", args=(opponent_passage.pk,)) opponent_content = format_lazy(opponent_text, opponent=opponent_passage.defender.team.trigram, @@ -1001,7 +1001,7 @@ class Participation(models.Model): reviewer_text = _("

You will report the solution of the team {reviewer} on the " "problem {problem}. " - "You can upload your synthesis sheet on this page.

") + "You can upload your written review on this page.

") solution_url = reviewer_passage.defended_solution.file.url passage_url = reverse_lazy("participation:passage_detail", args=(reviewer_passage.pk,)) reviewer_content = format_lazy(reviewer_text, reviewer=reviewer_passage.defender.team.trigram, @@ -1011,7 +1011,7 @@ class Participation(models.Model): if observer_passage: observer_text = _("

You will observe the solution of the team {observer} on the " "problem {problem}. " - "You can upload your synthesis sheet on this page.

") + "You can upload your written review on this page.

") solution_url = observer_passage.defended_solution.file.url passage_url = reverse_lazy("participation:passage_detail", args=(observer_passage.pk,)) observer_content = format_lazy(observer_text, @@ -1022,17 +1022,17 @@ class Participation(models.Model): observer_content = "" if settings.TFJM_APP == "TFJM": - syntheses_template_begin = f"{settings.STATIC_URL}tfjm/Fiche_synthèse." - syntheses_templates = " — ".join(f"{ext.upper()}" - for ext in ["pdf", "tex", "odt", "docx"]) + reviews_template_begin = f"{settings.STATIC_URL}tfjm/Fiche_synthèse." + reviews_templates = " — ".join(f"{ext.upper()}" + for ext in ["pdf", "tex", "odt", "docx"]) else: - syntheses_template_begin = f"{settings.STATIC_URL}eteam/Written_review." - syntheses_templates = " — ".join(f"{ext.upper()}" - for ext in ["pdf", "tex"]) - syntheses_templates_content = f"

{_('Templates:')} {syntheses_templates}

" + reviews_template_begin = f"{settings.STATIC_URL}eteam/Written_review." + reviews_templates = " — ".join(f"{ext.upper()}" + for ext in ["pdf", "tex"]) + reviews_templates_content = f"

{_('Templates:')} {reviews_templates}

" content = defender_content + opponent_content + reviewer_content + observer_content \ - + syntheses_templates_content + + reviews_templates_content informations.append({ 'title': _("Second round"), 'type': "info", @@ -1040,7 +1040,7 @@ class Participation(models.Model): 'content': content, }) elif settings.TFJM_APP == "ETEAM" \ - and timezone.now() <= tournament.syntheses_third_phase_limit + timedelta(hours=2): + and timezone.now() <= tournament.reviews_third_phase_limit + timedelta(hours=2): defender_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=3, defender=self) opponent_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=3, opponent=self) reviewer_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=3, reviewer=self) @@ -1056,7 +1056,7 @@ class Participation(models.Model): opponent_text = _("

You will oppose the solution of the team {opponent} on the " "problem {problem}. " - "You can upload your synthesis sheet on this page.

") + "You can upload your written review on this page.

") solution_url = opponent_passage.defended_solution.file.url passage_url = reverse_lazy("participation:passage_detail", args=(opponent_passage.pk,)) opponent_content = format_lazy(opponent_text, opponent=opponent_passage.defender.team.trigram, @@ -1065,7 +1065,7 @@ class Participation(models.Model): reviewer_text = _("

You will report the solution of the team {reviewer} on the " "problem {problem}. " - "You can upload your synthesis sheet on this page.

") + "You can upload your written review on this page.

") solution_url = reviewer_passage.defended_solution.file.url passage_url = reverse_lazy("participation:passage_detail", args=(reviewer_passage.pk,)) reviewer_content = format_lazy(reviewer_text, reviewer=reviewer_passage.defender.team.trigram, @@ -1075,7 +1075,7 @@ class Participation(models.Model): if observer_passage: observer_text = _("

You will observe the solution of the team {observer} on the " "problem {problem}. " - "You can upload your synthesis sheet on this page.

") + "You can upload your written review on this page.

") solution_url = observer_passage.defended_solution.file.url passage_url = reverse_lazy("participation:passage_detail", args=(observer_passage.pk,)) observer_content = format_lazy(observer_text, @@ -1086,17 +1086,17 @@ class Participation(models.Model): observer_content = "" if settings.TFJM_APP == "TFJM": - syntheses_template_begin = f"{settings.STATIC_URL}tfjm/Fiche_synthèse." - syntheses_templates = " — ".join(f"{ext.upper()}" - for ext in ["pdf", "tex", "odt", "docx"]) + reviews_template_begin = f"{settings.STATIC_URL}tfjm/Fiche_synthèse." + reviews_templates = " — ".join(f"{ext.upper()}" + for ext in ["pdf", "tex", "odt", "docx"]) else: - syntheses_template_begin = f"{settings.STATIC_URL}eteam/Written_review." - syntheses_templates = " — ".join(f"{ext.upper()}" - for ext in ["pdf", "tex"]) - syntheses_templates_content = f"

{_('Templates:')} {syntheses_templates}

" + reviews_template_begin = f"{settings.STATIC_URL}eteam/Written_review." + reviews_templates = " — ".join(f"{ext.upper()}" + for ext in ["pdf", "tex"]) + reviews_templates_content = f"

{_('Templates:')} {reviews_templates}

" content = defender_content + opponent_content + reviewer_content + observer_content \ - + syntheses_templates_content + + reviews_templates_content informations.append({ 'title': _("Second round"), 'type': "info", @@ -1256,7 +1256,7 @@ class Pool(models.Model): f"{_('Reviewer')} ({passage.reviewer.team.trigram})", ""] + ([f"{_('Observer')} ({passage.observer.team.trigram})", ""] if has_observer else []) for passage in passages), start=[str(_("Role")), ""]), - sum(([f"{_('Writing')} (/{20 if settings.TFJM_APP == "TFJM" else 10})", + sum(([f"{_('Writing')} (/{20 if settings.TFJM_APP == 'TFJM' else 10})", f"{_('Oral')} (/{20 if settings.TFJM_APP == 'TFJM' else 10})", f"{_('Writing')} (/10)", f"{_('Oral')} (/10)", f"{_('Writing')} (/10)", f"{_('Oral')} (/10)"] + ([f"{_('Writing')} (/10)", f"{_('Oral')} (/10)"] if has_observer else []) @@ -1905,8 +1905,12 @@ def get_solution_filename(instance, filename): + ("_final" if instance.final_solution else "") +def get_review_filename(instance, filename): + return f"reviews/{instance.participation.team.trigram}_{instance.type}_{instance.passage.pk}" + + def get_synthesis_filename(instance, filename): - return f"syntheses/{instance.participation.team.trigram}_{instance.type}_{instance.passage.pk}" + return get_review_filename(instance, filename) class Solution(models.Model): @@ -1951,7 +1955,7 @@ class Solution(models.Model): ordering = ('participation__team__trigram', 'final_solution', 'problem',) -class Synthesis(models.Model): +class WrittenReview(models.Model): participation = models.ForeignKey( Participation, on_delete=models.CASCADE, @@ -1961,7 +1965,7 @@ class Synthesis(models.Model): passage = models.ForeignKey( Passage, on_delete=models.CASCADE, - related_name="syntheses", + related_name="written_reviews", verbose_name=_("passage"), ) @@ -1980,7 +1984,7 @@ class Synthesis(models.Model): ) def __str__(self): - return _("Synthesis of {team} as {type} for problem {problem} of {defender}").format( + return _("Written review of {team} as {type} for problem {problem} of {defender}").format( team=self.participation.team.trigram, type=self.get_type_display(), problem=self.passage.solution_number, @@ -1988,8 +1992,8 @@ class Synthesis(models.Model): ) class Meta: - verbose_name = _("synthesis") - verbose_name_plural = _("syntheses") + verbose_name = _("written review") + verbose_name_plural = _("written reviews") unique_together = (('participation', 'passage', 'type', ), ) ordering = ('passage__pool__round', 'type',) diff --git a/participation/templates/participation/passage_detail.html b/participation/templates/participation/passage_detail.html index 0733ef7..e345153 100644 --- a/participation/templates/participation/passage_detail.html +++ b/participation/templates/participation/passage_detail.html @@ -47,10 +47,10 @@
{% trans "Syntheses:" %}
- {% for synthesis in passage.syntheses.all %} - {{ synthesis }}{% if not forloop.last %}, {% endif %} + {% for review in passage.written_reviews.all %} + {{ review }}{% if not forloop.last %}, {% endif %} {% empty %} - {% trans "No synthesis was uploaded yet." %} + {% trans "No review was uploaded yet." %} {% endfor %}
@@ -63,7 +63,7 @@ {% elif user.registration.participates %} {% endif %} @@ -184,10 +184,10 @@ {% include "base_modal.html" with modal_id=note.modal_name %} {% endfor %} {% elif user.registration.participates %} - {% trans "Upload synthesis" as modal_title %} + {% trans "Upload review" as modal_title %} {% trans "Upload" as modal_button %} - {% url "participation:upload_synthesis" pk=passage.pk as modal_action %} - {% include "base_modal.html" with modal_id="uploadSynthesis" modal_enctype="multipart/form-data" %} + {% url "participation:upload_review" pk=passage.pk as modal_action %} + {% include "base_modal.html" with modal_id="uploadWrittenReview" modal_enctype="multipart/form-data" %} {% endif %} {% endblock %} @@ -201,8 +201,8 @@ initModal("{{ note.modal_name }}", "{% url "participation:update_notes" pk=note.pk %}") {% endfor %} {% elif user.registration.participates %} - initModal("uploadSynthesis", "{% url "participation:upload_synthesis" pk=passage.pk %}") + initModal("uploadWrittenReview", "{% url "participation:upload_review" pk=passage.pk %}") {% endif %} - }); + }) {% endblock %} diff --git a/participation/templates/participation/pool_detail.html b/participation/templates/participation/pool_detail.html index 66c3e11..28a5424 100644 --- a/participation/templates/participation/pool_detail.html +++ b/participation/templates/participation/pool_detail.html @@ -62,15 +62,15 @@ {% for passage in pool.passages.all %}
  • {{ passage.defender.team.trigram }} — {{ passage.get_solution_number_display }} : - {% for synthesis in passage.syntheses.all %} - {{ synthesis.participation.team.trigram }} ({{ synthesis.get_type_display }}){% if not forloop.last %}, {% endif %} + {% for review in passage.written_reviews.all %} + {{ review.participation.team.trigram }} ({{ review.get_type_display }}){% if not forloop.last %}, {% endif %} {% empty %} - {% trans "No synthesis was uploaded yet." %} + {% trans "No review was uploaded yet." %} {% endfor %}
  • {% endfor %} - + {% trans "Download all" %} diff --git a/participation/templates/participation/tournament_detail.html b/participation/templates/participation/tournament_detail.html index a6ef096..683d855 100644 --- a/participation/templates/participation/tournament_detail.html +++ b/participation/templates/participation/tournament_detail.html @@ -38,15 +38,15 @@
    {% trans 'date of the random draw'|capfirst %}
    {{ tournament.solutions_draw }}
    -
    {% trans 'date of maximal syntheses submission for the first round'|capfirst %}
    -
    {{ tournament.syntheses_first_phase_limit }}
    +
    {% trans 'date of maximal written reviews submission for the first round'|capfirst %}
    +
    {{ tournament.reviews_first_phase_limit }}
    -
    {% trans 'date of maximal syntheses submission for the second round'|capfirst %}
    -
    {{ tournament.syntheses_second_phase_limit }}
    +
    {% trans 'date of maximal written reviews submission for the second round'|capfirst %}
    +
    {{ tournament.reviews_second_phase_limit }}
    {% if TFJM.APP == "ETEAM" %} -
    {% trans 'date of maximal syntheses submission for the third round'|capfirst %}
    -
    {{ tournament.syntheses_third_phase_limit }}
    +
    {% trans 'date of maximal written reviews submission for the third round'|capfirst %}
    +
    {{ tournament.reviews_third_phase_limit }}
    {% endif %}
    {% trans 'description'|capfirst %}
    @@ -233,48 +233,48 @@ diff --git a/participation/templates/participation/upload_synthesis.html b/participation/templates/participation/upload_written_review.html similarity index 100% rename from participation/templates/participation/upload_synthesis.html rename to participation/templates/participation/upload_written_review.html diff --git a/participation/urls.py b/participation/urls.py index 2c97587..4812a05 100644 --- a/participation/urls.py +++ b/participation/urls.py @@ -8,11 +8,11 @@ from .views import CreateTeamView, FinalNotationSheetTemplateView, GSheetNotific PassageDetailView, PassageUpdateView, PoolCreateView, PoolDetailView, PoolJuryView, PoolNotesTemplateView, \ PoolPresideJuryView, PoolRemoveJuryView, PoolUpdateView, PoolUploadNotesView, \ ScaleNotationSheetTemplateView, SelectTeamFinalView, \ - SolutionsDownloadView, SolutionUploadView, SynthesisUploadView, \ + SolutionsDownloadView, SolutionUploadView, \ TeamAuthorizationsView, TeamDetailView, TeamLeaveView, TeamListView, TeamUpdateView, \ TeamUploadMotivationLetterView, TournamentCreateView, TournamentDetailView, TournamentExportCSVView, \ TournamentHarmonizeNoteView, TournamentHarmonizeView, TournamentListView, TournamentPaymentsView, \ - TournamentPublishNotesView, TournamentUpdateView + TournamentPublishNotesView, TournamentUpdateView, WrittenReviewUploadView app_name = "participation" @@ -42,8 +42,8 @@ urlpatterns = [ name="tournament_authorizations"), path("tournament//solutions/", SolutionsDownloadView.as_view(), name="tournament_solutions"), - path("tournament//syntheses/", SolutionsDownloadView.as_view(), - name="tournament_syntheses"), + path("tournament//written_reviews/", SolutionsDownloadView.as_view(), + name="tournament_written_reviews"), path("tournament//notation/sheets/", NotationSheetsArchiveView.as_view(), name="tournament_notation_sheets"), path("tournament//notation/notifications/", GSheetNotificationsView.as_view(), @@ -60,7 +60,7 @@ urlpatterns = [ path("pools//", PoolDetailView.as_view(), name="pool_detail"), path("pools//update/", PoolUpdateView.as_view(), name="pool_update"), path("pools//solutions/", SolutionsDownloadView.as_view(), name="pool_download_solutions"), - path("pools//syntheses/", SolutionsDownloadView.as_view(), name="pool_download_syntheses"), + path("pools//written_reviews/", SolutionsDownloadView.as_view(), name="pool_download_written_reviews"), path("pools//notation/scale/", ScaleNotationSheetTemplateView.as_view(), name="pool_scale_note_sheet"), path("pools//notation/final/", FinalNotationSheetTemplateView.as_view(), name="pool_final_note_sheet"), path("pools//notation/sheets/", NotationSheetsArchiveView.as_view(), name="pool_notation_sheets"), @@ -71,6 +71,6 @@ urlpatterns = [ path("pools//upload-notes/template/", PoolNotesTemplateView.as_view(), name="pool_notes_template"), path("pools/passages//", PassageDetailView.as_view(), name="passage_detail"), path("pools/passages//update/", PassageUpdateView.as_view(), name="passage_update"), - path("pools/passages//solution/", SynthesisUploadView.as_view(), name="upload_synthesis"), + path("pools/passages//written_review/", WrittenReviewUploadView.as_view(), name="upload_written_review"), path("pools/passages/notes//", NoteUpdateView.as_view(), name="update_notes"), ] diff --git a/participation/views.py b/participation/views.py index 8a3b4f4..0aebdf9 100644 --- a/participation/views.py +++ b/participation/views.py @@ -46,9 +46,9 @@ from tfjm.lists import get_sympa_client from tfjm.views import AdminMixin, VolunteerMixin from .forms import AddJuryForm, JoinTeamForm, MotivationLetterForm, NoteForm, ParticipationForm, PassageForm, \ - PoolForm, RequestValidationForm, SolutionForm, SynthesisForm, TeamForm, TournamentForm, \ - UploadNotesForm, ValidateParticipationForm -from .models import Note, Participation, Passage, Pool, Solution, Synthesis, Team, Tournament, Tweak + PoolForm, RequestValidationForm, SolutionForm, TeamForm, TournamentForm, UploadNotesForm, \ + ValidateParticipationForm, WrittenReviewForm +from .models import Note, Participation, Passage, Pool, Solution, Team, Tournament, Tweak, WrittenReview from .tables import NoteTable, ParticipationTable, PassageTable, PoolTable, TeamTable, TournamentTable @@ -977,7 +977,7 @@ class PoolUpdateView(VolunteerMixin, UpdateView): class SolutionsDownloadView(VolunteerMixin, View): """ - Download all solutions or syntheses as a ZIP archive. + Download all solutions or written reviews as a ZIP archive. """ def dispatch(self, request, *args, **kwargs): @@ -1018,11 +1018,12 @@ class SolutionsDownloadView(VolunteerMixin, View): if 'team_id' in kwargs: team = Team.objects.get(pk=kwargs["team_id"]) solutions = Solution.objects.filter(participation=team.participation).all() - syntheses = Synthesis.objects.filter(participation=team.participation).all() - filename = _("Solutions of team {trigram}.zip") if is_solution else _("Syntheses of team {trigram}.zip") + written_reviews = WrittenReview.objects.filter(participation=team.participation).all() + filename = _("Solutions of team {trigram}.zip") if is_solution \ + else _("Written reviews of team {trigram}.zip") filename = filename.format(trigram=team.trigram) - def prefix(s: Solution | Synthesis) -> str: + def prefix(s: Solution | WrittenReview) -> str: return "" elif 'tournament_id' in kwargs: tournament = Tournament.objects.get(pk=kwargs["tournament_id"]) @@ -1035,11 +1036,12 @@ class SolutionsDownloadView(VolunteerMixin, View): for sol in pool.solutions: sol.pool = pool solutions.append(sol) - syntheses = Synthesis.objects.filter(passage__pool__tournament=tournament).all() - filename = _("Solutions of {tournament}.zip") if is_solution else _("Syntheses of {tournament}.zip") + written_reviews = WrittenReview.objects.filter(passage__pool__tournament=tournament).all() + filename = _("Solutions of {tournament}.zip") if is_solution \ + else _("Written reviews of {tournament}.zip") filename = filename.format(tournament=tournament.name) - def prefix(s: Solution | Synthesis) -> str: + def prefix(s: Solution | WrittenReview) -> str: pool = s.pool if is_solution else s.passage.pool p = f"Poule {pool.short_name}/" if not is_solution: @@ -1050,27 +1052,28 @@ class SolutionsDownloadView(VolunteerMixin, View): solutions = Solution.objects.filter(participation__tournament=tournament).all() else: solutions = Solution.objects.filter(final_solution=True).all() - syntheses = Synthesis.objects.filter(passage__pool__tournament=tournament).all() - filename = _("Solutions of {tournament}.zip") if is_solution else _("Syntheses of {tournament}.zip") + written_reviews = WrittenReview.objects.filter(passage__pool__tournament=tournament).all() + filename = _("Solutions of {tournament}.zip") if is_solution \ + else _("Written reviews of {tournament}.zip") filename = filename.format(tournament=tournament.name) - def prefix(s: Solution | Synthesis) -> str: + def prefix(s: Solution | WrittenReview) -> str: return f"{s.participation.team.trigram}/" if sort_by == "team" else f"Problème {s.problem}/" else: pool = Pool.objects.get(pk=kwargs["pool_id"]) solutions = pool.solutions - syntheses = Synthesis.objects.filter(passage__pool=pool).all() + written_reviews = WrittenReview.objects.filter(passage__pool=pool).all() filename = _("Solutions for pool {pool} of tournament {tournament}.zip") \ - if is_solution else _("Syntheses for pool {pool} of tournament {tournament}.zip") + if is_solution else _("Written reviews for pool {pool} of tournament {tournament}.zip") filename = filename.format(pool=pool.short_name, tournament=pool.tournament.name) - def prefix(s: Solution | Synthesis) -> str: + def prefix(s: Solution | WrittenReview) -> str: return "" output = BytesIO() zf = ZipFile(output, "w") - for s in (solutions if is_solution else syntheses): + for s in (solutions if is_solution else written_reviews): if s.file.storage.exists(s.file.path): zf.write("media/" + s.file.name, prefix(s) + f"{s}.pdf") @@ -2028,9 +2031,9 @@ class PassageUpdateView(VolunteerMixin, UpdateView): return self.handle_no_permission() -class SynthesisUploadView(LoginRequiredMixin, FormView): - template_name = "participation/upload_synthesis.html" - form_class = SynthesisForm +class WrittenReviewUploadView(LoginRequiredMixin, FormView): + template_name = "participation/upload_written_review.html" + form_class = WrittenReviewForm def dispatch(self, request, *args, **kwargs): if not request.user.is_authenticated or not request.user.registration.participates: @@ -2057,14 +2060,14 @@ class SynthesisUploadView(LoginRequiredMixin, FormView): form_syn = form.instance form_syn.type = 1 if self.participation == self.passage.opponent \ else 2 if self.participation == self.passage.reviewer else 3 - syn_qs = Synthesis.objects.filter(participation=self.participation, - passage=self.passage, - type=form_syn.type).all() + syn_qs = WrittenReview.objects.filter(participation=self.participation, + passage=self.passage, + type=form_syn.type).all() - deadline = self.passage.pool.tournament.syntheses_first_phase_limit if self.passage.pool.round == 1 \ - else self.passage.pool.tournament.syntheses_second_phase_limit + deadline = self.passage.pool.tournament.reviews_first_phase_limit if self.passage.pool.round == 1 \ + else self.passage.pool.tournament.reviews_second_phase_limit if syn_qs.exists() and timezone.now() > deadline: - form.add_error(None, _("You can't upload a synthesis after the deadline.")) + form.add_error(None, _("You can't upload a written review after the deadline.")) return self.form_invalid(form) # Drop previous solution if existing diff --git a/registration/views.py b/registration/views.py index 2d0fe1a..60328d0 100644 --- a/registration/views.py +++ b/registration/views.py @@ -26,7 +26,7 @@ from django.utils.translation import gettext_lazy as _ from django.views.generic import CreateView, DetailView, RedirectView, TemplateView, UpdateView, View from django_tables2 import SingleTableView from magic import Magic -from participation.models import Passage, Solution, Synthesis, Tournament +from participation.models import Passage, Solution, Tournament, WrittenReview from tfjm.tokens import email_validation_token from tfjm.views import UserMixin, UserRegistrationMixin, VolunteerMixin @@ -871,30 +871,30 @@ class SolutionView(LoginRequiredMixin, View): return FileResponse(open(path, "rb"), content_type=mime_type, filename=true_file_name) -class SynthesisView(LoginRequiredMixin, View): +class WrittenReviewView(LoginRequiredMixin, View): """ - Display the sent synthesis. + Display the sent written reviews. """ def get(self, request, *args, **kwargs): filename = kwargs["filename"] - path = f"media/syntheses/{filename}" + path = f"media/reviews/{filename}" if not os.path.exists(path): raise Http404 - synthesis = Synthesis.objects.get(file__endswith=filename) + reviews = WrittenReview.objects.get(file__endswith=filename) user = request.user if not (user.registration.is_admin or user.registration.is_volunteer - and (user.registration in synthesis.passage.pool.juries.all() - or user.registration in synthesis.passage.pool.tournament.organizers.all() - or user.registration.pools_presided.filter(tournament=synthesis.passage.pool.tournament).exists()) - or user.registration.participates and user.registration.team == synthesis.participation.team): + and (user.registration in reviews.passage.pool.juries.all() + or user.registration in reviews.passage.pool.tournament.organizers.all() + or user.registration.pools_presided.filter(tournament=reviews.passage.pool.tournament).exists()) + or user.registration.participates and user.registration.team == reviews.participation.team): raise PermissionDenied # Guess mime type of the file mime = Magic(mime=True) mime_type = mime.from_file(path) ext = mime_type.split("/")[1].replace("jpeg", "jpg") # Replace file name - true_file_name = str(synthesis) + f".{ext}" + true_file_name = str(reviews) + f".{ext}" return FileResponse(open(path, "rb"), content_type=mime_type, filename=true_file_name) diff --git a/tfjm/urls.py b/tfjm/urls.py index 16bac38..d2aa6f9 100644 --- a/tfjm/urls.py +++ b/tfjm/urls.py @@ -24,7 +24,7 @@ from django.views.defaults import bad_request, page_not_found, permission_denied from django.views.generic import TemplateView from participation.views import MotivationLetterView from registration.views import HealthSheetView, ParentalAuthorizationView, PhotoAuthorizationView, \ - ReceiptView, SolutionView, SynthesisView, VaccineSheetView + ReceiptView, SolutionView, VaccineSheetView, WrittenReviewView from .views import AdminSearchView @@ -61,8 +61,8 @@ urlpatterns = [ path('media/solutions//', SolutionView.as_view(), name='solution'), - path('media/syntheses//', SynthesisView.as_view(), - name='synthesis'), + path('media/reviews//', WrittenReviewView.as_view(), + name='reviews'), ] if settings.DEBUG: