From 49e5d97ec9b46c0bcd7d94dfe063dde2912d19e2 Mon Sep 17 00:00:00 2001 From: Emmy D'Anello Date: Sat, 13 Apr 2024 21:28:32 +0200 Subject: [PATCH] Generate spreadsheet with all teams at the second place Signed-off-by: Emmy D'Anello --- .../commands/generate_seconds_sheet.py | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 participation/management/commands/generate_seconds_sheet.py diff --git a/participation/management/commands/generate_seconds_sheet.py b/participation/management/commands/generate_seconds_sheet.py new file mode 100644 index 0000000..287ac21 --- /dev/null +++ b/participation/management/commands/generate_seconds_sheet.py @@ -0,0 +1,149 @@ +# Copyright (C) 2024 by Animath +# SPDX-License-Identifier: GPL-3.0-or-later + +from django.conf import settings +from django.core.management import BaseCommand +from django.utils.translation import activate +import gspread +from gspread.utils import a1_range_to_grid_range, MergeType + +from participation.models import Tournament + + +class Command(BaseCommand): + def handle(self, *args, **options): + activate('fr') + gc = gspread.service_account_from_dict(settings.GOOGLE_SERVICE_CLIENT) + try: + spreadsheet = gc.open("Tableau des deuxièmes", folder_id=settings.NOTES_DRIVE_FOLDER_ID) + except gspread.SpreadsheetNotFound: + spreadsheet = gc.create("Tableau des deuxièmes", folder_id=settings.NOTES_DRIVE_FOLDER_ID) + spreadsheet.update_locale("fr_FR") + spreadsheet.share(None, "anyone", "writer", with_link=True) + + sheet = spreadsheet.sheet1 + + header1 = ["Tournoi", "Équipe 2", "Tour 1", "", "", "", "", "", "", "", "Tour 2", "", "", "", "", "", "", "", + "Score total", "Score équipe 1", "Score équipe 3"] + header2 = ["", ""] + 2 * ["PJ", "Problème", "Défenseur⋅se", "", "Opposant⋅e", "", "Rapporteur⋅rice", ""] + header2 += ["", "", ""] + header3 = ["", ""] + 2 * (["", ""] + 3 * ["Écrit", "Oral"]) + ["", "", ""] + lines = [header1, header2, header3] + nb_tournaments = Tournament.objects.filter(final=False).count() + for tournament in Tournament.objects.filter(final=False).all(): + line = [tournament.name] + lines.append(line) + + notes = dict() + for participation in tournament.participations.filter(valid=True).all(): + note = sum(pool.average(participation) + for pool in tournament.pools.filter(participations=participation).all()) + if note: + notes[participation] = note + + if not notes: + continue + + sorted_notes = sorted(notes.items(), key=lambda x: x[1], reverse=True) + + team1, score1 = sorted_notes[0] + team2, score2 = sorted_notes[1] + team3, score3 = sorted_notes[2] + + pool1 = tournament.pools.get(round=1, participations=team2) + defender_passage_1 = pool1.passages.get(defender=team2) + opponent_passage_1 = pool1.passages.get(opponent=team2) + reporter_passage_1 = pool1.passages.get(reporter=team2) + pool2 = tournament.pools.get(round=2, participations=team2) + defender_passage_2 = pool2.passages.get(defender=team2) + opponent_passage_2 = pool2.passages.get(opponent=team2) + reporter_passage_2 = pool2.passages.get(reporter=team2) + + line.append(team2.team.trigram) + line.append(str(pool1.jury_president or "")) + line.append(f"Pb. {defender_passage_1.solution_number}") + line.extend([defender_passage_1.average_defender_writing, defender_passage_1.average_defender_oral, + opponent_passage_1.average_opponent_writing, opponent_passage_1.average_opponent_oral, + reporter_passage_1.average_reporter_writing, reporter_passage_1.average_reporter_oral]) + line.append(str(pool2.jury_president or "")) + line.append(f"Pb. {defender_passage_2.solution_number}") + line.extend([defender_passage_2.average_defender_writing, defender_passage_2.average_defender_oral, + opponent_passage_2.average_opponent_writing, opponent_passage_2.average_opponent_oral, + reporter_passage_2.average_reporter_writing, reporter_passage_2.average_reporter_oral]) + line.extend([score2, f"{score1:.1f} ({team1.team.trigram})", + f"{score3:.1f} ({team3.team.trigram})"]) + + sheet.update(lines) + + format_requests = [] + merge_cells = ["A1:A3", "B1:B3", "C1:J1", "K1:R1", "E2:F2", "G2:H2", "I2:J2", "M2:N2", "O2:P2", "Q2:R2", + "C2:C3", "D2:D3", "K2:K3", "L2:L3", "S1:S3", "T1:T3", "U1:U3"] + format_requests.append({"unmergeCells": {"range": a1_range_to_grid_range("A1:AF", sheet.id)}}) + for name in merge_cells: + grid_range = a1_range_to_grid_range(name, sheet.id) + format_requests.append({"mergeCells": {"mergeType": MergeType.merge_all, "range": grid_range}}) + + bold_ranges = [("A1:AF", False), ("A1:U3", True), (f"A4:A{3 + nb_tournaments}", True)] + for bold_range, bold in bold_ranges: + format_requests.append({ + "repeatCell": { + "range": a1_range_to_grid_range(bold_range, sheet.id), + "cell": {"userEnteredFormat": {"textFormat": {"bold": bold}}}, + "fields": "userEnteredFormat(textFormat)", + } + }) + + border_ranges = [("A1:AF", "0000"), + (f"A1:U{3 + nb_tournaments}", "1111")] + sides_names = ['top', 'bottom', 'left', 'right'] + styles = ["NONE", "SOLID", "SOLID_MEDIUM", "SOLID_THICK", "DOUBLE"] + for border_range, sides in border_ranges: + borders = {} + for side_name, side in zip(sides_names, sides): + borders[side_name] = {"style": styles[int(side)]} + format_requests.append({ + "repeatCell": { + "range": a1_range_to_grid_range(border_range, sheet.id), + "cell": { + "userEnteredFormat": { + "borders": borders, + "horizontalAlignment": "CENTER", + }, + }, + "fields": "userEnteredFormat(borders,horizontalAlignment)", + } + }) + + column_widths = [("A", 120), ("B", 80), ("C", 180), ("D", 80)] + [(chr(ord("E") + i), 60) for i in range(6)] + column_widths += [("K", 180), ("L", 80)] + [(chr(ord("M") + i), 60) for i in range(6)] + column_widths += [("S", 100), ("T", 120), ("U", 120)] + for column, width in column_widths: + grid_range = a1_range_to_grid_range(column, sheet.id) + format_requests.append({ + "updateDimensionProperties": { + "range": { + "sheetId": sheet.id, + "dimension": "COLUMNS", + "startIndex": grid_range['startColumnIndex'], + "endIndex": grid_range['endColumnIndex'], + }, + "properties": { + "pixelSize": width, + }, + "fields": "pixelSize", + } + }) + + # Set number format, display only one decimal + number_format_ranges = [f"E4:J{3 + nb_tournaments}", f"M4:S{3 + nb_tournaments}"] + for number_format_range in number_format_ranges: + format_requests.append({ + "repeatCell": { + "range": a1_range_to_grid_range(number_format_range, sheet.id), + "cell": {"userEnteredFormat": {"numberFormat": {"type": "NUMBER", "pattern": "0.0"}}}, + "fields": "userEnteredFormat.numberFormat", + } + }) + + body = {"requests": format_requests} + sheet.client.batch_update(spreadsheet.id, body)