Database angepasst. Code aufgeräumt. Silly Name Generator. gui_style Sheet.

This commit is contained in:
Daniel Nagel 2026-03-01 20:34:42 +01:00
parent 4c6d069ed3
commit 5774138ecb
8 changed files with 174 additions and 27 deletions

View File

@ -0,0 +1 @@
{"authenticated":true,"discord_id":"277898241750859776","discord_name":"mrteels","db_id":1,"display_name":"Zorniger Klebschnüffler","discord_avatar_url":"https://cdn.discordapp.com/avatars/277898241750859776/7c3446bb51fafd72b1b4c21124b4994f.png"}

View File

@ -1,4 +1,5 @@
import sqlite3
import random
if __name__ == "__main__":
@ -16,8 +17,9 @@ def init_db():
CREATE TABLE IF NOT EXISTS players (
id INTEGER PRIMARY KEY AUTOINCREMENT,
discord_id TEXT UNIQUE,
name TEXT NOT NULL,
avatar_url TEXT
discord_name TEXT NOT NULL,
discord_avatar_url TEXT,
display_name TEXT
)
''')
@ -63,12 +65,37 @@ def init_db():
)
''')
# 5. Tabelle: achievements (Der globale Katalog aller möglichen Erfolge - Stammdaten)
cursor.execute('''
CREATE TABLE IF NOT EXISTS achievements (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
description TEXT NOT NULL,
icon TEXT
)
''')
# 6. Tabelle: player_achievements (Wer hat welchen Erfolg wann bekommen? - Bewegungsdaten)
cursor.execute('''
CREATE TABLE IF NOT EXISTS player_achievements (
id INTEGER PRIMARY KEY AUTOINCREMENT,
player_id INTEGER,
achievement_id INTEGER,
earned_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
earned_in INTEGER,
FOREIGN KEY (earned_in) REFERENCES gamesystems (id),
FOREIGN KEY (player_id) REFERENCES players (id),
FOREIGN KEY (achievement_id) REFERENCES achievements (id)
)
''')
connection.commit()
connection.close()
print("Database structures created successfully!")
seed_gamesystems()
print("Standard Daten in die DB Geschrieben.")
# --------------------
# --- Start Setup der DB Daten. Damit sie nicht GANZ leer sind.
# --------------------
def seed_gamesystems():
connection = sqlite3.connect("warhammer_league.db")
cursor = connection.cursor()
@ -85,26 +112,56 @@ def seed_gamesystems():
connection.close()
print("Spielsysteme wurden angelegt!")
def seed_achievements():
connection = sqlite3.connect("warhammer_league.db")
cursor = connection.cursor()
# Unsere Start-Stückliste an Erfolgen (Name, Beschreibung, Icon)
achievements = [
("Kingslayer", "Hat den Spieler auf Platz 1 besiegt!", "👑"),
("Unstoppable", "3 Spiele in Folge gewonnen.", "🔥"),
("First Blood", "Das allererste Ligaspiel absolviert.", "🩸")
]
cursor.executemany("INSERT INTO achievements (name, description, icon) VALUES (?, ?, ?)", achievements)
connection.commit()
connection.close()
print("Achievements wurden in den Katalog geladen!")
def change_display_name(player_id, new_name):
connection = sqlite3.connect("warhammer_league.db")
cursor = connection.cursor()
cursor.execute("UPDATE players SET display_name = ? WHERE id = ?", (new_name, player_id))
connection.commit()
connection.close()
def get_or_create_player(discord_id, discord_name, avatar_url):
connection = sqlite3.connect("warhammer_league.db")
cursor = connection.cursor()
# REPARIERT: Wir fragen nur noch id, name und avatar_url aus 'players' ab
cursor.execute("SELECT id, name, avatar_url FROM players WHERE discord_id = ?", (discord_id,))
# REPARIERT: Wir fragen 4 Dinge ab (id, discord_name, display_name, discord_avatar_url)
cursor.execute("SELECT id, discord_name, display_name, discord_avatar_url FROM players WHERE discord_id = ?", (discord_id,))
player = cursor.fetchone()
if player is None:
cursor.execute("INSERT INTO players (discord_id, name, avatar_url) VALUES (?, ?, ?)", (discord_id, discord_name, avatar_url))
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))
connection.commit()
cursor.execute("SELECT id, name, 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()
else:
# Falls sich Name oder Bild auf Discord geändert haben, machen wir ein Update
cursor.execute("UPDATE players SET name = ?, avatar_url = ? WHERE discord_id = ?", (discord_name, avatar_url, discord_id))
cursor.execute("UPDATE players SET discord_name = ?, discord_avatar_url = ? WHERE discord_id = ?", (discord_name, avatar_url, discord_id))
connection.commit()
cursor.execute("SELECT id, name, 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()
connection.close()
@ -127,4 +184,23 @@ def get_all_players():
return result
def generate_silly_name():
adjectives = [
"Verwirrter", "Blinder", "Heulender", "Zorniger", "Chaos", ""
"Verzweifelter", "Schreiender", "Stolpernder", "Schwitzender"
]
nouns = [
"Grot", "Kultist", "Servitor", "Snotling",
"Guardmen", "Würfellecker", "Regelvergesser", "Meta-Chaser", "Klebschnüffler"
]
# random.choice() nimmt zufällig ein Element aus der Liste
adj = random.choice(adjectives)
noun = random.choice(nouns)
# Verbindet beide Wörter mit einem Leerzeichen (z.B. "Verwirrter Grot")
return f"{adj} {noun}"

View File

@ -62,7 +62,8 @@ def setup_login_routes():
app.storage.user['discord_id'] = discord_id
app.storage.user['discord_name'] = discord_name
app.storage.user['db_id'] = player[0]
app.storage.user['avatar_url'] = player[2] # Bild speichern!
app.storage.user['display_name'] = player[2]
app.storage.user['discord_avatar_url'] = player[3] # Bild speichern!
ui.navigate.to('/')
else:

20
gui/gui_style.py Normal file
View File

@ -0,0 +1,20 @@
from nicegui import ui
def apply_design():
# 1. Dark Mode aktivieren
ui.dark_mode(True)
# 2. Hier definierst du deine Farben fest im Code!
# Du kannst normale englische Farbnamen (wie 'red') oder HEX-Codes (wie '#ff0000') nutzen.
ui.colors(
primary='#b91c1c', # Hauptfarbe (z.B. für Standard-Buttons) - Hier ein dunkles Rot
secondary='#1f2937', # Zweitfarbe
accent='#3b82f6', # Akzentfarbe (z.B. Blau)
positive='#22c55e', # Farbe für Erfolg (Grün)
negative='#ef4444', # Farbe für Fehler/Abbruch (Rot)
info='#3b82f6', # Info-Farbe
warning='#f59e0b' # Warn-Farbe (Orange)
)
# (Optional) Wenn du die Hintergrundfarbe der ganzen Seite ändern willst:
# ui.query('body').style('background-color: #121212;')

View File

@ -1,37 +1,84 @@
from nicegui import ui, app
from gui import discord_login
import database
from gui import discord_login, gui_style
def setup_routes():
@ui.page('/')
def home_page():
ui.dark_mode(True)
gui_style.apply_design()
# --- NAVIGATIONSLEISTE (HEADER) ---
with ui.header().classes('items-center justify-between bg-zinc-900 p-4 shadow-lg'):
# --- LINKE SEITE ---
# Vereinslogo und den Titel in einer eigenen Reihe (Reihe 1)
with ui.row().classes('items-center gap-4'):
ui.image("gui/pictures/wsdg.png").classes('w-20 h-20 rounded-full')
ui.label('Diceghost Liga').classes('text-2xl font-bold text-white')
# --- RECHTE SEITE ---
if app.storage.user.get('authenticated', False):
with ui.row().classes('items-center gap-4'):
ui.label(app.storage.user.get('discord_name')).classes('text-lg text-gray-300')
discord_name = app.storage.user.get('discord_name')
display_name = app.storage.user.get('display_name')
db_id = app.storage.user.get('db_id')
# 1. Wir definieren eine kleine Funktion, die zwischen Text und Eingabe hin- und herschaltet
def toggle_edit_mode():
display_row.visible = not display_row.visible
edit_row.visible = not edit_row.visible
# --- ANSICHT 1: Der normale Text mit Edit-Button ---
with ui.row().classes('items-center gap-2') as display_row:
ui.label(display_name).classes('text-xl font-bold text-white')
ui.label('aka').classes('text-sm text-gray-500')
ui.label(discord_name).classes('text-lg text-gray-400')
# Ein runder Button (.props('round')), der exakt wie ein FAB aussieht!
ui.button(icon='edit', color='primary', on_click=toggle_edit_mode).props('round dense')
# --- ANSICHT 2: Das Eingabefeld (startet unsichtbar!) ---
with ui.row().classes('items-center gap-2') as edit_row:
edit_row.visible = False # Am Anfang verstecken
def save_new_name():
new_name = name_input.value
# Nur speichern, wenn ein Name drinsteht und er anders ist als vorher
if new_name and new_name != display_name:
import database
database.change_display_name(db_id, new_name) # Deine DB Funktion
app.storage.user['display_name'] = new_name
ui.notify('Name gespeichert!', color='positive')
ui.navigate.reload()
else:
# Wenn nichts geändert wurde, einfach wieder einklappen
toggle_edit_mode()
name_input = ui.input('Neuer Name', value=display_name).on('keydown.enter', save_new_name)
ui.button(icon='save', color='positive', on_click=save_new_name).props('round dense')
ui.button(icon='close', color='negative', on_click=toggle_edit_mode).props('round dense')
# ---------------------------------------------
avatar = app.storage.user.get('avatar_url')
if avatar:
ui.image(avatar).classes('w-12 h-12 rounded-full border-2 border-blue-500')
ui.image(avatar).classes('w-12 h-12 rounded-full border-2 border-red-500')
def logout():
app.storage.user.clear()
ui.navigate.to('/')
ui.button('Logout', on_click=logout).classes('mt-4 bg-red-500 text-white')
ui.button('Logout', on_click=logout).classes('bg-red-500 text-white')
else:
auth_url = discord_login.get_auth_url()
ui.button('Login with Discord', on_click=lambda: ui.navigate.to(auth_url))
# ----------------------------------
# --- Spielsysteme ---
if app.storage.user.get('authenticated', False):
with ui.card().classes("w-full"):
ui.button('Enter Match', on_click=lambda: ui.navigate.to('/add-match')).classes('mt-4 bg-blue-500 text-white')
ui.label(text="Meine Ligaplätze").classes("font-bold text-white")
with ui.row().classes("w-full h-30 gap-4 items-center"):
#Einfügen: Eine UI Card PRO Spielsystem des Spielers.
@ -44,7 +91,5 @@ def setup_routes():
with ui.card().classes("flex-1 h-24 items-center justify-center cursor-pointer hover:bg-zinc-800 transition-colors").on('click', lambda: ui.navigate.to('/statistic/Spearhead')):
ui.label(text="Spearhead").classes('text-xl font-bold')
with ui.card().classes("w-full"):
ui.label(text="Meine Statistik").classes("font-bold text-white")

View File

@ -1,11 +1,14 @@
from nicegui import ui, app
from gui import gui_style
def setup_match_routes():
# Unsere neue Unterseite für das Eintragen der Spiele
@ui.page('/add-match')
def add_match_page():
ui.dark_mode(True)
gui_style.apply_design()
with ui.card().classes('w-full items-center mt-10'):
ui.label('Enter New Match').classes('text-2xl font-bold')

BIN
gui/pictures/wsdg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 KiB

View File

@ -21,6 +21,7 @@ if not os.path.exists(db_file):
# 1. Erstellt die leere Datei und alle Tabellen-Strukturen
database.init_db()
database.seed_gamesystems()
database.seed_achievements()
print("Datenbank erfolgreich aufgebaut!")
else: