diff --git a/.nicegui/storage-user-c446a3b8-a6ed-40c3-a878-3069e9d230cb.json b/.nicegui/storage-user-c446a3b8-a6ed-40c3-a878-3069e9d230cb.json index 9e26dfe..cf2e059 100644 --- a/.nicegui/storage-user-c446a3b8-a6ed-40c3-a878-3069e9d230cb.json +++ b/.nicegui/storage-user-c446a3b8-a6ed-40c3-a878-3069e9d230cb.json @@ -1 +1 @@ -{} \ No newline at end of file +{"authenticated":true,"discord_id":"277898241750859776","discord_name":"mrteels","db_id":2,"display_name":"DN","discord_avatar_url":"https://cdn.discordapp.com/avatars/277898241750859776/7c3446bb51fafd72b1b4c21124b4994f.png"} \ No newline at end of file diff --git a/data/data_api.py b/data/data_api.py index 97dc0d6..ab2a1fc 100644 --- a/data/data_api.py +++ b/data/data_api.py @@ -54,7 +54,7 @@ def get_or_create_player(discord_id, discord_name, avatar_url): # Random Silly Name Generator für neue Spieler. Damit sie angeregt werden ihren richtigen Namen einzutragen. silly_name = generate_silly_name() cursor.execute("INSERT INTO players (discord_id, discord_name, display_name, discord_avatar_url) VALUES (?, ?, ?, ?)", (discord_id, discord_name, silly_name, avatar_url)) - logger.log("NEW PLAYER", str("Ein neuer Spieler wurde angelegt - " + discord_name)) + logger.log("data_api.get_or_create_player", str("Ein neuer Spieler wurde angelegt - " + discord_name)) connection.commit() cursor.execute("SELECT id, discord_name, display_name, discord_avatar_url FROM players WHERE discord_id = ?", (discord_id,)) player = cursor.fetchone() @@ -178,7 +178,7 @@ def join_league(player_id, gamesystem_id): INSERT INTO player_game_statistic (player_id, gamesystem_id) VALUES (?, ?) """ - logger.log("DataAPI", f"{get_player_name(player_id)} joined {gamesystem_id}", player_id) + logger.log("data_api.join_league", f"{get_player_name(player_id)} joined {gamesystem_id}", player_id) cursor.execute(query, (player_id, gamesystem_id)) connection.commit() @@ -250,7 +250,7 @@ def add_new_match(system_name, player1_id, player2_id, score_p1, score_p2): cursor.execute(query, (sys_id, player1_id, player2_id, score_p1, score_p2)) new_match_id = cursor.lastrowid - logger.log("DataAPI", f"{get_player_name(player1_id)}:({score_p1}) posted Match. System: {system_name}, {get_player_name(player2_id)}:({score_p2})", player1_id) + logger.log("data_api.add_new_match", f"{get_player_name(player1_id)}:({score_p1}) posted Match. System: {system_name}, {get_player_name(player2_id)}:({score_p2})", player1_id) connection.commit() connection.close() @@ -335,12 +335,12 @@ def save_calculated_match(calc_results: dict): )) connection.commit() - logger.log("MATCH_CALC", f"Match ID {match_id} wurde komplett berechnet und verbucht.") + logger.log("pi.save_calculated_match", f"Match ID:{match_id} berechnet.") return True except Exception as e: connection.rollback() - print(f"KRITISCHER FEHLER beim Speichern des Matches: {e}") + logger.log("data_api.save_calculated_match", f"KRITISCHER FEHLER beim Speichern des Matches: {e}") return False finally: @@ -363,9 +363,6 @@ def get_gamesystem_data(system_id): return dict(zip([col[0] for col in cursor.description], row)) if row else None - - - def get_gamesystems_data(): connection = sqlite3.connect(DB_PATH) @@ -572,7 +569,6 @@ def set_match_counted(match_id): # Ändert nur die Spalte match_is_counted auf 1 (True) cursor.execute("UPDATE matches SET match_is_counted = 1 WHERE id = ?", (match_id,)) - logger.log("data_api.set_match_counted", f"Match mit ID: {match_id} berechnet.") connection.commit() connection.close() @@ -602,15 +598,20 @@ def get_submitted_matches(player_id): def get_match_history_log(player_id): - """Holt ALLE Matches eines Spielers inklusive der MMR-Änderungen für das Log.""" + """Holt ALLE Matches eines Spielers inklusive der MMR-Änderungen und Faktoren für das Log.""" connection = sqlite3.connect(DB_PATH) connection.row_factory = sqlite3.Row cursor = connection.cursor() query = """ SELECT m.played_at, sys.name AS gamesystem_name, - m.player1_id, p1.display_name AS p1_display, p1.discord_name AS p1_discord, m.score_player1, m.player1_mmr_change, - m.player2_id, p2.display_name AS p2_display, p2.discord_name AS p2_discord, m.score_player2, m.player2_mmr_change, + m.player1_id, p1.display_name AS p1_display, p1.discord_name AS p1_discord, + m.score_player1, m.player1_mmr_change, + m.player1_khorne, m.player1_tzeentch, m.player1_slaanesh, m.player1_base_change, + m.player2_id, p2.display_name AS p2_display, p2.discord_name AS p2_discord, + m.score_player2, m.player2_mmr_change, + m.player2_khorne, m.player2_tzeentch, m.player2_slaanesh, m.player2_base_change, + m.elo_factor, m.rust_factor, m.player2_check, m.match_is_counted FROM matches m JOIN gamesystems sys ON m.gamesystem_id = sys.id @@ -629,6 +630,7 @@ def get_match_history_log(player_id): + # ----------------------------------------------------- # Testing and Prototyping # ----------------------------------------------------- diff --git a/gui/match_history_gui.py b/gui/match_history_gui.py index 1ccd79a..8244ec2 100644 --- a/gui/match_history_gui.py +++ b/gui/match_history_gui.py @@ -1,6 +1,7 @@ from nicegui import ui, app from data import data_api -from gui import gui_style +from gui import gui_style + def setup_routes(): @ui.page('/matchhistory', dark=True) @@ -8,17 +9,14 @@ def setup_routes(): gui_style.apply_design() - # Sicherheits-Check: Ist der Nutzer eingeloggt? if not app.storage.user.get('authenticated', False): ui.label('Bitte logge dich ein.').classes('text-red-500 text-2xl m-4') return player_id = app.storage.user.get('db_id') - # Das Haupt-Layout der Seite - with ui.column().classes('w-full max-w-5xl mx-auto p-4'): + with ui.column().classes('w-full max-w-7xl mx-auto p-4'): - # Kopfbereich mit Zurück-Button with ui.row().classes('w-full items-center justify-between mb-6'): ui.label("Komplette Match Historie").classes("text-3xl font-bold text-white") ui.button("Zurück", icon="arrow_back", on_click=lambda: ui.navigate.to('/')).classes('bg-zinc-700 text-white') @@ -26,21 +24,37 @@ def setup_routes(): raw_matches = data_api.get_match_history_log(player_id) table_rows = [] - # Daten für die Tabelle aufbereiten + def fmt_signed(val, pending=False): + """Formatiert einen Integer-Wert mit Vorzeichen oder gibt Sondertexte zurück.""" + if pending: + return "Ausstehend" + if val is None: + return "0" + if val > 0: + return f"+{val}" + return str(val) + for i, match in enumerate(raw_matches): - # Bin ich P1 oder P2? - if match['player1_id'] == player_id: + is_player1 = match['player1_id'] == player_id + pending = match['match_is_counted'] == 0 + + if is_player1: opponent = f"{match['p2_display']} aka {match['p2_discord']}" my_score = match['score_player1'] opp_score = match['score_player2'] my_mmr_change = match['player1_mmr_change'] + my_khorne = match['player1_khorne'] + my_tzeentch = match['player1_tzeentch'] + my_slaanesh = match['player1_slaanesh'] else: opponent = f"{match['p1_display']} aka {match['p1_discord']}" my_score = match['score_player2'] opp_score = match['score_player1'] my_mmr_change = match['player2_mmr_change'] + my_khorne = match['player2_khorne'] + my_tzeentch = match['player2_tzeentch'] + my_slaanesh = match['player2_slaanesh'] - # Ergebnis Text if my_score > opp_score: result = "Gewonnen" elif my_score < opp_score: @@ -48,51 +62,61 @@ def setup_routes(): else: result = "Unentschieden" - # MMR Text schön formatieren - if match['match_is_counted'] == 0: - mmr_text = "Ausstehend" - elif my_mmr_change is None: - mmr_text = "0" - elif my_mmr_change > 0: - mmr_text = f"+{my_mmr_change}" - elif my_mmr_change < 0: - mmr_text = f"{my_mmr_change}" - else: - mmr_text = str(my_mmr_change) + elo_factor = match['elo_factor'] + rust_factor = match['rust_factor'] table_rows.append({ 'id': i, 'date': str(match['played_at'])[:10], 'system': match['gamesystem_name'], + 'score': str(my_score), 'opponent': opponent, - 'score': f"{my_score}", - 'opp_score': f"{opp_score}", + 'opp_score': str(opp_score), 'result': result, - 'mmr': mmr_text + 'elo': fmt_signed(round(elo_factor, 2) if elo_factor is not None else None, pending), + 'rust': fmt_signed(round(rust_factor, 2) if rust_factor is not None else None, pending), + 'khorne': fmt_signed(my_khorne, pending), + 'tzeentch': fmt_signed(my_tzeentch, pending), + 'slaanesh': fmt_signed(my_slaanesh, pending), + 'mmr': fmt_signed(my_mmr_change, pending), }) - # Spalten definieren columns = [ - {'name': 'date', 'label': 'Datum', 'field': 'date', 'align': 'left'}, - {'name': 'system', 'label': 'System', 'field': 'system', 'align': 'left'}, - {'name': 'score', 'label': 'Punkte', 'field': 'score', 'align': 'left'}, - {'name': 'opponent', 'label': 'Gegner', 'field': 'opponent', 'align': 'left'}, - {'name': 'opp_score', 'label': 'Gegner Punkte', 'field': 'score', 'align': 'center'}, - {'name': 'result', 'label': 'Ergebnis', 'field': 'result', 'align': 'left'}, - {'name': 'mmr', 'label': 'MMR Änderung', 'field': 'mmr', 'align': 'right'} + {'name': 'date', 'label': 'Datum', 'field': 'date', 'align': 'left'}, + {'name': 'system', 'label': 'System', 'field': 'system', 'align': 'left'}, + {'name': 'score', 'label': 'Eigene Punkte', 'field': 'score', 'align': 'center'}, + {'name': 'opponent', 'label': 'Gegner', 'field': 'opponent', 'align': 'left'}, + {'name': 'opp_score','label': 'Gegner Punkte', 'field': 'opp_score','align': 'center'}, + {'name': 'result', 'label': 'Ergebnis', 'field': 'result', 'align': 'left'}, + {'name': 'elo', 'label': 'Elo Faktor', 'field': 'elo', 'align': 'right'}, + {'name': 'rust', 'label': 'Rost Faktor', 'field': 'rust', 'align': 'right'}, + {'name': 'khorne', 'label': 'Khorne', 'field': 'khorne', 'align': 'right'}, + {'name': 'tzeentch', 'label': 'Tzeentch', 'field': 'tzeentch', 'align': 'right'}, + {'name': 'slaanesh', 'label': 'Slaanesh', 'field': 'slaanesh', 'align': 'right'}, + {'name': 'mmr', 'label': 'MMR Änderung', 'field': 'mmr', 'align': 'right'}, ] - # Tabelle zeichnen - if len(table_rows) > 0: - history_table = ui.table(columns=columns, rows=table_rows, row_key='id').classes('w-full bg-zinc-900 text-white') + # Shared slot template for colored signed values + colored_slot = ''' + + + {{ props.row[props.col.field] }} + + + ''' - # KLEINER TRICK: Wir färben die MMR-Spalte grün oder rot, je nachdem ob da ein "+" oder "-" steht! - history_table.add_slot('body-cell-mmr', ''' - - - {{ props.row.mmr }} - - - ''') + if table_rows: + history_table = ui.table( + columns=columns, + rows=table_rows, + row_key='id' + ).classes('w-full bg-zinc-900 text-white') + + for col in ['elo', 'rust', 'khorne', 'tzeentch', 'slaanesh', 'mmr']: + history_table.add_slot(f'body-cell-{col}', colored_slot) else: ui.label("Keine Spiele gefunden.").classes("text-gray-400 italic")