API/DB: add Event.muted with full CRUD wiring (Alembic migration), persist/return with autoplay/loop/volume
Dashboard: per‑event video options (autoplay/loop/volume/muted) with system defaults; Settings → Events → Videos defaults
Settings UX: nested tabs with controlled selection; Academic Calendar: merge “Schulferien Import”+“Liste” into “📥 Import & Liste”
Docs: update README and copilot-instructions (video payload, streaming 206, defaults keys); update program-info.json changelog; bump version to 2025.1.0‑alpha.11
73 lines
3.4 KiB
Python
73 lines
3.4 KiB
Python
from sqlalchemy import create_engine, text
|
||
import os
|
||
from dotenv import load_dotenv
|
||
import bcrypt
|
||
|
||
# .env laden
|
||
load_dotenv()
|
||
|
||
DB_URL = f"mysql+pymysql://{os.getenv('DB_USER')}:{os.getenv('DB_PASSWORD')}@{os.getenv('DB_HOST')}:3306/{os.getenv('DB_NAME')}"
|
||
engine = create_engine(DB_URL, isolation_level="AUTOCOMMIT")
|
||
|
||
with engine.connect() as conn:
|
||
# Default-Gruppe mit id=1 anlegen, falls nicht vorhanden
|
||
result = conn.execute(
|
||
text("SELECT COUNT(*) FROM client_groups WHERE id=1"))
|
||
if result.scalar() == 0:
|
||
conn.execute(
|
||
text(
|
||
"INSERT INTO client_groups (id, name, is_active) VALUES (1, 'Nicht zugeordnet', 1)")
|
||
)
|
||
print("✅ Default-Gruppe mit id=1 angelegt.")
|
||
|
||
# Superadmin-Benutzer anlegen, falls nicht vorhanden
|
||
admin_user = os.getenv("DEFAULT_SUPERADMIN_USERNAME", "superadmin")
|
||
admin_pw = os.getenv("DEFAULT_SUPERADMIN_PASSWORD")
|
||
|
||
if not admin_pw:
|
||
print("⚠️ DEFAULT_SUPERADMIN_PASSWORD nicht gesetzt. Superadmin wird nicht erstellt.")
|
||
else:
|
||
# Passwort hashen mit bcrypt
|
||
hashed_pw = bcrypt.hashpw(admin_pw.encode(
|
||
'utf-8'), bcrypt.gensalt()).decode('utf-8')
|
||
# Prüfen, ob User existiert
|
||
result = conn.execute(text(
|
||
"SELECT COUNT(*) FROM users WHERE username=:username"), {"username": admin_user})
|
||
if result.scalar() == 0:
|
||
# Rolle: 'superadmin' gemäß UserRole enum
|
||
conn.execute(
|
||
text("INSERT INTO users (username, password_hash, role, is_active) VALUES (:username, :password_hash, 'superadmin', 1)"),
|
||
{"username": admin_user, "password_hash": hashed_pw}
|
||
)
|
||
print(f"✅ Superadmin-Benutzer '{admin_user}' angelegt.")
|
||
else:
|
||
print(f"ℹ️ Superadmin-Benutzer '{admin_user}' existiert bereits.")
|
||
|
||
# Default System Settings anlegen
|
||
default_settings = [
|
||
('supplement_table_url', '', 'URL für Vertretungsplan / WebUntis (Stundenplan-Änderungstabelle)'),
|
||
('supplement_table_enabled', 'false', 'Ob Vertretungsplan aktiviert ist'),
|
||
('presentation_interval', '10', 'Standard Intervall für Präsentationen (Sekunden)'),
|
||
('presentation_page_progress', 'true', 'Seitenfortschrift anzeigen (Page-Progress) für Präsentationen'),
|
||
('presentation_auto_progress', 'true', 'Automatischer Fortschritt (Auto-Progress) für Präsentationen'),
|
||
('video_autoplay', 'true', 'Autoplay (automatisches Abspielen) für Videos'),
|
||
('video_loop', 'true', 'Loop (Wiederholung) für Videos'),
|
||
('video_volume', '0.8', 'Standard Lautstärke für Videos (0.0 - 1.0)'),
|
||
]
|
||
|
||
for key, value, description in default_settings:
|
||
result = conn.execute(
|
||
text("SELECT COUNT(*) FROM system_settings WHERE `key`=:key"),
|
||
{"key": key}
|
||
)
|
||
if result.scalar() == 0:
|
||
conn.execute(
|
||
text("INSERT INTO system_settings (`key`, value, description) VALUES (:key, :value, :description)"),
|
||
{"key": key, "value": value, "description": description}
|
||
)
|
||
print(f"✅ System-Einstellung '{key}' angelegt.")
|
||
else:
|
||
print(f"ℹ️ System-Einstellung '{key}' existiert bereits.")
|
||
|
||
print("✅ Initialisierung abgeschlossen.")
|