modified: app.py

This commit is contained in:
SimolZimol
2025-08-24 01:11:53 +02:00
parent 383f28a3f0
commit 3de4d6b455

207
app.py
View File

@@ -11,7 +11,6 @@ import mysql.connector
from datetime import datetime, timedelta
from flask_session import Session
import logging
import time
app = Flask(__name__)
app.secret_key = os.getenv("FLASK_SECRET_KEY")
@@ -87,68 +86,14 @@ def stop_bot():
print("Bot läuft nicht.")
def get_db_connection():
"""Stellt eine robuste Verbindung zur MySQL-Datenbank her mit Retry-Logik."""
retry_count = 3
retry_delay = 1
for attempt in range(retry_count):
try:
connection = mysql.connector.connect(
host=DB_HOST,
port=DB_PORT,
user=DB_USER,
password=DB_PASS,
database=DB_NAME,
autocommit=True,
pool_reset_session=True,
connect_timeout=10,
charset='utf8mb4',
collation='utf8mb4_unicode_ci',
use_unicode=True
)
# Test the connection
if connection.is_connected():
return connection
else:
connection.close()
raise mysql.connector.Error("Connection test failed")
except mysql.connector.Error as e:
print(f"Datenbankverbindung Versuch {attempt + 1} fehlgeschlagen: {e}")
if attempt < retry_count - 1:
time.sleep(retry_delay)
retry_delay *= 2 # Exponential backoff
else:
print("Alle Datenbankverbindungsversuche fehlgeschlagen")
raise
except Exception as e:
print(f"Unerwarteter Fehler bei Datenbankverbindung: {e}")
if attempt < retry_count - 1:
time.sleep(retry_delay)
retry_delay *= 2
else:
raise
def safe_close_connection(connection):
"""Schließt eine Datenbankverbindung sicher."""
try:
if connection and connection.is_connected():
connection.close()
except Exception as e:
print(f"Fehler beim Schließen der Datenbankverbindung: {e}")
class DatabaseConnection:
"""Context Manager für Datenbankverbindungen."""
def __init__(self):
self.connection = None
def __enter__(self):
self.connection = get_db_connection()
return self.connection
def __exit__(self, exc_type, exc_val, exc_tb):
safe_close_connection(self.connection)
"""Stellt eine Verbindung zur MySQL-Datenbank her."""
return mysql.connector.connect(
host=DB_HOST,
port=DB_PORT,
user=DB_USER,
password=DB_PASS,
database=DB_NAME
)
def token_updater(token):
session['oauth_token'] = token
@@ -271,29 +216,23 @@ def load_user_data():
g.is_admin = session.get("is_admin", False)
g.bot_running = bot_status() # Lädt den Bot-Status in g
# Hole die Liste der Gilden aus der Datenbank mit robuster Verbindung
try:
with DatabaseConnection() as connection:
cursor = connection.cursor(dictionary=True)
# Lade die Gilden des Nutzers
user_guilds = session.get("discord_guilds", [])
user_guild_ids = [guild["id"] for guild in user_guilds]
# Hole die Liste der Gilden aus der Datenbank
connection = get_db_connection()
cursor = connection.cursor(dictionary=True)
# Lade die Gilden des Nutzers
user_guilds = session.get("discord_guilds", [])
user_guild_ids = [guild["id"] for guild in user_guilds]
if user_guild_ids:
# Finde nur die Gilden, die auch in der Datenbank existieren
cursor.execute("SELECT guild_id FROM guilds WHERE guild_id IN (%s)" % ','.join(['%s'] * len(user_guild_ids)), user_guild_ids)
existing_guilds = cursor.fetchall()
# Finde nur die Gilden, die auch in der Datenbank existieren
cursor.execute("SELECT guild_id FROM guilds WHERE guild_id IN (%s)" % ','.join(['%s'] * len(user_guild_ids)), user_guild_ids)
existing_guilds = cursor.fetchall()
# Filtere die Gilden des Nutzers basierend auf der Existenz in der Datenbank
g.guilds = [guild for guild in user_guilds if int(guild["id"]) in {g["guild_id"] for g in existing_guilds}]
else:
g.guilds = []
# Filtere die Gilden des Nutzers basierend auf der Existenz in der Datenbank
g.guilds = [guild for guild in user_guilds if int(guild["id"]) in {g["guild_id"] for g in existing_guilds}]
cursor.close()
except Exception as e:
print(f"Fehler beim Laden der Benutzerdaten: {e}")
g.guilds = []
cursor.close()
connection.close()
else:
# Falls der Benutzer nicht eingeloggt ist, keine Daten setzen
g.user_info = None
@@ -543,34 +482,30 @@ def user_dashboard(guild_id):
# Debugging-Ausgaben
print(f"Accessing user_dashboard for user_id: {user_id}, guild_id: {guild_id}")
try:
# Hole die serverbezogenen Nutzerdaten
with DatabaseConnection() as connection:
cursor = connection.cursor(dictionary=True)
# Hole die serverbezogenen Nutzerdaten
connection = get_db_connection()
cursor = connection.cursor(dictionary=True)
# Überprüfe, ob der Benutzer Mitglied des Servers (Gilde) ist
cursor.execute("SELECT * FROM user_data WHERE user_id = %s AND guild_id = %s", (user_id, guild_id))
user_data = cursor.fetchone()
# Überprüfe, ob der Benutzer Mitglied des Servers (Gilde) ist
cursor.execute("SELECT * FROM user_data WHERE user_id = %s AND guild_id = %s", (user_id, guild_id))
user_data = cursor.fetchone()
# Debugging-Ausgabe für user_data
print(f"user_data for user_id {user_id} on guild_id {guild_id}: {user_data}")
# Debugging-Ausgabe für user_data
print(f"user_data for user_id {user_id} on guild_id {guild_id}: {user_data}")
cursor.close()
cursor.close()
connection.close()
if user_data:
# Falls `user_data` vorhanden ist, setze `g.guild_id` und `g.user_data`
g.guild_id = guild_id
g.user_data = user_data
print("Access granted to user_dashboard.")
return render_template("user_dashboard.html")
else:
# Debugging-Ausgabe für Fehlerfall
print(f"No access for user_id {user_id} on guild_id {guild_id}")
flash("You do not have access to this server.", "danger")
return redirect(url_for("user_landing_page"))
except Exception as e:
print(f"Fehler beim Laden des User-Dashboards: {e}")
flash("Fehler beim Laden des Dashboards. Bitte versuchen Sie es später erneut.", "error")
if user_data:
# Falls `user_data` vorhanden ist, setze `g.guild_id` und `g.user_data`
g.guild_id = guild_id
g.user_data = user_data
print("Access granted to user_dashboard.")
return render_template("user_dashboard.html")
else:
# Debugging-Ausgabe für Fehlerfall
print(f"No access for user_id {user_id} on guild_id {guild_id}")
flash("You do not have access to this server.", "danger")
return redirect(url_for("user_landing_page"))
# Falls der Benutzer nicht eingeloggt ist
@@ -582,42 +517,38 @@ def user_dashboard(guild_id):
def leaderboard(guild_id):
"""Zeigt das Level Leaderboard für einen bestimmten Server an."""
if "discord_user" in session:
try:
with DatabaseConnection() as connection:
cursor = connection.cursor(dictionary=True)
connection = get_db_connection()
cursor = connection.cursor(dictionary=True)
current_date = datetime.now()
one_month_ago = current_date - timedelta(days=30)
current_date = datetime.now()
one_month_ago = current_date - timedelta(days=30)
# Hole die Leaderboard-Daten
cursor.execute("""
SELECT nickname, profile_picture, level, xp, join_date
FROM user_data
WHERE guild_id = %s
AND ban = 0
AND (leave_date IS NULL OR leave_date > %s)
ORDER BY level DESC, xp DESC
""", (guild_id, one_month_ago))
leaderboard_data = cursor.fetchall()
# Hole die Leaderboard-Daten
cursor.execute("""
SELECT nickname, profile_picture, level, xp, join_date
FROM user_data
WHERE guild_id = %s
AND ban = 0
AND (leave_date IS NULL OR leave_date > %s)
ORDER BY level DESC, xp DESC
""", (guild_id, one_month_ago))
leaderboard_data = cursor.fetchall()
# Hole den Server-Namen aus der guilds-Tabelle
cursor.execute("SELECT name FROM guilds WHERE guild_id = %s", (guild_id,))
guild_name_result = cursor.fetchone()
guild_name = guild_name_result["name"] if guild_name_result else f"Server {guild_id}"
# Hole den Server-Namen aus der guilds-Tabelle
cursor.execute("SELECT name FROM guilds WHERE guild_id = %s", (guild_id,))
guild_name_result = cursor.fetchone()
guild_name = guild_name_result["name"] if guild_name_result else f"Server {guild_id}"
cursor.close()
cursor.close()
connection.close()
# Übergabe von enumerate und guild_name an das Template
return render_template("leaderboard.html",
leaderboard=leaderboard_data,
guild_id=guild_id,
guild_name=guild_name,
enumerate=enumerate)
except Exception as e:
print(f"Fehler beim Laden des Leaderboards: {e}")
flash("Fehler beim Laden des Leaderboards. Bitte versuchen Sie es später erneut.", "error")
return redirect(url_for("user_landing_page"))
# Übergabe von enumerate und guild_name an das Template
return render_template("leaderboard.html",
leaderboard=leaderboard_data,
guild_id=guild_id,
guild_name=guild_name,
enumerate=enumerate)
return redirect(url_for("landing_page"))