modified: app.py
This commit is contained in:
207
app.py
207
app.py
@@ -11,7 +11,6 @@ import mysql.connector
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from flask_session import Session
|
from flask_session import Session
|
||||||
import logging
|
import logging
|
||||||
import time
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.secret_key = os.getenv("FLASK_SECRET_KEY")
|
app.secret_key = os.getenv("FLASK_SECRET_KEY")
|
||||||
@@ -87,68 +86,14 @@ def stop_bot():
|
|||||||
print("Bot läuft nicht.")
|
print("Bot läuft nicht.")
|
||||||
|
|
||||||
def get_db_connection():
|
def get_db_connection():
|
||||||
"""Stellt eine robuste Verbindung zur MySQL-Datenbank her mit Retry-Logik."""
|
"""Stellt eine Verbindung zur MySQL-Datenbank her."""
|
||||||
retry_count = 3
|
return mysql.connector.connect(
|
||||||
retry_delay = 1
|
host=DB_HOST,
|
||||||
|
port=DB_PORT,
|
||||||
for attempt in range(retry_count):
|
user=DB_USER,
|
||||||
try:
|
password=DB_PASS,
|
||||||
connection = mysql.connector.connect(
|
database=DB_NAME
|
||||||
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)
|
|
||||||
|
|
||||||
def token_updater(token):
|
def token_updater(token):
|
||||||
session['oauth_token'] = token
|
session['oauth_token'] = token
|
||||||
@@ -271,29 +216,23 @@ def load_user_data():
|
|||||||
g.is_admin = session.get("is_admin", False)
|
g.is_admin = session.get("is_admin", False)
|
||||||
g.bot_running = bot_status() # Lädt den Bot-Status in g
|
g.bot_running = bot_status() # Lädt den Bot-Status in g
|
||||||
|
|
||||||
# Hole die Liste der Gilden aus der Datenbank mit robuster Verbindung
|
# Hole die Liste der Gilden aus der Datenbank
|
||||||
try:
|
connection = get_db_connection()
|
||||||
with DatabaseConnection() as connection:
|
cursor = connection.cursor(dictionary=True)
|
||||||
cursor = connection.cursor(dictionary=True)
|
|
||||||
|
# Lade die Gilden des Nutzers
|
||||||
# Lade die Gilden des Nutzers
|
user_guilds = session.get("discord_guilds", [])
|
||||||
user_guilds = session.get("discord_guilds", [])
|
user_guild_ids = [guild["id"] for guild in user_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
|
||||||
# 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)
|
||||||
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()
|
||||||
existing_guilds = cursor.fetchall()
|
|
||||||
|
|
||||||
# Filtere die Gilden des Nutzers basierend auf der Existenz in der Datenbank
|
# 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}]
|
g.guilds = [guild for guild in user_guilds if int(guild["id"]) in {g["guild_id"] for g in existing_guilds}]
|
||||||
else:
|
|
||||||
g.guilds = []
|
|
||||||
|
|
||||||
cursor.close()
|
cursor.close()
|
||||||
except Exception as e:
|
connection.close()
|
||||||
print(f"Fehler beim Laden der Benutzerdaten: {e}")
|
|
||||||
g.guilds = []
|
|
||||||
else:
|
else:
|
||||||
# Falls der Benutzer nicht eingeloggt ist, keine Daten setzen
|
# Falls der Benutzer nicht eingeloggt ist, keine Daten setzen
|
||||||
g.user_info = None
|
g.user_info = None
|
||||||
@@ -543,34 +482,30 @@ def user_dashboard(guild_id):
|
|||||||
# Debugging-Ausgaben
|
# Debugging-Ausgaben
|
||||||
print(f"Accessing user_dashboard for user_id: {user_id}, guild_id: {guild_id}")
|
print(f"Accessing user_dashboard for user_id: {user_id}, guild_id: {guild_id}")
|
||||||
|
|
||||||
try:
|
# Hole die serverbezogenen Nutzerdaten
|
||||||
# Hole die serverbezogenen Nutzerdaten
|
connection = get_db_connection()
|
||||||
with DatabaseConnection() as connection:
|
cursor = connection.cursor(dictionary=True)
|
||||||
cursor = connection.cursor(dictionary=True)
|
|
||||||
|
|
||||||
# Überprüfe, ob der Benutzer Mitglied des Servers (Gilde) ist
|
# Ü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))
|
cursor.execute("SELECT * FROM user_data WHERE user_id = %s AND guild_id = %s", (user_id, guild_id))
|
||||||
user_data = cursor.fetchone()
|
user_data = cursor.fetchone()
|
||||||
|
|
||||||
# Debugging-Ausgabe für user_data
|
# Debugging-Ausgabe für user_data
|
||||||
print(f"user_data for user_id {user_id} on guild_id {guild_id}: {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:
|
if user_data:
|
||||||
# Falls `user_data` vorhanden ist, setze `g.guild_id` und `g.user_data`
|
# Falls `user_data` vorhanden ist, setze `g.guild_id` und `g.user_data`
|
||||||
g.guild_id = guild_id
|
g.guild_id = guild_id
|
||||||
g.user_data = user_data
|
g.user_data = user_data
|
||||||
print("Access granted to user_dashboard.")
|
print("Access granted to user_dashboard.")
|
||||||
return render_template("user_dashboard.html")
|
return render_template("user_dashboard.html")
|
||||||
else:
|
else:
|
||||||
# Debugging-Ausgabe für Fehlerfall
|
# Debugging-Ausgabe für Fehlerfall
|
||||||
print(f"No access for user_id {user_id} on guild_id {guild_id}")
|
print(f"No access for user_id {user_id} on guild_id {guild_id}")
|
||||||
flash("You do not have access to this server.", "danger")
|
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")
|
|
||||||
return redirect(url_for("user_landing_page"))
|
return redirect(url_for("user_landing_page"))
|
||||||
|
|
||||||
# Falls der Benutzer nicht eingeloggt ist
|
# Falls der Benutzer nicht eingeloggt ist
|
||||||
@@ -582,42 +517,38 @@ def user_dashboard(guild_id):
|
|||||||
def leaderboard(guild_id):
|
def leaderboard(guild_id):
|
||||||
"""Zeigt das Level Leaderboard für einen bestimmten Server an."""
|
"""Zeigt das Level Leaderboard für einen bestimmten Server an."""
|
||||||
if "discord_user" in session:
|
if "discord_user" in session:
|
||||||
try:
|
connection = get_db_connection()
|
||||||
with DatabaseConnection() as connection:
|
cursor = connection.cursor(dictionary=True)
|
||||||
cursor = connection.cursor(dictionary=True)
|
|
||||||
|
|
||||||
current_date = datetime.now()
|
current_date = datetime.now()
|
||||||
one_month_ago = current_date - timedelta(days=30)
|
one_month_ago = current_date - timedelta(days=30)
|
||||||
|
|
||||||
# Hole die Leaderboard-Daten
|
# Hole die Leaderboard-Daten
|
||||||
cursor.execute("""
|
cursor.execute("""
|
||||||
SELECT nickname, profile_picture, level, xp, join_date
|
SELECT nickname, profile_picture, level, xp, join_date
|
||||||
FROM user_data
|
FROM user_data
|
||||||
WHERE guild_id = %s
|
WHERE guild_id = %s
|
||||||
AND ban = 0
|
AND ban = 0
|
||||||
AND (leave_date IS NULL OR leave_date > %s)
|
AND (leave_date IS NULL OR leave_date > %s)
|
||||||
ORDER BY level DESC, xp DESC
|
ORDER BY level DESC, xp DESC
|
||||||
""", (guild_id, one_month_ago))
|
""", (guild_id, one_month_ago))
|
||||||
|
|
||||||
leaderboard_data = cursor.fetchall()
|
leaderboard_data = cursor.fetchall()
|
||||||
|
|
||||||
# Hole den Server-Namen aus der guilds-Tabelle
|
# Hole den Server-Namen aus der guilds-Tabelle
|
||||||
cursor.execute("SELECT name FROM guilds WHERE guild_id = %s", (guild_id,))
|
cursor.execute("SELECT name FROM guilds WHERE guild_id = %s", (guild_id,))
|
||||||
guild_name_result = cursor.fetchone()
|
guild_name_result = cursor.fetchone()
|
||||||
guild_name = guild_name_result["name"] if guild_name_result else f"Server {guild_id}"
|
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
|
# Übergabe von enumerate und guild_name an das Template
|
||||||
return render_template("leaderboard.html",
|
return render_template("leaderboard.html",
|
||||||
leaderboard=leaderboard_data,
|
leaderboard=leaderboard_data,
|
||||||
guild_id=guild_id,
|
guild_id=guild_id,
|
||||||
guild_name=guild_name,
|
guild_name=guild_name,
|
||||||
enumerate=enumerate)
|
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"))
|
|
||||||
return redirect(url_for("landing_page"))
|
return redirect(url_for("landing_page"))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user