Compare commits
1 Commits
2e99b3ea8e
...
fdd02e5922
Author | SHA1 | Date |
---|---|---|
Emmy D'Anello | fdd02e5922 |
|
@ -470,10 +470,10 @@ class Tournament(models.Model):
|
||||||
gc = gspread.service_account_from_dict(settings.GOOGLE_SERVICE_CLIENT)
|
gc = gspread.service_account_from_dict(settings.GOOGLE_SERVICE_CLIENT)
|
||||||
spreadsheet = gc.open_by_key(self.notes_sheet_id)
|
spreadsheet = gc.open_by_key(self.notes_sheet_id)
|
||||||
worksheets = spreadsheet.worksheets()
|
worksheets = spreadsheet.worksheets()
|
||||||
if str(_("Final ranking")) not in [ws.title for ws in worksheets]:
|
if _("Final ranking") not in [ws.title for ws in worksheets]:
|
||||||
worksheet = spreadsheet.add_worksheet(str(_("Final ranking")), 30, 10)
|
worksheet = spreadsheet.add_worksheet(_("Final ranking"), 30, 10)
|
||||||
else:
|
else:
|
||||||
worksheet = spreadsheet.worksheet(str(_("Final ranking")))
|
worksheet = spreadsheet.worksheet(_("Final ranking"))
|
||||||
|
|
||||||
if worksheet.index != self.pools.count():
|
if worksheet.index != self.pools.count():
|
||||||
worksheet.update_index(self.pools.count())
|
worksheet.update_index(self.pools.count())
|
||||||
|
@ -575,7 +575,7 @@ class Tournament(models.Model):
|
||||||
format_requests = []
|
format_requests = []
|
||||||
|
|
||||||
# Set the width of the columns
|
# Set the width of the columns
|
||||||
column_widths = [("A", 350), ("B", 150), ("C", 150), ("D", 150), ("E", 150), ("F", 150), ("G", 150),
|
column_widths = [("A", 300), ("B", 150), ("C", 150), ("D", 150), ("E", 150), ("F", 150), ("G", 150),
|
||||||
("H", 150), ("I", 150), ("J", 150)]
|
("H", 150), ("I", 150), ("J", 150)]
|
||||||
for column, width in column_widths:
|
for column, width in column_widths:
|
||||||
grid_range = a1_range_to_grid_range(column, worksheet.id)
|
grid_range = a1_range_to_grid_range(column, worksheet.id)
|
||||||
|
@ -640,7 +640,7 @@ class Tournament(models.Model):
|
||||||
(f"A{participations.count() + 5}:C{2 * participations.count() + 4}", (0.9, 0.9, 0.9)),]
|
(f"A{participations.count() + 5}:C{2 * participations.count() + 4}", (0.9, 0.9, 0.9)),]
|
||||||
if settings.NB_ROUNDS >= 3:
|
if settings.NB_ROUNDS >= 3:
|
||||||
bg_colors.append((f"F2:G{participations.count() + 1}", (0.9, 0.9, 0.9)))
|
bg_colors.append((f"F2:G{participations.count() + 1}", (0.9, 0.9, 0.9)))
|
||||||
bg_colors.append((f"I2:J{participations.count() + 1}", (0.9, 0.9, 0.9)))
|
bg_colors.append((f"H2:I{participations.count() + 1}", (0.9, 0.9, 0.9)))
|
||||||
else:
|
else:
|
||||||
bg_colors.append((f"F2:G{participations.count() + 1}", (0.9, 0.9, 0.9)))
|
bg_colors.append((f"F2:G{participations.count() + 1}", (0.9, 0.9, 0.9)))
|
||||||
for bg_range, bg_color in bg_colors:
|
for bg_range, bg_color in bg_colors:
|
||||||
|
@ -695,7 +695,7 @@ class Tournament(models.Model):
|
||||||
"addProtectedRange": {
|
"addProtectedRange": {
|
||||||
"protectedRange": {
|
"protectedRange": {
|
||||||
"range": a1_range_to_grid_range(protected_range, worksheet.id),
|
"range": a1_range_to_grid_range(protected_range, worksheet.id),
|
||||||
"description": str(_("Don't update the table structure for a better automated integration.")),
|
"description": _("Don't update the table structure for a better automated integration."),
|
||||||
"warningOnly": True,
|
"warningOnly": True,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -713,9 +713,9 @@ class Tournament(models.Model):
|
||||||
|
|
||||||
gc = gspread.service_account_from_dict(settings.GOOGLE_SERVICE_CLIENT)
|
gc = gspread.service_account_from_dict(settings.GOOGLE_SERVICE_CLIENT)
|
||||||
spreadsheet = gc.open_by_key(self.notes_sheet_id)
|
spreadsheet = gc.open_by_key(self.notes_sheet_id)
|
||||||
worksheet = spreadsheet.worksheet(str(_("Final ranking")))
|
worksheet = spreadsheet.worksheet(_("Final ranking"))
|
||||||
|
|
||||||
score_cell = worksheet.find(str(_("Score")))
|
score_cell = worksheet.find(_("Score"))
|
||||||
max_row = score_cell.row - 3
|
max_row = score_cell.row - 3
|
||||||
if max_row == 1:
|
if max_row == 1:
|
||||||
# There is no team
|
# There is no team
|
||||||
|
@ -1214,11 +1214,6 @@ class Pool(models.Model):
|
||||||
def update_spreadsheet(self): # noqa: C901
|
def update_spreadsheet(self): # noqa: C901
|
||||||
translation.activate(settings.PREFERRED_LANGUAGE_CODE)
|
translation.activate(settings.PREFERRED_LANGUAGE_CODE)
|
||||||
|
|
||||||
pool_size = self.participations.count()
|
|
||||||
has_observer = settings.TFJM_APP == "ETEAM" and pool_size >= 4
|
|
||||||
passage_width = 6 + (2 if has_observer else 0)
|
|
||||||
passages = self.passages.all()
|
|
||||||
|
|
||||||
# Create tournament sheet if it does not exist
|
# Create tournament sheet if it does not exist
|
||||||
self.tournament.create_spreadsheet()
|
self.tournament.create_spreadsheet()
|
||||||
|
|
||||||
|
@ -1226,23 +1221,27 @@ class Pool(models.Model):
|
||||||
spreadsheet = gc.open_by_key(self.tournament.notes_sheet_id)
|
spreadsheet = gc.open_by_key(self.tournament.notes_sheet_id)
|
||||||
worksheets = spreadsheet.worksheets()
|
worksheets = spreadsheet.worksheets()
|
||||||
if f"{_('Pool')} {self.short_name}" not in [ws.title for ws in worksheets]:
|
if f"{_('Pool')} {self.short_name}" not in [ws.title for ws in worksheets]:
|
||||||
worksheet = spreadsheet.add_worksheet(f"{_('Pool')} {self.short_name}",
|
worksheet = spreadsheet.add_worksheet(f"{_('Pool')} {self.short_name}", 100, 34)
|
||||||
30, 2 + passages.count() * passage_width)
|
|
||||||
else:
|
else:
|
||||||
worksheet = spreadsheet.worksheet(f"{_('Pool')} {self.short_name}")
|
worksheet = spreadsheet.worksheet(f"{_('Pool')} {self.short_name}")
|
||||||
if any(ws.title == "Sheet1" for ws in worksheets):
|
if any(ws.title == "Sheet1" for ws in worksheets):
|
||||||
spreadsheet.del_worksheet(spreadsheet.worksheet("Sheet1"))
|
spreadsheet.del_worksheet(spreadsheet.worksheet("Sheet1"))
|
||||||
|
|
||||||
|
pool_size = self.participations.count()
|
||||||
|
has_observer = settings.TFJM_APP == "ETEAM" and pool_size >= 4
|
||||||
|
passage_width = 6 + (2 if has_observer else 0)
|
||||||
|
passages = self.passages.all()
|
||||||
|
|
||||||
header = [
|
header = [
|
||||||
sum(([str(_("Problem #{problem}").format(problem=passage.solution_number))] + (passage_width - 1) * [""]
|
sum(([_("Problem #{problem}").format(problem=passage.solution_number)] + (passage_width - 1) * [""]
|
||||||
for passage in passages), start=[str(_("Problem")), ""]),
|
for passage in passages), start=[_("Problem"), ""]),
|
||||||
sum(([f"{_('Defender')} ({passage.defender.team.trigram})", "",
|
sum(([f"{_('Defender')} ({passage.defender.team.trigram})", "",
|
||||||
f"{_('Opponent')} ({passage.opponent.team.trigram})", "",
|
f"{_('Opponent')} ({passage.opponent.team.trigram})", "",
|
||||||
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 [])
|
||||||
for _passage in passages), start=[str(_("Juree")), ""]),
|
for _passage in passages), start=[str(_("Juree")), ""]),
|
||||||
|
@ -1276,7 +1275,7 @@ class Pool(models.Model):
|
||||||
for passage in passages),
|
for passage in passages),
|
||||||
start=[str(_("Coefficient")), ""])
|
start=[str(_("Coefficient")), ""])
|
||||||
subtotal = [str(_("Subtotal")), ""]
|
subtotal = [str(_("Subtotal")), ""]
|
||||||
footer = [average, coeffs, subtotal, (2 + pool_size * passage_width) * [""]]
|
footer = [average, coeffs, subtotal, 34 * [""]]
|
||||||
|
|
||||||
min_row = 5
|
min_row = 5
|
||||||
max_row = min_row + self.juries.count()
|
max_row = min_row + self.juries.count()
|
||||||
|
@ -1355,9 +1354,8 @@ class Pool(models.Model):
|
||||||
|
|
||||||
all_values = header + notes + footer + ranking
|
all_values = header + notes + footer + ranking
|
||||||
|
|
||||||
max_col = getcol(2 + pool_size * passage_width)
|
worksheet.batch_clear([f"A1:AH{max_row + 5 + pool_size}"])
|
||||||
worksheet.batch_clear([f"A1:{max_col}{max_row + 5 + pool_size}"])
|
worksheet.update(all_values, "A1:AH", raw=False)
|
||||||
worksheet.update(all_values, f"A1:{max_col}", raw=False)
|
|
||||||
|
|
||||||
format_requests = []
|
format_requests = []
|
||||||
|
|
||||||
|
@ -1376,11 +1374,6 @@ class Pool(models.Model):
|
||||||
f":{getcol(6 + i * passage_width)}{max_row + 3}")
|
f":{getcol(6 + i * passage_width)}{max_row + 3}")
|
||||||
merge_cells.append(f"{getcol(7 + i * passage_width)}{max_row + 3}"
|
merge_cells.append(f"{getcol(7 + i * passage_width)}{max_row + 3}"
|
||||||
f":{getcol(8 + i * passage_width)}{max_row + 3}")
|
f":{getcol(8 + i * passage_width)}{max_row + 3}")
|
||||||
|
|
||||||
if has_observer:
|
|
||||||
merge_cells.append(f"{getcol(9 + i * passage_width)}2:{getcol(10 + i * passage_width)}2")
|
|
||||||
merge_cells.append(f"{getcol(9 + i * passage_width)}{max_row + 3}"
|
|
||||||
f":{getcol(10 + i * passage_width)}{max_row + 3}")
|
|
||||||
merge_cells.append(f"A{max_row + 1}:B{max_row + 1}")
|
merge_cells.append(f"A{max_row + 1}:B{max_row + 1}")
|
||||||
merge_cells.append(f"A{max_row + 2}:B{max_row + 2}")
|
merge_cells.append(f"A{max_row + 2}:B{max_row + 2}")
|
||||||
merge_cells.append(f"A{max_row + 3}:B{max_row + 3}")
|
merge_cells.append(f"A{max_row + 3}:B{max_row + 3}")
|
||||||
|
@ -1388,13 +1381,13 @@ class Pool(models.Model):
|
||||||
for i in range(pool_size + 1):
|
for i in range(pool_size + 1):
|
||||||
merge_cells.append(f"A{max_row + 5 + i}:B{max_row + 5 + i}")
|
merge_cells.append(f"A{max_row + 5 + i}:B{max_row + 5 + i}")
|
||||||
|
|
||||||
format_requests.append({"unmergeCells": {"range": a1_range_to_grid_range(f"A1:{max_col}", worksheet.id)}})
|
format_requests.append({"unmergeCells": {"range": a1_range_to_grid_range("A1:AH", worksheet.id)}})
|
||||||
for name in merge_cells:
|
for name in merge_cells:
|
||||||
grid_range = a1_range_to_grid_range(name, worksheet.id)
|
grid_range = a1_range_to_grid_range(name, worksheet.id)
|
||||||
format_requests.append({"mergeCells": {"mergeType": MergeType.merge_all, "range": grid_range}})
|
format_requests.append({"mergeCells": {"mergeType": MergeType.merge_all, "range": grid_range}})
|
||||||
|
|
||||||
# Make titles bold
|
# Make titles bold
|
||||||
bold_ranges = [(f"A1:{max_col}", False), (f"A1:{max_col}3", True),
|
bold_ranges = [("A1:AH", False), ("A1:AH3", True),
|
||||||
(f"A{max_row + 1}:B{max_row + 3}", True), (f"A{max_row + 5}:E{max_row + 5}", True)]
|
(f"A{max_row + 1}:B{max_row + 3}", True), (f"A{max_row + 5}:E{max_row + 5}", True)]
|
||||||
for bold_range, bold in bold_ranges:
|
for bold_range, bold in bold_ranges:
|
||||||
format_requests.append({
|
format_requests.append({
|
||||||
|
@ -1406,7 +1399,7 @@ class Pool(models.Model):
|
||||||
})
|
})
|
||||||
|
|
||||||
# Set background color for headers and footers
|
# Set background color for headers and footers
|
||||||
bg_colors = [(f"A1:{max_col}", (1, 1, 1)),
|
bg_colors = [("A1:AH", (1, 1, 1)),
|
||||||
(f"A1:{getcol(2 + passages.count() * passage_width)}3", (0.8, 0.8, 0.8)),
|
(f"A1:{getcol(2 + passages.count() * passage_width)}3", (0.8, 0.8, 0.8)),
|
||||||
(f"A{min_row - 1}:B{max_row}", (0.95, 0.95, 0.95)),
|
(f"A{min_row - 1}:B{max_row}", (0.95, 0.95, 0.95)),
|
||||||
(f"A{max_row + 1}:B{max_row + 3}", (0.8, 0.8, 0.8)),
|
(f"A{max_row + 1}:B{max_row + 3}", (0.8, 0.8, 0.8)),
|
||||||
|
@ -1441,10 +1434,10 @@ class Pool(models.Model):
|
||||||
})
|
})
|
||||||
|
|
||||||
# Set the width of the columns
|
# Set the width of the columns
|
||||||
column_widths = [("A", 350), ("B", 30)]
|
column_widths = [("A", 300), ("B", 30)]
|
||||||
for passage in passages:
|
for passage in passages:
|
||||||
column_widths.append((f"{getcol(3 + passage_width * (passage.position - 1))}"
|
column_widths.append((f"{getcol(3 + passage_width * (passage.position - 1))}"
|
||||||
f":{getcol(2 + passage_width * passage.position)}", 80))
|
f":{getcol(8 + passage_width * (passage.position - 1))}", 75))
|
||||||
for column, width in column_widths:
|
for column, width in column_widths:
|
||||||
grid_range = a1_range_to_grid_range(column, worksheet.id)
|
grid_range = a1_range_to_grid_range(column, worksheet.id)
|
||||||
format_requests.append({
|
format_requests.append({
|
||||||
|
@ -1495,7 +1488,7 @@ class Pool(models.Model):
|
||||||
})
|
})
|
||||||
|
|
||||||
# Define borders
|
# Define borders
|
||||||
border_ranges = [(f"A1:{max_col}", "0000"),
|
border_ranges = [("A1:AH", "0000"),
|
||||||
(f"A1:{getcol(2 + passages.count() * passage_width)}{max_row + 3}", "1111"),
|
(f"A1:{getcol(2 + passages.count() * passage_width)}{max_row + 3}", "1111"),
|
||||||
(f"A{max_row + 5}:E{max_row + pool_size + 5}", "1111"),
|
(f"A{max_row + 5}:E{max_row + pool_size + 5}", "1111"),
|
||||||
(f"A1:B{max_row + 3}", "1113"),
|
(f"A1:B{max_row + 3}", "1113"),
|
||||||
|
@ -1541,8 +1534,8 @@ class Pool(models.Model):
|
||||||
"values": [{"userEnteredValue": f'=ET(REGEXMATCH(TO_TEXT({column}4); "^-?[0-9]+$"); '
|
"values": [{"userEnteredValue": f'=ET(REGEXMATCH(TO_TEXT({column}4); "^-?[0-9]+$"); '
|
||||||
f'{column}4>={min_note}; {column}4<={max_note})'},],
|
f'{column}4>={min_note}; {column}4<={max_note})'},],
|
||||||
},
|
},
|
||||||
"inputMessage": str(_("Input must be a valid integer between {min_note} and {max_note}.")
|
"inputMessage": (_("Input must be a valid integer between {min_note} and {max_note}.")
|
||||||
.format(min_note=min_note, max_note=max_note)),
|
.format(min_note=min_note, max_note=max_note)),
|
||||||
"strict": True,
|
"strict": True,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1570,15 +1563,15 @@ class Pool(models.Model):
|
||||||
})
|
})
|
||||||
|
|
||||||
# Protect the header, the juries list, the footer and the ranking
|
# Protect the header, the juries list, the footer and the ranking
|
||||||
protected_ranges = [f"A1:{max_col}4",
|
protected_ranges = ["A1:AH4",
|
||||||
f"A{min_row}:B{max_row}",
|
f"A{min_row}:B{max_row}",
|
||||||
f"A{max_row}:{max_col}{max_row + 5 + pool_size}"]
|
f"A{max_row}:AH{max_row + 5 + pool_size}"]
|
||||||
for protected_range in protected_ranges:
|
for protected_range in protected_ranges:
|
||||||
format_requests.append({
|
format_requests.append({
|
||||||
"addProtectedRange": {
|
"addProtectedRange": {
|
||||||
"protectedRange": {
|
"protectedRange": {
|
||||||
"range": a1_range_to_grid_range(protected_range, worksheet.id),
|
"range": a1_range_to_grid_range(protected_range, worksheet.id),
|
||||||
"description": str(_("Don't update the table structure for a better automated integration.")),
|
"description": _("Don't update the table structure for a better automated integration."),
|
||||||
"warningOnly": True,
|
"warningOnly": True,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1594,7 +1587,7 @@ class Pool(models.Model):
|
||||||
spreadsheet = gc.open_by_key(self.tournament.notes_sheet_id)
|
spreadsheet = gc.open_by_key(self.tournament.notes_sheet_id)
|
||||||
worksheet = spreadsheet.worksheet(f"{_('Pool')} {self.short_name}")
|
worksheet = spreadsheet.worksheet(f"{_('Pool')} {self.short_name}")
|
||||||
|
|
||||||
average_cell = worksheet.find(str(_("Average")))
|
average_cell = worksheet.find(_("Average"))
|
||||||
min_row = 5
|
min_row = 5
|
||||||
max_row = average_cell.row - 1
|
max_row = average_cell.row - 1
|
||||||
juries_visible = worksheet.get(f"A{min_row}:B{max_row}")
|
juries_visible = worksheet.get(f"A{min_row}:B{max_row}")
|
||||||
|
@ -1616,7 +1609,7 @@ class Pool(models.Model):
|
||||||
spreadsheet = gc.open_by_key(self.tournament.notes_sheet_id)
|
spreadsheet = gc.open_by_key(self.tournament.notes_sheet_id)
|
||||||
worksheet = spreadsheet.worksheet(f"{_('Pool')} {self.short_name}")
|
worksheet = spreadsheet.worksheet(f"{_('Pool')} {self.short_name}")
|
||||||
|
|
||||||
average_cell = worksheet.find(str(_("Average")))
|
average_cell = worksheet.find(_("Average"))
|
||||||
min_row = 5
|
min_row = 5
|
||||||
max_row = average_cell.row - 2
|
max_row = average_cell.row - 2
|
||||||
data = worksheet.get_values(f"A{min_row}:AH{max_row}")
|
data = worksheet.get_values(f"A{min_row}:AH{max_row}")
|
||||||
|
|
Loading…
Reference in New Issue