Add button to download all solutions and syntheses in a ZIP file

Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
Emmy D'Anello 2023-05-19 14:44:31 +02:00
parent 9bc0e99d6d
commit 29074c4bfd
Signed by: ynerant
GPG Key ID: 3A75C55819C8CF85
5 changed files with 193 additions and 116 deletions

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: TFJM\n" "Project-Id-Version: TFJM\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-04-11 22:22+0200\n" "POT-Creation-Date: 2023-05-19 14:40+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"
@ -22,19 +22,19 @@ msgid "API"
msgstr "API" msgstr "API"
#: draw/admin.py:16 draw/admin.py:28 draw/admin.py:44 participation/admin.py:44 #: draw/admin.py:16 draw/admin.py:28 draw/admin.py:44 participation/admin.py:44
#: participation/models.py:126 participation/tables.py:86 #: participation/models.py:126 participation/tables.py:87
msgid "teams" msgid "teams"
msgstr "équipes" msgstr "équipes"
#: draw/admin.py:40 draw/admin.py:56 draw/models.py:24 #: draw/admin.py:40 draw/admin.py:56 draw/models.py:24
#: participation/admin.py:16 participation/admin.py:73 #: participation/admin.py:16 participation/admin.py:73
#: participation/admin.py:104 participation/models.py:295 #: participation/admin.py:104 participation/models.py:295
#: participation/models.py:319 participation/models.py:351 #: participation/models.py:319 participation/models.py:352
msgid "tournament" msgid "tournament"
msgstr "tournoi" msgstr "tournoi"
#: draw/admin.py:60 draw/models.py:231 draw/models.py:426 #: draw/admin.py:60 draw/models.py:231 draw/models.py:426
#: participation/models.py:355 #: participation/models.py:356
msgid "round" msgid "round"
msgstr "tour" msgstr "tour"
@ -46,64 +46,64 @@ msgstr "Tirage au sort"
msgid "You are not an organizer." msgid "You are not an organizer."
msgstr "Vous n'êtes pas un⋅e organisateur⋅rice." msgstr "Vous n'êtes pas un⋅e organisateur⋅rice."
#: draw/consumers.py:144 #: draw/consumers.py:151
msgid "The draw is already started." msgid "The draw is already started."
msgstr "Le tirage a déjà commencé." msgstr "Le tirage a déjà commencé."
#: draw/consumers.py:150 #: draw/consumers.py:157
msgid "Invalid format" msgid "Invalid format"
msgstr "Format invalide" msgstr "Format invalide"
#: draw/consumers.py:155 #: draw/consumers.py:162
#, python-brace-format #, python-brace-format
msgid "The sum must be equal to the number of teams: expected {len}, got {sum}" msgid "The sum must be equal to the number of teams: expected {len}, got {sum}"
msgstr "" msgstr ""
"La somme doit être égale au nombre d'équipes : attendu {len}, obtenu {sum}" "La somme doit être égale au nombre d'équipes : attendu {len}, obtenu {sum}"
#: draw/consumers.py:160 #: draw/consumers.py:167
msgid "There can be at most one pool with 5 teams." msgid "There can be at most one pool with 5 teams."
msgstr "Il ne peut y avoir au plus qu'une seule poule de 5 équipes." msgstr "Il ne peut y avoir au plus qu'une seule poule de 5 équipes."
#: draw/consumers.py:188 #: draw/consumers.py:207
msgid "Draw started!" msgid "Draw started!"
msgstr "Le tirage a commencé !" msgstr "Le tirage a commencé !"
#: draw/consumers.py:208 #: draw/consumers.py:229
#, python-brace-format #, python-brace-format
msgid "The draw for the tournament {tournament} will start." msgid "The draw for the tournament {tournament} will start."
msgstr "Le tirage au sort du tournoi {tournament} va commencer." msgstr "Le tirage au sort du tournoi {tournament} va commencer."
#: draw/consumers.py:219 draw/consumers.py:244 draw/consumers.py:578 #: draw/consumers.py:240 draw/consumers.py:266 draw/consumers.py:639
#: draw/consumers.py:767 draw/consumers.py:849 draw/consumers.py:866 #: draw/consumers.py:856 draw/consumers.py:945 draw/consumers.py:963
#: draw/consumers.py:936 draw/templates/draw/tournament_content.html:5 #: draw/consumers.py:1053 draw/templates/draw/tournament_content.html:5
msgid "The draw has not started yet." msgid "The draw has not started yet."
msgstr "Le tirage au sort n'a pas encore commencé." msgstr "Le tirage au sort n'a pas encore commencé."
#: draw/consumers.py:231 #: draw/consumers.py:253
#, python-brace-format #, python-brace-format
msgid "The draw for the tournament {tournament} is aborted." msgid "The draw for the tournament {tournament} is aborted."
msgstr "Le tirage au sort du tournoi {tournament} est annulé." msgstr "Le tirage au sort du tournoi {tournament} est annulé."
#: draw/consumers.py:271 draw/consumers.py:292 draw/consumers.py:524 #: draw/consumers.py:293 draw/consumers.py:314 draw/consumers.py:579
#: draw/consumers.py:583 draw/consumers.py:772 #: draw/consumers.py:644 draw/consumers.py:861
msgid "This is not the time for this." msgid "This is not the time for this."
msgstr "Ce n'est pas le moment pour cela." msgstr "Ce n'est pas le moment pour cela."
#: draw/consumers.py:284 draw/consumers.py:287 #: draw/consumers.py:306 draw/consumers.py:309
msgid "You've already launched the dice." msgid "You've already launched the dice."
msgstr "Vous avez déjà lancé le dé." msgstr "Vous avez déjà lancé le dé."
#: draw/consumers.py:290 #: draw/consumers.py:312
msgid "It is not your turn." msgid "It is not your turn."
msgstr "Ce n'est pas votre tour." msgstr "Ce n'est pas votre tour."
#: draw/consumers.py:371 #: draw/consumers.py:395
#, python-brace-format #, python-brace-format
msgid "Dices from teams {teams} are identical. Please relaunch your dices." msgid "Dices from teams {teams} are identical. Please relaunch your dices."
msgstr "" msgstr ""
"Les dés des équipes {teams} sont identiques. Merci de relancer vos dés." "Les dés des équipes {teams} sont identiques. Merci de relancer vos dés."
#: draw/consumers.py:869 #: draw/consumers.py:966
msgid "This is only available for the final tournament." msgid "This is only available for the final tournament."
msgstr "Cela n'est possible que pour la finale." msgstr "Cela n'est possible que pour la finale."
@ -168,7 +168,7 @@ msgstr "La poule en cours, où les équipes choisissent leurs problèmes"
msgid "rounds" msgid "rounds"
msgstr "tours" msgstr "tours"
#: draw/models.py:254 participation/models.py:369 #: draw/models.py:254 participation/models.py:370
msgid "letter" msgid "letter"
msgstr "lettre" msgstr "lettre"
@ -207,17 +207,17 @@ msgid "Pool {letter}{number}"
msgstr "Poule {letter}{number}" msgstr "Poule {letter}{number}"
#: draw/models.py:407 draw/models.py:434 participation/admin.py:69 #: draw/models.py:407 draw/models.py:434 participation/admin.py:69
#: participation/admin.py:88 participation/models.py:421 #: participation/admin.py:88 participation/models.py:423
#: participation/models.py:430 participation/tables.py:82 #: participation/models.py:432 participation/tables.py:83
msgid "pool" msgid "pool"
msgstr "poule" msgstr "poule"
#: draw/models.py:408 participation/models.py:422 #: draw/models.py:408 participation/models.py:424
msgid "pools" msgid "pools"
msgstr "poules" msgstr "poules"
#: draw/models.py:420 participation/models.py:342 participation/models.py:591 #: draw/models.py:420 participation/models.py:342 participation/models.py:593
#: participation/models.py:621 participation/models.py:659 #: participation/models.py:623 participation/models.py:661
msgid "participation" msgid "participation"
msgstr "participation" msgstr "participation"
@ -241,8 +241,8 @@ 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:457 draw/models.py:480 participation/models.py:444 #: draw/models.py:457 draw/models.py:480 participation/models.py:446
#: participation/models.py:628 #: participation/models.py:630
#, python-brace-format #, python-brace-format
msgid "Problem #{problem}" msgid "Problem #{problem}"
msgstr "Problème n°{problem}" msgstr "Problème n°{problem}"
@ -331,10 +331,10 @@ msgstr "équipe"
#: draw/templates/draw/tournament_content.html:228 #: draw/templates/draw/tournament_content.html:228
#: draw/templates/draw/tournament_content.html:229 #: draw/templates/draw/tournament_content.html:229
#: draw/templates/draw/tournament_content.html:230 #: draw/templates/draw/tournament_content.html:230
#: participation/templates/participation/pool_detail.html:62 #: participation/templates/participation/pool_detail.html:84
#: participation/templates/participation/pool_detail.html:66 #: participation/templates/participation/pool_detail.html:88
#: participation/templates/participation/pool_detail.html:72 #: participation/templates/participation/pool_detail.html:94
#: participation/templates/participation/pool_detail.html:76 #: participation/templates/participation/pool_detail.html:98
msgid "Room" msgid "Room"
msgstr "Salle" msgstr "Salle"
@ -443,21 +443,21 @@ msgid "selected for final"
msgstr "sélectionnée pour la finale" msgstr "sélectionnée pour la finale"
#: participation/admin.py:57 participation/admin.py:116 #: participation/admin.py:57 participation/admin.py:116
#: participation/models.py:451 participation/tables.py:109 #: participation/models.py:453 participation/tables.py:111
msgid "defender" msgid "defender"
msgstr "défenseur⋅se" msgstr "défenseur⋅se"
#: participation/admin.py:61 participation/models.py:458 #: participation/admin.py:61 participation/models.py:460
#: participation/models.py:671 #: participation/models.py:673
msgid "opponent" msgid "opponent"
msgstr "opposant⋅e" msgstr "opposant⋅e"
#: participation/admin.py:65 participation/models.py:465 #: participation/admin.py:65 participation/models.py:467
#: participation/models.py:672 #: participation/models.py:674
msgid "reporter" msgid "reporter"
msgstr "rapporteur⋅e" msgstr "rapporteur⋅e"
#: participation/admin.py:120 participation/models.py:626 #: participation/admin.py:120 participation/models.py:628
msgid "problem" msgid "problem"
msgstr "numéro de problème" msgstr "numéro de problème"
@ -515,7 +515,7 @@ msgid "Add new jury"
msgstr "Ajouter un⋅e nouvelleau juré⋅e" msgstr "Ajouter un⋅e nouvelleau juré⋅e"
#: participation/forms.py:227 #: participation/forms.py:227
#: participation/templates/participation/pool_detail.html:101 #: participation/templates/participation/pool_detail.html:123
#: participation/templates/participation/tournament_detail.html:111 #: participation/templates/participation/tournament_detail.html:111
msgid "Add" msgid "Add"
msgstr "Ajouter" msgstr "Ajouter"
@ -676,32 +676,32 @@ msgstr "L'équipe est sélectionnée pour la finale."
msgid "Participation of the team {name} ({trigram})" msgid "Participation of the team {name} ({trigram})"
msgstr "Participation de l'équipe {name} ({trigram})" msgstr "Participation de l'équipe {name} ({trigram})"
#: participation/models.py:343 participation/models.py:375 #: participation/models.py:343 participation/models.py:376
msgid "participations" msgid "participations"
msgstr "participations" msgstr "participations"
#: participation/models.py:357 participation/models.py:358 #: participation/models.py:358 participation/models.py:359
#, python-brace-format #, python-brace-format
msgid "Round {round}" msgid "Round {round}"
msgstr "Tour {round}" msgstr "Tour {round}"
#: participation/models.py:381 #: participation/models.py:382
msgid "juries" msgid "juries"
msgstr "jurys" msgstr "jurys"
#: participation/models.py:388 #: participation/models.py:389
msgid "BigBlueButton URL" msgid "BigBlueButton URL"
msgstr "Lien BigBlueButton" msgstr "Lien BigBlueButton"
#: participation/models.py:389 #: participation/models.py:390
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:394 #: participation/models.py:395
msgid "results available" msgid "results available"
msgstr "résultats disponibles" msgstr "résultats disponibles"
#: participation/models.py:395 #: participation/models.py:396
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."
@ -710,28 +710,28 @@ 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:415 #: participation/models.py:417
#, python-brace-format #, python-brace-format
msgid "Pool of day {round} for tournament {tournament} with teams {teams}" msgid "Pool of day {round} for tournament {tournament} with teams {teams}"
msgstr "Poule du jour {round} du tournoi {tournament} avec les équipes {teams}" msgstr "Poule du jour {round} du tournoi {tournament} avec les équipes {teams}"
#: participation/models.py:435 #: participation/models.py:437
msgid "position" msgid "position"
msgstr "position" msgstr "position"
#: participation/models.py:442 #: participation/models.py:444
msgid "defended solution" msgid "defended solution"
msgstr "solution défendue" msgstr "solution défendue"
#: participation/models.py:475 #: participation/models.py:477
msgid "observer" msgid "observer"
msgstr "observateur⋅rice" msgstr "observateur⋅rice"
#: participation/models.py:480 #: participation/models.py:482
msgid "penalties" msgid "penalties"
msgstr "pénalités" msgstr "pénalités"
#: participation/models.py:482 #: participation/models.py:484
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."
@ -739,124 +739,124 @@ msgstr ""
"Nombre de pénalités pour læ défenseur⋅se. Læ défenseur⋅se perd un " "Nombre de pénalités pour læ défenseur⋅se. Læ défenseur⋅se perd un "
"coefficient 0.5 sur sa présentation orale par pénalité." "coefficient 0.5 sur sa présentation orale par pénalité."
#: participation/models.py:558 participation/models.py:561 #: participation/models.py:560 participation/models.py:563
#: participation/models.py:564 participation/models.py:567 #: participation/models.py:566 participation/models.py:569
#, 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:572 #: participation/models.py:574
#, 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:576 participation/models.py:585 #: participation/models.py:578 participation/models.py:587
#: participation/models.py:666 participation/models.py:708 #: participation/models.py:668 participation/models.py:710
msgid "passage" msgid "passage"
msgstr "passage" msgstr "passage"
#: participation/models.py:577 #: participation/models.py:579
msgid "passages" msgid "passages"
msgstr "passages" msgstr "passages"
#: participation/models.py:596 #: participation/models.py:598
msgid "difference" msgid "difference"
msgstr "différence" msgstr "différence"
#: participation/models.py:597 #: participation/models.py:599
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:604 #: participation/models.py:606
msgid "tweak" msgid "tweak"
msgstr "harmonisation" msgstr "harmonisation"
#: participation/models.py:605 #: participation/models.py:607
msgid "tweaks" msgid "tweaks"
msgstr "harmonisations" msgstr "harmonisations"
#: participation/models.py:633 #: participation/models.py:635
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:638 participation/models.py:677 #: participation/models.py:640 participation/models.py:679
msgid "file" msgid "file"
msgstr "fichier" msgstr "fichier"
#: participation/models.py:644 #: participation/models.py:646
#, 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:646 #: participation/models.py:648
msgid "for final" msgid "for final"
msgstr "pour la finale" msgstr "pour la finale"
#: participation/models.py:649 #: participation/models.py:651
msgid "solution" msgid "solution"
msgstr "solution" msgstr "solution"
#: participation/models.py:650 #: participation/models.py:652
msgid "solutions" msgid "solutions"
msgstr "solutions" msgstr "solutions"
#: participation/models.py:683 #: participation/models.py:685
#, python-brace-format #, python-brace-format
msgid "Synthesis of {team} as {type} for problem {problem} of {defender}" msgid "Synthesis 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:691 #: participation/models.py:693
msgid "synthesis" msgid "synthesis"
msgstr "note de synthèse" msgstr "note de synthèse"
#: participation/models.py:692 #: participation/models.py:694
msgid "syntheses" msgid "syntheses"
msgstr "notes de synthèse" msgstr "notes de synthèse"
#: participation/models.py:701 #: participation/models.py:703
msgid "jury" msgid "jury"
msgstr "jury" msgstr "jury"
#: participation/models.py:713 #: participation/models.py:715
msgid "defender writing note" msgid "defender writing note"
msgstr "note d'écrit de læ défenseur⋅se" msgstr "note d'écrit de læ défenseur⋅se"
#: participation/models.py:719 #: participation/models.py:721
msgid "defender oral note" msgid "defender oral note"
msgstr "note d'oral de læ défenseur⋅se" msgstr "note d'oral de læ défenseur⋅se"
#: participation/models.py:725 #: participation/models.py:727
msgid "opponent writing note" msgid "opponent writing note"
msgstr "note d'écrit de l'opposant⋅e" msgstr "note d'écrit de l'opposant⋅e"
#: participation/models.py:731 #: participation/models.py:733
msgid "opponent oral note" msgid "opponent oral note"
msgstr "note d'oral de l'opposant⋅e" msgstr "note d'oral de l'opposant⋅e"
#: participation/models.py:737 #: participation/models.py:739
msgid "reporter writing note" msgid "reporter writing note"
msgstr "note d'écrit de læ rapporteur⋅e" msgstr "note d'écrit de læ rapporteur⋅e"
#: participation/models.py:743 #: participation/models.py:745
msgid "reporter oral note" msgid "reporter oral note"
msgstr "note d'oral de læ rapporteur⋅e" msgstr "note d'oral de læ rapporteur⋅e"
#: participation/models.py:749 #: participation/models.py:751
msgid "observer note" msgid "observer note"
msgstr "note de l'observateur⋅rice" msgstr "note de l'observateur⋅rice"
#: participation/models.py:778 #: participation/models.py:780
#, 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:785 #: participation/models.py:787
msgid "note" msgid "note"
msgstr "note" msgstr "note"
#: participation/models.py:786 #: participation/models.py:788
msgid "notes" msgid "notes"
msgstr "notes" msgstr "notes"
@ -872,21 +872,21 @@ msgstr "Validation en attente"
msgid "Not validated" msgid "Not validated"
msgstr "Non validée" msgstr "Non validée"
#: participation/tables.py:62 #: participation/tables.py:63
msgid "date" msgid "date"
msgstr "date" msgstr "date"
#: participation/tables.py:65 #: participation/tables.py:66
#, python-brace-format #, python-brace-format
msgid "From {start} to {end}" msgid "From {start} to {end}"
msgstr "Du {start} au {end}" msgstr "Du {start} au {end}"
#: participation/tables.py:91 #: participation/tables.py:93
#, python-brace-format #, python-brace-format
msgid "Pool {letter}{round}" msgid "Pool {letter}{round}"
msgstr "Poule {letter}{round}" msgstr "Poule {letter}{round}"
#: participation/tables.py:95 #: participation/tables.py:97
msgid "No defined team" msgid "No defined team"
msgstr "Pas d'équipe définie" msgstr "Pas d'équipe définie"
@ -940,9 +940,9 @@ msgstr "Rejoindre"
#: participation/templates/participation/passage_detail.html:120 #: participation/templates/participation/passage_detail.html:120
#: participation/templates/participation/passage_detail.html:126 #: participation/templates/participation/passage_detail.html:126
#: participation/templates/participation/pool_add_jurys.html:35 #: participation/templates/participation/pool_add_jurys.html:35
#: participation/templates/participation/pool_detail.html:88 #: participation/templates/participation/pool_detail.html:110
#: participation/templates/participation/pool_detail.html:106 #: participation/templates/participation/pool_detail.html:128
#: participation/templates/participation/pool_detail.html:111 #: participation/templates/participation/pool_detail.html:133
#: participation/templates/participation/team_detail.html:128 #: participation/templates/participation/team_detail.html:128
#: participation/templates/participation/team_detail.html:192 #: participation/templates/participation/team_detail.html:192
#: participation/templates/participation/tournament_form.html:12 #: participation/templates/participation/tournament_form.html:12
@ -1006,7 +1006,7 @@ msgstr "Envoyer une solution"
#: participation/templates/participation/participation_detail.html:59 #: participation/templates/participation/participation_detail.html:59
#: participation/templates/participation/passage_detail.html:132 #: participation/templates/participation/passage_detail.html:132
#: participation/templates/participation/pool_detail.html:116 #: participation/templates/participation/pool_detail.html:138
#: participation/templates/participation/team_detail.html:187 #: participation/templates/participation/team_detail.html:187
#: participation/templates/participation/upload_motivation_letter.html:13 #: participation/templates/participation/upload_motivation_letter.html:13
#: participation/templates/participation/upload_notes.html:17 #: participation/templates/participation/upload_notes.html:17
@ -1057,10 +1057,12 @@ msgid "Defender penalties count:"
msgstr "Nombre de pénalités :" msgstr "Nombre de pénalités :"
#: participation/templates/participation/passage_detail.html:39 #: participation/templates/participation/passage_detail.html:39
#: participation/templates/participation/pool_detail.html:46
msgid "Syntheses:" msgid "Syntheses:"
msgstr "Notes de synthèse :" msgstr "Notes de synthèse :"
#: participation/templates/participation/passage_detail.html:44 #: participation/templates/participation/passage_detail.html:44
#: participation/templates/participation/pool_detail.html:55
msgid "No synthesis was uploaded yet." msgid "No synthesis 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."
@ -1141,7 +1143,7 @@ msgstr ""
#: participation/templates/participation/pool_add_jurys.html:11 #: participation/templates/participation/pool_add_jurys.html:11
#: participation/templates/participation/pool_add_jurys.html:34 #: participation/templates/participation/pool_add_jurys.html:34
#: participation/templates/participation/pool_detail.html:105 #: participation/templates/participation/pool_detail.html:127
#: participation/templates/participation/pool_form.html:11 #: participation/templates/participation/pool_form.html:11
msgid "Update pool" msgid "Update pool"
msgstr "Modifier la poule" msgstr "Modifier la poule"
@ -1182,42 +1184,47 @@ msgstr "Ajouter des juré⋅es"
msgid "Defended solutions:" msgid "Defended solutions:"
msgstr "Solutions défendues :" msgstr "Solutions défendues :"
#: participation/templates/participation/pool_detail.html:43 #: participation/templates/participation/pool_detail.html:42
#: participation/templates/participation/pool_detail.html:61
msgid "Download all"
msgstr "Tout télécharger"
#: participation/templates/participation/pool_detail.html:65
msgid "BigBlueButton link:" msgid "BigBlueButton link:"
msgstr "Lien BigBlueButton :" msgstr "Lien BigBlueButton :"
#: participation/templates/participation/pool_detail.html:49 #: participation/templates/participation/pool_detail.html:71
#: participation/templates/participation/tournament_detail.html:97 #: participation/templates/participation/tournament_detail.html:97
msgid "Ranking" msgid "Ranking"
msgstr "Classement" msgstr "Classement"
#: participation/templates/participation/pool_detail.html:62 #: participation/templates/participation/pool_detail.html:84
msgid "Download the scale sheet" msgid "Download the scale sheet"
msgstr "Télécharger la feuille de barème" msgstr "Télécharger la feuille de barème"
#: participation/templates/participation/pool_detail.html:72 #: participation/templates/participation/pool_detail.html:94
msgid "Download the final notation sheet" msgid "Download the final notation sheet"
msgstr "Télécharger la fiche de notation finale" msgstr "Télécharger la fiche de notation finale"
#: participation/templates/participation/pool_detail.html:80 #: participation/templates/participation/pool_detail.html:102
msgid "Upload notes from a CSV file" msgid "Upload notes from a CSV file"
msgstr "Soumettre les notes à partir d'un fichier CSV" msgstr "Soumettre les notes à partir d'un fichier CSV"
#: participation/templates/participation/pool_detail.html:87 #: participation/templates/participation/pool_detail.html:109
#: participation/templates/participation/pool_detail.html:100 #: participation/templates/participation/pool_detail.html:122
msgid "Add passage" msgid "Add passage"
msgstr "Ajouter un passage" msgstr "Ajouter un passage"
#: participation/templates/participation/pool_detail.html:89 #: participation/templates/participation/pool_detail.html:111
#: participation/templates/participation/pool_detail.html:110 #: participation/templates/participation/pool_detail.html:132
msgid "Update teams" msgid "Update teams"
msgstr "Modifier les équipes" msgstr "Modifier les équipes"
#: participation/templates/participation/pool_detail.html:96 #: participation/templates/participation/pool_detail.html:118
msgid "Passages" msgid "Passages"
msgstr "Passages" msgstr "Passages"
#: participation/templates/participation/pool_detail.html:115 #: participation/templates/participation/pool_detail.html:137
msgid "Upload notes" msgid "Upload notes"
msgstr "Envoyer les notes" msgstr "Envoyer les notes"
@ -1582,33 +1589,43 @@ msgstr "L'équipe n'est pas encore validée."
msgid "Participation of team {trigram}" msgid "Participation of team {trigram}"
msgstr "Participation de l'équipe {trigram}" msgstr "Participation de l'équipe {trigram}"
#: participation/views.py:647 #: participation/views.py:655
msgid "You can't upload a solution after the deadline." msgid "You can't upload a solution after the deadline."
msgstr "Vous ne pouvez pas envoyer de solution après la date limite." msgstr "Vous ne pouvez pas envoyer de solution après la date limite."
#: participation/views.py:738 #: participation/views.py:763
#, python-brace-format
msgid "Solutions for pool {pool} of tournament {tournament}.zip"
msgstr "Solutions pour la poule {pool} du tournoi {tournament}.zip"
#: participation/views.py:764
#, python-brace-format
msgid "Syntheses for pool {pool} of tournament {tournament}.zip"
msgstr "Notes de synthèses pour la poule {pool} du tournoi {tournament}.zip"
#: participation/views.py:782
#, python-brace-format #, python-brace-format
msgid "Jurys of {pool}" msgid "Jurys of {pool}"
msgstr "Juré⋅es de la {pool}" msgstr "Juré⋅es de la {pool}"
#: participation/views.py:765 #: participation/views.py:809
msgid "New TFJM² jury account" msgid "New TFJM² jury account"
msgstr "Nouveau compte de juré⋅e pour le TFJM²" msgstr "Nouveau compte de juré⋅e pour le TFJM²"
#: participation/views.py:778 #: participation/views.py:822
#, python-brace-format #, python-brace-format
msgid "The jury {name} has been successfully added!" msgid "The jury {name} has been successfully added!"
msgstr "Læ juré⋅e {name} a été ajouté⋅e avec succès !" msgstr "Læ juré⋅e {name} a été ajouté⋅e avec succès !"
#: participation/views.py:815 #: participation/views.py:859
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:829 #: participation/views.py:873
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:1493 #: participation/views.py:1537
msgid "You can't upload a synthesis after the deadline." msgid "You can't upload a synthesis after the deadline."
msgstr "Vous ne pouvez pas envoyer de note de synthèse après la date limite." msgstr "Vous ne pouvez pas envoyer de note de synthèse après la date limite."
@ -2317,11 +2334,11 @@ msgstr "Autorisation parentale de {student}.{ext}"
msgid "Scholarship attestation of {user}.{ext}" msgid "Scholarship attestation of {user}.{ext}"
msgstr "Notification de bourse de {user}.{ext}" msgstr "Notification de bourse de {user}.{ext}"
#: tfjm/settings.py:165 #: tfjm/settings.py:170
msgid "English" msgid "English"
msgstr "Anglais" msgstr "Anglais"
#: tfjm/settings.py:166 #: tfjm/settings.py:171
msgid "French" msgid "French"
msgstr "Français" msgstr "Français"

