Merge pull request 'dev' (#17) from dev into master
Reviewed-on: daniel/Diceghost-Liga-System#17
This commit is contained in:
commit
3e935200f2
|
|
@ -0,0 +1 @@
|
||||||
|
{"authenticated":true,"discord_id":"277898241750859776","discord_name":"mrteels","db_id":2,"display_name":"Daniel","discord_avatar_url":"https://cdn.discordapp.com/avatars/277898241750859776/7c3446bb51fafd72b1b4c21124b4994f.png"}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import random
|
import random
|
||||||
|
from wood import logger
|
||||||
|
|
||||||
from data.setup_database import DB_PATH
|
from data.setup_database import DB_PATH
|
||||||
|
|
||||||
|
|
@ -50,13 +51,11 @@ def get_or_create_player(discord_id, discord_name, avatar_url):
|
||||||
player = cursor.fetchone()
|
player = cursor.fetchone()
|
||||||
|
|
||||||
if player is None:
|
if player is None:
|
||||||
|
|
||||||
# Random Silly Name Generator für neue Spieler. Damit sie angeregt werden ihren richtigen Namen einzutragen.
|
# Random Silly Name Generator für neue Spieler. Damit sie angeregt werden ihren richtigen Namen einzutragen.
|
||||||
|
|
||||||
silly_name = generate_silly_name()
|
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))
|
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), player_id)
|
||||||
connection.commit()
|
connection.commit()
|
||||||
|
|
||||||
cursor.execute("SELECT id, discord_name, display_name, discord_avatar_url FROM players WHERE discord_id = ?", (discord_id,))
|
cursor.execute("SELECT id, discord_name, display_name, discord_avatar_url FROM players WHERE discord_id = ?", (discord_id,))
|
||||||
player = cursor.fetchone()
|
player = cursor.fetchone()
|
||||||
else:
|
else:
|
||||||
|
|
@ -225,7 +224,7 @@ def join_league(player_id, gamesystem_id):
|
||||||
INSERT INTO player_game_statistic (player_id, gamesystem_id)
|
INSERT INTO player_game_statistic (player_id, gamesystem_id)
|
||||||
VALUES (?, ?)
|
VALUES (?, ?)
|
||||||
"""
|
"""
|
||||||
|
logger.log("INTO", f"{get_player_name(player_id)} ist Liga {gamesystem_id} beigetreten", player_id)
|
||||||
cursor.execute(query, (player_id, gamesystem_id))
|
cursor.execute(query, (player_id, gamesystem_id))
|
||||||
connection.commit()
|
connection.commit()
|
||||||
|
|
||||||
|
|
@ -233,7 +232,6 @@ def join_league(player_id, gamesystem_id):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_recent_matches_for_player(player_id):
|
def get_recent_matches_for_player(player_id):
|
||||||
connection = sqlite3.connect(DB_PATH)
|
connection = sqlite3.connect(DB_PATH)
|
||||||
connection.row_factory = sqlite3.Row
|
connection.row_factory = sqlite3.Row
|
||||||
|
|
@ -298,6 +296,8 @@ 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))
|
cursor.execute(query, (sys_id, player1_id, player2_id, score_p1, score_p2))
|
||||||
new_match_id = cursor.lastrowid
|
new_match_id = cursor.lastrowid
|
||||||
|
|
||||||
|
logger.log("MATCH", f"Match eingetragen. {get_system_name(sys_id)} - {get_player_name(player1_id)} ({score_p1}) vs. {get_player_name(player2_id)} ({score_p2})", player1_id)
|
||||||
|
|
||||||
connection.commit()
|
connection.commit()
|
||||||
connection.close()
|
connection.close()
|
||||||
|
|
||||||
|
|
@ -394,8 +394,6 @@ def get_match_by_id(match_id):
|
||||||
return dict(row)
|
return dict(row)
|
||||||
|
|
||||||
return None # Falls die ID nicht existiert
|
return None # Falls die ID nicht existiert
|
||||||
|
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
def get_days_since_last_game(player_id):
|
def get_days_since_last_game(player_id):
|
||||||
|
|
@ -465,7 +463,7 @@ def apply_match_to_player_statistic (player_id, gamesystem_id, mmr_change, score
|
||||||
# ACHTUNG: Wir müssen scored_points ZWEIMAL übergeben!
|
# ACHTUNG: Wir müssen scored_points ZWEIMAL übergeben!
|
||||||
# Einmal für die 'points' und einmal für die Berechnung der 'avv_points'.
|
# Einmal für die 'points' und einmal für die Berechnung der 'avv_points'.
|
||||||
cursor.execute(query, (mmr_change, scored_points, scored_points, player_id, gamesystem_id))
|
cursor.execute(query, (mmr_change, scored_points, scored_points, player_id, gamesystem_id))
|
||||||
|
logger.log("MATCH CALC", f"Bei {get_player_name(player_id)} haben sich die MMR Punkte um {mmr_change} geändert.")
|
||||||
connection.commit()
|
connection.commit()
|
||||||
connection.close()
|
connection.close()
|
||||||
|
|
||||||
|
|
@ -515,6 +513,48 @@ def update_match_mmr_change(match_id, p1_change, p2_change):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def get_player_name(player_id):
|
||||||
|
"""Gibt den Namen eines Spielers im Format 'Anzeigename (Discordname)' zurück."""
|
||||||
|
|
||||||
|
# Sicherheits-Check: Falls aus Versehen gar keine ID übergeben wird
|
||||||
|
if player_id is None:
|
||||||
|
return "Unbekannter Spieler"
|
||||||
|
|
||||||
|
connection = sqlite3.connect(DB_PATH)
|
||||||
|
cursor = connection.cursor()
|
||||||
|
|
||||||
|
cursor.execute("SELECT display_name, discord_name FROM players WHERE id = ?", (player_id,))
|
||||||
|
row = cursor.fetchone()
|
||||||
|
connection.close()
|
||||||
|
|
||||||
|
# Wenn die Datenbank den Spieler gefunden hat:
|
||||||
|
if row:
|
||||||
|
display_name = row[0]
|
||||||
|
discord_name = row[1]
|
||||||
|
return f"{display_name} ({discord_name})"
|
||||||
|
else:
|
||||||
|
return "Gelöschter Spieler"
|
||||||
|
|
||||||
|
def get_system_name(sys_id):
|
||||||
|
if sys_id is None:
|
||||||
|
return "Unbekanntes System"
|
||||||
|
connection = sqlite3.connect(DB_PATH)
|
||||||
|
cursor = connection.cursor()
|
||||||
|
cursor.execute("SELECT name FROM gamesystems WHERE id = ?", (sys_id,))
|
||||||
|
|
||||||
|
row = cursor.fetchone()
|
||||||
|
connection.close()
|
||||||
|
|
||||||
|
if row:
|
||||||
|
return row[0]
|
||||||
|
else:
|
||||||
|
return "Gelöschtes System"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------
|
# -----------------------------------------------------
|
||||||
# Matches Bestätigen, Löschen, Berechnen, ...
|
# Matches Bestätigen, Löschen, Berechnen, ...
|
||||||
# -----------------------------------------------------
|
# -----------------------------------------------------
|
||||||
|
|
@ -544,14 +584,14 @@ def get_unconfirmed_matches(player_id):
|
||||||
return [dict(row) for row in rows]
|
return [dict(row) for row in rows]
|
||||||
|
|
||||||
|
|
||||||
def delete_match(match_id):
|
def delete_match(match_id, player_id):
|
||||||
"""Löscht ein Match anhand seiner ID komplett aus der Datenbank."""
|
"""Löscht ein Match anhand seiner ID komplett aus der Datenbank."""
|
||||||
connection = sqlite3.connect(DB_PATH)
|
connection = sqlite3.connect(DB_PATH)
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
|
|
||||||
# DELETE FROM löscht die gesamte Zeile, bei der die ID übereinstimmt.
|
# DELETE FROM löscht die gesamte Zeile, bei der die ID übereinstimmt.
|
||||||
cursor.execute("DELETE FROM matches WHERE id = ?", (match_id,))
|
cursor.execute("DELETE FROM matches WHERE id = ?", (match_id,))
|
||||||
|
logger.log ("MATCH", f"Match mit ID:{match_id} wurde gelöscht von {get_player_name(player_id)}")
|
||||||
connection.commit()
|
connection.commit()
|
||||||
connection.close()
|
connection.close()
|
||||||
|
|
||||||
|
|
@ -562,7 +602,7 @@ def confirm_match(match_id):
|
||||||
|
|
||||||
# Ändert nur die Spalte player2_check auf 1 (True)
|
# Ändert nur die Spalte player2_check auf 1 (True)
|
||||||
cursor.execute("UPDATE matches SET player2_check = 1 WHERE id = ?", (match_id,))
|
cursor.execute("UPDATE matches SET player2_check = 1 WHERE id = ?", (match_id,))
|
||||||
|
logger.log ("MATCH CALC", f"Match mit ID{match_id} wurde als 'Confirmed' gekennzeichnet")
|
||||||
connection.commit()
|
connection.commit()
|
||||||
connection.close()
|
connection.close()
|
||||||
|
|
||||||
|
|
@ -574,7 +614,7 @@ def set_match_counted(match_id):
|
||||||
|
|
||||||
# Ändert nur die Spalte match_is_counted auf 1 (True)
|
# Ändert nur die Spalte match_is_counted auf 1 (True)
|
||||||
cursor.execute("UPDATE matches SET match_is_counted = 1 WHERE id = ?", (match_id,))
|
cursor.execute("UPDATE matches SET match_is_counted = 1 WHERE id = ?", (match_id,))
|
||||||
|
logger.log ("MATCH CALC", f"Match mit ID{match_id} wurde als 'Counted' gekennzeichnet")
|
||||||
connection.commit()
|
connection.commit()
|
||||||
connection.close()
|
connection.close()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
def check_db():
|
def check_db():
|
||||||
# --- DATENBANK CHECK ---
|
# --- DATENBANK CHECK ---
|
||||||
# Prüfen, ob die Datei im aktuellen Ordner existiert
|
# Prüfen, ob die Datei existiert
|
||||||
db_file = DB_PATH
|
db_file = DB_PATH
|
||||||
|
|
||||||
if not os.path.exists(db_file):
|
if not os.path.exists(db_file):
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,41 @@
|
||||||
from nicegui import ui, app
|
from nicegui import ui, app
|
||||||
from data import database, data_api
|
from data import database, data_api
|
||||||
from gui import gui_style
|
from gui import gui_style
|
||||||
|
from wood import logger
|
||||||
|
|
||||||
def setup_routes():
|
def setup_routes():
|
||||||
@ui.page('/admin', dark=True)
|
@ui.page('/admin', dark=True)
|
||||||
def home_page():
|
def admin_page():
|
||||||
gui_style.apply_design()
|
gui_style.apply_design()
|
||||||
|
|
||||||
|
with ui.header().classes('items-center justify-between bg-zinc-900 p-4 shadow-lg'):
|
||||||
|
ui.button("Zurück", on_click= lambda: ui.navigate.to("/") )
|
||||||
|
|
||||||
if app.storage.user.get('authenticated', False):
|
if app.storage.user.get('authenticated', False):
|
||||||
ui.card().classes("w-full")
|
with ui.card().classes("w-full"):
|
||||||
|
with ui.row().classes("w-full"):
|
||||||
|
ui.button("test")
|
||||||
|
ui.button(icon="refresh", on_click=lambda: ui.navigate.reload)
|
||||||
|
|
||||||
|
ui.label("System Audit Log").classes('text-2xl font-bold text-white mb-4')
|
||||||
|
|
||||||
|
# Daten abrufen
|
||||||
|
log_data = logger.get_full_log()
|
||||||
|
|
||||||
|
# Tabelle aufbauen
|
||||||
|
columns = [
|
||||||
|
{'name': 'time', 'label': 'Zeitstempel', 'field': 'timestamp', 'align': 'left', 'sortable': True},
|
||||||
|
{'name': 'user', 'label': 'Auslöser', 'field': 'player_name', 'align': 'left'},
|
||||||
|
{'name': 'action', 'label': 'Aktion', 'field': 'action', 'align': 'left', 'sortable': True},
|
||||||
|
{'name': 'details', 'label': 'Details', 'field': 'details', 'align': 'left'}
|
||||||
|
]
|
||||||
|
|
||||||
|
if len(log_data) > 0:
|
||||||
|
# Wir schneiden bei den Millisekunden vom Zeitstempel wieder etwas ab [:19]
|
||||||
|
for row in log_data:
|
||||||
|
row['timestamp'] = str(row['timestamp'])[:19]
|
||||||
|
|
||||||
|
# Tabelle zeichnen
|
||||||
|
ui.table(columns=columns, rows=log_data, row_key='id').classes('w-full bg-zinc-900 text-gray-300')
|
||||||
|
else:
|
||||||
|
ui.label("Das Logbuch ist leer.").classes('text-gray-500 italic')
|
||||||
|
|
@ -105,10 +105,10 @@ def setup_routes(admin_discord_id):
|
||||||
ui.button('Login with Discord', on_click=lambda: ui.navigate.to(auth_url))
|
ui.button('Login with Discord', on_click=lambda: ui.navigate.to(auth_url))
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# --- Match Bestätigung ---
|
# --- Match Bestätigung ---
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# --- Bestätigungs-Bereich für offene Spiele --- Der "Marian Balken !!!1!11!"
|
# Bestätigungs für offene Spiele --- Der "Marian Balken !!!1!11!"
|
||||||
if app.storage.user.get('authenticated', False):
|
if app.storage.user.get('authenticated', False):
|
||||||
unconfirmed_matches = data_api.get_unconfirmed_matches(player_id)
|
unconfirmed_matches = data_api.get_unconfirmed_matches(player_id)
|
||||||
|
|
||||||
|
|
@ -119,7 +119,7 @@ def setup_routes(admin_discord_id):
|
||||||
|
|
||||||
for match in unconfirmed_matches:
|
for match in unconfirmed_matches:
|
||||||
|
|
||||||
# --- NEU: Die Funktion, die beim Klick ausgeführt wird ---
|
# Button Funktionen. Akzeptieren oder Rejecten. Der Reject Button löscht das Match aus der DB.
|
||||||
def reject_match(m_id):
|
def reject_match(m_id):
|
||||||
data_api.delete_match(m_id)
|
data_api.delete_match(m_id)
|
||||||
ui.notify("Spiel abgelehnt und gelöscht!", color="warning")
|
ui.notify("Spiel abgelehnt und gelöscht!", color="warning")
|
||||||
|
|
@ -130,9 +130,6 @@ def setup_routes(admin_discord_id):
|
||||||
ui.navigate.reload() # Lädt die Seite neu, um die Karte zu aktualisieren
|
ui.navigate.reload() # Lädt die Seite neu, um die Karte zu aktualisieren
|
||||||
calc_match.calculate_match(m_id)
|
calc_match.calculate_match(m_id)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Für jedes Match machen wir eine kleine Reihe
|
|
||||||
with ui.row().classes('w-full items-center justify-between bg-zinc-900 p-3 rounded shadow-inner'):
|
with ui.row().classes('w-full items-center justify-between bg-zinc-900 p-3 rounded shadow-inner'):
|
||||||
# Info-Text: Was wurde eingetragen?
|
# Info-Text: Was wurde eingetragen?
|
||||||
info_text = f"[{match['system_name']}] {match['p1_name']} behauptet: Er hat {match['score_player1']} : {match['score_player2']} gegen dich gespielt."
|
info_text = f"[{match['system_name']}] {match['p1_name']} behauptet: Er hat {match['score_player1']} : {match['score_player2']} gegen dich gespielt."
|
||||||
|
|
@ -146,11 +143,11 @@ def setup_routes(admin_discord_id):
|
||||||
# BESTÄTIGEN und spiel berechnen lassen
|
# BESTÄTIGEN und spiel berechnen lassen
|
||||||
ui.button("Bestätigen", color="positive", icon="check", on_click=lambda e, m_id=match['match_id']: acccept_match(m_id))
|
ui.button("Bestätigen", color="positive", icon="check", on_click=lambda e, m_id=match['match_id']: acccept_match(m_id))
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# --- Selbst eingetragene, offene Spiele ---
|
# --- Selbst eingetragene, offene Spiele ---
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
submitted_matches = data_api.get_submitted_matches(player_id)
|
submitted_matches = data_api.get_submitted_matches(player_id)
|
||||||
|
|
||||||
if len(submitted_matches) > 0:
|
if len(submitted_matches) > 0:
|
||||||
# Eine etwas dezentere Karte (grau)
|
# Eine etwas dezentere Karte (grau)
|
||||||
with ui.card().classes('w-full bg-zinc-800 border border-gray-600 mb-6'):
|
with ui.card().classes('w-full bg-zinc-800 border border-gray-600 mb-6'):
|
||||||
|
|
@ -160,7 +157,7 @@ def setup_routes(admin_discord_id):
|
||||||
|
|
||||||
# Die Lösch-Funktion, die beim Klick ausgeführt wird
|
# Die Lösch-Funktion, die beim Klick ausgeführt wird
|
||||||
def retract_match(m_id):
|
def retract_match(m_id):
|
||||||
data_api.delete_match(m_id)
|
data_api.delete_match(m_id, player_id)
|
||||||
ui.notify("Eingetragenes Spiel zurückgezogen!", color="warning")
|
ui.notify("Eingetragenes Spiel zurückgezogen!", color="warning")
|
||||||
ui.navigate.reload()
|
ui.navigate.reload()
|
||||||
|
|
||||||
|
|
@ -178,7 +175,6 @@ def setup_routes(admin_discord_id):
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
# --- Spielsysteme ---
|
# --- Spielsysteme ---
|
||||||
# ---------------------------
|
# ---------------------------
|
||||||
|
|
||||||
if app.storage.user.get('authenticated', False):
|
if app.storage.user.get('authenticated', False):
|
||||||
with ui.card().classes("w-full"):
|
with ui.card().classes("w-full"):
|
||||||
ui.label(text="Meine Ligaplätze").classes("font-bold text-white text-xl")
|
ui.label(text="Meine Ligaplätze").classes("font-bold text-white text-xl")
|
||||||
|
|
@ -186,8 +182,6 @@ def setup_routes(admin_discord_id):
|
||||||
placements = data_api.get_player_statistics(player_id)
|
placements = data_api.get_player_statistics(player_id)
|
||||||
systems = data_api.get_gamesystem_data()
|
systems = data_api.get_gamesystem_data()
|
||||||
|
|
||||||
# Python-Trick: Wir wandeln die Spieler-Stats in ein "Wörterbuch" (Dictionary) um.
|
|
||||||
# So können wir blitzschnell über die System-ID nachschauen, ob er Stats hat.
|
|
||||||
my_stats = { p['gamesystem_id']: p for p in placements }
|
my_stats = { p['gamesystem_id']: p for p in placements }
|
||||||
|
|
||||||
def click_join_league(p_id, sys_id):
|
def click_join_league(p_id, sys_id):
|
||||||
|
|
@ -203,22 +197,18 @@ def setup_routes(admin_discord_id):
|
||||||
for sys in systems:
|
for sys in systems:
|
||||||
sys_id = sys['id']
|
sys_id = sys['id']
|
||||||
sys_name = sys['name']
|
sys_name = sys['name']
|
||||||
|
sys_logo = sys["picture"]
|
||||||
|
sys_description = sys['description']
|
||||||
|
|
||||||
sys_card = ui.card().classes("h-60 w-full items-center justify-center transition-colors")
|
sys_card = ui.card().classes("h-60 w-full items-center justify-center transition-colors")
|
||||||
|
|
||||||
with sys_card:
|
with sys_card:
|
||||||
# Kopfzeile
|
ui.label(text=sys_name).classes('text-xl font-bold text-center')
|
||||||
ui.label(text=sys_name).classes('text-xl font-bold')
|
if sys_logo:
|
||||||
|
ui.image(f"/pictures/{sys_logo}").classes("w-60")
|
||||||
|
|
||||||
# --- BILD EINFÜGEN ---
|
if sys_description:
|
||||||
# prüfen, ob die Spalte 'pictures' existiert und nicht leer ist
|
ui.label(text=sys['description']).classes('text-xs text-gray-400 text-center mt-2')
|
||||||
if 'pictures' in sys and sys['pictures']:
|
|
||||||
ui.image(f"/pictures/{sys['pictures']}").classes('w-24 h-24 object-contain m-2')
|
|
||||||
|
|
||||||
if 'description' in sys and sys['description']:
|
|
||||||
ui.label(text=sys['description']).classes('text-xs text-gray-400 text-center')
|
|
||||||
|
|
||||||
ui.space()
|
|
||||||
|
|
||||||
# Prüfen: Ist diese sys_id in den Stats des Spielers? UND hat er ein MMR?
|
# Prüfen: Ist diese sys_id in den Stats des Spielers? UND hat er ein MMR?
|
||||||
if sys_id not in my_stats or my_stats[sys_id]['mmr'] is None:
|
if sys_id not in my_stats or my_stats[sys_id]['mmr'] is None:
|
||||||
|
|
|
||||||
3
main.py
3
main.py
|
|
@ -4,6 +4,7 @@ from nicegui import ui, app
|
||||||
|
|
||||||
from data import database
|
from data import database
|
||||||
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 wood import logger
|
||||||
|
|
||||||
# 1. Lade die geheimen Variablen aus der .env Datei in den Speicher
|
# 1. Lade die geheimen Variablen aus der .env Datei in den Speicher
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
@ -22,6 +23,8 @@ admin_discord_id = os.getenv("ADMIN")
|
||||||
url = os.getenv("APP_URL")
|
url = os.getenv("APP_URL")
|
||||||
|
|
||||||
database.check_db()
|
database.check_db()
|
||||||
|
logger.setup_log_db()
|
||||||
|
|
||||||
|
|
||||||
# 3. Seitenrouten aufbauen
|
# 3. Seitenrouten aufbauen
|
||||||
main_gui.setup_routes(admin_discord_id)
|
main_gui.setup_routes(admin_discord_id)
|
||||||
|
|
|
||||||
75
wood/logger.py
Normal file
75
wood/logger.py
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
import sqlite3
|
||||||
|
import os
|
||||||
|
|
||||||
|
from data.setup_database import DB_PATH
|
||||||
|
|
||||||
|
DB_FILE = "wood/log.db"
|
||||||
|
|
||||||
|
def log(action, details, player_id = None):
|
||||||
|
"""Schreibt ein Ereignis (Audit Trail) in das System-Log."""
|
||||||
|
connection = sqlite3.connect(DB_FILE)
|
||||||
|
cursor = connection.cursor()
|
||||||
|
|
||||||
|
cursor.execute(
|
||||||
|
"INSERT INTO system_log (player_id, action, details) VALUES (?, ?, ?)",
|
||||||
|
(player_id, action, details)
|
||||||
|
)
|
||||||
|
|
||||||
|
connection.commit()
|
||||||
|
connection.close()
|
||||||
|
|
||||||
|
|
||||||
|
def setup_log_db():
|
||||||
|
# --- DATENBANK CHECK ---
|
||||||
|
# ACHTUNG: Großschreibung bei DB_FILE beachten!
|
||||||
|
if not os.path.exists(DB_FILE):
|
||||||
|
print(f"WARNUNG: '{DB_FILE}' nicht gefunden!")
|
||||||
|
print("Starte Log-Datenbank-Einrichtung...")
|
||||||
|
|
||||||
|
# Wir bauen die Datei direkt HIER auf, ohne setup_database aufzurufen!
|
||||||
|
connection = sqlite3.connect(DB_FILE)
|
||||||
|
cursor = connection.cursor()
|
||||||
|
|
||||||
|
cursor.execute('''
|
||||||
|
CREATE TABLE IF NOT EXISTS system_log (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
player_id INTEGER,
|
||||||
|
action TEXT,
|
||||||
|
details TEXT
|
||||||
|
)
|
||||||
|
''')
|
||||||
|
connection.commit()
|
||||||
|
connection.close()
|
||||||
|
print("Log-Datenbank aufgebaut!")
|
||||||
|
else:
|
||||||
|
print(f"OK: Log-Datenbank '{DB_FILE}' gefunden. Lade System...")
|
||||||
|
|
||||||
|
|
||||||
|
def get_full_log():
|
||||||
|
"""Holt das komplette Log und übersetzt die Spieler-IDs in Namen."""
|
||||||
|
# 1. Alle Logs aus der log.db holen
|
||||||
|
log_conn = sqlite3.connect(DB_FILE)
|
||||||
|
log_conn.row_factory = sqlite3.Row
|
||||||
|
log_cursor = log_conn.cursor()
|
||||||
|
|
||||||
|
log_cursor.execute("SELECT * FROM system_log ORDER BY timestamp DESC")
|
||||||
|
logs = [dict(row) for row in log_cursor.fetchall()]
|
||||||
|
log_conn.close()
|
||||||
|
|
||||||
|
# 2. Spielernamen aus der Haupt-DB holen
|
||||||
|
main_conn = sqlite3.connect(DB_PATH)
|
||||||
|
main_cursor = main_conn.cursor()
|
||||||
|
main_cursor.execute("SELECT id, display_name, discord_name FROM players")
|
||||||
|
players_dict = {row[0]: f"{row[1]} ({row[2]})" for row in main_cursor.fetchall()}
|
||||||
|
main_conn.close()
|
||||||
|
|
||||||
|
# 3. Die IDs in den Logs durch Namen ersetzen
|
||||||
|
for log_entry in logs:
|
||||||
|
p_id = log_entry['player_id']
|
||||||
|
if p_id is not None and p_id in players_dict:
|
||||||
|
log_entry['player_name'] = players_dict[p_id]
|
||||||
|
else:
|
||||||
|
log_entry['player_name'] = "System / Unbekannt"
|
||||||
|
|
||||||
|
return logs
|
||||||
Loading…
Reference in New Issue
Block a user