Database angepasst. Code aufgeräumt. Silly Name Generator. gui_style Sheet.
This commit is contained in:
parent
4c6d069ed3
commit
5774138ecb
|
|
@ -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"}
|
||||||
98
database.py
98
database.py
|
|
@ -1,4 +1,5 @@
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
import random
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
@ -16,8 +17,9 @@ def init_db():
|
||||||
CREATE TABLE IF NOT EXISTS players (
|
CREATE TABLE IF NOT EXISTS players (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
discord_id TEXT UNIQUE,
|
discord_id TEXT UNIQUE,
|
||||||
name TEXT NOT NULL,
|
discord_name TEXT NOT NULL,
|
||||||
avatar_url TEXT
|
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.commit()
|
||||||
connection.close()
|
connection.close()
|
||||||
print("Database structures created successfully!")
|
|
||||||
seed_gamesystems()
|
|
||||||
print("Standard Daten in die DB Geschrieben.")
|
print("Standard Daten in die DB Geschrieben.")
|
||||||
|
|
||||||
|
# --------------------
|
||||||
|
# --- Start Setup der DB Daten. Damit sie nicht GANZ leer sind.
|
||||||
|
# --------------------
|
||||||
def seed_gamesystems():
|
def seed_gamesystems():
|
||||||
connection = sqlite3.connect("warhammer_league.db")
|
connection = sqlite3.connect("warhammer_league.db")
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
|
|
@ -85,26 +112,56 @@ def seed_gamesystems():
|
||||||
connection.close()
|
connection.close()
|
||||||
print("Spielsysteme wurden angelegt!")
|
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):
|
def get_or_create_player(discord_id, discord_name, avatar_url):
|
||||||
connection = sqlite3.connect("warhammer_league.db")
|
connection = sqlite3.connect("warhammer_league.db")
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
|
|
||||||
# REPARIERT: Wir fragen nur noch id, name und avatar_url aus 'players' ab
|
# REPARIERT: Wir fragen 4 Dinge ab (id, discord_name, display_name, discord_avatar_url)
|
||||||
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()
|
player = cursor.fetchone()
|
||||||
|
|
||||||
if player is None:
|
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()
|
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()
|
player = cursor.fetchone()
|
||||||
else:
|
else:
|
||||||
# Falls sich Name oder Bild auf Discord geändert haben, machen wir ein Update
|
# 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()
|
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()
|
player = cursor.fetchone()
|
||||||
|
|
||||||
connection.close()
|
connection.close()
|
||||||
|
|
@ -127,4 +184,23 @@ def get_all_players():
|
||||||
return result
|
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}"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,8 @@ def setup_login_routes():
|
||||||
app.storage.user['discord_id'] = discord_id
|
app.storage.user['discord_id'] = discord_id
|
||||||
app.storage.user['discord_name'] = discord_name
|
app.storage.user['discord_name'] = discord_name
|
||||||
app.storage.user['db_id'] = player[0]
|
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('/')
|
ui.navigate.to('/')
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
20
gui/gui_style.py
Normal file
20
gui/gui_style.py
Normal 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;')
|
||||||
|
|
@ -1,37 +1,84 @@
|
||||||
from nicegui import ui, app
|
from nicegui import ui, app
|
||||||
from gui import discord_login
|
import database
|
||||||
|
from gui import discord_login, gui_style
|
||||||
|
|
||||||
def setup_routes():
|
def setup_routes():
|
||||||
@ui.page('/')
|
@ui.page('/')
|
||||||
def home_page():
|
def home_page():
|
||||||
ui.dark_mode(True)
|
gui_style.apply_design()
|
||||||
|
|
||||||
# --- NAVIGATIONSLEISTE (HEADER) ---
|
# --- NAVIGATIONSLEISTE (HEADER) ---
|
||||||
with ui.header().classes('items-center justify-between bg-zinc-900 p-4 shadow-lg'):
|
with ui.header().classes('items-center justify-between bg-zinc-900 p-4 shadow-lg'):
|
||||||
ui.label('Diceghost Liga').classes('text-2xl font-bold text-white')
|
|
||||||
|
|
||||||
|
# --- 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):
|
if app.storage.user.get('authenticated', False):
|
||||||
with ui.row().classes('items-center gap-4'):
|
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')
|
avatar = app.storage.user.get('avatar_url')
|
||||||
if avatar:
|
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():
|
def logout():
|
||||||
app.storage.user.clear()
|
app.storage.user.clear()
|
||||||
ui.navigate.to('/')
|
ui.navigate.to('/')
|
||||||
|
|
||||||
|
ui.button('Logout', on_click=logout).classes('bg-red-500 text-white')
|
||||||
|
|
||||||
ui.button('Logout', on_click=logout).classes('mt-4 bg-red-500 text-white')
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
auth_url = discord_login.get_auth_url()
|
auth_url = discord_login.get_auth_url()
|
||||||
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))
|
||||||
|
# ----------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# --- 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.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")
|
ui.label(text="Meine Ligaplätze").classes("font-bold text-white")
|
||||||
with ui.row().classes("w-full h-30 gap-4 items-center"):
|
with ui.row().classes("w-full h-30 gap-4 items-center"):
|
||||||
#Einfügen: Eine UI Card PRO Spielsystem des Spielers.
|
#Einfügen: Eine UI Card PRO Spielsystem des Spielers.
|
||||||
|
|
@ -43,8 +90,6 @@ 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')):
|
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')
|
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")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
from nicegui import ui, app
|
from nicegui import ui, app
|
||||||
|
from gui import gui_style
|
||||||
|
|
||||||
def setup_match_routes():
|
def setup_match_routes():
|
||||||
|
|
||||||
# Unsere neue Unterseite für das Eintragen der Spiele
|
# Unsere neue Unterseite für das Eintragen der Spiele
|
||||||
@ui.page('/add-match')
|
@ui.page('/add-match')
|
||||||
def add_match_page():
|
def add_match_page():
|
||||||
ui.dark_mode(True)
|
|
||||||
|
gui_style.apply_design()
|
||||||
|
|
||||||
with ui.card().classes('w-full items-center mt-10'):
|
with ui.card().classes('w-full items-center mt-10'):
|
||||||
ui.label('Enter New Match').classes('text-2xl font-bold')
|
ui.label('Enter New Match').classes('text-2xl font-bold')
|
||||||
|
|
||||||
|
|
|
||||||
BIN
gui/pictures/wsdg.png
Normal file
BIN
gui/pictures/wsdg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 464 KiB |
1
main.py
1
main.py
|
|
@ -21,6 +21,7 @@ if not os.path.exists(db_file):
|
||||||
# 1. Erstellt die leere Datei und alle Tabellen-Strukturen
|
# 1. Erstellt die leere Datei und alle Tabellen-Strukturen
|
||||||
database.init_db()
|
database.init_db()
|
||||||
database.seed_gamesystems()
|
database.seed_gamesystems()
|
||||||
|
database.seed_achievements()
|
||||||
|
|
||||||
print("Datenbank erfolgreich aufgebaut!")
|
print("Datenbank erfolgreich aufgebaut!")
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user