__version__ = "dev-0.6.2" __all__ = ["Discordbot-chatai-webpanel (Discord)"] __author__ = "SimolZimol" from flask import Flask, render_template, redirect, url_for, request, session, jsonify, send_file, flash, g from requests_oauthlib import OAuth2Session import os import subprocess import mysql.connector from datetime import datetime, timedelta from flask_session import Session import redis import requests app = Flask(__name__) app.secret_key = os.getenv("FLASK_SECRET_KEY") LOG_FILE_PATH = os.path.join("logs", f"{datetime.now().strftime('%Y-%m-%d')}.log") app.config["SESSION_TYPE"] = "filesystem" # Oder 'redis' für Redis-basierte Speicherung Session(app) print(f"Session Type: {app.config['SESSION_TYPE']}") DB_HOST = os.getenv("DB_HOST") DB_PORT = os.getenv("DB_PORT") DB_USER = os.getenv("DB_USER") DB_PASS = os.getenv("DB_PASSWORD") DB_NAME = os.getenv("DB_DATABASE") DISCORD_CLIENT_ID = os.getenv("DISCORD_CLIENT_ID") DISCORD_CLIENT_SECRET = os.getenv("DISCORD_CLIENT_SECRET") DISCORD_REDIRECT_URI = os.getenv("DISCORD_REDIRECT_URI") DISCORD_OAUTH2_URL = "https://discord.com/api/oauth2/authorize" DISCORD_TOKEN_URL = "https://discord.com/api/oauth2/token" DISCORD_API_URL = "https://discord.com/api/users/@me" os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' # Redis-Verbindung redis_url = "redis://:Uo28JDAlM3LiwjKyaOgyt08PCjJUKsW8dFKrcmZn3jN2TF074dNkFnQoSpyLo8WL@skgwsss0wc8040o4sgg044gs:6379/0" r = redis.Redis.from_url(redis_url) # Verzeichnis für Profilbilder PROFILE_IMAGE_DIR = 'static/profile_images' os.makedirs(PROFILE_IMAGE_DIR, exist_ok=True) bot_process = None def bot_status(): """Überprüft, ob der Bot läuft.""" global bot_process if bot_process is None: return False return bot_process.poll() is None # None bedeutet, dass der Prozess noch läuft def start_bot(): """Startet den Bot.""" global bot_process if not bot_status(): bot_process = subprocess.Popen(["python", "bot.py"], cwd=os.path.dirname(os.path.abspath(__file__))) else: print("Bot läuft bereits.") def stop_bot(): """Stoppt den Bot.""" global bot_process if bot_process and bot_status(): bot_process.terminate() bot_process.wait() # Warten, bis der Prozess beendet ist bot_process = None else: print("Bot läuft nicht.") def get_db_connection(): """Stellt eine Verbindung zur MySQL-Datenbank her und aktiviert die automatische Wiederverbindung.""" try: connection = mysql.connector.connect( host=DB_HOST, port=DB_PORT, user=DB_USER, password=DB_PASS, database=DB_NAME, connection_timeout=300, # Timeout auf 300 Sekunden setzen autocommit=True ) connection.reconnect(attempts=3, delay=5) # Versuche die Verbindung dreimal wiederherzustellen, mit 5 Sekunden Abstand return connection except mysql.connector.Error as e: print(f"Database error: {e}") return None def token_updater(token): session['oauth_token'] = token def make_discord_session(token=None, state=None): return OAuth2Session( DISCORD_CLIENT_ID, token=token or session.get("oauth_token"), state=state, redirect_uri=DISCORD_REDIRECT_URI, scope=["identify", "guilds"], auto_refresh_kwargs={ 'client_id': DISCORD_CLIENT_ID, 'client_secret': DISCORD_CLIENT_SECRET, }, auto_refresh_url=DISCORD_TOKEN_URL, token_updater=token_updater ) def fetch_and_cache_profile_picture(user_id, avatar_url): """Lädt das Profilbild herunter, speichert es lokal und in Redis, wenn es nicht vorhanden ist.""" # Überprüfen auf gültige user_id if not user_id or user_id == "": print(f"Invalid or empty user_id: {user_id}. Using default profile picture.") return "/static/default_profile.png" # Konvertiere user_id sicher zu einem String user_id_str = str(user_id) local_image_path = os.path.join(PROFILE_IMAGE_DIR, f"{user_id_str}.png") # Prüfe, ob das Bild lokal vorhanden ist if os.path.exists(local_image_path): print(f"Local image found for user {user_id}: {local_image_path}") r.set(user_id_str, local_image_path) # Speichere den Pfad in Redis für zukünftige Anfragen return local_image_path # Prüfe Redis für den Pfad cached_image = r.get(user_id_str) if cached_image: print(f"Redis cache hit for user {user_id}: {cached_image.decode('utf-8')}") return cached_image.decode('utf-8') # Wenn das Bild weder lokal noch in Redis vorhanden ist, versuche, es herunterzuladen if avatar_url: try: print(f"Downloading profile picture for user {user_id} from {avatar_url}") response = requests.get(avatar_url, timeout=10) response.raise_for_status() # Speichere das Bild lokal with open(local_image_path, 'wb') as img_file: img_file.write(response.content) # Speichere den Pfad in Redis r.set(user_id_str, local_image_path) print(f"Profile picture for user {user_id} downloaded and cached at {local_image_path}") return local_image_path except requests.RequestException as e: print(f"Failed to download profile picture for user {user_id}: {e}") return "/static/default_profile.png" print(f"No avatar URL provided for user {user_id}. Using default profile picture.") return "/static/default_profile.png" def get_profile_picture(user_id, avatar_url): """Gibt den Pfad zum Profilbild eines Benutzers zurück oder lädt es herunter, falls es nicht in Redis oder lokal vorhanden ist.""" cached_image = r.get(str(user_id)) if cached_image: print(f"Using cached image for user {user_id}") return cached_image.decode('utf-8') # Rückgabe des Pfads aus Redis return fetch_and_cache_profile_picture(user_id, avatar_url) @app.context_processor def utility_processor(): def get_profile_picture(user_id, avatar_url): return fetch_and_cache_profile_picture(user_id, avatar_url) return dict(get_profile_picture=get_profile_picture) @app.route("/update_all_profile_pictures") def update_all_profile_pictures(): """Aktualisiert alle Profilbilder der Benutzer.""" connection = get_db_connection() cursor = connection.cursor(dictionary=True) # Alle Benutzer mit Avatar-URL abrufen cursor.execute("SELECT user_id, profile_picture FROM user_data") users = cursor.fetchall() for user in users: user_id = user['user_id'] avatar_url = user['profile_picture'] if avatar_url: fetch_and_cache_profile_picture(user_id, avatar_url) cursor.close() connection.close() flash("Profile pictures updated successfully!", "success") return redirect(url_for("global_admin_dashboard")) @app.route("/logs") def view_logs(): """Zeigt die Logs des Bots im Admin-Panel an.""" if is_bot_admin(): return render_template("logs.html") return redirect(url_for("landing_page")) @app.route("/get_logs") def get_logs(): """Liest den Inhalt der Log-Datei und gibt ihn zurück.""" if is_bot_admin(): try: with open(LOG_FILE_PATH, 'r', encoding='utf-8') as file: logs = file.read() return jsonify({"logs": logs}) except FileNotFoundError: return jsonify({"logs": "Log file not found."}) return redirect(url_for("landing_page")) @app.route("/download_logs") def download_logs(): """Bietet die Log-Datei zum Download an.""" if is_bot_admin(): return send_file(LOG_FILE_PATH, as_attachment=True) return redirect(url_for("landing_page")) def is_bot_admin(): """Überprüft, ob der Benutzer globale Admin-Rechte hat.""" if "discord_user" in session: user_info = session["discord_user"] user_id = user_info["id"] connection = get_db_connection() cursor = connection.cursor(dictionary=True) cursor.execute("SELECT global_permission FROM bot_data WHERE user_id = %s", (user_id,)) user_data = cursor.fetchone() cursor.close() connection.close() return user_data and user_data["global_permission"] >= 8 return False def is_server_admin(guild_id): """Überprüft, ob der Benutzer Admin-Rechte auf einem bestimmten Server (Guild) hat.""" if "discord_user" in session: user_info = session["discord_user"] user_id = user_info["id"] connection = get_db_connection() cursor = connection.cursor(dictionary=True) cursor.execute("SELECT permission FROM user_data WHERE user_id = %s AND guild_id = %s", (user_id, guild_id)) user_data = cursor.fetchone() cursor.close() connection.close() return user_data and user_data["permission"] >= 8 return False @app.route("/") def landing_page(): """Landing Page""" return render_template("landing.html") @app.route("/about") def about(): """Öffentliche Über-uns-Seite""" return render_template("about.html") @app.route("/contact") def contact(): """Öffentliche Kontaktseite""" return render_template("contact.html") @app.route("/faq") def faq(): """Öffentliche FAQ-Seite""" return render_template("faq.html") @app.route("/help") def help_page(): """Öffentliche Hilfeseite""" return render_template("help.html") @app.route("/login") def login(): """Startet den Discord-OAuth2-Flow.""" discord = make_discord_session() authorization_url, state = discord.authorization_url(DISCORD_OAUTH2_URL) session['oauth_state'] = state return redirect(authorization_url) @app.before_request def load_user_data(): """Lädt Benutzerdaten vor jeder Anfrage für geschützte Routen.""" if "discord_user" in session: g.user_info = session["discord_user"] 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 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] # 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}] cursor.close() connection.close() else: # Falls der Benutzer nicht eingeloggt ist, keine Daten setzen g.user_info = None g.is_admin = False g.guilds = [] g.bot_running = False @app.route("/callback") def callback(): """Verarbeitet den OAuth2-Rückruf von Discord.""" try: discord = make_discord_session(state=session.get("oauth_state")) token = discord.fetch_token( DISCORD_TOKEN_URL, client_secret=DISCORD_CLIENT_SECRET, authorization_response=request.url, ) session['oauth_token'] = token # Abrufen der Benutzerinformationen von Discord user_info = discord.get(DISCORD_API_URL).json() session['discord_user'] = user_info # Hole die Gilden (Server), auf denen der Benutzer ist guilds_response = discord.get('https://discord.com/api/users/@me/guilds') if guilds_response.status_code != 200: flash("Fehler beim Abrufen der Gilden.", "danger") return redirect(url_for("landing_page")) guilds = guilds_response.json() session['discord_guilds'] = guilds # Speichere die Gilden in der Session # Prüfe die Admin-Berechtigungen in der bot_data Tabelle connection = get_db_connection() cursor = connection.cursor(dictionary=True) cursor.execute("SELECT global_permission FROM bot_data WHERE user_id = %s", (user_info["id"],)) bot_admin_data = cursor.fetchone() # Speichere Admin-Rechte in der Session session['is_admin'] = bool(bot_admin_data and bot_admin_data['global_permission'] >= 8) cursor.close() connection.close() # Leite zur User-Landing-Page weiter return redirect(url_for("user_landing_page")) except Exception as e: print(f"Error in OAuth2 callback: {e}") flash("Ein Fehler ist beim Authentifizierungsprozess aufgetreten.", "danger") return redirect(url_for("landing_page")) @app.route("/user_server_data/") def user_server_data(guild_id): """Zeigt die serverbezogenen Nutzerdaten für den ausgewählten Server an.""" if "discord_user" in session: user_info = session["discord_user"] user_id = user_info["id"] connection = get_db_connection() cursor = connection.cursor(dictionary=True) # Hole die serverbezogenen Nutzerdaten cursor.execute("SELECT * FROM user_data WHERE user_id = %s AND guild_id = %s", (user_id, guild_id)) user_data = cursor.fetchone() cursor.close() connection.close() if user_data: return render_template("user_server_data.html", user_info=user_info, user_data=user_data, guild_id=guild_id) else: flash("Keine Daten für diesen Server gefunden.", "warning") return redirect(url_for("user_landing_page")) return redirect(url_for("landing_page")) @app.route("/server_admin_dashboard/") def server_admin_dashboard(guild_id): """Serverbasiertes Admin-Dashboard für server-spezifische Admin-Rechte.""" if is_server_admin(guild_id): connection = get_db_connection() cursor = connection.cursor(dictionary=True) # Giveaways für den Server abrufen cursor.execute("SELECT * FROM giveaway_data WHERE guild_id = %s", (guild_id,)) giveaways = cursor.fetchall() # Benutzer auf dem Server abrufen cursor.execute("SELECT * FROM user_data WHERE guild_id = %s", (guild_id,)) server_users = cursor.fetchall() # Servername aus der guilds-Tabelle holen 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 "Unknown Guild" cursor.close() connection.close() return render_template("server_admin_dashboard.html", giveaways=giveaways, server_users=server_users, guild_id=guild_id, guild_name=guild_name) flash("You do not have permission to access this server's admin dashboard.", "danger") return redirect(url_for("user_landing_page")) @app.route("/edit_user//", methods=["GET", "POST"]) def edit_user(guild_id, user_id): """Bearbeitet die Daten eines spezifischen Benutzers auf einem bestimmten Server.""" if is_server_admin(guild_id): connection = get_db_connection() cursor = connection.cursor(dictionary=True) # Hole die Berechtigungen des aktuellen Admins admin_user_id = session["discord_user"]["id"] cursor.execute("SELECT permission FROM user_data WHERE guild_id = %s AND user_id = %s", (guild_id, admin_user_id)) admin_data = cursor.fetchone() max_permission = admin_data["permission"] if admin_data else 0 if request.method == "POST": points = int(request.form.get("points", 0)) level = int(request.form.get("level", 1)) ban = int(request.form.get("ban", 0)) permission = int(request.form.get("permission", 0)) askmultus = int(request.form.get("askmultus", 0)) filter_value = int(request.form.get("filter_value", 0)) rank = request.form.get("rank", "") xp = int(request.form.get("xp", 0)) # Validierung der Berechtigungen if permission > max_permission: flash("You cannot assign a permission level higher than your own.", "danger") return redirect(url_for("edit_user", guild_id=guild_id, user_id=user_id)) # Update der Benutzerdaten cursor.execute(""" UPDATE user_data SET points = %s, level = %s, ban = %s, permission = %s, askmultus = %s, filter_value = %s, rank = %s, xp = %s WHERE guild_id = %s AND user_id = %s """, (points, level, ban, permission, askmultus, filter_value, rank, xp, guild_id, user_id)) connection.commit() flash("User data updated successfully!", "success") return redirect(url_for("server_admin_dashboard", guild_id=guild_id)) # Daten des spezifischen Benutzers laden cursor.execute("SELECT * FROM user_data WHERE guild_id = %s AND user_id = %s", (guild_id, user_id)) user_data = cursor.fetchone() cursor.close() connection.close() return render_template("edit_user.html", user_data=user_data, guild_id=guild_id, max_permission=max_permission) return redirect(url_for("landing_page")) @app.route("/ban_user//") def ban_user(guild_id, user_id): """Banned einen Benutzer auf einem spezifischen Server.""" if is_server_admin(guild_id): connection = get_db_connection() cursor = connection.cursor() try: cursor.execute("UPDATE user_data SET ban = 1 WHERE user_id = %s AND guild_id = %s", (user_id, guild_id)) connection.commit() return redirect(url_for("server_admin_dashboard", guild_id=guild_id)) except Exception as e: print(f"Error banning user: {e}") connection.rollback() return redirect(url_for("server_admin_dashboard", guild_id=guild_id)) finally: cursor.close() connection.close() return redirect(url_for("landing_page")) @app.route("/update_points//", methods=["POST"]) def update_points(guild_id, user_id): """Aktualisiert die Punkte eines Benutzers auf einem spezifischen Server.""" if is_server_admin(guild_id): points_change = int(request.form["points_change"]) connection = get_db_connection() cursor = connection.cursor() try: cursor.execute("UPDATE user_data SET points = points + %s WHERE user_id = %s AND guild_id = %s", (points_change, user_id, guild_id)) connection.commit() return redirect(url_for("server_admin_dashboard", guild_id=guild_id)) except Exception as e: print(f"Error updating points: {e}") connection.rollback() return redirect(url_for("server_admin_dashboard", guild_id=guild_id)) finally: cursor.close() connection.close() return redirect(url_for("landing_page")) @app.route("/unban_user//") def unban_user(guild_id, user_id): """Entbannt einen Benutzer auf einem spezifischen Server.""" if is_server_admin(guild_id): connection = get_db_connection() cursor = connection.cursor() try: cursor.execute("UPDATE user_data SET ban = 0 WHERE user_id = %s AND guild_id = %s", (user_id, guild_id)) connection.commit() return redirect(url_for("server_admin_dashboard", guild_id=guild_id)) except Exception as e: print(f"Error unbanning user: {e}") connection.rollback() return redirect(url_for("server_admin_dashboard", guild_id=guild_id)) finally: cursor.close() connection.close() return redirect(url_for("landing_page")) @app.route("/update_role//", methods=["POST"]) def update_role(guild_id, user_id): """Aktualisiert die Rolle (Berechtigung) eines Benutzers auf einem spezifischen Server.""" if is_server_admin(guild_id): new_permission = request.form["permission"] connection = get_db_connection() cursor = connection.cursor() try: cursor.execute("UPDATE user_data SET permission = %s WHERE user_id = %s AND guild_id = %s", (new_permission, user_id, guild_id)) connection.commit() return redirect(url_for("server_admin_dashboard", guild_id=guild_id)) except Exception as e: print(f"Error updating role: {e}") connection.rollback() return redirect(url_for("server_admin_dashboard", guild_id=guild_id)) finally: cursor.close() connection.close() return redirect(url_for("landing_page")) @app.route("/user_dashboard/") def user_dashboard(guild_id): """Serverbasiertes User-Dashboard""" if g.user_info: user_id = g.user_info["id"] # Debugging-Ausgaben print(f"Accessing user_dashboard for user_id: {user_id}, guild_id: {guild_id}") # 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() # Debugging-Ausgabe für user_data print(f"user_data for user_id {user_id} on guild_id {guild_id}: {user_data}") 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")) # Falls der Benutzer nicht eingeloggt ist print("User not logged in, redirecting to landing page.") flash("Please log in to view your dashboard.", "danger") return redirect(url_for("landing_page")) @app.route("/user_dashboard//leaderboard") def leaderboard(guild_id): """Zeigt das Level Leaderboard für einen bestimmten Server an.""" if "discord_user" in session: connection = get_db_connection() cursor = connection.cursor(dictionary=True) current_date = datetime.now() one_month_ago = current_date - timedelta(days=30) 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() cursor.close() connection.close() # Übergabe von enumerate an das Template return render_template("leaderboard.html", leaderboard=leaderboard_data, guild_id=guild_id, enumerate=enumerate) return redirect(url_for("landing_page")) @app.route("/server_giveaways/") def server_giveaways(guild_id): """Serverbasiertes Giveaway-Management.""" if is_server_admin(guild_id): connection = get_db_connection() cursor = connection.cursor(dictionary=True) # Hole die Giveaways für den spezifischen Server cursor.execute("SELECT * FROM giveaway_data WHERE guild_id = %s", (guild_id,)) giveaways = cursor.fetchall() cursor.close() connection.close() return render_template("server_giveaways.html", giveaways=giveaways, guild_id=guild_id) return redirect(url_for("landing_page")) @app.route("/edit_giveaway//", methods=["GET", "POST"]) def edit_giveaway(guild_id, uuid): """Bearbeitet ein spezifisches Giveaway für einen bestimmten Server.""" if is_server_admin(guild_id): connection = get_db_connection() cursor = connection.cursor(dictionary=True) if request.method == "POST": platform = request.form.get("platform") name = request.form.get("name") game_key = request.form.get("game_key") winner_dc_id = request.form.get("winner_dc_id") aktiv = bool(request.form.get("aktiv")) # Update der Giveaways-Daten cursor.execute(""" UPDATE giveaway_data SET platform = %s, name = %s, game_key = %s, winner_dc_id = %s, aktiv = %s WHERE guild_id = %s AND uuid = %s """, (platform, name, game_key, winner_dc_id, aktiv, guild_id, uuid)) connection.commit() flash("Giveaway updated successfully!", "success") # Nach dem Speichern zum server_admin_dashboard weiterleiten return redirect(url_for("server_admin_dashboard", guild_id=guild_id)) # Daten des spezifischen Giveaways laden cursor.execute("SELECT * FROM giveaway_data WHERE guild_id = %s AND uuid = %s", (guild_id, uuid)) giveaway = cursor.fetchone() cursor.close() connection.close() return render_template("edit_giveaway.html", giveaway=giveaway, guild_id=guild_id) return redirect(url_for("landing_page")) @app.route("/user_giveaways/") def user_giveaways(guild_id): """Zeigt dem Benutzer die Giveaways an, die er auf einem bestimmten Server gewonnen hat.""" if "discord_user" in session: user_info = session["discord_user"] user_id = user_info["id"] connection = get_db_connection() cursor = connection.cursor(dictionary=True) # Suche nach Giveaways, bei denen der eingeloggte Benutzer der Gewinner ist cursor.execute(""" SELECT * FROM giveaway_data WHERE winner_dc_id = %s AND guild_id = %s """, (user_id, guild_id)) won_giveaways = cursor.fetchall() # Hole den Servernamen 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() connection.close() return render_template("user_giveaways.html", won_giveaways=won_giveaways, guild_id=guild_id, guild_name=guild_name) return redirect(url_for("landing_page")) @app.route("/redeem_giveaway//", methods=["GET", "POST"]) def redeem_giveaway(guild_id, uuid): """Erlaubt dem Benutzer, einen gewonnenen Giveaway-Code für einen bestimmten Server einzulösen und erneut anzuzeigen, falls bereits eingelöst.""" if "discord_user" in session: user_info = session["discord_user"] user_id = user_info["id"] connection = get_db_connection() cursor = connection.cursor(dictionary=True) # Überprüfen, ob der eingeloggte Benutzer der Gewinner ist cursor.execute(""" SELECT * FROM giveaway_data WHERE guild_id = %s AND uuid = %s AND winner_dc_id = %s """, (guild_id, uuid, user_id)) giveaway = cursor.fetchone() if giveaway: if request.method == "POST" and not giveaway["aktiv"]: # Wenn der Benutzer den Key einlöst, setze `aktiv` auf TRUE cursor.execute("UPDATE giveaway_data SET aktiv = TRUE WHERE guild_id = %s AND uuid = %s", (guild_id, uuid)) connection.commit() giveaway["aktiv"] = True # Aktualisiere den Status in `giveaway` für die Anzeige flash("Giveaway redeemed successfully!", "success") # Zeige den Game Key an, ob er eingelöst ist oder gerade eingelöst wurde return render_template("redeem_giveaway.html", giveaway=giveaway, key=giveaway["game_key"] if giveaway["aktiv"] else None) else: flash("You are not the winner of this giveaway or the giveaway is no longer available.", "danger") cursor.close() connection.close() return redirect(url_for("user_giveaways", guild_id=guild_id)) return redirect(url_for("landing_page")) @app.route("/user_landing_page") def user_landing_page(): """Zeigt die globale Benutzerdaten und die Liste der Server an.""" if g.user_info and "discord_guilds" in session: guilds = session["discord_guilds"] return render_template("user_landing_page.html", user_info=g.user_info, guilds=guilds) return redirect(url_for("landing_page")) @app.route("/global_admin_dashboard") def global_admin_dashboard(): """Globales Admin-Dashboard nur für globale Admins""" if g.is_admin: bot_running = bot_status() # Funktion, die den Status des Bots prüft return render_template("global_admin_dashboard.html", user_info=g.user_info, bot_running=bot_running) return redirect(url_for("user_landing_page")) @app.route("/logout") def logout(): """Meldet den Benutzer ab.""" session.clear() return redirect(url_for("landing_page")) # Bot Management Routes @app.route("/start_bot") def start(): if g.is_admin: start_bot() return redirect(url_for("global_admin_dashboard")) return redirect(url_for("landing_page")) @app.route("/stop_bot") def stop(): if g.is_admin: stop_bot() return redirect(url_for("global_admin_dashboard")) return redirect(url_for("landing_page")) if __name__ == "__main__": app.run(host="0.0.0.0", port=5000, debug=True)