implement registering and unregistering from tournament
This commit is contained in:
parent
fffb607b16
commit
caacd8bbc1
@ -43,16 +43,28 @@ class TournamentDetailsPage(Component):
|
||||
self.loading = True
|
||||
if not self.user:
|
||||
return
|
||||
self.is_success = True
|
||||
self.message = f"Erfolgreich angemeldet!" # ToDo: Hook into Tournament Service
|
||||
|
||||
try:
|
||||
await self.session[TournamentService].register_user_for_tournament(self.user.user_id, self.tournament.id)
|
||||
self.is_success = True
|
||||
self.message = f"Erfolgreich angemeldet!"
|
||||
except Exception as e:
|
||||
self.is_success = False
|
||||
self.message = f"Fehler: {e}"
|
||||
self.loading = False
|
||||
|
||||
async def unregister_pressed(self) -> None:
|
||||
self.loading = True
|
||||
if not self.user:
|
||||
return
|
||||
self.is_success = True
|
||||
self.message = f"Erfolgreich abgemeldet!" # ToDo: Hook into Tournament Service
|
||||
|
||||
try:
|
||||
await self.session[TournamentService].unregister_user_from_tournament(self.user.user_id, self.tournament.id)
|
||||
self.is_success = True
|
||||
self.message = f"Erfolgreich abgemeldet!"
|
||||
except Exception as e:
|
||||
self.is_success = False
|
||||
self.message = f"Fehler: {e}"
|
||||
self.loading = False
|
||||
|
||||
async def tree_button_clicked(self) -> None:
|
||||
|
||||
@ -931,3 +931,37 @@ class DatabaseService:
|
||||
tournaments.append(current_tournament)
|
||||
|
||||
return tournaments
|
||||
|
||||
async def add_participant_to_tournament(self, participant: Participant, tournament: Tournament) -> None:
|
||||
async with self._connection_pool.acquire() as conn:
|
||||
async with conn.cursor(aiomysql.Cursor) as cursor:
|
||||
try:
|
||||
await cursor.execute(
|
||||
"INSERT INTO tournament_participants (tournament_id, user_id, participant_type) VALUES (%s, %s, %s);",
|
||||
(tournament.id, participant.id, participant.participant_type.name)
|
||||
)
|
||||
await conn.commit()
|
||||
except aiomysql.InterfaceError:
|
||||
pool_init_result = await self.init_db_pool()
|
||||
if not pool_init_result:
|
||||
raise NoDatabaseConnectionError
|
||||
return await self.add_participant_to_tournament(participant, tournament)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error adding participant to tournament: {e}")
|
||||
|
||||
async def remove_participant_from_tournament(self, participant: Participant, tournament: Tournament) -> None:
|
||||
async with self._connection_pool.acquire() as conn:
|
||||
async with conn.cursor(aiomysql.Cursor) as cursor:
|
||||
try:
|
||||
await cursor.execute(
|
||||
"DELETE FROM tournament_participants WHERE (tournament_id = %s AND user_id = %s);",
|
||||
(tournament.id, participant.id)
|
||||
)
|
||||
await conn.commit()
|
||||
except aiomysql.InterfaceError:
|
||||
pool_init_result = await self.init_db_pool()
|
||||
if not pool_init_result:
|
||||
raise NoDatabaseConnectionError
|
||||
return await self.remove_participant_from_tournament(participant, tournament)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error removing participant from tournament: {e}")
|
||||
|
||||
@ -1,76 +1,45 @@
|
||||
from asyncio import sleep
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from src.ezgg_lan_manager.services.DatabaseService import DatabaseService
|
||||
from src.ezgg_lan_manager.services.UserService import UserService
|
||||
from src.ezgg_lan_manager.types.Participant import Participant
|
||||
from src.ezgg_lan_manager.types.Tournament import Tournament
|
||||
from src.ezgg_lan_manager.types.TournamentBase import GameTitle, TournamentFormat, TournamentStatus, ParticipantType
|
||||
|
||||
DEV_LOREM_IPSUM = """
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Dieses LAN-Turnier bringt Spieler aus verschiedenen Regionen zusammen, um gemeinsam spannende Matches zu erleben. Tastaturen klappern, Monitore leuchten und die Stimmung ist von Anfang an von Vorfreude und Ehrgeiz geprägt.
|
||||
|
||||
Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. In intensiven Partien zählen Strategie, Reaktion und Teamarbeit. Zwischen den Spielen wird gefachsimpelt, gelacht und neue Kontakte entstehen, während Server stabil laufen und das Netzwerk dauerhaft gefordert ist.
|
||||
|
||||
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Wenn die Finalspiele beginnen, steigt die Spannung spürbar. Am Ende bleiben faire Wettkämpfe, gemeinsame Erinnerungen und das Gefühl, Teil einer starken Community gewesen zu sein.
|
||||
"""
|
||||
from src.ezgg_lan_manager.types.TournamentBase import ParticipantType, TournamentError
|
||||
|
||||
|
||||
class TournamentService:
|
||||
def __init__(self, db_service: DatabaseService, user_service: UserService) -> None:
|
||||
self._db_service = db_service
|
||||
self._user_service = user_service
|
||||
|
||||
# Crude cache mechanism. If performance suffers, maybe implement a queue with Single-Owner-Pattern or a Lock
|
||||
self._cache: dict[int, Tournament] = {}
|
||||
self._cache_dirty: bool = True # Setting this flag invokes cache update on next read
|
||||
|
||||
# This overrides the database access and is meant for easy development.
|
||||
# Set to None before merging back into main.
|
||||
self._dev_data = [
|
||||
Tournament(
|
||||
1,
|
||||
"Rocket League 3vs3",
|
||||
DEV_LOREM_IPSUM,
|
||||
GameTitle(
|
||||
"Rocket League",
|
||||
"Rocket League is a high-powered hybrid of arcade-style soccer and vehicular mayhem with easy-to-understand controls and fluid, physics-driven competition.",
|
||||
"https://steamcommunity.com/app/252950",
|
||||
"rl.png"
|
||||
),
|
||||
TournamentFormat.SINGLE_ELIMINATION_BO_3,
|
||||
datetime(2026, 5, 8, 18, 0, 0),
|
||||
TournamentStatus.OPEN,
|
||||
[Participant(30, ParticipantType.PLAYER)],
|
||||
None,
|
||||
[],
|
||||
8
|
||||
),
|
||||
Tournament(
|
||||
2,
|
||||
"Worms Armageddon 1vs1",
|
||||
DEV_LOREM_IPSUM,
|
||||
GameTitle(
|
||||
"Worms Armageddon",
|
||||
"2D turn-based artillery strategy game.",
|
||||
"https://store.steampowered.com/app/217200/Worms_Armageddon/",
|
||||
"worms.png"
|
||||
),
|
||||
TournamentFormat.SINGLE_ELIMINATION_BO_1,
|
||||
datetime(2026, 5, 8, 18, 30, 0),
|
||||
TournamentStatus.CLOSED,
|
||||
[],
|
||||
None,
|
||||
[],
|
||||
16
|
||||
)
|
||||
]
|
||||
|
||||
async def _update_cache(self) -> None:
|
||||
tournaments = await self._db_service.get_all_tournaments()
|
||||
for tournament in tournaments:
|
||||
self._cache[tournament.id] = tournament
|
||||
self._cache_dirty = False
|
||||
|
||||
async def register_user_for_tournament(self, user_id: int, tournament_id: int) -> None:
|
||||
tournament = await self.get_tournament_by_id(tournament_id)
|
||||
if not tournament:
|
||||
raise TournamentError(f"No tournament with ID {tournament_id} was found")
|
||||
participant = Participant(id_=user_id, participant_type=ParticipantType.PLAYER)
|
||||
tournament.add_participant(participant)
|
||||
await self._db_service.add_participant_to_tournament(participant, tournament)
|
||||
self._cache_dirty = True
|
||||
|
||||
async def unregister_user_from_tournament(self, user_id: int, tournament_id: int) -> None:
|
||||
tournament = await self.get_tournament_by_id(tournament_id)
|
||||
if not tournament:
|
||||
raise TournamentError(f"No tournament with ID {tournament_id} was found")
|
||||
participant = next(filter(lambda p: p.id == user_id, tournament.participants), None)
|
||||
if participant is not None:
|
||||
tournament.remove_participant(participant)
|
||||
await self._db_service.remove_participant_from_tournament(participant, tournament)
|
||||
self._cache_dirty = True
|
||||
|
||||
async def get_tournaments(self) -> list[Tournament]:
|
||||
if self._cache_dirty:
|
||||
|
||||
@ -90,6 +90,10 @@ class Tournament:
|
||||
raise TournamentError(f"Participant with ID {participant.id} already registered for tournament")
|
||||
self._participants.append(participant)
|
||||
|
||||
def remove_participant(self, participant: Participant) -> None:
|
||||
if participant.id not in (p.id for p in self._participants):
|
||||
raise TournamentError(f"Participant with ID {participant.id} not registered for tournament")
|
||||
self._participants.remove(participant)
|
||||
|
||||
def match_has_ended_callback(self, match: Match) -> None:
|
||||
if self._matches is None:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user