Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow restriction of tournaments on results screens #35

Merged
merged 8 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions common/config_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class ConfigReader(ConfigParser):
'update',
'show_unpaired',
'limit',
'tournaments',
]

def __init__(self, ini_file: Path, ini_marker_file: Path, silent: bool):
Expand Down
24 changes: 19 additions & 5 deletions data/screen.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import json
from typing import Self
from typing import Self, Unpack
import warnings
from contextlib import suppress
from dataclasses import dataclass, field
Expand Down Expand Up @@ -194,10 +194,11 @@ def show_unpaired(self) -> bool:
class ResultsScreen(AScreen):
def __init__(
self, event_id: str, screen_id: str, family_id: str | None, name: str, columns: int,
menu_text: str | None, menu: str, show_timer: bool, limit: int):
menu_text: str | None, menu: str, show_timer: bool, limit: int, *tournaments: Unpack[str]):
super().__init__(event_id, screen_id, family_id, name, columns, menu_text, menu, show_timer)
self._type = ScreenType.Results
self.limit: int = limit
self.tournaments = tuple(tournaments)

@property
def type_str(self) -> str:
Expand All @@ -211,7 +212,7 @@ def icon_str(self) -> str:
def results_lists(self) -> list[list[Result]]:
with EventDatabase(self.event_id, 'r') as event_database:
event_database: EventDatabase
results: list[Result] = event_database.get_results(self.limit)
results: list[Result] = event_database.get_results(self.limit, *self.tournaments)
results_by_column: list[list[Result]] = []
column_size: int = (self.limit if self.limit else len(results)) // self.columns
for i in range(self.columns):
Expand Down Expand Up @@ -377,7 +378,7 @@ def _build_screen(self, screen_id: str) -> AScreen | None:
key = 'record_illegal_moves'
if key in screen_section:
self._config_reader.add_warning(
f"l'option doit désormais être utilisée dans les rubriques des tournois, ignorée",
"l'option doit désormais être utilisée dans les rubriques des tournois, ignorée",
screen_section_key, key)
key = 'show_unpaired'
default_show_unpaired: bool = DEFAULT_SHOW_UNPAIRED
Expand Down Expand Up @@ -413,6 +414,18 @@ def _build_screen(self, screen_id: str) -> AScreen | None:
self._config_reader.add_warning(
f"l'option n'est pas autorisée pour les écrans de type [{screen_type}], ignorée",
screen_section_key, key)
key = 'tournaments'
tournaments: list[str] = []
if screen_type == ScreenType.Results:
tournaments_str: str | None = screen_section.get(key)
if tournaments_str is not None:
tournaments = [tournament_name.strip() for tournament_name in tournaments_str.split(',')]
else:
if key in screen_section:
self._config_reader.add_warning(
f"l'option n'est pas autorisée pour les écrans de type [{screen_type}], ignorée",
screen_section_key, key)

screen_sets: list[ScreenSet] | None = None
if screen_type in [ScreenType.Boards, ScreenType.Players, ]:
screen_sets = ScreenSetBuilder(
Expand Down Expand Up @@ -475,7 +488,8 @@ def _build_screen(self, screen_id: str) -> AScreen | None:
menu_text,
menu,
show_timer,
limit
limit,
*tournaments
)
screen_file_dependencies += [tournament.file for tournament in self._tournaments.values()]
screen.set_file_dependencies(screen_file_dependencies, )
Expand Down
39 changes: 31 additions & 8 deletions database/sqlite.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from logging import Logger
from pathlib import Path
from sqlite3 import Connection, Cursor, connect, OperationalError
from typing import Self, Any
from typing import Self, Any, Unpack

from packaging.version import Version

Expand Down Expand Up @@ -206,13 +206,36 @@ def delete_result(self, tournament_id: str, round: int, board_id: int):
(tournament_id, round, board_id),
)