View File

@ -399,7 +399,7 @@ class Pool(models.Model):
@property @property
def solutions(self): def solutions(self):
return Solution.objects.filter(participation__in=self.participations, final_solution=self.tournament.final) return [passage.defended_solution for passage in self.passages.all()]
def average(self, participation): def average(self, participation):
return sum(passage.average(participation) for passage in self.passages.all()) \ return sum(passage.average(participation) for passage in self.passages.all()) \

View File

@ -36,8 +36,30 @@
<dt class="col-sm-3">{% trans "Defended solutions:" %}</dt> <dt class="col-sm-3">{% trans "Defended solutions:" %}</dt>
<dd class="col-sm-9"> <dd class="col-sm-9">
{% for passage in pool.passages.all %} {% for passage in pool.passages.all %}
<a href="{{ passage.defended_solution.file.url }}">{{ passage.defended_solution }}{% if not forloop.last %}, {% endif %}</a> <a href="{{ passage.defended_solution.file.url }}">{{ passage.defender.team.trigram }} — {{ passage.get_solution_number_display }}</a>{% if not forloop.last %}, {% endif %}
{% endfor %} {% endfor %}
<a href="{% url 'participation:pool_download_solutions' pk=pool.pk %}" class="badge rounded-pill text-bg-secondary">
<i class="fas fa-download"></i> {% trans "Download all" %}
</a>
</dd>
<dt class="col-sm-3">{% trans "Syntheses:" %}</dt>
<dd class="col-sm-9">
<ul class="list-group list-group-flush">
{% for passage in pool.passages.all %}
<li class="list-group-item">
{{ passage.defender.team.trigram }} — {{ passage.get_solution_number_display }} :
{% for synthesis in passage.syntheses.all %}
<a href="{{ synthesis.file.url }}">{{ synthesis.participation.team.trigram }} ({{ synthesis.get_type_display }})</a>{% if not forloop.last %}, {% endif %}
{% empty %}
{% trans "No synthesis was uploaded yet." %}
{% endfor %}
</li>
{% endfor %}
</ul>
<a href="{% url 'participation:pool_download_syntheses' pk=pool.pk %}" class="badge rounded-pill text-bg-secondary">
<i class="fas fa-download"></i> {% trans "Download all" %}
</a>
</dd> </dd>
<dt class="col-sm-3">{% trans "BigBlueButton link:" %}</dt> <dt class="col-sm-3">{% trans "BigBlueButton link:" %}</dt>

