implement Details View UI for tournaments
This commit is contained in:
parent
b6ef2b5995
commit
1137a9e7c7
33
src/ezgg_lan_manager/components/TournamentDetailsInfoRow.py
Normal file
33
src/ezgg_lan_manager/components/TournamentDetailsInfoRow.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from rio import Component, Row, Text, TextStyle, Color
|
||||||
|
|
||||||
|
|
||||||
|
class TournamentDetailsInfoRow(Component):
|
||||||
|
key: str
|
||||||
|
value: str
|
||||||
|
color: Optional[Color] = None
|
||||||
|
|
||||||
|
def build(self) -> Component:
|
||||||
|
return Row(
|
||||||
|
Text(
|
||||||
|
text=self.key,
|
||||||
|
style=TextStyle(
|
||||||
|
fill=self.session.theme.background_color,
|
||||||
|
font_size=1
|
||||||
|
),
|
||||||
|
margin_bottom=0.5,
|
||||||
|
align_x=0
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
text=self.value,
|
||||||
|
style=TextStyle(
|
||||||
|
fill=self.color if self.color is not None else self.session.theme.background_color,
|
||||||
|
font_size=1
|
||||||
|
),
|
||||||
|
margin_bottom=0.5,
|
||||||
|
align_x=1
|
||||||
|
),
|
||||||
|
margin_left=4,
|
||||||
|
margin_right=4
|
||||||
|
)
|
||||||
@ -1,16 +1,26 @@
|
|||||||
from typing import Optional
|
from typing import Optional, Union, Literal
|
||||||
|
|
||||||
from rio import Column, Component, event, TextStyle, Text, Rectangle, Row, Image, Icon, Tooltip, Spacer, Color, PointerEventListener, ProgressCircle
|
from from_root import from_root
|
||||||
|
from rio import Column, Component, event, TextStyle, Text, Row, Image, Spacer, ProgressCircle, Button, Checkbox, ThemeContextSwitcher, Link
|
||||||
|
|
||||||
from src.ezgg_lan_manager import ConfigurationService, TournamentService
|
from src.ezgg_lan_manager import ConfigurationService, TournamentService, UserService
|
||||||
from src.ezgg_lan_manager.components.MainViewContentBox import MainViewContentBox
|
from src.ezgg_lan_manager.components.MainViewContentBox import MainViewContentBox
|
||||||
from src.ezgg_lan_manager.components.TournamentPageRow import TournamentPageRow
|
from src.ezgg_lan_manager.components.TournamentDetailsInfoRow import TournamentDetailsInfoRow
|
||||||
|
from src.ezgg_lan_manager.types.DateUtil import weekday_to_display_text
|
||||||
|
from src.ezgg_lan_manager.types.SessionStorage import SessionStorage
|
||||||
from src.ezgg_lan_manager.types.Tournament import Tournament
|
from src.ezgg_lan_manager.types.Tournament import Tournament
|
||||||
from src.ezgg_lan_manager.types.TournamentBase import TournamentStatus
|
from src.ezgg_lan_manager.types.TournamentBase import TournamentStatus, tournament_status_to_display_text, tournament_format_to_display_texts
|
||||||
|
from src.ezgg_lan_manager.types.User import User
|
||||||
|
|
||||||
|
|
||||||
class TournamentDetailsPage(Component):
|
class TournamentDetailsPage(Component):
|
||||||
tournament: Optional[Tournament] = None
|
tournament: Optional[Union[Tournament, str]] = None
|
||||||
|
rules_accepted: bool = False
|
||||||
|
user: Optional[User] = None
|
||||||
|
loading: bool = False
|
||||||
|
# State for message above register button
|
||||||
|
message: str = ""
|
||||||
|
is_success: bool = False
|
||||||
|
|
||||||
@event.on_populate
|
@event.on_populate
|
||||||
async def on_populate(self) -> None:
|
async def on_populate(self) -> None:
|
||||||
@ -20,44 +30,166 @@ class TournamentDetailsPage(Component):
|
|||||||
tournament_id = None
|
tournament_id = None
|
||||||
if tournament_id is not None:
|
if tournament_id is not None:
|
||||||
self.tournament = await self.session[TournamentService].get_tournament_by_id(tournament_id)
|
self.tournament = await self.session[TournamentService].get_tournament_by_id(tournament_id)
|
||||||
await self.session.set_title(f"{self.session[ConfigurationService].get_lan_info().name} - {self.tournament.name}")
|
if self.tournament is not None:
|
||||||
|
await self.session.set_title(f"{self.session[ConfigurationService].get_lan_info().name} - {self.tournament.name}")
|
||||||
else:
|
else:
|
||||||
await self.session.set_title(f"{self.session[ConfigurationService].get_lan_info().name} - Turniere")
|
await self.session.set_title(f"{self.session[ConfigurationService].get_lan_info().name} - Turniere")
|
||||||
|
|
||||||
|
self.user = await self.session[UserService].get_user(self.session[SessionStorage].user_id)
|
||||||
|
|
||||||
|
self.loading_done()
|
||||||
|
|
||||||
|
async def register_pressed(self) -> None:
|
||||||
|
self.loading = True
|
||||||
|
if not self.user:
|
||||||
|
return
|
||||||
|
self.is_success = True
|
||||||
|
self.message = f"Erfolgreich angemeldet!" # ToDo: Hook into Tournament Service
|
||||||
|
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
|
||||||
|
self.loading = False
|
||||||
|
|
||||||
|
def loading_done(self) -> None:
|
||||||
|
if self.tournament is None:
|
||||||
|
self.tournament = "Turnier konnte nicht gefunden werden"
|
||||||
|
self.session[SessionStorage].subscribe_to_logged_in_or_out_event(str(self.__class__), self.on_populate)
|
||||||
|
|
||||||
def build(self) -> Component:
|
def build(self) -> Component:
|
||||||
if not self.tournament:
|
if self.tournament is None:
|
||||||
return Column(
|
content = Column(
|
||||||
MainViewContentBox(
|
ProgressCircle(
|
||||||
Column(
|
color="secondary",
|
||||||
Column(
|
align_x=0.5,
|
||||||
ProgressCircle(
|
margin_top=0,
|
||||||
color="secondary",
|
margin_bottom=0
|
||||||
align_x=0.5,
|
|
||||||
margin_top=0,
|
|
||||||
margin_bottom=0
|
|
||||||
),
|
|
||||||
min_height=10
|
|
||||||
),
|
|
||||||
Spacer(min_height=1)
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
align_y = 0
|
min_height=10
|
||||||
)
|
)
|
||||||
|
elif isinstance(self.tournament, str):
|
||||||
|
content = Row(
|
||||||
|
Text(
|
||||||
|
text=self.tournament,
|
||||||
|
style=TextStyle(
|
||||||
|
fill=self.session.theme.background_color,
|
||||||
|
font_size=1
|
||||||
|
),
|
||||||
|
margin_top=2,
|
||||||
|
margin_bottom=2,
|
||||||
|
align_x=0.5
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
tournament_status_color = self.session.theme.background_color
|
||||||
|
if self.tournament.status == TournamentStatus.OPEN:
|
||||||
|
tournament_status_color = self.session.theme.success_color
|
||||||
|
elif self.tournament.status == TournamentStatus.CLOSED:
|
||||||
|
tournament_status_color = self.session.theme.danger_color
|
||||||
|
elif self.tournament.status == TournamentStatus.ONGOING:
|
||||||
|
tournament_status_color = self.session.theme.warning_color
|
||||||
|
|
||||||
return Column(
|
|
||||||
MainViewContentBox(
|
# ToDo: Integrate Teams logic
|
||||||
Column(
|
ids_of_participants = [p.id for p in self.tournament.participants]
|
||||||
|
color_key: Literal["hud", "danger"] = "hud"
|
||||||
|
on_press_function = self.register_pressed
|
||||||
|
if self.user and self.user.user_id in ids_of_participants: # User already registered for tournament
|
||||||
|
button_text = "Abmelden"
|
||||||
|
button_sensitive_hook = True # User has already accepted the rules previously
|
||||||
|
color_key = "danger"
|
||||||
|
on_press_function = self.unregister_pressed
|
||||||
|
elif self.user and self.user.user_id not in ids_of_participants:
|
||||||
|
button_text = "Anmelden"
|
||||||
|
button_sensitive_hook = self.rules_accepted
|
||||||
|
else:
|
||||||
|
# This should NEVER happen
|
||||||
|
button_text = "Anmelden"
|
||||||
|
button_sensitive_hook = False
|
||||||
|
|
||||||
|
if self.tournament.status != TournamentStatus.OPEN or self.tournament.is_full:
|
||||||
|
button_sensitive_hook = False # Override button controls if tournament is not open anymore or full
|
||||||
|
|
||||||
|
if self.user:
|
||||||
|
accept_rules_row = Row(
|
||||||
|
ThemeContextSwitcher(content=Checkbox(is_on=self.bind().rules_accepted, margin_left=4), color=self.session.theme.hud_color),
|
||||||
|
Text("Ich akzeptiere die ", margin_left=1, style=TextStyle(fill=self.session.theme.background_color, font_size=0.8), overflow="nowrap", justify="right"),
|
||||||
|
Link(Text("Turnierregeln", margin_right=4, style=TextStyle(fill=self.session.theme.background_color, font_size=0.8, italic=True), overflow="nowrap", justify="left"), "https://google.de") # ToDo: Add rules
|
||||||
|
)
|
||||||
|
button = Button(
|
||||||
|
content=button_text,
|
||||||
|
shape="rectangle",
|
||||||
|
style="major",
|
||||||
|
color=color_key,
|
||||||
|
margin_left=2,
|
||||||
|
margin_right=2,
|
||||||
|
is_sensitive=button_sensitive_hook,
|
||||||
|
on_press=on_press_function,
|
||||||
|
is_loading=self.loading
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# No UI here if user not logged in
|
||||||
|
accept_rules_row, button = Spacer(), Spacer()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
content = Column(
|
||||||
|
Row(
|
||||||
|
Image(image=from_root(f"src/ezgg_lan_manager/assets/img/games/{self.tournament.game_title.image_name}")),
|
||||||
Text(
|
Text(
|
||||||
text=self.tournament.name,
|
text=self.tournament.name,
|
||||||
style=TextStyle(
|
style=TextStyle(
|
||||||
fill=self.session.theme.background_color,
|
fill=self.session.theme.background_color,
|
||||||
font_size=1.2
|
font_size=1.2
|
||||||
),
|
),
|
||||||
margin_top=2,
|
margin_top=1,
|
||||||
margin_bottom=2,
|
margin_bottom=1,
|
||||||
align_x=0.5
|
align_x=0.5
|
||||||
),
|
),
|
||||||
|
margin_right=6,
|
||||||
|
margin_left=6
|
||||||
|
),
|
||||||
|
Spacer(min_height=1),
|
||||||
|
TournamentDetailsInfoRow("Status", tournament_status_to_display_text(self.tournament.status), tournament_status_color),
|
||||||
|
TournamentDetailsInfoRow("Startzeit", f"{weekday_to_display_text(self.tournament.start_time.weekday())}, {self.tournament.start_time.strftime('%H:%M')} Uhr"),
|
||||||
|
TournamentDetailsInfoRow("Format", tournament_format_to_display_texts(self.tournament.format)[0]),
|
||||||
|
TournamentDetailsInfoRow("Best of", tournament_format_to_display_texts(self.tournament.format)[1]),
|
||||||
|
TournamentDetailsInfoRow(
|
||||||
|
"Teilnehmer",
|
||||||
|
f"{len(self.tournament.participants)} / {self.tournament.max_participants}",
|
||||||
|
self.session.theme.danger_color if self.tournament.is_full else self.session.theme.background_color
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
Text(
|
||||||
|
text="Info",
|
||||||
|
style=TextStyle(
|
||||||
|
fill=self.session.theme.background_color,
|
||||||
|
font_size=1.2
|
||||||
|
),
|
||||||
|
margin_top=1,
|
||||||
|
margin_bottom=1,
|
||||||
|
align_x=0.5
|
||||||
|
)
|
||||||
|
),
|
||||||
|
# FixMe: Use rio.Markdown with correct TextStyle instead to allow basic text formatting from DB-side.
|
||||||
|
Text(self.tournament.description, margin_left=2, margin_right=2, style=TextStyle(fill=self.session.theme.background_color, font_size=1), overflow="wrap"),
|
||||||
|
Spacer(min_height=2),
|
||||||
|
accept_rules_row,
|
||||||
|
Spacer(min_height=0.5),
|
||||||
|
Text(self.message, margin_left=2, margin_right=2, style=TextStyle(fill=self.session.theme.success_color if self.is_success else self.session.theme.danger_color, font_size=1), overflow="wrap", justify="center"),
|
||||||
|
Spacer(min_height=0.5),
|
||||||
|
button
|
||||||
|
)
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
MainViewContentBox(
|
||||||
|
Column(
|
||||||
|
Spacer(min_height=1),
|
||||||
|
content,
|
||||||
Spacer(min_height=1)
|
Spacer(min_height=1)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|||||||
@ -4,8 +4,17 @@ from typing import Optional
|
|||||||
|
|
||||||
from src.ezgg_lan_manager.services.DatabaseService import DatabaseService
|
from src.ezgg_lan_manager.services.DatabaseService import DatabaseService
|
||||||
from src.ezgg_lan_manager.services.UserService import UserService
|
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.Tournament import Tournament
|
||||||
from src.ezgg_lan_manager.types.TournamentBase import GameTitle, TournamentFormat, TournamentStatus
|
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.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class TournamentService:
|
class TournamentService:
|
||||||
@ -19,6 +28,7 @@ class TournamentService:
|
|||||||
Tournament(
|
Tournament(
|
||||||
0,
|
0,
|
||||||
"Teeworlds 2vs2",
|
"Teeworlds 2vs2",
|
||||||
|
DEV_LOREM_IPSUM,
|
||||||
GameTitle(
|
GameTitle(
|
||||||
"Teeworlds",
|
"Teeworlds",
|
||||||
"Teeworlds is a free online multiplayer game, available for all major operating systems. Battle with up to 16 players in a variety of game modes.",
|
"Teeworlds is a free online multiplayer game, available for all major operating systems. Battle with up to 16 players in a variety of game modes.",
|
||||||
@ -36,6 +46,7 @@ class TournamentService:
|
|||||||
Tournament(
|
Tournament(
|
||||||
1,
|
1,
|
||||||
"Rocket League 3vs3",
|
"Rocket League 3vs3",
|
||||||
|
DEV_LOREM_IPSUM,
|
||||||
GameTitle(
|
GameTitle(
|
||||||
"Rocket League",
|
"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.",
|
"Rocket League is a high-powered hybrid of arcade-style soccer and vehicular mayhem with easy-to-understand controls and fluid, physics-driven competition.",
|
||||||
@ -45,7 +56,7 @@ class TournamentService:
|
|||||||
TournamentFormat.SINGLE_ELIMINATION_BO_3,
|
TournamentFormat.SINGLE_ELIMINATION_BO_3,
|
||||||
datetime(2026, 5, 8, 18, 0, 0),
|
datetime(2026, 5, 8, 18, 0, 0),
|
||||||
TournamentStatus.OPEN,
|
TournamentStatus.OPEN,
|
||||||
[],
|
[Participant(30, "Typhus", ParticipantType.PLAYER)],
|
||||||
None,
|
None,
|
||||||
[],
|
[],
|
||||||
8
|
8
|
||||||
@ -53,6 +64,7 @@ class TournamentService:
|
|||||||
Tournament(
|
Tournament(
|
||||||
2,
|
2,
|
||||||
"Worms Armageddon 1vs1",
|
"Worms Armageddon 1vs1",
|
||||||
|
DEV_LOREM_IPSUM,
|
||||||
GameTitle(
|
GameTitle(
|
||||||
"Worms Armageddon",
|
"Worms Armageddon",
|
||||||
"2D turn-based artillery strategy game.",
|
"2D turn-based artillery strategy game.",
|
||||||
@ -61,7 +73,7 @@ class TournamentService:
|
|||||||
),
|
),
|
||||||
TournamentFormat.SINGLE_ELIMINATION_BO_1,
|
TournamentFormat.SINGLE_ELIMINATION_BO_1,
|
||||||
datetime(2026, 5, 8, 18, 30, 0),
|
datetime(2026, 5, 8, 18, 30, 0),
|
||||||
TournamentStatus.OPEN,
|
TournamentStatus.CLOSED,
|
||||||
[],
|
[],
|
||||||
None,
|
None,
|
||||||
[],
|
[],
|
||||||
|
|||||||
15
src/ezgg_lan_manager/types/DateUtil.py
Normal file
15
src/ezgg_lan_manager/types/DateUtil.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
def weekday_to_display_text(weekday: int) -> str:
|
||||||
|
if weekday == 0:
|
||||||
|
return "Montag"
|
||||||
|
elif weekday == 1:
|
||||||
|
return "Dienstag"
|
||||||
|
elif weekday == 2:
|
||||||
|
return "Mittwoch"
|
||||||
|
elif weekday == 3:
|
||||||
|
return "Donnerstag"
|
||||||
|
elif weekday == 4:
|
||||||
|
return "Freitag"
|
||||||
|
elif weekday == 5:
|
||||||
|
return "Samstag"
|
||||||
|
else:
|
||||||
|
return "Sonntag"
|
||||||
@ -12,6 +12,7 @@ class Tournament:
|
|||||||
def __init__(self,
|
def __init__(self,
|
||||||
id_: int,
|
id_: int,
|
||||||
name: str,
|
name: str,
|
||||||
|
description: str,
|
||||||
game_title: GameTitle,
|
game_title: GameTitle,
|
||||||
format_: TournamentFormat,
|
format_: TournamentFormat,
|
||||||
start_time: datetime,
|
start_time: datetime,
|
||||||
@ -22,6 +23,7 @@ class Tournament:
|
|||||||
max_participants: int) -> None:
|
max_participants: int) -> None:
|
||||||
self._id = id_
|
self._id = id_
|
||||||
self._name = name
|
self._name = name
|
||||||
|
self._description = description
|
||||||
self._game_title = game_title
|
self._game_title = game_title
|
||||||
self._format = format_
|
self._format = format_
|
||||||
self._start_time = start_time
|
self._start_time = start_time
|
||||||
@ -75,6 +77,14 @@ class Tournament:
|
|||||||
def max_participants(self) -> int:
|
def max_participants(self) -> int:
|
||||||
return self._max_participants
|
return self._max_participants
|
||||||
|
|
||||||
|
@property
|
||||||
|
def description(self) -> str:
|
||||||
|
return self._description
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_full(self) -> bool:
|
||||||
|
return len(self._participants) >= self._max_participants
|
||||||
|
|
||||||
def add_participant(self, participant: Participant) -> None:
|
def add_participant(self, participant: Participant) -> None:
|
||||||
if participant.id in (p.id for p in self._participants):
|
if participant.id in (p.id for p in self._participants):
|
||||||
raise TournamentError(f"Participant with ID {participant.id} already registered for tournament")
|
raise TournamentError(f"Participant with ID {participant.id} already registered for tournament")
|
||||||
@ -310,16 +320,18 @@ class Tournament:
|
|||||||
match.check_completion()
|
match.check_completion()
|
||||||
|
|
||||||
|
|
||||||
def generate_new_tournament(name: str, game_title: GameTitle, format_: TournamentFormat, start_time: datetime, initial_status: TournamentStatus = TournamentStatus.CLOSED) -> Tournament:
|
def generate_new_tournament(name: str, description: str, game_title: GameTitle, format_: TournamentFormat, start_time: datetime, max_participants: int, initial_status: TournamentStatus = TournamentStatus.CLOSED) -> Tournament:
|
||||||
id_ = uuid.uuid4().int
|
id_ = uuid.uuid4().int
|
||||||
return Tournament(
|
return Tournament(
|
||||||
id_,
|
id_,
|
||||||
name,
|
name,
|
||||||
|
description,
|
||||||
game_title,
|
game_title,
|
||||||
format_,
|
format_,
|
||||||
start_time,
|
start_time,
|
||||||
initial_status,
|
initial_status,
|
||||||
list(),
|
list(),
|
||||||
None,
|
None,
|
||||||
list()
|
list(),
|
||||||
|
max_participants
|
||||||
)
|
)
|
||||||
|
|||||||
@ -17,6 +17,23 @@ class TournamentFormat(Enum):
|
|||||||
DOUBLE_ELIMINATION_BO_3 = 5
|
DOUBLE_ELIMINATION_BO_3 = 5
|
||||||
DOUBLE_ELIMINATION_BO_5 = 6
|
DOUBLE_ELIMINATION_BO_5 = 6
|
||||||
|
|
||||||
|
def tournament_format_to_display_texts(tournament_format: TournamentFormat) -> tuple[str, str]:
|
||||||
|
""" Returns tuple where idx 0 is SE/DE string and idx 1 is match count """
|
||||||
|
if tournament_format == TournamentFormat.SINGLE_ELIMINATION_BO_1:
|
||||||
|
return "Single Elimination", "1"
|
||||||
|
elif tournament_format == TournamentFormat.SINGLE_ELIMINATION_BO_3:
|
||||||
|
return "Single Elimination", "3"
|
||||||
|
elif tournament_format == TournamentFormat.SINGLE_ELIMINATION_BO_5:
|
||||||
|
return "Single Elimination", "5"
|
||||||
|
elif tournament_format == TournamentFormat.DOUBLE_ELIMINATION_BO_1:
|
||||||
|
return "Double Elimination", "1"
|
||||||
|
elif tournament_format == TournamentFormat.DOUBLE_ELIMINATION_BO_3:
|
||||||
|
return "Double Elimination", "3"
|
||||||
|
elif tournament_format == TournamentFormat.DOUBLE_ELIMINATION_BO_5:
|
||||||
|
return "Double Elimination", "5"
|
||||||
|
else:
|
||||||
|
raise RuntimeError(f"Unknown tournament status: {str(tournament_format)}")
|
||||||
|
|
||||||
|
|
||||||
class TournamentStatus(Enum):
|
class TournamentStatus(Enum):
|
||||||
CLOSED = 1
|
CLOSED = 1
|
||||||
@ -26,6 +43,22 @@ class TournamentStatus(Enum):
|
|||||||
INVITE_ONLY = 5 # For Show-matches
|
INVITE_ONLY = 5 # For Show-matches
|
||||||
ONGOING = 6
|
ONGOING = 6
|
||||||
|
|
||||||
|
def tournament_status_to_display_text(tournament_status: TournamentStatus) -> str:
|
||||||
|
if tournament_status == TournamentStatus.OPEN:
|
||||||
|
return "Offen"
|
||||||
|
elif tournament_status == TournamentStatus.CLOSED:
|
||||||
|
return "Geschlossen"
|
||||||
|
elif tournament_status == TournamentStatus.ONGOING:
|
||||||
|
return "Läuft"
|
||||||
|
elif tournament_status == TournamentStatus.COMPLETED:
|
||||||
|
return "Abgeschlossen"
|
||||||
|
elif tournament_status == TournamentStatus.CANCELED:
|
||||||
|
return "Abgesagt"
|
||||||
|
elif tournament_status == TournamentStatus.INVITE_ONLY:
|
||||||
|
return "Invite-only"
|
||||||
|
else:
|
||||||
|
raise RuntimeError(f"Unknown tournament status: {str(tournament_status)}")
|
||||||
|
|
||||||
|
|
||||||
class TournamentError(Exception):
|
class TournamentError(Exception):
|
||||||
def __init__(self, message: str) -> None:
|
def __init__(self, message: str) -> None:
|
||||||
|
|||||||
@ -9,7 +9,8 @@ class TournamentDomainTests(unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
# Generic Tournament config
|
# Generic Tournament config
|
||||||
self.name = "Tetris 1vs1"
|
self.name = "Tetris 1vs1"
|
||||||
self.game_title = GameTitle("Tetris99", "Some Description", "https://de.wikipedia.org/wiki/Tetris_99")
|
self.description = "Just play Tetris, yo"
|
||||||
|
self.game_title = GameTitle("Tetris99", "Some Description", "https://de.wikipedia.org/wiki/Tetris_99", "tetris.png")
|
||||||
self.format_ = TournamentFormat.SINGLE_ELIMINATION_BO_3
|
self.format_ = TournamentFormat.SINGLE_ELIMINATION_BO_3
|
||||||
self.start_time = datetime(year=2100, month=6, day=23, hour=16, minute=30, second=0)
|
self.start_time = datetime(year=2100, month=6, day=23, hour=16, minute=30, second=0)
|
||||||
self.initial_status = TournamentStatus.CLOSED
|
self.initial_status = TournamentStatus.CLOSED
|
||||||
@ -20,18 +21,18 @@ class TournamentDomainTests(unittest.TestCase):
|
|||||||
self.participant_c = Participant(3, "FunnyUserName", ParticipantType.PLAYER)
|
self.participant_c = Participant(3, "FunnyUserName", ParticipantType.PLAYER)
|
||||||
|
|
||||||
def test_tournament_without_participants_can_not_be_started(self) -> None:
|
def test_tournament_without_participants_can_not_be_started(self) -> None:
|
||||||
tournament_under_test = generate_new_tournament(self.name, self.game_title, self.format_, self.start_time, self.initial_status)
|
tournament_under_test = generate_new_tournament(self.name, self.description, self.game_title, self.format_, self.start_time, 32, self.initial_status)
|
||||||
with self.assertRaises(TournamentError):
|
with self.assertRaises(TournamentError):
|
||||||
tournament_under_test.start()
|
tournament_under_test.start()
|
||||||
|
|
||||||
def test_adding_the_same_participant_twice_leads_to_exception(self) -> None:
|
def test_adding_the_same_participant_twice_leads_to_exception(self) -> None:
|
||||||
tournament_under_test = generate_new_tournament(self.name, self.game_title, self.format_, self.start_time, self.initial_status)
|
tournament_under_test = generate_new_tournament(self.name, self.description, self.game_title, self.format_, self.start_time, 32, self.initial_status)
|
||||||
tournament_under_test.add_participant(self.participant_a)
|
tournament_under_test.add_participant(self.participant_a)
|
||||||
with self.assertRaises(TournamentError):
|
with self.assertRaises(TournamentError):
|
||||||
tournament_under_test.add_participant(self.participant_a)
|
tournament_under_test.add_participant(self.participant_a)
|
||||||
|
|
||||||
def test_single_elimination_bo3_tournament_gets_generated_correctly(self) -> None:
|
def test_single_elimination_bo3_tournament_gets_generated_correctly(self) -> None:
|
||||||
tournament_under_test = generate_new_tournament(self.name, self.game_title, self.format_, self.start_time, self.initial_status)
|
tournament_under_test = generate_new_tournament(self.name, self.description, self.game_title, self.format_, self.start_time, 32, self.initial_status)
|
||||||
|
|
||||||
tournament_under_test.add_participant(self.participant_a)
|
tournament_under_test.add_participant(self.participant_a)
|
||||||
tournament_under_test.add_participant(self.participant_b)
|
tournament_under_test.add_participant(self.participant_b)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user