def get_results(self, limit: int) -> list[DataResult]:
query: str = ('SELECT `tournament_id`, `round`, `board_id`, `white_player`, `black_player`, `date`, `value` '
'FROM `result` ORDER BY `date` DESC')
params: tuple = ()
if limit:
query += ' LIMIT ?'
params = (limit, )
def get_results(self, limit: int, *tournaments: Unpack[str]) -> list[DataResult]:
if not tournaments:
query: str = ('SELECT `tournament_id`, `round`, `board_id`, `white_player`, `black_player`, `date`, `value` '
'FROM `result` ORDER BY `date` DESC')
params: tuple = ()
if limit:
query += ' LIMIT ?'
params = (limit, )
elif len(tournaments) == 1:
query: str = ('SELECT `tournament_id`, `round`, `board_id`, `white_player`, `black_player`, `date`, `value` '
'FROM `result` WHERE `tournament_id` = ? ORDER BY `date` DESC')
params = (tournaments[0], )
if limit:
query += ' LIMIT ?'
params += (limit, )
else:
query_parts: list[str] = []
params: tuple = ()
for tournament in tournaments:
query_part: str = ('SELECT `tournament_id`, `round`, `board_id`, `white_player`, `black_player`, `date`, `value` '
'FROM `result` WHERE `tournament_id` = ? ORDER BY `date` DESC')
params += (tournament, )
if limit:
query_part += ' LIMIT ?'
params += (limit, )
query_parts.append('\n'.join(('SELECT * FROM (', query_part, ')')))
query: str = '\nUNION\n'.join(query_parts) + ' ORDER BY `date` DESC'
if limit:
query += ' LIMIT ?'
params += (limit, )
Comment on lines +226 to +239
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check if IN (?, ?, ...) pattern is possible in SQLITE prepared statements

self._execute(query, params)
results: list[DataResult] = []
for row in self._fetchall():
Expand Down
15 changes: 14 additions & 1 deletion docs/24-last-results.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,21 @@ limit = 30

Le paramètre `limit` permet de limiter le nombre de résultats affichés (ici 30).

## Limitation des tournois dans les écrans de résultats

Dans le cas où un écran de résultats est affiché aux spectateurs, il peut être appréciable de scinder cet écran pour ne montrer que les résultats d'un ou plusieurs tournois. Pour un événement comprenant 3 tournois (`a`, `b` et `jeunes`), il est possible de définir deux écrans de résultats, un nommé `résultats-tc` (tournois `a` et `b`), et un autre nommé `résultats-j` (tournoi jeunes) de cette manière :
Amaras marked this conversation as resolved.
Show resolved Hide resolved
```
[screen.résultats-tc]
type = results
tournaments = a, b

[screen.résultats-j]
type = results
tournaments = j
```

> [!NOTE]
> - les résultats de tous les tournois sont affichés sur les écrans de résultats ;
> - par défaut, les résultats de tous les tournois sont affichés sur les écrans de résultats ;
> - les résultats sont conservés au maximum une heure sur le serveur.

> [!NOTE]
Expand Down
1 change: 1 addition & 0 deletions docs/40-ref.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ L'identifiant de l'écran (`<screen_id>`) est obligatoire.
| `show_timer` | `show_timer = on` pour afficher le chronomètre, `show_timer = off` sinon (facultatif, par défaut `show_timer = on`). |
| `limit` | Le nombre maximal de résultats affichés (cette option n'est autorisée que pour les écrans de résultats). |
| `columns` | Le nombre de colonnes utilisé pour le rendu de l'écran (facultatif, par défaut `1`). |
| `tournaments` | La liste des tournois dont les résultats sont affichés, séparée par des virgules (cette option n'est autorisée que pour les écrans de résultats). |

Voir également :
- [Saisie des résultats](21-update.md)
Expand Down
2 changes: 1 addition & 1 deletion docs/99-todo.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
- [ ] Envoi des appariements aux joueur·euses par mél et texto (PL)
- [ ] Prise en charge de la méthode HEAD pour les afficheurs dynamiques (PA)
- [ ] Limiter le temps d'affichage des résultats sur les écrans de type `results` (SP)
- [ ] Restreindre les tournois sur les écrans de type `results` (SP)
- [ ] Ajouter une barre de recherche sur les écrans de type `results` pour les arbitres (SP)
- [ ] Ajouter la possibilité de supprimer des résultats depuis les écrans de type `results` pour les arbitres (SP)
- [ ] Ajouter la possibilité d'afficher des tables fixes sur des écrans particuliers sur les écrans de type `boards` (SP)
- [x] ~~Affichage du statut pointé·e/non pointé·e des joueur·euses avant l'affichage de la première ronde (ajouté en version 2.2)~~
- [x] ~~Enregistrement des coups illégaux des joueur·euses (ajouté en version 2.2)~~
- [x] ~~Spécification d'un nombre donné d'échiquiers/joueur·euses par écran (KB, ajouté en version 2.1)~~
- [x] ~~Ajout de l'affichage des appariements par ordre alphabétique (PL, ajouté en version 2.0)~~
- [x] ~~Restreindre les tournois sur les écrans de type `results` (SP, ajouté en version 2.4)~~

## Autres réflexions en cours

Expand Down
Loading