View File

@ -6,9 +6,9 @@ from django.views.generic import TemplateView
from .views import CreateTeamView, FinalNotationSheetTemplateView, JoinTeamView, MyParticipationDetailView, \ from .views import CreateTeamView, FinalNotationSheetTemplateView, JoinTeamView, MyParticipationDetailView, \
MyTeamDetailView, NoteUpdateView, ParticipationDetailView, PassageCreateView, PassageDetailView, \ MyTeamDetailView, NoteUpdateView, ParticipationDetailView, PassageCreateView, PassageDetailView, \
PassageUpdateView, PoolAddJurysView, PoolCreateView, PoolDetailView, PoolNotesTemplateView, PoolUpdateTeamsView, \ PassageUpdateView, PoolAddJurysView, PoolCreateView, PoolDetailView, PoolDownloadView, PoolNotesTemplateView, \
PoolUpdateView, PoolUploadNotesView, ScaleNotationSheetTemplateView, SolutionUploadView, SynthesisUploadView, \ PoolUpdateTeamsView, PoolUpdateView, PoolUploadNotesView, ScaleNotationSheetTemplateView, SolutionUploadView, \
TeamAuthorizationsView, TeamDetailView, TeamLeaveView, TeamListView, TeamUpdateView, \ SynthesisUploadView, TeamAuthorizationsView, TeamDetailView, TeamLeaveView, TeamListView, TeamUpdateView, \
TeamUploadMotivationLetterView, TournamentCreateView, TournamentDetailView, TournamentExportCSVView, \ TeamUploadMotivationLetterView, TournamentCreateView, TournamentDetailView, TournamentExportCSVView, \
TournamentListView, TournamentUpdateView TournamentListView, TournamentUpdateView
@ -37,6 +37,8 @@ urlpatterns = [
path("pools/create/", PoolCreateView.as_view(), name="pool_create"), path("pools/create/", PoolCreateView.as_view(), name="pool_create"),
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:pk>/solutions/", PoolDownloadView.as_view(), name="pool_download_solutions"),
path("pools/<int:pk>/syntheses/", PoolDownloadView.as_view(), name="pool_download_syntheses"),
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:pk>/update-teams/", PoolUpdateTeamsView.as_view(), name="pool_update_teams"), path("pools/<int:pk>/update-teams/", PoolUpdateTeamsView.as_view(), name="pool_update_teams"),

View File

@ -733,6 +733,42 @@ class PoolUpdateTeamsView(VolunteerMixin, UpdateView):
return self.handle_no_permission() return self.handle_no_permission()
class PoolDownloadView(VolunteerMixin, DetailView):
"""
Download all solutions or syntheses as a ZIP archive.
"""
model = Pool
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated:
return self.handle_no_permission()
if request.user.registration.is_admin or request.user.registration.is_volunteer \
and (self.get_object().tournament in request.user.registration.organized_tournaments.all()
or request.user.registration in self.get_object().juries.all()):
return super().dispatch(request, *args, **kwargs)
return self.handle_no_permission()
def get(self, request, *args, **kwargs):
pool = self.get_object()
is_solution = 'solutions' in request.path
output = BytesIO()
zf = ZipFile(output, "w")
for s in (pool.solutions if is_solution else Synthesis.objects.filter(passage__pool=pool).all()):
zf.write("media/" + s.file.name, f"{s}.pdf")
zf.close()
response = HttpResponse(content_type="application/zip")
filename = _("Solutions for pool {pool} of tournament {tournament}.zip") \
if is_solution else _("Syntheses for pool {pool} of tournament {tournament}.zip")
filename = filename.format(pool=pool.get_letter_display() + str(pool.round), tournament=pool.tournament.name)
response["Content-Disposition"] = "attachment; filename=\"{filename}\"" \
.format(filename=filename)
response.write(output.getvalue())
return response
class PoolAddJurysView(VolunteerMixin, FormView, DetailView): class PoolAddJurysView(VolunteerMixin, FormView, DetailView):
""" """
This view lets organizers set jurys for a pool, without multiplying clicks. This view lets organizers set jurys for a pool, without multiplying clicks.