Merge pull request 'dev' (#13) from dev into master

Reviewed-on: daniel/Diceghost-Liga-System#13
This commit is contained in:
Daniel Nagel 2026-03-09 09:56:58 +01:00
commit 68a32bd03c
18 changed files with 49 additions and 26 deletions

View File

@ -1 +1 @@
{"authenticated":true,"discord_id":"277898241750859776","discord_name":"mrteels","db_id":1,"display_name":"Daniel N.","discord_avatar_url":"https://cdn.discordapp.com/avatars/277898241750859776/7c3446bb51fafd72b1b4c21124b4994f.png"} {"authenticated":true,"discord_id":"277898241750859776","discord_name":"mrteels","db_id":1,"display_name":"Chaos Servitor","discord_avatar_url":"https://cdn.discordapp.com/avatars/277898241750859776/7c3446bb51fafd72b1b4c21124b4994f.png"}

View File

@ -477,6 +477,26 @@ def get_leaderboard(system_name):
return result return result
def update_match_mmr_change(match_id, p1_change, p2_change):
"""Speichert die tatsächliche MMR-Änderung für das Log fest im Match ab."""
connection = sqlite3.connect(DB_PATH)
cursor = connection.cursor()
cursor.execute("""
UPDATE matches
SET player1_mmr_change = ?, player2_mmr_change = ?
WHERE id = ?
""", (p1_change, p2_change, match_id))
connection.commit()
connection.close()
# -----------------------------------------------------
# Matches Bestätigen, Löschen, Berechnen, ...
# -----------------------------------------------------
def get_unconfirmed_matches(player_id): def get_unconfirmed_matches(player_id):
"""Holt alle offenen Matches, die der Spieler noch bestätigen muss.""" """Holt alle offenen Matches, die der Spieler noch bestätigen muss."""
connection = sqlite3.connect(DB_PATH) connection = sqlite3.connect(DB_PATH)
@ -537,7 +557,6 @@ def set_match_counted(match_id):
connection.close() connection.close()
def get_submitted_matches(player_id): def get_submitted_matches(player_id):
"""Holt alle offenen Matches, die der Spieler selbst eingetragen hat, aber vom Gegner noch nicht bestätigt wurden.""" """Holt alle offenen Matches, die der Spieler selbst eingetragen hat, aber vom Gegner noch nicht bestätigt wurden."""
connection = sqlite3.connect(DB_PATH) connection = sqlite3.connect(DB_PATH)

View File

@ -2,7 +2,7 @@ import sqlite3
import os import os
import json import json
dummy_is_in = False dummy_is_in = True
# 1. Sucht den exakten, absoluten Pfad zu diesem Skript (z.B. /srv/Diceghost-Liga-System/data/) # 1. Sucht den exakten, absoluten Pfad zu diesem Skript (z.B. /srv/Diceghost-Liga-System/data/)
BASE_DIR = os.path.dirname(os.path.abspath(__file__)) BASE_DIR = os.path.dirname(os.path.abspath(__file__))
@ -10,6 +10,7 @@ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
DB_PATH = os.path.join(BASE_DIR, "league_database.db") DB_PATH = os.path.join(BASE_DIR, "league_database.db")
def init_db(): def init_db():
connection = sqlite3.connect(DB_PATH) connection = sqlite3.connect(DB_PATH)
cursor = connection.cursor() cursor = connection.cursor()

View File

@ -44,7 +44,7 @@ def setup_routes():
table_rows.append({ table_rows.append({
'rank': current_rank, 'rank': current_rank,
'trend': '', # Platzhalter für später 'trend': '', # Platzhalter für später
'name': f"{player['display_name']} aka {player['discord_name']}", 'name': f"{player['display_name']} 'aka' {player['discord_name']}",
'mmr': player['mmr'] 'mmr': player['mmr']
}) })

View File

@ -238,25 +238,21 @@ def setup_routes(admin_discord_id):
# --------------------------- # ---------------------------
with ui.card().classes("w-full"): with ui.card().classes("w-full"):
ui.label(text= "Meine letzten Spiele").classes("font-bold text-white text-xl") ui.label(text= "Meine letzten Spiele").classes("font-bold text-white text-xl")
# 1. Daten aus der DB holen # 1. Daten aus der DB holen ABER per [:5] hart auf die neuesten 5 Listen-Einträge abschneiden!
raw_matches = data_api.get_recent_matches_for_player(player_id) raw_matches = data_api.get_recent_matches_for_player(player_id)[:5]
# 2. Daten für die Tabelle aufbereiten # 2. Daten für die Tabelle aufbereiten (Bleibt exakt gleich wie bei dir)
table_rows = [] table_rows = []
for match in raw_matches: for match in raw_matches:
# Bin ich Spieler 1 oder Spieler 2?
if match['player1_id'] == player_id: if match['player1_id'] == player_id:
# Ich bin Spieler 1, also ist Spieler 2 der Gegner
opponent_name = f"{match['p2_display']} aka {match['p2_discord']}" opponent_name = f"{match['p2_display']} aka {match['p2_discord']}"
my_score = match['score_player1'] my_score = match['score_player1']
opp_score = match['score_player2'] opp_score = match['score_player2']
else: else:
# Ich bin Spieler 2, also ist Spieler 1 der Gegner
opponent_name = f"{match['p1_display']} aka {match['p1_discord']}" opponent_name = f"{match['p1_display']} aka {match['p1_discord']}"
my_score = match['score_player2'] my_score = match['score_player2']
opp_score = match['score_player1'] opp_score = match['score_player1']
# Gewonnen oder Verloren?
if my_score > opp_score: if my_score > opp_score:
result_text = "Gewonnen" result_text = "Gewonnen"
elif my_score < opp_score: elif my_score < opp_score:
@ -264,10 +260,8 @@ def setup_routes(admin_discord_id):
else: else:
result_text = "Unentschieden" result_text = "Unentschieden"
# Datum hübsch machen (schneidet die Millisekunden weg)
date_clean = str(match['played_at'])[:10] date_clean = str(match['played_at'])[:10]
# Eine fertige Zeile für unsere Tabelle bauen
table_rows.append({ table_rows.append({
'date': date_clean, 'date': date_clean,
'system': match['gamesystem_name'], 'system': match['gamesystem_name'],
@ -275,7 +269,6 @@ def setup_routes(admin_discord_id):
'result': f"{result_text} ({my_score} : {opp_score})" 'result': f"{result_text} ({my_score} : {opp_score})"
}) })
# 3. Das Layout (Die Spalten) der Tabelle definieren
table_columns = [ table_columns = [
{'name': 'date', 'label': 'Gespielt am', 'field': 'date', 'align': 'left'}, {'name': 'date', 'label': 'Gespielt am', 'field': 'date', 'align': 'left'},
{'name': 'system', 'label': 'System', 'field': 'system', 'align': 'left'}, {'name': 'system', 'label': 'System', 'field': 'system', 'align': 'left'},
@ -283,15 +276,12 @@ def setup_routes(admin_discord_id):
{'name': 'result', 'label': 'Ergebnis', 'field': 'result', 'align': 'left'} {'name': 'result', 'label': 'Ergebnis', 'field': 'result', 'align': 'left'}
] ]
# 4. Die Tabelle zeichnen! # 4. Die Tabelle zeichnen und den NEUEN BUTTON hinzufügen
if len(table_rows) > 0: if len(table_rows) > 0:
ui.table(columns=table_columns, rows=table_rows, row_key='date').classes('w-full bg-zinc-900 text-white') ui.table(columns=table_columns, rows=table_rows, row_key='date').classes('w-full bg-zinc-900 text-white')
# NEU: Der Button, der zur großen Log-Seite führt
ui.button("Komplette Historie & Log anzeigen", icon="history", on_click=lambda: ui.navigate.to('/matchhistory')).classes('w-full mt-4 bg-zinc-700 text-white hover:bg-zinc-600')
else: else:
ui.label("Noch keine Spiele absolviert.").classes("text-gray-500 italic") ui.label("Noch keine Spiele absolviert.").classes("text-gray-500 italic")

View File

@ -37,7 +37,7 @@ def setup_routes():
for p in raw_players: for p in raw_players:
if p['player_id'] == my_id: if p['player_id'] == my_id:
continue continue
dropdown_options[p['player_id']] = f"{p['display_name']} aka {p['discord_name']}" dropdown_options[p['player_id']] = f"{p['display_name']} 'aka' {p['discord_name']}"
# ÄNDERUNG: .classes('w-full') hinzugefügt, damit der Slider sich anpasst # ÄNDERUNG: .classes('w-full') hinzugefügt, damit der Slider sich anpasst
p1_points = ui.slider(min=0, max=100, value=10).props("label-always").classes('w-full') p1_points = ui.slider(min=0, max=100, value=10).props("label-always").classes('w-full')

View File

@ -1,7 +1,6 @@
from nicegui import ui, app from nicegui import ui, app
from data import data_api from data import data_api
# Falls du eine gui_style.py für Farben/Header hast, hier importieren! from gui import gui_style
# from gui import gui_style
def setup_routes(): def setup_routes():
@ui.page('/matchhistory', dark=True) @ui.page('/matchhistory', dark=True)

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
gui/pictures/KT_Logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,10 +1,9 @@
import os import os
from nicegui import app
from dotenv import load_dotenv from dotenv import load_dotenv
from nicegui import ui from nicegui import ui
from gui import main_gui, match_gui, discord_login, league_statistic, admin_gui, match_history_gui from gui import main_gui, match_gui, discord_login, league_statistic, admin_gui, match_history_gui
from nicegui import app
from data import database from data import database
@ -17,6 +16,7 @@ app.add_static_files('/pictures', 'gui/pictures')
client_id = os.getenv("DISCORD_CLIENT_ID") client_id = os.getenv("DISCORD_CLIENT_ID")
client_secret = os.getenv("DISCORD_CLIENT_SECRET") client_secret = os.getenv("DISCORD_CLIENT_SECRET")
admin_discord_id = os.getenv("ADMIN") admin_discord_id = os.getenv("ADMIN")
url = os.getenv("APP_URL")
database.check_db() database.check_db()

View File

@ -64,6 +64,20 @@ def calculate_match (match_id):
data_api.apply_match_to_player_statistic (winner_id, sys_id, mmr_change_winner, winner_score) data_api.apply_match_to_player_statistic (winner_id, sys_id, mmr_change_winner, winner_score)
data_api.apply_match_to_player_statistic (looser_id, sys_id, mmr_change_looser, looser_score) data_api.apply_match_to_player_statistic (looser_id, sys_id, mmr_change_looser, looser_score)
# Zuordnen: Welcher Change gehört zu P1 und welcher zu P2?
if winner_id == p1_id:
p1_change = mmr_change_winner
p2_change = mmr_change_looser
else:
# Wenn der Sieger nicht P1 ist, muss P1 der Verlierer sein (oder Draw, da ist es egal)
p1_change = mmr_change_looser
p2_change = mmr_change_winner
# Die Änderungen für das Log ins Match eintragen!
data_api.update_match_mmr_change(match_id, p1_change, p2_change)
# Das Match als Berechnet markieren
data_api.set_match_counted(match_id) data_api.set_match_counted(match_id)