Rename synthesis to written review
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
parent
696863f6c3
commit
12205f953b
|
@ -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: 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"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: Emmy D'Anello <emmy.danello@animath.fr>\n"
|
"Last-Translator: Emmy D'Anello <emmy.danello@animath.fr>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\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
|
#: 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
|
#: draw/models.py:27 participation/admin.py:79 participation/admin.py:144
|
||||||
#: participation/admin.py:176 participation/models.py:783
|
#: 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/models.py:763
|
||||||
#: registration/templates/registration/payment_form.html:53
|
#: registration/templates/registration/payment_form.html:53
|
||||||
msgid "tournament"
|
msgid "tournament"
|
||||||
|
@ -95,7 +95,7 @@ msgstr ""
|
||||||
|
|
||||||
#: chat/models.py:73 draw/models.py:446 draw/models.py:473
|
#: chat/models.py:73 draw/models.py:446 draw/models.py:473
|
||||||
#: participation/admin.py:140 participation/admin.py:160
|
#: 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
|
#: participation/tables.py:84
|
||||||
msgid "pool"
|
msgid "pool"
|
||||||
msgstr "poule"
|
msgstr "poule"
|
||||||
|
@ -265,7 +265,7 @@ msgid "teams"
|
||||||
msgstr "équipes"
|
msgstr "équipes"
|
||||||
|
|
||||||
#: draw/admin.py:92 draw/models.py:245 draw/models.py:465
|
#: draw/admin.py:92 draw/models.py:245 draw/models.py:465
|
||||||
#: participation/models.py:1120
|
#: participation/models.py:1135
|
||||||
msgid "round"
|
msgid "round"
|
||||||
msgstr "tour"
|
msgstr "tour"
|
||||||
|
|
||||||
|
@ -634,7 +634,7 @@ msgstr "Le numéro du tour doit être entre 1 et {nb}."
|
||||||
msgid "rounds"
|
msgid "rounds"
|
||||||
msgstr "tours"
|
msgstr "tours"
|
||||||
|
|
||||||
#: draw/models.py:268 participation/models.py:1128
|
#: draw/models.py:268 participation/models.py:1143
|
||||||
msgid "letter"
|
msgid "letter"
|
||||||
msgstr "lettre"
|
msgstr "lettre"
|
||||||
|
|
||||||
|
@ -672,12 +672,12 @@ msgstr "L'instance complète de la poule."
|
||||||
msgid "Pool {letter}{number}"
|
msgid "Pool {letter}{number}"
|
||||||
msgstr "Poule {letter}{number}"
|
msgstr "Poule {letter}{number}"
|
||||||
|
|
||||||
#: draw/models.py:447 participation/models.py:1652
|
#: draw/models.py:447 participation/models.py:1667
|
||||||
msgid "pools"
|
msgid "pools"
|
||||||
msgstr "poules"
|
msgstr "poules"
|
||||||
|
|
||||||
#: draw/models.py:459 participation/models.py:1106 participation/models.py:1871
|
#: draw/models.py:459 participation/models.py:1121 participation/models.py:1886
|
||||||
#: participation/models.py:1901 participation/models.py:1943
|
#: participation/models.py:1920 participation/models.py:1962
|
||||||
msgid "participation"
|
msgid "participation"
|
||||||
msgstr "participation"
|
msgstr "participation"
|
||||||
|
|
||||||
|
@ -701,9 +701,9 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"L'ordre de choix dans la poule, entre 0 et la taille de la poule moins 1."
|
"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
|
#: draw/models.py:496 draw/models.py:519 participation/models.py:1252
|
||||||
#: participation/models.py:1674 participation/models.py:1908
|
#: participation/models.py:1689 participation/models.py:1927
|
||||||
#: participation/views.py:1489 participation/views.py:1754
|
#: participation/views.py:1492 participation/views.py:1757
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Problem #{problem}"
|
msgid "Problem #{problem}"
|
||||||
msgstr "Problème n°{problem}"
|
msgstr "Problème n°{problem}"
|
||||||
|
@ -919,26 +919,26 @@ msgid "selected for final"
|
||||||
msgstr "sélectionnée pour la finale"
|
msgstr "sélectionnée pour la finale"
|
||||||
|
|
||||||
#: participation/admin.py:124 participation/admin.py:188
|
#: 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"
|
msgid "defender"
|
||||||
msgstr "défenseur⋅se"
|
msgstr "défenseur⋅se"
|
||||||
|
|
||||||
#: participation/admin.py:128 participation/models.py:1688
|
#: participation/admin.py:128 participation/models.py:1703
|
||||||
#: participation/models.py:1955
|
#: participation/models.py:1974
|
||||||
msgid "opponent"
|
msgid "opponent"
|
||||||
msgstr "opposant⋅e"
|
msgstr "opposant⋅e"
|
||||||
|
|
||||||
#: participation/admin.py:132 participation/models.py:1695
|
#: participation/admin.py:132 participation/models.py:1710
|
||||||
#: participation/models.py:1956
|
#: participation/models.py:1975
|
||||||
msgid "reviewer"
|
msgid "reviewer"
|
||||||
msgstr "rapporteur⋅rice"
|
msgstr "rapporteur⋅rice"
|
||||||
|
|
||||||
#: participation/admin.py:136 participation/models.py:1702
|
#: participation/admin.py:136 participation/models.py:1717
|
||||||
#: participation/models.py:1957
|
#: participation/models.py:1976
|
||||||
msgid "observer"
|
msgid "observer"
|
||||||
msgstr "observateur⋅rice"
|
msgstr "observateur⋅rice"
|
||||||
|
|
||||||
#: participation/admin.py:192 participation/models.py:1906
|
#: participation/admin.py:192 participation/models.py:1925
|
||||||
msgid "problem"
|
msgid "problem"
|
||||||
msgstr "numéro de problème"
|
msgstr "numéro de problème"
|
||||||
|
|
||||||
|
@ -1239,7 +1239,7 @@ msgid "first phase date"
|
||||||
msgstr "date du premier tour"
|
msgstr "date du premier tour"
|
||||||
|
|
||||||
#: participation/models.py:327
|
#: 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"
|
msgstr "date limite pour envoyer les notes de synthèses pour la première phase"
|
||||||
|
|
||||||
#: participation/models.py:332
|
#: participation/models.py:332
|
||||||
|
@ -1252,7 +1252,7 @@ msgstr ""
|
||||||
"cocher la case lorsque les solutions pour le second tour sont accessibles"
|
"cocher la case lorsque les solutions pour le second tour sont accessibles"
|
||||||
|
|
||||||
#: participation/models.py:342
|
#: 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"
|
msgstr "date limite d'envoi des notes de synthèse pour la seconde phase"
|
||||||
|
|
||||||
#: participation/models.py:347
|
#: participation/models.py:347
|
||||||
|
@ -1265,7 +1265,7 @@ msgstr ""
|
||||||
"cocher la case lorsque les solutions pour le second tour sont accessibles"
|
"cocher la case lorsque les solutions pour le second tour sont accessibles"
|
||||||
|
|
||||||
#: participation/models.py:357
|
#: 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 ""
|
msgstr ""
|
||||||
"date limite pour envoyer les notes de synthèses pour la troisième phase"
|
"date limite pour envoyer les notes de synthèses pour la troisième phase"
|
||||||
|
|
||||||
|
@ -1294,7 +1294,7 @@ msgid "Final ranking"
|
||||||
msgstr "Classement final"
|
msgstr "Classement final"
|
||||||
|
|
||||||
#: participation/models.py:481 participation/models.py:553
|
#: 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"
|
msgid "Team"
|
||||||
msgstr "Équipe"
|
msgstr "Équipe"
|
||||||
|
|
||||||
|
@ -1326,15 +1326,15 @@ msgstr "Scores jour 3"
|
||||||
msgid "Tweaks day 3"
|
msgid "Tweaks day 3"
|
||||||
msgstr "Ajustements 3"
|
msgstr "Ajustements 3"
|
||||||
|
|
||||||
#: participation/models.py:485 participation/models.py:1312
|
#: participation/models.py:485 participation/models.py:1327
|
||||||
#: participation/views.py:1735
|
#: participation/views.py:1738
|
||||||
msgid "Total"
|
msgid "Total"
|
||||||
msgstr "Total"
|
msgstr "Total"
|
||||||
|
|
||||||
#: participation/models.py:485 participation/models.py:553
|
#: participation/models.py:485 participation/models.py:553
|
||||||
#: participation/models.py:1312
|
#: participation/models.py:1327
|
||||||
#: participation/templates/participation/tournament_harmonize.html:14
|
#: participation/templates/participation/tournament_harmonize.html:14
|
||||||
#: participation/views.py:1738
|
#: participation/views.py:1741
|
||||||
msgid "Rank"
|
msgid "Rank"
|
||||||
msgstr "Rang"
|
msgstr "Rang"
|
||||||
|
|
||||||
|
@ -1346,7 +1346,7 @@ msgstr "Score"
|
||||||
msgid "Mention"
|
msgid "Mention"
|
||||||
msgstr "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."
|
msgid "Don't update the table structure for a better automated integration."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Ne pas mettre à jour la structure de la table pour une meilleure intégration "
|
"Ne pas mettre à jour la structure de la table pour une meilleure intégration "
|
||||||
|
@ -1456,47 +1456,47 @@ msgstr ""
|
||||||
"tour, vous défendrez <a href='{solution_url}'>votre solution du problème "
|
"tour, vous défendrez <a href='{solution_url}'>votre solution du problème "
|
||||||
"{problem}</a>.</p>"
|
"{problem}</a>.</p>"
|
||||||
|
|
||||||
#: participation/models.py:930 participation/models.py:988
|
#: participation/models.py:930 participation/models.py:993
|
||||||
#: participation/models.py:1047
|
#: participation/models.py:1057
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"<p>You will oppose the solution of the team {opponent} on the <a "
|
"<p>You will oppose the solution of the team {opponent} on the <a "
|
||||||
"href='{solution_url}'>problem {problem}</a>. You can upload your synthesis "
|
"href='{solution_url}'>problem {problem}</a>. You can upload your written "
|
||||||
"sheet on <a href='{passage_url}'>this page</a>.</p>"
|
"review on <a href='{passage_url}'>this page</a>.</p>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"<p>Vous opposerez la solution de l'équipe {opponent} sur le <a "
|
"<p>Vous opposerez la solution de l'équipe {opponent} sur le <a "
|
||||||
"href='{solution_url}'>problème {problem}</a>. Vous pouvez envoyer votre note "
|
"href='{solution_url}'>problème {problem}</a>. Vous pouvez envoyer votre note "
|
||||||
"de synthèse sur <a href='{passage_url}'>cette page</a>.</p>"
|
"de synthèse sur <a href='{passage_url}'>cette page</a>.</p>"
|
||||||
|
|
||||||
#: participation/models.py:939 participation/models.py:997
|
#: participation/models.py:939 participation/models.py:1002
|
||||||
#: participation/models.py:1056
|
#: participation/models.py:1066
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"<p>You will report the solution of the team {reviewer} on the <a "
|
"<p>You will report the solution of the team {reviewer} on the <a "
|
||||||
"href='{solution_url}'>problem {problem}. You can upload your synthesis sheet "
|
"href='{solution_url}'>problem {problem}</a>. You can upload your written "
|
||||||
"on <a href='{passage_url}'>this page</a>.</p>"
|
"review on <a href='{passage_url}'>this page</a>.</p>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"<p>Vous rapporterez la solution de l'équipe {reviewer} sur le <a "
|
"<p>Vous rapporterez la solution de l'équipe {reviewer} sur le <a "
|
||||||
"href='{solution_url}'>problème {problem}</a>. Vous pouvez envoyer votre note "
|
"href='{solution_url}'>problème {problem}</a>. Vous pouvez envoyer votre note "
|
||||||
"de synthèse sur <a href='{passage_url}'>cette page</a>.</p>"
|
"de synthèse sur <a href='{passage_url}'>cette page</a>.</p>"
|
||||||
|
|
||||||
#: participation/models.py:949 participation/models.py:1007
|
#: participation/models.py:949 participation/models.py:1012
|
||||||
#: participation/models.py:1066
|
#: participation/models.py:1076
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"<p>You will observe the solution of the team {observer} on the <a "
|
"<p>You will observe the solution of the team {observer} on the <a "
|
||||||
"href='{solution_url}'>problem {problem}. You can upload your synthesis sheet "
|
"href='{solution_url}'>problem {problem}</a>. You can upload your written "
|
||||||
"on <a href='{passage_url}'>this page</a>.</p>"
|
"review on <a href='{passage_url}'>this page</a>.</p>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"<p>Vous observerez la solution de l'équipe {observer} sur le <a "
|
"<p>Vous observerez la solution de l'équipe {observer} sur le <a "
|
||||||
"href='{solution_url}'>problème {problem}</a>. Vous pouvez envoyer votre note "
|
"href='{solution_url}'>problème {problem}</a>. Vous pouvez envoyer votre note "
|
||||||
"de synthèse sur <a href='{passage_url}'>cette page</a>.</p>"
|
"de synthèse sur <a href='{passage_url}'>cette page</a>.</p>"
|
||||||
|
|
||||||
#: participation/models.py:969 registration/models.py:629
|
#: participation/models.py:974 registration/models.py:629
|
||||||
msgid "First round"
|
msgid "First round"
|
||||||
msgstr "Premier tour"
|
msgstr "Premier tour"
|
||||||
|
|
||||||
#: participation/models.py:981
|
#: participation/models.py:986
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"<p>For the second round, you will defend <a href='{solution_url}'>your "
|
"<p>For the second round, you will defend <a href='{solution_url}'>your "
|
||||||
|
@ -1505,12 +1505,12 @@ msgstr ""
|
||||||
"<p>Pour le second tour, vous défendrez <a href='{solution_url}'>votre "
|
"<p>Pour le second tour, vous défendrez <a href='{solution_url}'>votre "
|
||||||
"solution du problème {problem}</a>.</p>"
|
"solution du problème {problem}</a>.</p>"
|
||||||
|
|
||||||
#: participation/models.py:1027 participation/models.py:1086
|
#: participation/models.py:1037 participation/models.py:1101
|
||||||
#: registration/models.py:640
|
#: registration/models.py:640
|
||||||
msgid "Second round"
|
msgid "Second round"
|
||||||
msgstr "Second tour"
|
msgstr "Second tour"
|
||||||
|
|
||||||
#: participation/models.py:1040
|
#: participation/models.py:1050
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"<p>For the third round, you will defend <a href='{solution_url}'>your "
|
"<p>For the third round, you will defend <a href='{solution_url}'>your "
|
||||||
|
@ -1519,7 +1519,7 @@ msgstr ""
|
||||||
"<p>Pour le troisième tour, vous défendrez <a href='{solution_url}'>votre "
|
"<p>Pour le troisième tour, vous défendrez <a href='{solution_url}'>votre "
|
||||||
"solution du problème {problem}</a>.</p>"
|
"solution du problème {problem}</a>.</p>"
|
||||||
|
|
||||||
#: participation/models.py:1092
|
#: participation/models.py:1107
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"<p>The tournament {tournament} is ended. You can check the results on the <a "
|
"<p>The tournament {tournament} is ended. You can check the results on the <a "
|
||||||
|
@ -1528,57 +1528,57 @@ msgstr ""
|
||||||
"<p>Le tournoi {tournament} est terminé. Vous pouvez consulter les résultats "
|
"<p>Le tournoi {tournament} est terminé. Vous pouvez consulter les résultats "
|
||||||
"sur la <a href='{url}'>page du tournoi</a>.</p>"
|
"sur la <a href='{url}'>page du tournoi</a>.</p>"
|
||||||
|
|
||||||
#: participation/models.py:1097
|
#: participation/models.py:1112
|
||||||
msgid "Tournament ended"
|
msgid "Tournament ended"
|
||||||
msgstr "Tournoi terminé"
|
msgstr "Tournoi terminé"
|
||||||
|
|
||||||
#: participation/models.py:1107 participation/models.py:1150
|
#: participation/models.py:1122 participation/models.py:1165
|
||||||
msgid "participations"
|
msgid "participations"
|
||||||
msgstr "participations"
|
msgstr "participations"
|
||||||
|
|
||||||
#: participation/models.py:1122 participation/models.py:1123
|
#: participation/models.py:1137 participation/models.py:1138
|
||||||
#: participation/models.py:1124
|
#: participation/models.py:1139
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Round {round}"
|
msgid "Round {round}"
|
||||||
msgstr "Tour {round}"
|
msgstr "Tour {round}"
|
||||||
|
|
||||||
#: participation/models.py:1138
|
#: participation/models.py:1153
|
||||||
msgid "room"
|
msgid "room"
|
||||||
msgstr "salle"
|
msgstr "salle"
|
||||||
|
|
||||||
#: participation/models.py:1140
|
#: participation/models.py:1155
|
||||||
msgid "Room 1"
|
msgid "Room 1"
|
||||||
msgstr "Salle 1"
|
msgstr "Salle 1"
|
||||||
|
|
||||||
#: participation/models.py:1141
|
#: participation/models.py:1156
|
||||||
msgid "Room 2"
|
msgid "Room 2"
|
||||||
msgstr "Salle 2"
|
msgstr "Salle 2"
|
||||||
|
|
||||||
#: participation/models.py:1144
|
#: participation/models.py:1159
|
||||||
msgid "For 5-teams pools only"
|
msgid "For 5-teams pools only"
|
||||||
msgstr "Pour les poules de 5 équipe uniquement"
|
msgstr "Pour les poules de 5 équipe uniquement"
|
||||||
|
|
||||||
#: participation/models.py:1156
|
#: participation/models.py:1171
|
||||||
msgid "juries"
|
msgid "juries"
|
||||||
msgstr "jurys"
|
msgstr "jurys"
|
||||||
|
|
||||||
#: participation/models.py:1165
|
#: participation/models.py:1180
|
||||||
msgid "president of the jury"
|
msgid "president of the jury"
|
||||||
msgstr "président⋅e du jury"
|
msgstr "président⋅e du jury"
|
||||||
|
|
||||||
#: participation/models.py:1172
|
#: participation/models.py:1187
|
||||||
msgid "BigBlueButton URL"
|
msgid "BigBlueButton URL"
|
||||||
msgstr "Lien BigBlueButton"
|
msgstr "Lien BigBlueButton"
|
||||||
|
|
||||||
#: participation/models.py:1173
|
#: participation/models.py:1188
|
||||||
msgid "The link of the BBB visio for this pool."
|
msgid "The link of the BBB visio for this pool."
|
||||||
msgstr "Le lien du salon BBB pour cette poule."
|
msgstr "Le lien du salon BBB pour cette poule."
|
||||||
|
|
||||||
#: participation/models.py:1178
|
#: participation/models.py:1193
|
||||||
msgid "results available"
|
msgid "results available"
|
||||||
msgstr "résultats disponibles"
|
msgstr "résultats disponibles"
|
||||||
|
|
||||||
#: participation/models.py:1179
|
#: participation/models.py:1194
|
||||||
msgid ""
|
msgid ""
|
||||||
"Check this case when results become accessible to teams. They stay "
|
"Check this case when results become accessible to teams. They stay "
|
||||||
"accessible to you. Only averages are given."
|
"accessible to you. Only averages are given."
|
||||||
|
@ -1587,65 +1587,65 @@ msgstr ""
|
||||||
"Ils restent toujours accessibles pour vous. Seules les moyennes sont "
|
"Ils restent toujours accessibles pour vous. Seules les moyennes sont "
|
||||||
"communiquées."
|
"communiquées."
|
||||||
|
|
||||||
#: participation/models.py:1211
|
#: participation/models.py:1226
|
||||||
msgid "The president of the jury must be part of the jury."
|
msgid "The president of the jury must be part of the jury."
|
||||||
msgstr "Læ président⋅e du jury doit faire partie du jury."
|
msgstr "Læ président⋅e du jury doit faire partie du jury."
|
||||||
|
|
||||||
#: participation/models.py:1238 participation/models.py:1312
|
#: participation/models.py:1253 participation/models.py:1327
|
||||||
#: participation/views.py:1483 participation/views.py:1732
|
#: participation/views.py:1486 participation/views.py:1735
|
||||||
msgid "Problem"
|
msgid "Problem"
|
||||||
msgstr "Problème"
|
msgstr "Problème"
|
||||||
|
|
||||||
#: participation/models.py:1243 participation/views.py:1498
|
#: participation/models.py:1258 participation/views.py:1501
|
||||||
msgid "Role"
|
msgid "Role"
|
||||||
msgstr "Rôle"
|
msgstr "Rôle"
|
||||||
|
|
||||||
#: participation/models.py:1248 participation/views.py:1532
|
#: participation/models.py:1263 participation/views.py:1535
|
||||||
#: participation/views.py:1533
|
#: participation/views.py:1536
|
||||||
msgid "Juree"
|
msgid "Juree"
|
||||||
msgstr "Juré⋅e"
|
msgstr "Juré⋅e"
|
||||||
|
|
||||||
#: participation/models.py:1271 participation/models.py:1597
|
#: participation/models.py:1286 participation/models.py:1612
|
||||||
#: participation/models.py:1619 participation/views.py:1602
|
#: participation/models.py:1634 participation/views.py:1605
|
||||||
msgid "Average"
|
msgid "Average"
|
||||||
msgstr "Moyenne"
|
msgstr "Moyenne"
|
||||||
|
|
||||||
#: participation/models.py:1277 participation/views.py:1621
|
#: participation/models.py:1292 participation/views.py:1624
|
||||||
msgid "Coefficient"
|
msgid "Coefficient"
|
||||||
msgstr "Coefficien"
|
msgstr "Coefficien"
|
||||||
|
|
||||||
#: participation/models.py:1278 participation/views.py:1664
|
#: participation/models.py:1293 participation/views.py:1667
|
||||||
msgid "Subtotal"
|
msgid "Subtotal"
|
||||||
msgstr "Sous-total"
|
msgstr "Sous-total"
|
||||||
|
|
||||||
#: participation/models.py:1544
|
#: participation/models.py:1559
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Input must be a valid integer between {min_note} and {max_note}."
|
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}."
|
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
|
#, python-brace-format
|
||||||
msgid "The jury {jury} is not part of the jury for this pool."
|
msgid "The jury {jury} is not part of the jury for this pool."
|
||||||
msgstr "{jury} ne fait pas partie du jury pour cette poule."
|
msgstr "{jury} ne fait pas partie du jury pour cette poule."
|
||||||
|
|
||||||
#: participation/models.py:1645
|
#: participation/models.py:1660
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Pool {code} for tournament {tournament} with teams {teams}"
|
msgid "Pool {code} for tournament {tournament} with teams {teams}"
|
||||||
msgstr "Poule {code} du tournoi {tournament} avec les équipes {teams}"
|
msgstr "Poule {code} du tournoi {tournament} avec les équipes {teams}"
|
||||||
|
|
||||||
#: participation/models.py:1665
|
#: participation/models.py:1680
|
||||||
msgid "position"
|
msgid "position"
|
||||||
msgstr "position"
|
msgstr "position"
|
||||||
|
|
||||||
#: participation/models.py:1672
|
#: participation/models.py:1687
|
||||||
msgid "defended solution"
|
msgid "defended solution"
|
||||||
msgstr "solution défendue"
|
msgstr "solution défendue"
|
||||||
|
|
||||||
#: participation/models.py:1710
|
#: participation/models.py:1725
|
||||||
msgid "penalties"
|
msgid "penalties"
|
||||||
msgstr "pénalités"
|
msgstr "pénalités"
|
||||||
|
|
||||||
#: participation/models.py:1712
|
#: participation/models.py:1727
|
||||||
msgid ""
|
msgid ""
|
||||||
"Number of penalties for the defender. The defender will loose a 0.5 "
|
"Number of penalties for the defender. The defender will loose a 0.5 "
|
||||||
"coefficient per penalty."
|
"coefficient per penalty."
|
||||||
|
@ -1653,128 +1653,128 @@ msgstr ""
|
||||||
"Nombre de pénalités pour l'équipe défenseuse. Elle perd un coefficient 0.5 "
|
"Nombre de pénalités pour l'équipe défenseuse. Elle perd un coefficient 0.5 "
|
||||||
"sur sa présentation orale par pénalité."
|
"sur sa présentation orale par pénalité."
|
||||||
|
|
||||||
#: participation/models.py:1838 participation/models.py:1841
|
#: participation/models.py:1853 participation/models.py:1856
|
||||||
#: participation/models.py:1844 participation/models.py:1847
|
#: participation/models.py:1859 participation/models.py:1862
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Team {trigram} is not registered in the pool."
|
msgid "Team {trigram} is not registered in the pool."
|
||||||
msgstr "L'équipe {trigram} n'est pas inscrite dans la poule."
|
msgstr "L'équipe {trigram} n'est pas inscrite dans la poule."
|
||||||
|
|
||||||
#: participation/models.py:1852
|
#: participation/models.py:1867
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Passage of {defender} for problem {problem}"
|
msgid "Passage of {defender} for problem {problem}"
|
||||||
msgstr "Passage de {defender} pour le problème {problem}"
|
msgstr "Passage de {defender} pour le problème {problem}"
|
||||||
|
|
||||||
#: participation/models.py:1856 participation/models.py:1865
|
#: participation/models.py:1871 participation/models.py:1880
|
||||||
#: participation/models.py:1950 participation/models.py:1993
|
#: participation/models.py:1969 participation/models.py:2012
|
||||||
msgid "passage"
|
msgid "passage"
|
||||||
msgstr "passage"
|
msgstr "passage"
|
||||||
|
|
||||||
#: participation/models.py:1857
|
#: participation/models.py:1872
|
||||||
msgid "passages"
|
msgid "passages"
|
||||||
msgstr "passages"
|
msgstr "passages"
|
||||||
|
|
||||||
#: participation/models.py:1876
|
#: participation/models.py:1891
|
||||||
msgid "difference"
|
msgid "difference"
|
||||||
msgstr "différence"
|
msgstr "différence"
|
||||||
|
|
||||||
#: participation/models.py:1877
|
#: participation/models.py:1892
|
||||||
msgid "Score to add/remove on the final score"
|
msgid "Score to add/remove on the final score"
|
||||||
msgstr "Score à ajouter/retrancher au score final"
|
msgstr "Score à ajouter/retrancher au score final"
|
||||||
|
|
||||||
#: participation/models.py:1884
|
#: participation/models.py:1899
|
||||||
msgid "tweak"
|
msgid "tweak"
|
||||||
msgstr "harmonisation"
|
msgstr "harmonisation"
|
||||||
|
|
||||||
#: participation/models.py:1885
|
#: participation/models.py:1900
|
||||||
msgid "tweaks"
|
msgid "tweaks"
|
||||||
msgstr "harmonisations"
|
msgstr "harmonisations"
|
||||||
|
|
||||||
#: participation/models.py:1913
|
#: participation/models.py:1932
|
||||||
msgid "solution for the final tournament"
|
msgid "solution for the final tournament"
|
||||||
msgstr "solution pour la finale"
|
msgstr "solution pour la finale"
|
||||||
|
|
||||||
#: participation/models.py:1918 participation/models.py:1962
|
#: participation/models.py:1937 participation/models.py:1981
|
||||||
msgid "file"
|
msgid "file"
|
||||||
msgstr "fichier"
|
msgstr "fichier"
|
||||||
|
|
||||||
#: participation/models.py:1928
|
#: participation/models.py:1947
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Solution of team {team} for problem {problem}"
|
msgid "Solution of team {team} for problem {problem}"
|
||||||
msgstr "Solution de l'équipe {team} pour le problème {problem}"
|
msgstr "Solution de l'équipe {team} pour le problème {problem}"
|
||||||
|
|
||||||
#: participation/models.py:1930
|
#: participation/models.py:1949
|
||||||
msgid "for final"
|
msgid "for final"
|
||||||
msgstr "pour la finale"
|
msgstr "pour la finale"
|
||||||
|
|
||||||
#: participation/models.py:1933
|
#: participation/models.py:1952
|
||||||
msgid "solution"
|
msgid "solution"
|
||||||
msgstr "solution"
|
msgstr "solution"
|
||||||
|
|
||||||
#: participation/models.py:1934
|
#: participation/models.py:1953
|
||||||
msgid "solutions"
|
msgid "solutions"
|
||||||
msgstr "solutions"
|
msgstr "solutions"
|
||||||
|
|
||||||
#: participation/models.py:1968
|
#: participation/models.py:1987
|
||||||
#, python-brace-format
|
#, 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 ""
|
msgstr ""
|
||||||
"Note de synthèse de l'équipe {team} en tant que {type} pour le problème "
|
"Note de synthèse de l'équipe {team} en tant que {type} pour le problème "
|
||||||
"{problem} de {defender}"
|
"{problem} de {defender}"
|
||||||
|
|
||||||
#: participation/models.py:1976
|
#: participation/models.py:1995
|
||||||
msgid "synthesis"
|
msgid "written review"
|
||||||
msgstr "note de synthèse"
|
msgstr "note de synthèse"
|
||||||
|
|
||||||
#: participation/models.py:1977
|
#: participation/models.py:1996
|
||||||
msgid "syntheses"
|
msgid "written reviews"
|
||||||
msgstr "notes de synthèse"
|
msgstr "notes de synthèse"
|
||||||
|
|
||||||
#: participation/models.py:1986
|
#: participation/models.py:2005
|
||||||
msgid "jury"
|
msgid "jury"
|
||||||
msgstr "jury"
|
msgstr "jury"
|
||||||
|
|
||||||
#: participation/models.py:1998
|
#: participation/models.py:2017
|
||||||
msgid "defender writing note"
|
msgid "defender writing note"
|
||||||
msgstr "note d'écrit défenseur⋅se"
|
msgstr "note d'écrit défenseur⋅se"
|
||||||
|
|
||||||
#: participation/models.py:2004
|
#: participation/models.py:2023
|
||||||
msgid "defender oral note"
|
msgid "defender oral note"
|
||||||
msgstr "note d'oral défenseur⋅se"
|
msgstr "note d'oral défenseur⋅se"
|
||||||
|
|
||||||
#: participation/models.py:2010
|
#: participation/models.py:2029
|
||||||
msgid "opponent writing note"
|
msgid "opponent writing note"
|
||||||
msgstr "note d'écrit opposant⋅e"
|
msgstr "note d'écrit opposant⋅e"
|
||||||
|
|
||||||
#: participation/models.py:2016
|
#: participation/models.py:2035
|
||||||
msgid "opponent oral note"
|
msgid "opponent oral note"
|
||||||
msgstr "note d'oral opposant⋅e"
|
msgstr "note d'oral opposant⋅e"
|
||||||
|
|
||||||
#: participation/models.py:2022
|
#: participation/models.py:2041
|
||||||
msgid "reviewer writing note"
|
msgid "reviewer writing note"
|
||||||
msgstr "note d'écrit rapporteur⋅rice"
|
msgstr "note d'écrit rapporteur⋅rice"
|
||||||
|
|
||||||
#: participation/models.py:2028
|
#: participation/models.py:2047
|
||||||
msgid "reviewer oral note"
|
msgid "reviewer oral note"
|
||||||
msgstr "note d'oral du rapporteur⋅rice"
|
msgstr "note d'oral du rapporteur⋅rice"
|
||||||
|
|
||||||
#: participation/models.py:2034
|
#: participation/models.py:2053
|
||||||
msgid "observer writing note"
|
msgid "observer writing note"
|
||||||
msgstr "note d'écrit de l'observateur⋅rice"
|
msgstr "note d'écrit de l'observateur⋅rice"
|
||||||
|
|
||||||
#: participation/models.py:2040
|
#: participation/models.py:2059
|
||||||
msgid "observer oral note"
|
msgid "observer oral note"
|
||||||
msgstr "note d'oral de l'observateur⋅rice"
|
msgstr "note d'oral de l'observateur⋅rice"
|
||||||
|
|
||||||
#: participation/models.py:2105
|
#: participation/models.py:2124
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Notes of {jury} for {passage}"
|
msgid "Notes of {jury} for {passage}"
|
||||||
msgstr "Notes de {jury} pour le {passage}"
|
msgstr "Notes de {jury} pour le {passage}"
|
||||||
|
|
||||||
#: participation/models.py:2108
|
#: participation/models.py:2127
|
||||||
msgid "note"
|
msgid "note"
|
||||||
msgstr "note"
|
msgstr "note"
|
||||||
|
|
||||||
#: participation/models.py:2109
|
#: participation/models.py:2128
|
||||||
msgid "notes"
|
msgid "notes"
|
||||||
msgstr "notes"
|
msgstr "notes"
|
||||||
|
|
||||||
|
@ -1910,7 +1910,7 @@ msgstr "Envoyer une solution"
|
||||||
#: participation/templates/participation/upload_motivation_letter.html:13
|
#: participation/templates/participation/upload_motivation_letter.html:13
|
||||||
#: participation/templates/participation/upload_notes.html:24
|
#: participation/templates/participation/upload_notes.html:24
|
||||||
#: participation/templates/participation/upload_solution.html:11
|
#: 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_health_sheet.html:17
|
||||||
#: registration/templates/registration/upload_parental_authorization.html:17
|
#: registration/templates/registration/upload_parental_authorization.html:17
|
||||||
#: registration/templates/registration/upload_photo_authorization.html:18
|
#: 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/passage_detail.html:53
|
||||||
#: participation/templates/participation/pool_detail.html:68
|
#: 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."
|
msgstr "Aucune note de synthèse n'a encore été envoyée."
|
||||||
|
|
||||||
#: participation/templates/participation/passage_detail.html:61
|
#: 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:66
|
||||||
#: participation/templates/participation/passage_detail.html:187
|
#: participation/templates/participation/passage_detail.html:187
|
||||||
msgid "Upload synthesis"
|
msgid "Upload review"
|
||||||
msgstr "Envoyer une note de synthèse"
|
msgstr "Envoyer la note de synthèse"
|
||||||
|
|
||||||
#: participation/templates/participation/passage_detail.html:74
|
#: participation/templates/participation/passage_detail.html:74
|
||||||
msgid "Notes detail"
|
msgid "Notes detail"
|
||||||
|
@ -2374,15 +2374,15 @@ msgid "date of the random draw"
|
||||||
msgstr "date du tirage au sort"
|
msgstr "date du tirage au sort"
|
||||||
|
|
||||||
#: participation/templates/participation/tournament_detail.html:41
|
#: 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"
|
msgstr "date limite de soumission des notes de synthèse pour le premier tour"
|
||||||
|
|
||||||
#: participation/templates/participation/tournament_detail.html:44
|
#: 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"
|
msgstr "date limite de soumission des notes de synthèse pour le second tour"
|
||||||
|
|
||||||
#: participation/templates/participation/tournament_detail.html:48
|
#: 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"
|
msgstr "date limite de soumission des notes de synthèse pour le troisième tour"
|
||||||
|
|
||||||
#: participation/templates/participation/tournament_detail.html:56
|
#: 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"
|
msgid "Files available for download"
|
||||||
msgstr "Fichiers disponibles au téléchargement"
|
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
|
#: participation/templates/participation/tournament_harmonize.html:16
|
||||||
#: registration/models.py:655
|
#: registration/models.py:655
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
|
@ -2504,11 +2540,11 @@ msgstr ""
|
||||||
msgid "Download empty notation sheet"
|
msgid "Download empty notation sheet"
|
||||||
msgstr "Télécharger la fiche de notation vierge"
|
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:"
|
msgid "Templates:"
|
||||||
msgstr "Modèles :"
|
msgstr "Modèles :"
|
||||||
|
|
||||||
#: participation/templates/participation/upload_synthesis.html:13
|
#: participation/templates/participation/upload_written_review.html:14
|
||||||
msgid "Warning: non-free format"
|
msgid "Warning: non-free format"
|
||||||
msgstr "Attention : format non libre"
|
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"
|
msgid "Solutions of team {trigram}.zip"
|
||||||
msgstr "Solutions de l'équipe {trigram}.zip"
|
msgstr "Solutions de l'équipe {trigram}.zip"
|
||||||
|
|
||||||
#: participation/views.py:1022
|
#: participation/views.py:1023
|
||||||
#, python-brace-format
|
#, 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"
|
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
|
#, python-brace-format
|
||||||
msgid "Solutions of {tournament}.zip"
|
msgid "Solutions of {tournament}.zip"
|
||||||
msgstr "Solutions de {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
|
#, python-brace-format
|
||||||
msgid "Syntheses of {tournament}.zip"
|
msgid "Written reviews of {tournament}.zip"
|
||||||
msgstr "Notes de synthèse de {tournament}.zip"
|
msgstr "Notes de synthèse de {tournament}.zip"
|
||||||
|
|
||||||
#: participation/views.py:1063
|
#: participation/views.py:1066
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Solutions for pool {pool} of tournament {tournament}.zip"
|
msgid "Solutions for pool {pool} of tournament {tournament}.zip"
|
||||||
msgstr "Solutions pour la poule {pool} du tournoi {tournament}.zip"
|
msgstr "Solutions pour la poule {pool} du tournoi {tournament}.zip"
|
||||||
|
|
||||||
#: participation/views.py:1064
|
#: participation/views.py:1067
|
||||||
#, python-brace-format
|
#, 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"
|
msgstr "Notes de synthèses pour la poule {pool} du tournoi {tournament}.zip"
|
||||||
|
|
||||||
#: participation/views.py:1106
|
#: participation/views.py:1109
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Jury of pool {pool} for {tournament} with teams {teams}"
|
msgid "Jury of pool {pool} for {tournament} with teams {teams}"
|
||||||
msgstr "Jury de la poule {pool} pour {tournament} avec les équipes {teams}"
|
msgstr "Jury de la poule {pool} pour {tournament} avec les équipes {teams}"
|
||||||
|
|
||||||
#: participation/views.py:1122
|
#: participation/views.py:1125
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "The jury {name} is already in the pool!"
|
msgid "The jury {name} is already in the pool!"
|
||||||
msgstr "{name} est déjà dans la poule !"
|
msgstr "{name} est déjà dans la poule !"
|
||||||
|
|
||||||
#: participation/views.py:1142
|
#: participation/views.py:1145
|
||||||
msgid "New jury account"
|
msgid "New jury account"
|
||||||
msgstr "Nouveau compte de juré⋅e"
|
msgstr "Nouveau compte de juré⋅e"
|
||||||
|
|
||||||
#: participation/views.py:1163
|
#: participation/views.py:1166
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "The jury {name} has been successfully added!"
|
msgid "The jury {name} has been successfully added!"
|
||||||
msgstr "{name} a été ajouté⋅e avec succès en tant que juré⋅e !"
|
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
|
#, python-brace-format
|
||||||
msgid "The jury {name} has been successfully removed!"
|
msgid "The jury {name} has been successfully removed!"
|
||||||
msgstr "{name} a été retiré⋅e avec succès du jury !"
|
msgstr "{name} a été retiré⋅e avec succès du jury !"
|
||||||
|
|
||||||
#: participation/views.py:1225
|
#: participation/views.py:1228
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "The jury {name} has been successfully promoted president!"
|
msgid "The jury {name} has been successfully promoted president!"
|
||||||
msgstr "{name} a été nommé⋅e président⋅e du jury !"
|
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:"
|
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 :"
|
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."
|
msgid "Notes were successfully uploaded."
|
||||||
msgstr "Les notes ont bien été envoyées."
|
msgstr "Les notes ont bien été envoyées."
|
||||||
|
|
||||||
#: participation/views.py:1504
|
#: participation/views.py:1507
|
||||||
msgid "Defender"
|
msgid "Defender"
|
||||||
msgstr "Défenseur⋅se"
|
msgstr "Défenseur⋅se"
|
||||||
|
|
||||||
#: participation/views.py:1510
|
#: participation/views.py:1513
|
||||||
msgid "Opponent"
|
msgid "Opponent"
|
||||||
msgstr "Opposant⋅e"
|
msgstr "Opposant⋅e"
|
||||||
|
|
||||||
#: participation/views.py:1517
|
#: participation/views.py:1520
|
||||||
msgid "Reviewer"
|
msgid "Reviewer"
|
||||||
msgstr "Rapporteur⋅rice"
|
msgstr "Rapporteur⋅rice"
|
||||||
|
|
||||||
#: participation/views.py:1524
|
#: participation/views.py:1527
|
||||||
msgid "Observer"
|
msgid "Observer"
|
||||||
msgstr "Observateur⋅rice"
|
msgstr "Observateur⋅rice"
|
||||||
|
|
||||||
#: participation/views.py:1895
|
#: participation/views.py:1898
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Notation sheets of pool {pool} of {tournament}.zip"
|
msgid "Notation sheets of pool {pool} of {tournament}.zip"
|
||||||
msgstr "Feuilles de notations pour la poule {pool} du tournoi {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
|
#, python-brace-format
|
||||||
msgid "Notation sheets of {tournament}.zip"
|
msgid "Notation sheets of {tournament}.zip"
|
||||||
msgstr "Feuilles de notation de {tournament}.zip"
|
msgstr "Feuilles de notation de {tournament}.zip"
|
||||||
|
|
||||||
#: participation/views.py:2067
|
#: participation/views.py:2070
|
||||||
msgid "You can't upload a synthesis after the deadline."
|
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."
|
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
|
#: registration/admin.py:53 registration/admin.py:69 registration/admin.py:85
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.utils.translation import gettext_lazy as _
|
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):
|
class ParticipationInline(admin.StackedInline):
|
||||||
|
@ -32,8 +32,8 @@ class SolutionInline(admin.TabularInline):
|
||||||
show_change_link = True
|
show_change_link = True
|
||||||
|
|
||||||
|
|
||||||
class SynthesisInline(admin.TabularInline):
|
class WrittenReviewInline(admin.TabularInline):
|
||||||
model = Synthesis
|
model = WrittenReview
|
||||||
extra = 0
|
extra = 0
|
||||||
ordering = ('passage__solution_number', 'type',)
|
ordering = ('passage__solution_number', 'type',)
|
||||||
autocomplete_fields = ('passage',)
|
autocomplete_fields = ('passage',)
|
||||||
|
@ -95,7 +95,7 @@ class ParticipationAdmin(admin.ModelAdmin):
|
||||||
search_fields = ('team__name', 'team__trigram',)
|
search_fields = ('team__name', 'team__trigram',)
|
||||||
list_filter = ('valid', 'tournament',)
|
list_filter = ('valid', 'tournament',)
|
||||||
autocomplete_fields = ('team', 'tournament',)
|
autocomplete_fields = ('team', 'tournament',)
|
||||||
inlines = (SolutionInline, SynthesisInline,)
|
inlines = (SolutionInline, WrittenReviewInline,)
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Pool)
|
@admin.register(Pool)
|
||||||
|
@ -178,19 +178,19 @@ class SolutionAdmin(admin.ModelAdmin):
|
||||||
return Tournament.final_tournament() if record.final_solution else record.participation.tournament
|
return Tournament.final_tournament() if record.final_solution else record.participation.tournament
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Synthesis)
|
@admin.register(WrittenReview)
|
||||||
class SynthesisAdmin(admin.ModelAdmin):
|
class WrittenReviewAdmin(admin.ModelAdmin):
|
||||||
list_display = ('participation', 'type', 'defender', 'passage',)
|
list_display = ('participation', 'type', 'defender', 'passage',)
|
||||||
list_filter = ('participation__tournament', 'type', 'passage__solution_number',)
|
list_filter = ('participation__tournament', 'type', 'passage__solution_number',)
|
||||||
search_fields = ('participation__team__name', 'participation__team__trigram',)
|
search_fields = ('participation__team__name', 'participation__team__trigram',)
|
||||||
autocomplete_fields = ('participation', 'passage',)
|
autocomplete_fields = ('participation', 'passage',)
|
||||||
|
|
||||||
@admin.display(description=_("defender"))
|
@admin.display(description=_("defender"))
|
||||||
def defender(self, record: Synthesis):
|
def defender(self, record: WrittenReview):
|
||||||
return record.passage.defender
|
return record.passage.defender
|
||||||
|
|
||||||
@admin.display(description=_("problem"))
|
@admin.display(description=_("problem"))
|
||||||
def problem(self, record: Synthesis):
|
def problem(self, record: WrittenReview):
|
||||||
return record.passage.solution_number
|
return record.passage.solution_number
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
from rest_framework import serializers
|
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):
|
class NoteSerializer(serializers.ModelSerializer):
|
||||||
|
@ -38,9 +38,9 @@ class SolutionSerializer(serializers.ModelSerializer):
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
class SynthesisSerializer(serializers.ModelSerializer):
|
class WrittenReviewSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Synthesis
|
model = WrittenReview
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,9 +58,9 @@ class TournamentSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Tournament
|
model = Tournament
|
||||||
fields = ('id', 'pk', 'name', 'date_start', 'date_end', 'place', 'max_teams', 'price', 'remote',
|
fields = ('id', 'pk', 'name', 'date_start', 'date_end', 'place', 'max_teams', 'price', 'remote',
|
||||||
'inscription_limit', 'solution_limit', 'solutions_draw', 'syntheses_first_phase_limit',
|
'inscription_limit', 'solution_limit', 'solutions_draw', 'reviews_first_phase_limit',
|
||||||
'solutions_available_second_phase', 'syntheses_second_phase_limit',
|
'solutions_available_second_phase', 'reviews_second_phase_limit',
|
||||||
'solutions_available_third_phase', 'syntheses_third_phase_limit',
|
'solutions_available_third_phase', 'reviews_third_phase_limit',
|
||||||
'description', 'organizers', 'final', 'participations',)
|
'description', 'organizers', 'final', 'participations',)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
from .views import NoteViewSet, ParticipationViewSet, PassageViewSet, PoolViewSet, \
|
from .views import NoteViewSet, ParticipationViewSet, PassageViewSet, PoolViewSet, \
|
||||||
SolutionViewSet, SynthesisViewSet, TeamViewSet, TournamentViewSet, TweakViewSet
|
SolutionViewSet, TeamViewSet, TournamentViewSet, TweakViewSet, WrittenReviewViewSet
|
||||||
|
|
||||||
|
|
||||||
def register_participation_urls(router, path):
|
def register_participation_urls(router, path):
|
||||||
|
@ -13,8 +13,8 @@ def register_participation_urls(router, path):
|
||||||
router.register(path + "/participation", ParticipationViewSet)
|
router.register(path + "/participation", ParticipationViewSet)
|
||||||
router.register(path + "/passage", PassageViewSet)
|
router.register(path + "/passage", PassageViewSet)
|
||||||
router.register(path + "/pool", PoolViewSet)
|
router.register(path + "/pool", PoolViewSet)
|
||||||
|
router.register(path + "/review", WrittenReviewViewSet)
|
||||||
router.register(path + "/solution", SolutionViewSet)
|
router.register(path + "/solution", SolutionViewSet)
|
||||||
router.register(path + "/synthesis", SynthesisViewSet)
|
|
||||||
router.register(path + "/team", TeamViewSet)
|
router.register(path + "/team", TeamViewSet)
|
||||||
router.register(path + "/tournament", TournamentViewSet)
|
router.register(path + "/tournament", TournamentViewSet)
|
||||||
router.register(path + "/tweak", TweakViewSet)
|
router.register(path + "/tweak", TweakViewSet)
|
||||||
|
|
|
@ -4,8 +4,8 @@ from django_filters.rest_framework import DjangoFilterBackend
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
from .serializers import NoteSerializer, ParticipationSerializer, PassageSerializer, PoolSerializer, \
|
from .serializers import NoteSerializer, ParticipationSerializer, PassageSerializer, PoolSerializer, \
|
||||||
SolutionSerializer, SynthesisSerializer, TeamSerializer, TournamentSerializer, TweakSerializer
|
SolutionSerializer, TeamSerializer, TournamentSerializer, TweakSerializer, WrittenReviewSerializer
|
||||||
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 NoteViewSet(ModelViewSet):
|
class NoteViewSet(ModelViewSet):
|
||||||
|
@ -44,9 +44,9 @@ class SolutionViewSet(ModelViewSet):
|
||||||
filterset_fields = ['participation', 'number', 'problem', 'final_solution', ]
|
filterset_fields = ['participation', 'number', 'problem', 'final_solution', ]
|
||||||
|
|
||||||
|
|
||||||
class SynthesisViewSet(ModelViewSet):
|
class WrittenReviewViewSet(ModelViewSet):
|
||||||
queryset = Synthesis.objects.all()
|
queryset = WrittenReview.objects.all()
|
||||||
serializer_class = SynthesisSerializer
|
serializer_class = WrittenReviewSerializer
|
||||||
filter_backends = [DjangoFilterBackend]
|
filter_backends = [DjangoFilterBackend]
|
||||||
filterset_fields = ['participation', 'number', 'passage', 'type', ]
|
filterset_fields = ['participation', 'number', 'passage', 'type', ]
|
||||||
|
|
||||||
|
@ -64,9 +64,9 @@ class TournamentViewSet(ModelViewSet):
|
||||||
serializer_class = TournamentSerializer
|
serializer_class = TournamentSerializer
|
||||||
filter_backends = [DjangoFilterBackend]
|
filter_backends = [DjangoFilterBackend]
|
||||||
filterset_fields = ['name', 'date_start', 'date_end', 'place', 'max_teams', 'price', 'remote',
|
filterset_fields = ['name', 'date_start', 'date_end', 'place', 'max_teams', 'price', 'remote',
|
||||||
'inscription_limit', 'solution_limit', 'solutions_draw', 'syntheses_first_phase_limit',
|
'inscription_limit', 'solution_limit', 'solutions_draw', 'reviews_first_phase_limit',
|
||||||
'solutions_available_second_phase', 'syntheses_second_phase_limit',
|
'solutions_available_second_phase', 'reviews_second_phase_limit',
|
||||||
'solutions_available_third_phase', 'syntheses_third_phase_limit',
|
'solutions_available_third_phase', 'reviews_third_phase_limit',
|
||||||
'description', 'organizers', 'final', ]
|
'description', 'organizers', 'final', ]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ from pypdf import PdfReader
|
||||||
from registration.models import VolunteerRegistration
|
from registration.models import VolunteerRegistration
|
||||||
from tfjm import settings
|
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):
|
class TeamForm(forms.ModelForm):
|
||||||
|
@ -137,7 +137,7 @@ class TournamentForm(forms.ModelForm):
|
||||||
if settings.NB_ROUNDS < 3:
|
if settings.NB_ROUNDS < 3:
|
||||||
del self.fields['date_third_phase']
|
del self.fields['date_third_phase']
|
||||||
del self.fields['solutions_available_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:
|
if not settings.PAYMENT_MANAGEMENT:
|
||||||
del self.fields['price']
|
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'),
|
'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'),
|
'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'),
|
'date_first_phase': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'),
|
||||||
'syntheses_first_phase_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'},
|
'reviews_first_phase_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'},
|
||||||
format='%Y-%m-%d %H:%M'),
|
format='%Y-%m-%d %H:%M'),
|
||||||
'date_second_phase': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'),
|
'date_second_phase': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'),
|
||||||
'syntheses_second_phase_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'},
|
'reviews_second_phase_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'},
|
||||||
format='%Y-%m-%d %H:%M'),
|
format='%Y-%m-%d %H:%M'),
|
||||||
'date_third_phase': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'),
|
'date_third_phase': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'),
|
||||||
'syntheses_third_phase_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'},
|
'reviews_third_phase_limit': forms.DateTimeInput(attrs={'type': 'datetime-local'},
|
||||||
format='%Y-%m-%d %H:%M'),
|
format='%Y-%m-%d %H:%M'),
|
||||||
'organizers': forms.SelectMultiple(attrs={
|
'organizers': forms.SelectMultiple(attrs={
|
||||||
'class': 'selectpicker',
|
'class': 'selectpicker',
|
||||||
'data-live-search': 'true',
|
'data-live-search': 'true',
|
||||||
|
@ -359,7 +359,7 @@ class PassageForm(forms.ModelForm):
|
||||||
fields = ('position', 'solution_number', 'defender', 'opponent', 'reviewer', 'opponent', 'defender_penalties',)
|
fields = ('position', 'solution_number', 'defender', 'opponent', 'reviewer', 'opponent', 'defender_penalties',)
|
||||||
|
|
||||||
|
|
||||||
class SynthesisForm(forms.ModelForm):
|
class WrittenReviewForm(forms.ModelForm):
|
||||||
def clean_file(self):
|
def clean_file(self):
|
||||||
if "file" in self.files:
|
if "file" in self.files:
|
||||||
file = self.files["file"]
|
file = self.files["file"]
|
||||||
|
@ -375,11 +375,11 @@ class SynthesisForm(forms.ModelForm):
|
||||||
|
|
||||||
def save(self, commit=True):
|
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:
|
class Meta:
|
||||||
model = Synthesis
|
model = WrittenReview
|
||||||
fields = ('file',)
|
fields = ('file',)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -323,8 +323,8 @@ class Tournament(models.Model):
|
||||||
default=date.today,
|
default=date.today,
|
||||||
)
|
)
|
||||||
|
|
||||||
syntheses_first_phase_limit = models.DateTimeField(
|
reviews_first_phase_limit = models.DateTimeField(
|
||||||
verbose_name=_("limit date to upload the syntheses for the first phase"),
|
verbose_name=_("limit date to upload the written reviews for the first phase"),
|
||||||
default=timezone.now,
|
default=timezone.now,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -338,8 +338,8 @@ class Tournament(models.Model):
|
||||||
default=False,
|
default=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
syntheses_second_phase_limit = models.DateTimeField(
|
reviews_second_phase_limit = models.DateTimeField(
|
||||||
verbose_name=_("limit date to upload the syntheses for the second phase"),
|
verbose_name=_("limit date to upload the written reviews for the second phase"),
|
||||||
default=timezone.now,
|
default=timezone.now,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -353,8 +353,8 @@ class Tournament(models.Model):
|
||||||
default=False,
|
default=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
syntheses_third_phase_limit = models.DateTimeField(
|
reviews_third_phase_limit = models.DateTimeField(
|
||||||
verbose_name=_("limit date to upload the syntheses for the third phase"),
|
verbose_name=_("limit date to upload the written reviews for the third phase"),
|
||||||
default=timezone.now,
|
default=timezone.now,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -442,10 +442,10 @@ class Tournament(models.Model):
|
||||||
return Solution.objects.filter(participation__tournament=self)
|
return Solution.objects.filter(participation__tournament=self)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def syntheses(self):
|
def written_reviews(self):
|
||||||
if self.final:
|
if self.final:
|
||||||
return Synthesis.objects.filter(final_solution=True)
|
return WrittenReview.objects.filter(final_solution=True)
|
||||||
return Synthesis.objects.filter(participation__tournament=self)
|
return WrittenReview.objects.filter(participation__tournament=self)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def best_format(self):
|
def best_format(self):
|
||||||
|
@ -911,7 +911,7 @@ class Participation(models.Model):
|
||||||
'priority': 1,
|
'priority': 1,
|
||||||
'content': content,
|
'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)
|
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)
|
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)
|
reviewer_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=1, reviewer=self)
|
||||||
|
@ -929,7 +929,7 @@ class Participation(models.Model):
|
||||||
|
|
||||||
opponent_text = _("<p>You will oppose the solution of the team {opponent} on the "
|
opponent_text = _("<p>You will oppose the solution of the team {opponent} on the "
|
||||||
"<a href='{solution_url}'>problem {problem}</a>. "
|
"<a href='{solution_url}'>problem {problem}</a>. "
|
||||||
"You can upload your synthesis sheet on <a href='{passage_url}'>this page</a>.</p>")
|
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
||||||
solution_url = opponent_passage.defended_solution.file.url
|
solution_url = opponent_passage.defended_solution.file.url
|
||||||
passage_url = reverse_lazy("participation:passage_detail", args=(opponent_passage.pk,))
|
passage_url = reverse_lazy("participation:passage_detail", args=(opponent_passage.pk,))
|
||||||
opponent_content = format_lazy(opponent_text, opponent=opponent_passage.defender.team.trigram,
|
opponent_content = format_lazy(opponent_text, opponent=opponent_passage.defender.team.trigram,
|
||||||
|
@ -938,7 +938,7 @@ class Participation(models.Model):
|
||||||
|
|
||||||
reviewer_text = _("<p>You will report the solution of the team {reviewer} on the "
|
reviewer_text = _("<p>You will report the solution of the team {reviewer} on the "
|
||||||
"<a href='{solution_url}'>problem {problem}</a>. "
|
"<a href='{solution_url}'>problem {problem}</a>. "
|
||||||
"You can upload your synthesis sheet on <a href='{passage_url}'>this page</a>.</p>")
|
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
||||||
solution_url = reviewer_passage.defended_solution.file.url
|
solution_url = reviewer_passage.defended_solution.file.url
|
||||||
passage_url = reverse_lazy("participation:passage_detail", args=(reviewer_passage.pk,))
|
passage_url = reverse_lazy("participation:passage_detail", args=(reviewer_passage.pk,))
|
||||||
reviewer_content = format_lazy(reviewer_text, reviewer=reviewer_passage.defender.team.trigram,
|
reviewer_content = format_lazy(reviewer_text, reviewer=reviewer_passage.defender.team.trigram,
|
||||||
|
@ -948,7 +948,7 @@ class Participation(models.Model):
|
||||||
if observer_passage:
|
if observer_passage:
|
||||||
observer_text = _("<p>You will observe the solution of the team {observer} on the "
|
observer_text = _("<p>You will observe the solution of the team {observer} on the "
|
||||||
"<a href='{solution_url}'>problem {problem}</a>. "
|
"<a href='{solution_url}'>problem {problem}</a>. "
|
||||||
"You can upload your synthesis sheet on <a href='{passage_url}'>this page</a>.</p>")
|
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
||||||
solution_url = observer_passage.defended_solution.file.url
|
solution_url = observer_passage.defended_solution.file.url
|
||||||
passage_url = reverse_lazy("participation:passage_detail", args=(observer_passage.pk,))
|
passage_url = reverse_lazy("participation:passage_detail", args=(observer_passage.pk,))
|
||||||
observer_content = format_lazy(observer_text,
|
observer_content = format_lazy(observer_text,
|
||||||
|
@ -959,24 +959,24 @@ class Participation(models.Model):
|
||||||
observer_content = ""
|
observer_content = ""
|
||||||
|
|
||||||
if settings.TFJM_APP == "TFJM":
|
if settings.TFJM_APP == "TFJM":
|
||||||
syntheses_template_begin = f"{settings.STATIC_URL}tfjm/Fiche_synthèse."
|
reviews_template_begin = f"{settings.STATIC_URL}tfjm/Fiche_synthèse."
|
||||||
syntheses_templates = " — ".join(f"<a href='{syntheses_template_begin}{ext}'>{ext.upper()}</a>"
|
reviews_templates = " — ".join(f"<a href='{reviews_template_begin}{ext}'>{ext.upper()}</a>"
|
||||||
for ext in ["pdf", "tex", "odt", "docx"])
|
for ext in ["pdf", "tex", "odt", "docx"])
|
||||||
else:
|
else:
|
||||||
syntheses_template_begin = f"{settings.STATIC_URL}eteam/Written_review."
|
reviews_template_begin = f"{settings.STATIC_URL}eteam/Written_review."
|
||||||
syntheses_templates = " — ".join(f"<a href='{syntheses_template_begin}{ext}'>{ext.upper()}</a>"
|
reviews_templates = " — ".join(f"<a href='{reviews_template_begin}{ext}'>{ext.upper()}</a>"
|
||||||
for ext in ["pdf", "tex"])
|
for ext in ["pdf", "tex"])
|
||||||
syntheses_templates_content = f"<p>{_('Templates:')} {syntheses_templates}</p>"
|
reviews_templates_content = f"<p>{_('Templates:')} {reviews_templates}</p>"
|
||||||
|
|
||||||
content = defender_content + opponent_content + reviewer_content + observer_content \
|
content = defender_content + opponent_content + reviewer_content + observer_content \
|
||||||
+ syntheses_templates_content
|
+ reviews_templates_content
|
||||||
informations.append({
|
informations.append({
|
||||||
'title': _("First round"),
|
'title': _("First round"),
|
||||||
'type': "info",
|
'type': "info",
|
||||||
'priority': 1,
|
'priority': 1,
|
||||||
'content': content,
|
'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)
|
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)
|
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)
|
reviewer_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=2, reviewer=self)
|
||||||
|
@ -992,7 +992,7 @@ class Participation(models.Model):
|
||||||
|
|
||||||
opponent_text = _("<p>You will oppose the solution of the team {opponent} on the "
|
opponent_text = _("<p>You will oppose the solution of the team {opponent} on the "
|
||||||
"<a href='{solution_url}'>problem {problem}</a>. "
|
"<a href='{solution_url}'>problem {problem}</a>. "
|
||||||
"You can upload your synthesis sheet on <a href='{passage_url}'>this page</a>.</p>")
|
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
||||||
solution_url = opponent_passage.defended_solution.file.url
|
solution_url = opponent_passage.defended_solution.file.url
|
||||||
passage_url = reverse_lazy("participation:passage_detail", args=(opponent_passage.pk,))
|
passage_url = reverse_lazy("participation:passage_detail", args=(opponent_passage.pk,))
|
||||||
opponent_content = format_lazy(opponent_text, opponent=opponent_passage.defender.team.trigram,
|
opponent_content = format_lazy(opponent_text, opponent=opponent_passage.defender.team.trigram,
|
||||||
|
@ -1001,7 +1001,7 @@ class Participation(models.Model):
|
||||||
|
|
||||||
reviewer_text = _("<p>You will report the solution of the team {reviewer} on the "
|
reviewer_text = _("<p>You will report the solution of the team {reviewer} on the "
|
||||||
"<a href='{solution_url}'>problem {problem}</a>. "
|
"<a href='{solution_url}'>problem {problem}</a>. "
|
||||||
"You can upload your synthesis sheet on <a href='{passage_url}'>this page</a>.</p>")
|
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
||||||
solution_url = reviewer_passage.defended_solution.file.url
|
solution_url = reviewer_passage.defended_solution.file.url
|
||||||
passage_url = reverse_lazy("participation:passage_detail", args=(reviewer_passage.pk,))
|
passage_url = reverse_lazy("participation:passage_detail", args=(reviewer_passage.pk,))
|
||||||
reviewer_content = format_lazy(reviewer_text, reviewer=reviewer_passage.defender.team.trigram,
|
reviewer_content = format_lazy(reviewer_text, reviewer=reviewer_passage.defender.team.trigram,
|
||||||
|
@ -1011,7 +1011,7 @@ class Participation(models.Model):
|
||||||
if observer_passage:
|
if observer_passage:
|
||||||
observer_text = _("<p>You will observe the solution of the team {observer} on the "
|
observer_text = _("<p>You will observe the solution of the team {observer} on the "
|
||||||
"<a href='{solution_url}'>problem {problem}</a>. "
|
"<a href='{solution_url}'>problem {problem}</a>. "
|
||||||
"You can upload your synthesis sheet on <a href='{passage_url}'>this page</a>.</p>")
|
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
||||||
solution_url = observer_passage.defended_solution.file.url
|
solution_url = observer_passage.defended_solution.file.url
|
||||||
passage_url = reverse_lazy("participation:passage_detail", args=(observer_passage.pk,))
|
passage_url = reverse_lazy("participation:passage_detail", args=(observer_passage.pk,))
|
||||||
observer_content = format_lazy(observer_text,
|
observer_content = format_lazy(observer_text,
|
||||||
|
@ -1022,17 +1022,17 @@ class Participation(models.Model):
|
||||||
observer_content = ""
|
observer_content = ""
|
||||||
|
|
||||||
if settings.TFJM_APP == "TFJM":
|
if settings.TFJM_APP == "TFJM":
|
||||||
syntheses_template_begin = f"{settings.STATIC_URL}tfjm/Fiche_synthèse."
|
reviews_template_begin = f"{settings.STATIC_URL}tfjm/Fiche_synthèse."
|
||||||
syntheses_templates = " — ".join(f"<a href='{syntheses_template_begin}{ext}'>{ext.upper()}</a>"
|
reviews_templates = " — ".join(f"<a href='{reviews_template_begin}{ext}'>{ext.upper()}</a>"
|
||||||
for ext in ["pdf", "tex", "odt", "docx"])
|
for ext in ["pdf", "tex", "odt", "docx"])
|
||||||
else:
|
else:
|
||||||
syntheses_template_begin = f"{settings.STATIC_URL}eteam/Written_review."
|
reviews_template_begin = f"{settings.STATIC_URL}eteam/Written_review."
|
||||||
syntheses_templates = " — ".join(f"<a href='{syntheses_template_begin}{ext}'>{ext.upper()}</a>"
|
reviews_templates = " — ".join(f"<a href='{reviews_template_begin}{ext}'>{ext.upper()}</a>"
|
||||||
for ext in ["pdf", "tex"])
|
for ext in ["pdf", "tex"])
|
||||||
syntheses_templates_content = f"<p>{_('Templates:')} {syntheses_templates}</p>"
|
reviews_templates_content = f"<p>{_('Templates:')} {reviews_templates}</p>"
|
||||||
|
|
||||||
content = defender_content + opponent_content + reviewer_content + observer_content \
|
content = defender_content + opponent_content + reviewer_content + observer_content \
|
||||||
+ syntheses_templates_content
|
+ reviews_templates_content
|
||||||
informations.append({
|
informations.append({
|
||||||
'title': _("Second round"),
|
'title': _("Second round"),
|
||||||
'type': "info",
|
'type': "info",
|
||||||
|
@ -1040,7 +1040,7 @@ class Participation(models.Model):
|
||||||
'content': content,
|
'content': content,
|
||||||
})
|
})
|
||||||
elif settings.TFJM_APP == "ETEAM" \
|
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)
|
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)
|
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)
|
reviewer_passage = Passage.objects.get(pool__tournament=self.tournament, pool__round=3, reviewer=self)
|
||||||
|
@ -1056,7 +1056,7 @@ class Participation(models.Model):
|
||||||
|
|
||||||
opponent_text = _("<p>You will oppose the solution of the team {opponent} on the "
|
opponent_text = _("<p>You will oppose the solution of the team {opponent} on the "
|
||||||
"<a href='{solution_url}'>problem {problem}</a>. "
|
"<a href='{solution_url}'>problem {problem}</a>. "
|
||||||
"You can upload your synthesis sheet on <a href='{passage_url}'>this page</a>.</p>")
|
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
||||||
solution_url = opponent_passage.defended_solution.file.url
|
solution_url = opponent_passage.defended_solution.file.url
|
||||||
passage_url = reverse_lazy("participation:passage_detail", args=(opponent_passage.pk,))
|
passage_url = reverse_lazy("participation:passage_detail", args=(opponent_passage.pk,))
|
||||||
opponent_content = format_lazy(opponent_text, opponent=opponent_passage.defender.team.trigram,
|
opponent_content = format_lazy(opponent_text, opponent=opponent_passage.defender.team.trigram,
|
||||||
|
@ -1065,7 +1065,7 @@ class Participation(models.Model):
|
||||||
|
|
||||||
reviewer_text = _("<p>You will report the solution of the team {reviewer} on the "
|
reviewer_text = _("<p>You will report the solution of the team {reviewer} on the "
|
||||||
"<a href='{solution_url}'>problem {problem}</a>. "
|
"<a href='{solution_url}'>problem {problem}</a>. "
|
||||||
"You can upload your synthesis sheet on <a href='{passage_url}'>this page</a>.</p>")
|
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
||||||
solution_url = reviewer_passage.defended_solution.file.url
|
solution_url = reviewer_passage.defended_solution.file.url
|
||||||
passage_url = reverse_lazy("participation:passage_detail", args=(reviewer_passage.pk,))
|
passage_url = reverse_lazy("participation:passage_detail", args=(reviewer_passage.pk,))
|
||||||
reviewer_content = format_lazy(reviewer_text, reviewer=reviewer_passage.defender.team.trigram,
|
reviewer_content = format_lazy(reviewer_text, reviewer=reviewer_passage.defender.team.trigram,
|
||||||
|
@ -1075,7 +1075,7 @@ class Participation(models.Model):
|
||||||
if observer_passage:
|
if observer_passage:
|
||||||
observer_text = _("<p>You will observe the solution of the team {observer} on the "
|
observer_text = _("<p>You will observe the solution of the team {observer} on the "
|
||||||
"<a href='{solution_url}'>problem {problem}</a>. "
|
"<a href='{solution_url}'>problem {problem}</a>. "
|
||||||
"You can upload your synthesis sheet on <a href='{passage_url}'>this page</a>.</p>")
|
"You can upload your written review on <a href='{passage_url}'>this page</a>.</p>")
|
||||||
solution_url = observer_passage.defended_solution.file.url
|
solution_url = observer_passage.defended_solution.file.url
|
||||||
passage_url = reverse_lazy("participation:passage_detail", args=(observer_passage.pk,))
|
passage_url = reverse_lazy("participation:passage_detail", args=(observer_passage.pk,))
|
||||||
observer_content = format_lazy(observer_text,
|
observer_content = format_lazy(observer_text,
|
||||||
|
@ -1086,17 +1086,17 @@ class Participation(models.Model):
|
||||||
observer_content = ""
|
observer_content = ""
|
||||||
|
|
||||||
if settings.TFJM_APP == "TFJM":
|
if settings.TFJM_APP == "TFJM":
|
||||||
syntheses_template_begin = f"{settings.STATIC_URL}tfjm/Fiche_synthèse."
|
reviews_template_begin = f"{settings.STATIC_URL}tfjm/Fiche_synthèse."
|
||||||
syntheses_templates = " — ".join(f"<a href='{syntheses_template_begin}{ext}'>{ext.upper()}</a>"
|
reviews_templates = " — ".join(f"<a href='{reviews_template_begin}{ext}'>{ext.upper()}</a>"
|
||||||
for ext in ["pdf", "tex", "odt", "docx"])
|
for ext in ["pdf", "tex", "odt", "docx"])
|
||||||
else:
|
else:
|
||||||
syntheses_template_begin = f"{settings.STATIC_URL}eteam/Written_review."
|
reviews_template_begin = f"{settings.STATIC_URL}eteam/Written_review."
|
||||||
syntheses_templates = " — ".join(f"<a href='{syntheses_template_begin}{ext}'>{ext.upper()}</a>"
|
reviews_templates = " — ".join(f"<a href='{reviews_template_begin}{ext}'>{ext.upper()}</a>"
|
||||||
for ext in ["pdf", "tex"])
|
for ext in ["pdf", "tex"])
|
||||||
syntheses_templates_content = f"<p>{_('Templates:')} {syntheses_templates}</p>"
|
reviews_templates_content = f"<p>{_('Templates:')} {reviews_templates}</p>"
|
||||||
|
|
||||||
content = defender_content + opponent_content + reviewer_content + observer_content \
|
content = defender_content + opponent_content + reviewer_content + observer_content \
|
||||||
+ syntheses_templates_content
|
+ reviews_templates_content
|
||||||
informations.append({
|
informations.append({
|
||||||
'title': _("Second round"),
|
'title': _("Second round"),
|
||||||
'type': "info",
|
'type': "info",
|
||||||
|
@ -1256,7 +1256,7 @@ class Pool(models.Model):
|
||||||
f"{_('Reviewer')} ({passage.reviewer.team.trigram})", ""]
|
f"{_('Reviewer')} ({passage.reviewer.team.trigram})", ""]
|
||||||
+ ([f"{_('Observer')} ({passage.observer.team.trigram})", ""] if has_observer else [])
|
+ ([f"{_('Observer')} ({passage.observer.team.trigram})", ""] if has_observer else [])
|
||||||
for passage in passages), start=[str(_("Role")), ""]),
|
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"{_('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)", f"{_('Writing')} (/10)", f"{_('Oral')} (/10)"]
|
||||||
+ ([f"{_('Writing')} (/10)", f"{_('Oral')} (/10)"] if has_observer else [])
|
+ ([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 "")
|
+ ("_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):
|
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):
|
class Solution(models.Model):
|
||||||
|
@ -1951,7 +1955,7 @@ class Solution(models.Model):
|
||||||
ordering = ('participation__team__trigram', 'final_solution', 'problem',)
|
ordering = ('participation__team__trigram', 'final_solution', 'problem',)
|
||||||
|
|
||||||
|
|
||||||
class Synthesis(models.Model):
|
class WrittenReview(models.Model):
|
||||||
participation = models.ForeignKey(
|
participation = models.ForeignKey(
|
||||||
Participation,
|
Participation,
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
|
@ -1961,7 +1965,7 @@ class Synthesis(models.Model):
|
||||||
passage = models.ForeignKey(
|
passage = models.ForeignKey(
|
||||||
Passage,
|
Passage,
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
related_name="syntheses",
|
related_name="written_reviews",
|
||||||
verbose_name=_("passage"),
|
verbose_name=_("passage"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1980,7 +1984,7 @@ class Synthesis(models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
def __str__(self):
|
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,
|
team=self.participation.team.trigram,
|
||||||
type=self.get_type_display(),
|
type=self.get_type_display(),
|
||||||
problem=self.passage.solution_number,
|
problem=self.passage.solution_number,
|
||||||
|
@ -1988,8 +1992,8 @@ class Synthesis(models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("synthesis")
|
verbose_name = _("written review")
|
||||||
verbose_name_plural = _("syntheses")
|
verbose_name_plural = _("written reviews")
|
||||||
unique_together = (('participation', 'passage', 'type', ), )
|
unique_together = (('participation', 'passage', 'type', ), )
|
||||||
ordering = ('passage__pool__round', 'type',)
|
ordering = ('passage__pool__round', 'type',)
|
||||||
|
|
||||||
|
|
|
@ -47,10 +47,10 @@
|
||||||
|
|
||||||
<dt class="col-sm-3">{% trans "Syntheses:" %}</dt>
|
<dt class="col-sm-3">{% trans "Syntheses:" %}</dt>
|
||||||
<dd class="col-sm-9">
|
<dd class="col-sm-9">
|
||||||
{% for synthesis in passage.syntheses.all %}
|
{% for review in passage.written_reviews.all %}
|
||||||
<a href="{{ synthesis.file.url }}">{{ synthesis }}{% if not forloop.last %}, {% endif %}</a>
|
<a href="{{ review.file.url }}">{{ review }}{% if not forloop.last %}, {% endif %}</a>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
{% trans "No synthesis was uploaded yet." %}
|
{% trans "No review was uploaded yet." %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
@ -63,7 +63,7 @@
|
||||||
</div>
|
</div>
|
||||||
{% elif user.registration.participates %}
|
{% elif user.registration.participates %}
|
||||||
<div class="card-footer text-center">
|
<div class="card-footer text-center">
|
||||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#uploadSynthesisModal">{% trans "Upload synthesis" %}</button>
|
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#uploadWrittenReviewModal">{% trans "Upload review" %}</button>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -184,10 +184,10 @@
|
||||||
{% include "base_modal.html" with modal_id=note.modal_name %}
|
{% include "base_modal.html" with modal_id=note.modal_name %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% elif user.registration.participates %}
|
{% elif user.registration.participates %}
|
||||||
{% trans "Upload synthesis" as modal_title %}
|
{% trans "Upload review" as modal_title %}
|
||||||
{% trans "Upload" as modal_button %}
|
{% trans "Upload" as modal_button %}
|
||||||
{% url "participation:upload_synthesis" pk=passage.pk as modal_action %}
|
{% url "participation:upload_review" pk=passage.pk as modal_action %}
|
||||||
{% include "base_modal.html" with modal_id="uploadSynthesis" modal_enctype="multipart/form-data" %}
|
{% include "base_modal.html" with modal_id="uploadWrittenReview" modal_enctype="multipart/form-data" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
@ -201,8 +201,8 @@
|
||||||
initModal("{{ note.modal_name }}", "{% url "participation:update_notes" pk=note.pk %}")
|
initModal("{{ note.modal_name }}", "{% url "participation:update_notes" pk=note.pk %}")
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% elif user.registration.participates %}
|
{% elif user.registration.participates %}
|
||||||
initModal("uploadSynthesis", "{% url "participation:upload_synthesis" pk=passage.pk %}")
|
initModal("uploadWrittenReview", "{% url "participation:upload_review" pk=passage.pk %}")
|
||||||
{% endif %}
|
{% endif %}
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -62,15 +62,15 @@
|
||||||
{% for passage in pool.passages.all %}
|
{% for passage in pool.passages.all %}
|
||||||
<li class="list-group-item">
|
<li class="list-group-item">
|
||||||
{{ passage.defender.team.trigram }} — {{ passage.get_solution_number_display }} :
|
{{ passage.defender.team.trigram }} — {{ passage.get_solution_number_display }} :
|
||||||
{% for synthesis in passage.syntheses.all %}
|
{% for review in passage.written_reviews.all %}
|
||||||
<a href="{{ synthesis.file.url }}">{{ synthesis.participation.team.trigram }} ({{ synthesis.get_type_display }})</a>{% if not forloop.last %}, {% endif %}
|
<a href="{{ review.file.url }}">{{ review.participation.team.trigram }} ({{ review.get_type_display }})</a>{% if not forloop.last %}, {% endif %}
|
||||||
{% empty %}
|
{% empty %}
|
||||||
{% trans "No synthesis was uploaded yet." %}
|
{% trans "No review was uploaded yet." %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
<a href="{% url 'participation:pool_download_syntheses' pool_id=pool.id %}" class="badge rounded-pill text-bg-secondary">
|
<a href="{% url 'participation:pool_download_written_review' pool_id=pool.id %}" class="badge rounded-pill text-bg-secondary">
|
||||||
<i class="fas fa-download"></i> {% trans "Download all" %}
|
<i class="fas fa-download"></i> {% trans "Download all" %}
|
||||||
</a>
|
</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -38,15 +38,15 @@
|
||||||
<dt class="col-sm-6 text-sm-end">{% trans 'date of the random draw'|capfirst %}</dt>
|
<dt class="col-sm-6 text-sm-end">{% trans 'date of the random draw'|capfirst %}</dt>
|
||||||
<dd class="col-sm-6">{{ tournament.solutions_draw }}</dd>
|
<dd class="col-sm-6">{{ tournament.solutions_draw }}</dd>
|
||||||
|
|
||||||
<dt class="col-sm-6 text-sm-end">{% trans 'date of maximal syntheses submission for the first round'|capfirst %}</dt>
|
<dt class="col-sm-6 text-sm-end">{% trans 'date of maximal written reviews submission for the first round'|capfirst %}</dt>
|
||||||
<dd class="col-sm-6">{{ tournament.syntheses_first_phase_limit }}</dd>
|
<dd class="col-sm-6">{{ tournament.reviews_first_phase_limit }}</dd>
|
||||||
|
|
||||||
<dt class="col-sm-6 text-sm-end">{% trans 'date of maximal syntheses submission for the second round'|capfirst %}</dt>
|
<dt class="col-sm-6 text-sm-end">{% trans 'date of maximal written reviews submission for the second round'|capfirst %}</dt>
|
||||||
<dd class="col-sm-6">{{ tournament.syntheses_second_phase_limit }}</dd>
|
<dd class="col-sm-6">{{ tournament.reviews_second_phase_limit }}</dd>
|
||||||
|
|
||||||
{% if TFJM.APP == "ETEAM" %}
|
{% if TFJM.APP == "ETEAM" %}
|
||||||
<dt class="col-sm-6 text-sm-end">{% trans 'date of maximal syntheses submission for the third round'|capfirst %}</dt>
|
<dt class="col-sm-6 text-sm-end">{% trans 'date of maximal written reviews submission for the third round'|capfirst %}</dt>
|
||||||
<dd class="col-sm-6">{{ tournament.syntheses_third_phase_limit }}</dd>
|
<dd class="col-sm-6">{{ tournament.reviews_third_phase_limit }}</dd>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<dt class="col-sm-6 text-sm-end">{% trans 'description'|capfirst %}</dt>
|
<dt class="col-sm-6 text-sm-end">{% trans 'description'|capfirst %}</dt>
|
||||||
|
@ -233,48 +233,48 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url "participation:tournament_csv" pk=tournament.pk %}">
|
<a href="{% url "participation:tournament_csv" pk=tournament.pk %}">
|
||||||
Validated team participant data spreadsheet
|
{% trans "Validated team participant data spreadsheet" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url "participation:tournament_csv" pk=tournament.pk %}?all">
|
<a href="{% url "participation:tournament_csv" pk=tournament.pk %}?all">
|
||||||
All teams participant data spreadsheet
|
{% trans "All teams participant data spreadsheet" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url "participation:tournament_authorizations" tournament_id=tournament.id %}">
|
<a href="{% url "participation:tournament_authorizations" tournament_id=tournament.id %}">
|
||||||
Archive of all authorisations sorted by team and person
|
{% trans "Archive of all authorisations sorted by team and person" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url "participation:tournament_solutions" tournament_id=tournament.id %}">
|
<a href="{% url "participation:tournament_solutions" tournament_id=tournament.id %}">
|
||||||
Archive of all submitted solutions sorted by team
|
{% trans "Archive of all submitted solutions sorted by team" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url "participation:tournament_solutions" tournament_id=tournament.id %}?sort_by=problem">
|
<a href="{% url "participation:tournament_solutions" tournament_id=tournament.id %}?sort_by=problem">
|
||||||
Archive of all sent solutions sorted by problem
|
{% trans "Archive of all sent solutions sorted by problem" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url "participation:tournament_solutions" tournament_id=tournament.id %}?sort_by=pool">
|
<a href="{% url "participation:tournament_solutions" tournament_id=tournament.id %}?sort_by=pool">
|
||||||
Archive of all sent solutions sorted by pool
|
{% trans "Archive of all sent solutions sorted by pool" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url "participation:tournament_syntheses" tournament_id=tournament.id %}?sort_by=pool">
|
<a href="{% url "participation:tournament_written_reviews" tournament_id=tournament.id %}?sort_by=pool">
|
||||||
Archive of all summary notes sorted by pool and passage
|
{% trans "Archive of all summary notes sorted by pool and passage" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="https://docs.google.com/spreadsheets/d/{{ tournament.notes_sheet_id }}/edit">
|
<a href="https://docs.google.com/spreadsheets/d/{{ tournament.notes_sheet_id }}/edit">
|
||||||
<i class="fas fa-table"></i>
|
<i class="fas fa-table"></i>
|
||||||
Note spreadsheet on Google Sheets
|
{% trans "Note spreadsheet on Google Sheets" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url "participation:tournament_notation_sheets" tournament_id=tournament.id %}">
|
<a href="{% url "participation:tournament_notation_sheets" tournament_id=tournament.id %}">
|
||||||
Archive of all printable note sheets sorted by pool
|
{% trans "Archive of all printable note sheets sorted by pool" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -8,11 +8,11 @@ from .views import CreateTeamView, FinalNotationSheetTemplateView, GSheetNotific
|
||||||
PassageDetailView, PassageUpdateView, PoolCreateView, PoolDetailView, PoolJuryView, PoolNotesTemplateView, \
|
PassageDetailView, PassageUpdateView, PoolCreateView, PoolDetailView, PoolJuryView, PoolNotesTemplateView, \
|
||||||
PoolPresideJuryView, PoolRemoveJuryView, PoolUpdateView, PoolUploadNotesView, \
|
PoolPresideJuryView, PoolRemoveJuryView, PoolUpdateView, PoolUploadNotesView, \
|
||||||
ScaleNotationSheetTemplateView, SelectTeamFinalView, \
|
ScaleNotationSheetTemplateView, SelectTeamFinalView, \
|
||||||
SolutionsDownloadView, SolutionUploadView, SynthesisUploadView, \
|
SolutionsDownloadView, SolutionUploadView, \
|
||||||
TeamAuthorizationsView, TeamDetailView, TeamLeaveView, TeamListView, TeamUpdateView, \
|
TeamAuthorizationsView, TeamDetailView, TeamLeaveView, TeamListView, TeamUpdateView, \
|
||||||
TeamUploadMotivationLetterView, TournamentCreateView, TournamentDetailView, TournamentExportCSVView, \
|
TeamUploadMotivationLetterView, TournamentCreateView, TournamentDetailView, TournamentExportCSVView, \
|
||||||
TournamentHarmonizeNoteView, TournamentHarmonizeView, TournamentListView, TournamentPaymentsView, \
|
TournamentHarmonizeNoteView, TournamentHarmonizeView, TournamentListView, TournamentPaymentsView, \
|
||||||
TournamentPublishNotesView, TournamentUpdateView
|
TournamentPublishNotesView, TournamentUpdateView, WrittenReviewUploadView
|
||||||
|
|
||||||
|
|
||||||
app_name = "participation"
|
app_name = "participation"
|
||||||
|
@ -42,8 +42,8 @@ urlpatterns = [
|
||||||
name="tournament_authorizations"),
|
name="tournament_authorizations"),
|
||||||
path("tournament/<int:tournament_id>/solutions/", SolutionsDownloadView.as_view(),
|
path("tournament/<int:tournament_id>/solutions/", SolutionsDownloadView.as_view(),
|
||||||
name="tournament_solutions"),
|
name="tournament_solutions"),
|
||||||
path("tournament/<int:tournament_id>/syntheses/", SolutionsDownloadView.as_view(),
|
path("tournament/<int:tournament_id>/written_reviews/", SolutionsDownloadView.as_view(),
|
||||||
name="tournament_syntheses"),
|
name="tournament_written_reviews"),
|
||||||
path("tournament/<int:tournament_id>/notation/sheets/", NotationSheetsArchiveView.as_view(),
|
path("tournament/<int:tournament_id>/notation/sheets/", NotationSheetsArchiveView.as_view(),
|
||||||
name="tournament_notation_sheets"),
|
name="tournament_notation_sheets"),
|
||||||
path("tournament/<int:pk>/notation/notifications/", GSheetNotificationsView.as_view(),
|
path("tournament/<int:pk>/notation/notifications/", GSheetNotificationsView.as_view(),
|
||||||
|
@ -60,7 +60,7 @@ urlpatterns = [
|
||||||
path("pools/<int:pk>/", PoolDetailView.as_view(), name="pool_detail"),
|
path("pools/<int:pk>/", PoolDetailView.as_view(), name="pool_detail"),
|
||||||
path("pools/<int:pk>/update/", PoolUpdateView.as_view(), name="pool_update"),
|
path("pools/<int:pk>/update/", PoolUpdateView.as_view(), name="pool_update"),
|
||||||
path("pools/<int:pool_id>/solutions/", SolutionsDownloadView.as_view(), name="pool_download_solutions"),
|
path("pools/<int:pool_id>/solutions/", SolutionsDownloadView.as_view(), name="pool_download_solutions"),
|
||||||
path("pools/<int:pool_id>/syntheses/", SolutionsDownloadView.as_view(), name="pool_download_syntheses"),
|
path("pools/<int:pool_id>/written_reviews/", SolutionsDownloadView.as_view(), name="pool_download_written_reviews"),
|
||||||
path("pools/<int:pk>/notation/scale/", ScaleNotationSheetTemplateView.as_view(), name="pool_scale_note_sheet"),
|
path("pools/<int:pk>/notation/scale/", ScaleNotationSheetTemplateView.as_view(), name="pool_scale_note_sheet"),
|
||||||
path("pools/<int:pk>/notation/final/", FinalNotationSheetTemplateView.as_view(), name="pool_final_note_sheet"),
|
path("pools/<int:pk>/notation/final/", FinalNotationSheetTemplateView.as_view(), name="pool_final_note_sheet"),
|
||||||
path("pools/<int:pool_id>/notation/sheets/", NotationSheetsArchiveView.as_view(), name="pool_notation_sheets"),
|
path("pools/<int:pool_id>/notation/sheets/", NotationSheetsArchiveView.as_view(), name="pool_notation_sheets"),
|
||||||
|
@ -71,6 +71,6 @@ urlpatterns = [
|
||||||
path("pools/<int:pk>/upload-notes/template/", PoolNotesTemplateView.as_view(), name="pool_notes_template"),
|
path("pools/<int:pk>/upload-notes/template/", PoolNotesTemplateView.as_view(), name="pool_notes_template"),
|
||||||
path("pools/passages/<int:pk>/", PassageDetailView.as_view(), name="passage_detail"),
|
path("pools/passages/<int:pk>/", PassageDetailView.as_view(), name="passage_detail"),
|
||||||
path("pools/passages/<int:pk>/update/", PassageUpdateView.as_view(), name="passage_update"),
|
path("pools/passages/<int:pk>/update/", PassageUpdateView.as_view(), name="passage_update"),
|
||||||
path("pools/passages/<int:pk>/solution/", SynthesisUploadView.as_view(), name="upload_synthesis"),
|
path("pools/passages/<int:pk>/written_review/", WrittenReviewUploadView.as_view(), name="upload_written_review"),
|
||||||
path("pools/passages/notes/<int:pk>/", NoteUpdateView.as_view(), name="update_notes"),
|
path("pools/passages/notes/<int:pk>/", NoteUpdateView.as_view(), name="update_notes"),
|
||||||
]
|
]
|
||||||
|
|
|
@ -46,9 +46,9 @@ from tfjm.lists import get_sympa_client
|
||||||
from tfjm.views import AdminMixin, VolunteerMixin
|
from tfjm.views import AdminMixin, VolunteerMixin
|
||||||
|
|
||||||
from .forms import AddJuryForm, JoinTeamForm, MotivationLetterForm, NoteForm, ParticipationForm, PassageForm, \
|
from .forms import AddJuryForm, JoinTeamForm, MotivationLetterForm, NoteForm, ParticipationForm, PassageForm, \
|
||||||
PoolForm, RequestValidationForm, SolutionForm, SynthesisForm, TeamForm, TournamentForm, \
|
PoolForm, RequestValidationForm, SolutionForm, TeamForm, TournamentForm, UploadNotesForm, \
|
||||||
UploadNotesForm, ValidateParticipationForm
|
ValidateParticipationForm, WrittenReviewForm
|
||||||
from .models import Note, Participation, Passage, Pool, Solution, Synthesis, Team, Tournament, Tweak
|
from .models import Note, Participation, Passage, Pool, Solution, Team, Tournament, Tweak, WrittenReview
|
||||||
from .tables import NoteTable, ParticipationTable, PassageTable, PoolTable, TeamTable, TournamentTable
|
from .tables import NoteTable, ParticipationTable, PassageTable, PoolTable, TeamTable, TournamentTable
|
||||||
|
|
||||||
|
|
||||||
|
@ -977,7 +977,7 @@ class PoolUpdateView(VolunteerMixin, UpdateView):
|
||||||
|
|
||||||
class SolutionsDownloadView(VolunteerMixin, View):
|
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):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
|
@ -1018,11 +1018,12 @@ class SolutionsDownloadView(VolunteerMixin, View):
|
||||||
if 'team_id' in kwargs:
|
if 'team_id' in kwargs:
|
||||||
team = Team.objects.get(pk=kwargs["team_id"])
|
team = Team.objects.get(pk=kwargs["team_id"])
|
||||||
solutions = Solution.objects.filter(participation=team.participation).all()
|
solutions = Solution.objects.filter(participation=team.participation).all()
|
||||||
syntheses = Synthesis.objects.filter(participation=team.participation).all()
|
written_reviews = WrittenReview.objects.filter(participation=team.participation).all()
|
||||||
filename = _("Solutions of team {trigram}.zip") if is_solution else _("Syntheses of team {trigram}.zip")
|
filename = _("Solutions of team {trigram}.zip") if is_solution \
|
||||||
|
else _("Written reviews of team {trigram}.zip")
|
||||||
filename = filename.format(trigram=team.trigram)
|
filename = filename.format(trigram=team.trigram)
|
||||||
|
|
||||||
def prefix(s: Solution | Synthesis) -> str:
|
def prefix(s: Solution | WrittenReview) -> str:
|
||||||
return ""
|
return ""
|
||||||
elif 'tournament_id' in kwargs:
|
elif 'tournament_id' in kwargs:
|
||||||
tournament = Tournament.objects.get(pk=kwargs["tournament_id"])
|
tournament = Tournament.objects.get(pk=kwargs["tournament_id"])
|
||||||
|
@ -1035,11 +1036,12 @@ class SolutionsDownloadView(VolunteerMixin, View):
|
||||||
for sol in pool.solutions:
|
for sol in pool.solutions:
|
||||||
sol.pool = pool
|
sol.pool = pool
|
||||||
solutions.append(sol)
|
solutions.append(sol)
|
||||||
syntheses = Synthesis.objects.filter(passage__pool__tournament=tournament).all()
|
written_reviews = WrittenReview.objects.filter(passage__pool__tournament=tournament).all()
|
||||||
filename = _("Solutions of {tournament}.zip") if is_solution else _("Syntheses of {tournament}.zip")
|
filename = _("Solutions of {tournament}.zip") if is_solution \
|
||||||
|
else _("Written reviews of {tournament}.zip")
|
||||||
filename = filename.format(tournament=tournament.name)
|
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
|
pool = s.pool if is_solution else s.passage.pool
|
||||||
p = f"Poule {pool.short_name}/"
|
p = f"Poule {pool.short_name}/"
|
||||||
if not is_solution:
|
if not is_solution:
|
||||||
|
@ -1050,27 +1052,28 @@ class SolutionsDownloadView(VolunteerMixin, View):
|
||||||
solutions = Solution.objects.filter(participation__tournament=tournament).all()
|
solutions = Solution.objects.filter(participation__tournament=tournament).all()
|
||||||
else:
|
else:
|
||||||
solutions = Solution.objects.filter(final_solution=True).all()
|
solutions = Solution.objects.filter(final_solution=True).all()
|
||||||
syntheses = Synthesis.objects.filter(passage__pool__tournament=tournament).all()
|
written_reviews = WrittenReview.objects.filter(passage__pool__tournament=tournament).all()
|
||||||
filename = _("Solutions of {tournament}.zip") if is_solution else _("Syntheses of {tournament}.zip")
|
filename = _("Solutions of {tournament}.zip") if is_solution \
|
||||||
|
else _("Written reviews of {tournament}.zip")
|
||||||
filename = filename.format(tournament=tournament.name)
|
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}/"
|
return f"{s.participation.team.trigram}/" if sort_by == "team" else f"Problème {s.problem}/"
|
||||||
else:
|
else:
|
||||||
pool = Pool.objects.get(pk=kwargs["pool_id"])
|
pool = Pool.objects.get(pk=kwargs["pool_id"])
|
||||||
solutions = pool.solutions
|
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") \
|
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,
|
filename = filename.format(pool=pool.short_name,
|
||||||
tournament=pool.tournament.name)
|
tournament=pool.tournament.name)
|
||||||
|
|
||||||
def prefix(s: Solution | Synthesis) -> str:
|
def prefix(s: Solution | WrittenReview) -> str:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
output = BytesIO()
|
output = BytesIO()
|
||||||
zf = ZipFile(output, "w")
|
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):
|
if s.file.storage.exists(s.file.path):
|
||||||
zf.write("media/" + s.file.name, prefix(s) + f"{s}.pdf")
|
zf.write("media/" + s.file.name, prefix(s) + f"{s}.pdf")
|
||||||
|
|
||||||
|
@ -2028,9 +2031,9 @@ class PassageUpdateView(VolunteerMixin, UpdateView):
|
||||||
return self.handle_no_permission()
|
return self.handle_no_permission()
|
||||||
|
|
||||||
|
|
||||||
class SynthesisUploadView(LoginRequiredMixin, FormView):
|
class WrittenReviewUploadView(LoginRequiredMixin, FormView):
|
||||||
template_name = "participation/upload_synthesis.html"
|
template_name = "participation/upload_written_review.html"
|
||||||
form_class = SynthesisForm
|
form_class = WrittenReviewForm
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
if not request.user.is_authenticated or not request.user.registration.participates:
|
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 = form.instance
|
||||||
form_syn.type = 1 if self.participation == self.passage.opponent \
|
form_syn.type = 1 if self.participation == self.passage.opponent \
|
||||||
else 2 if self.participation == self.passage.reviewer else 3
|
else 2 if self.participation == self.passage.reviewer else 3
|
||||||
syn_qs = Synthesis.objects.filter(participation=self.participation,
|
syn_qs = WrittenReview.objects.filter(participation=self.participation,
|
||||||
passage=self.passage,
|
passage=self.passage,
|
||||||
type=form_syn.type).all()
|
type=form_syn.type).all()
|
||||||
|
|
||||||
deadline = self.passage.pool.tournament.syntheses_first_phase_limit if self.passage.pool.round == 1 \
|
deadline = self.passage.pool.tournament.reviews_first_phase_limit if self.passage.pool.round == 1 \
|
||||||
else self.passage.pool.tournament.syntheses_second_phase_limit
|
else self.passage.pool.tournament.reviews_second_phase_limit
|
||||||
if syn_qs.exists() and timezone.now() > deadline:
|
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)
|
return self.form_invalid(form)
|
||||||
|
|
||||||
# Drop previous solution if existing
|
# Drop previous solution if existing
|
||||||
|
|
|
@ -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.views.generic import CreateView, DetailView, RedirectView, TemplateView, UpdateView, View
|
||||||
from django_tables2 import SingleTableView
|
from django_tables2 import SingleTableView
|
||||||
from magic import Magic
|
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.tokens import email_validation_token
|
||||||
from tfjm.views import UserMixin, UserRegistrationMixin, VolunteerMixin
|
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)
|
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):
|
def get(self, request, *args, **kwargs):
|
||||||
filename = kwargs["filename"]
|
filename = kwargs["filename"]
|
||||||
path = f"media/syntheses/{filename}"
|
path = f"media/reviews/{filename}"
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
raise Http404
|
raise Http404
|
||||||
synthesis = Synthesis.objects.get(file__endswith=filename)
|
reviews = WrittenReview.objects.get(file__endswith=filename)
|
||||||
user = request.user
|
user = request.user
|
||||||
if not (user.registration.is_admin or user.registration.is_volunteer
|
if not (user.registration.is_admin or user.registration.is_volunteer
|
||||||
and (user.registration in synthesis.passage.pool.juries.all()
|
and (user.registration in reviews.passage.pool.juries.all()
|
||||||
or user.registration in synthesis.passage.pool.tournament.organizers.all()
|
or user.registration in reviews.passage.pool.tournament.organizers.all()
|
||||||
or user.registration.pools_presided.filter(tournament=synthesis.passage.pool.tournament).exists())
|
or user.registration.pools_presided.filter(tournament=reviews.passage.pool.tournament).exists())
|
||||||
or user.registration.participates and user.registration.team == synthesis.participation.team):
|
or user.registration.participates and user.registration.team == reviews.participation.team):
|
||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
# Guess mime type of the file
|
# Guess mime type of the file
|
||||||
mime = Magic(mime=True)
|
mime = Magic(mime=True)
|
||||||
mime_type = mime.from_file(path)
|
mime_type = mime.from_file(path)
|
||||||
ext = mime_type.split("/")[1].replace("jpeg", "jpg")
|
ext = mime_type.split("/")[1].replace("jpeg", "jpg")
|
||||||
# Replace file name
|
# 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)
|
return FileResponse(open(path, "rb"), content_type=mime_type, filename=true_file_name)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ from django.views.defaults import bad_request, page_not_found, permission_denied
|
||||||
from django.views.generic import TemplateView
|
from django.views.generic import TemplateView
|
||||||
from participation.views import MotivationLetterView
|
from participation.views import MotivationLetterView
|
||||||
from registration.views import HealthSheetView, ParentalAuthorizationView, PhotoAuthorizationView, \
|
from registration.views import HealthSheetView, ParentalAuthorizationView, PhotoAuthorizationView, \
|
||||||
ReceiptView, SolutionView, SynthesisView, VaccineSheetView
|
ReceiptView, SolutionView, VaccineSheetView, WrittenReviewView
|
||||||
|
|
||||||
from .views import AdminSearchView
|
from .views import AdminSearchView
|
||||||
|
|
||||||
|
@ -61,8 +61,8 @@ urlpatterns = [
|
||||||
|
|
||||||
path('media/solutions/<str:filename>/', SolutionView.as_view(),
|
path('media/solutions/<str:filename>/', SolutionView.as_view(),
|
||||||
name='solution'),
|
name='solution'),
|
||||||
path('media/syntheses/<str:filename>/', SynthesisView.as_view(),
|
path('media/reviews/<str:filename>/', WrittenReviewView.as_view(),
|
||||||
name='synthesis'),
|
name='reviews'),
|
||||||
]
|
]
|
||||||
|
|
||||||
if settings.DEBUG:
|
if settings.DEBUG:
|
||||||
|
|
Loading…
Reference in New Issue