diff --git a/app.py b/app.py index a1cc212..bd44cbf 100644 --- a/app.py +++ b/app.py @@ -93,36 +93,17 @@ def make_discord_session(token=None, state=None): scope=["identify"] ) -def is_global_admin(): - """Überprüft, ob der Benutzer globale Admin-Rechte hat.""" +def is_admin(): + """Überprüft, ob der Benutzer Admin-Rechte hat.""" if "discord_user" in session: user_info = session["discord_user"] user_id = user_info["id"] - # Überprüfe die globalen Admin-Rechte des Benutzers + # Überprüfe die Admin-Rechte des Benutzers 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() - - if user_data and user_data["global_permission"] >= 8: - return True - 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)) + cursor.execute("SELECT permission FROM user_data WHERE user_id = %s", (user_id,)) user_data = cursor.fetchone() cursor.close() @@ -146,6 +127,26 @@ def login(): session['oauth_state'] = state return redirect(authorization_url) +@app.route("/about") +def about(): + """Zeigt eine öffentliche Über uns Seite an.""" + return render_template("about.html") + +@app.route("/contact") +def contact(): + """Zeigt eine öffentliche Kontaktseite an.""" + return render_template("contact.html") + +@app.route("/faq") +def faq(): + """Zeigt eine öffentliche FAQ Seite an.""" + return render_template("faq.html") + +@app.route("/help") +def help_page(): + """Zeigt eine öffentliche Hilfeseite an.""" + return render_template("help.html") + @app.route("/callback") def callback(): """Verarbeitet den OAuth2-Rückruf von Discord.""" @@ -164,114 +165,66 @@ def callback(): # Speichere die Benutzerinformationen in der Session session['discord_user'] = user_info - # Überprüfe, ob der Benutzer globale Admin-Rechte hat - if is_global_admin(): - return redirect(url_for("global_admin_dashboard")) - else: - return redirect(url_for("select_guild")) + # Hole Benutzerrollen und andere Daten aus der Datenbank + connection = get_db_connection() + cursor = connection.cursor(dictionary=True) + + cursor.execute("SELECT permission FROM user_data WHERE user_id = %s", (user_info["id"],)) + user_data = cursor.fetchone() + + cursor.close() + connection.close() -@app.route("/select_guild") -def select_guild(): - """Bietet dem Benutzer eine Liste der Server (Guilds), auf denen er Mitglied ist.""" + # Weiterleiten basierend auf den Berechtigungen + if user_data and user_data["permission"] >= 8: + return redirect(url_for("admin_dashboard")) + else: + return redirect(url_for("user_dashboard")) + +@app.route("/admin_dashboard") +def admin_dashboard(): + """Zeigt das Admin-Dashboard an (nur für Admins).""" if "discord_user" in session: user_info = session["discord_user"] user_id = user_info["id"] + # Überprüfe, ob der Benutzer Admin-Rechte hat connection = get_db_connection() cursor = connection.cursor(dictionary=True) - cursor.execute("SELECT DISTINCT guild_id FROM user_data WHERE user_id = %s", (user_id,)) - guilds = cursor.fetchall() + cursor.execute("SELECT permission FROM user_data WHERE user_id = %s", (user_id,)) + user_data = cursor.fetchone() + + cursor.close() + connection.close() + + if user_data and user_data["permission"] >= 8: + return render_template("admin_dashboard.html", user_info=user_info, bot_running=bot_status()) + else: + return redirect(url_for("user_dashboard")) + return redirect(url_for("landing_page")) + +@app.route("/user_dashboard") +def user_dashboard(): + """Zeigt das User-Dashboard 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) + + cursor.execute("SELECT points, permission, ban FROM user_data WHERE user_id = %s", (user_id,)) + user_data = cursor.fetchone() cursor.close() connection.close() - return render_template("select_guild.html", guilds=guilds) - return redirect(url_for("login")) - -@app.route("/server_dashboard/") -def server_dashboard(guild_id): - """Zeigt das Server-Admin-Dashboard an (nur für Admins eines bestimmten Servers).""" - if is_server_admin(guild_id): - connection = get_db_connection() - cursor = connection.cursor(dictionary=True) - - # Hole Server-spezifische Daten (Giveaways, Punkte usw.) - cursor.execute("SELECT * FROM giveaway_data WHERE guild_id = %s", (guild_id,)) - giveaways = cursor.fetchall() - - cursor.close() - connection.close() - - return render_template("server_dashboard.html", guild_id=guild_id, giveaways=giveaways) - return redirect(url_for("select_guild")) - -@app.route("/global_admin_dashboard") -def global_admin_dashboard(): - """Zeigt das globale Admin-Dashboard an (nur für globale Admins).""" - if is_global_admin(): - user_info = session["discord_user"] - return render_template("global_admin_dashboard.html", user_info=user_info, bot_running=bot_status()) - return redirect(url_for("select_guild")) - -@app.route("/start_bot") -def start(): - if is_global_admin(): - start_bot() - user_info = session["discord_user"] - return render_template("global_admin_dashboard.html", user_info=user_info, bot_running=bot_status()) + if user_data: + return render_template("user_dashboard.html", user_info=user_info, user_data=user_data, bot_running=bot_status()) + else: + return "User data not found", 404 return redirect(url_for("landing_page")) -@app.route("/stop_bot") -def stop(): - if is_global_admin(): - stop_bot() - user_info = session["discord_user"] - return render_template("global_admin_dashboard.html", user_info=user_info, bot_running=bot_status()) - return redirect(url_for("landing_page")) - -@app.route("/server_settings/", methods=["GET", "POST"]) -def server_settings(guild_id): - """Server-spezifische Einstellungen für den Server-Admin.""" - if is_server_admin(guild_id): - if request.method == "POST": - introduction = request.form.get("introduction") - asknotes_introduction = request.form.get("asknotes_introduction") - - # Speichern der Intros - save_text_file(INTRO_FILE, introduction) - save_text_file(ASKNOTES_INTRO_FILE, asknotes_introduction) - - return redirect(url_for("server_settings", guild_id=guild_id)) - - # Laden der aktuellen Inhalte aus den Textdateien - introduction = load_text_file(INTRO_FILE) - asknotes_introduction = load_text_file(ASKNOTES_INTRO_FILE) - - return render_template("server_settings.html", guild_id=guild_id, introduction=introduction, asknotes_introduction=asknotes_introduction) - return redirect(url_for("select_guild")) - -@app.route("/global_settings", methods=["GET", "POST"]) -def global_settings(): - """Globale Einstellungen für den Bot-Admin.""" - if is_global_admin(): - if request.method == "POST": - introduction = request.form.get("introduction") - asknotes_introduction = request.form.get("asknotes_introduction") - - # Speichern der Intros - save_text_file(INTRO_FILE, introduction) - save_text_file(ASKNOTES_INTRO_FILE, asknotes_introduction) - - return redirect(url_for("global_settings")) - - # Laden der aktuellen Inhalte aus den Textdateien - introduction = load_text_file(INTRO_FILE) - asknotes_introduction = load_text_file(ASKNOTES_INTRO_FILE) - - return render_template("global_settings.html", introduction=introduction, asknotes_introduction=asknotes_introduction) - return redirect(url_for("global_admin_dashboard")) - @app.route("/logout") def logout(): """Löscht die Benutzersitzung und meldet den Benutzer ab.""" @@ -279,40 +232,280 @@ def logout(): session.pop('oauth_token', None) return redirect(url_for('landing_page')) -@app.route("/server_giveaways/") -def server_giveaways(guild_id): - """Zeigt die Giveaways für einen spezifischen Server an.""" - if is_server_admin(guild_id): +@app.route("/start_bot") +def start(): + if is_admin(): + start_bot() + user_info = session["discord_user"] + return render_template("admin_dashboard.html", user_info=user_info, bot_running=bot_status()) + return redirect(url_for("landing_page")) + + +@app.route("/stop_bot") +def stop(): + if is_admin(): + stop_bot() + user_info = session["discord_user"] + return render_template("admin_dashboard.html", user_info=user_info, bot_running=bot_status()) + return redirect(url_for("landing_page")) + +@app.route("/settings", methods=["GET", "POST"]) +def settings(): + if is_admin(): + if request.method == "POST": + introduction = request.form.get("introduction") + asknotes_introduction = request.form.get("asknotes_introduction") + + # Speichern der Intros + save_text_file(INTRO_FILE, introduction) + save_text_file(ASKNOTES_INTRO_FILE, asknotes_introduction) + + return redirect(url_for("settings")) + + # Laden der aktuellen Inhalte aus den Textdateien + introduction = load_text_file(INTRO_FILE) + asknotes_introduction = load_text_file(ASKNOTES_INTRO_FILE) + + return render_template("settings.html", introduction=introduction, asknotes_introduction=asknotes_introduction) + return redirect(url_for("landing_page")) + +@app.route("/users") +def users(): + """Zeigt eine Liste aller Benutzer an.""" + if is_admin(): connection = get_db_connection() cursor = connection.cursor(dictionary=True) - cursor.execute("SELECT * FROM giveaway_data WHERE guild_id = %s", (guild_id,)) - giveaways = cursor.fetchall() + cursor.execute("SELECT user_id, permission, points, ban FROM user_data") + users = cursor.fetchall() cursor.close() connection.close() + return render_template("users.html", users=users) + return redirect(url_for("landing_page")) - return render_template("server_giveaways.html", guild_id=guild_id, giveaways=giveaways) - return redirect(url_for("select_guild")) - -@app.route("/global_giveaways", methods=["GET", "POST"]) -def global_giveaways(): - """Zeigt globale Giveaways an und ermöglicht globale Änderungen.""" - if is_global_admin(): +@app.route("/ban_user/") +def ban_user(user_id): + """Banned einen Benutzer.""" + if is_admin(): connection = get_db_connection() + cursor = connection.cursor() + + try: + cursor.execute("UPDATE user_data SET ban = 1 WHERE user_id = %s", (user_id,)) + connection.commit() + return redirect(url_for("users")) + except Exception as e: + print(f"Error banning user: {e}") + connection.rollback() + return redirect(url_for("users")) + finally: + cursor.close() + connection.close() + return redirect(url_for("landing_page")) + +@app.route("/update_points/", methods=["POST"]) +def update_points(user_id): + """Aktualisiert die Punkte eines Benutzers.""" + if is_admin(): + 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", (points_change, user_id)) + connection.commit() + return redirect(url_for("users")) + except Exception as e: + print(f"Error updating points: {e}") + connection.rollback() + return redirect(url_for("users")) + finally: + cursor.close() + connection.close() + return redirect(url_for("landing_page")) + +@app.route("/unban_user/") +def unban_user(user_id): + """Entbannt einen Benutzer.""" + if is_admin(): + connection = get_db_connection() + cursor = connection.cursor() + + try: + cursor.execute("UPDATE user_data SET ban = 0 WHERE user_id = %s", (user_id,)) + connection.commit() + return redirect(url_for("users")) + except Exception as e: + print(f"Error unbanning user: {e}") + connection.rollback() + return redirect(url_for("users")) + finally: + cursor.close() + connection.close() + return redirect(url_for("landing_page")) + +@app.route("/update_role/", methods=["POST"]) +def update_role(user_id): + """Aktualisiert die Rolle (Berechtigung) eines Benutzers.""" + if is_admin(): + 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", (new_permission, user_id)) + connection.commit() + return redirect(url_for("users")) + except Exception as e: + print(f"Error updating role: {e}") + connection.rollback() + return redirect(url_for("users")) + finally: + cursor.close() + connection.close() + return redirect(url_for("landing_page")) + +@app.route("/logs") +def view_logs(): + """Zeigt die Logs des Bots im Admin-Panel an.""" + if is_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_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_admin(): + return send_file(LOG_FILE_PATH, as_attachment=True) + return redirect(url_for("landing_page")) + +@app.route("/admin/giveaways", methods=["GET", "POST"]) +def admin_giveaways(): + """Zeigt eine Liste aller Giveaways an und ermöglicht das Bearbeiten und Sortieren.""" + if is_admin(): + connection = get_giveaway_db_connection() # Verbindung zur Giveaway-Datenbank cursor = connection.cursor(dictionary=True) + # Sortierung nach bestimmten Feldern sort_field = request.args.get("sort", "id") # Standardmäßig nach 'id' sortieren order = request.args.get("order", "asc") # Standardmäßig aufsteigend sortieren - cursor.execute(f"SELECT * FROM giveaway_data ORDER BY {sort_field} {order}") + # Holen aller Giveaways aus der Datenbank + cursor.execute(f"SELECT * FROM giveaways ORDER BY {sort_field} {order}") giveaways = cursor.fetchall() cursor.close() connection.close() - return render_template("global_giveaways.html", giveaways=giveaways) - return redirect(url_for("global_admin_dashboard")) + return render_template("admin_giveaways.html", giveaways=giveaways, sort_field=sort_field, order=order) + return redirect(url_for("login")) + +@app.route("/admin/giveaways/edit/", methods=["GET", "POST"]) +def edit_giveaway(giveaway_id): + """Bearbeitet ein spezifisches Giveaway.""" + if is_admin(): + connection = get_giveaway_db_connection() # Verbindung zur Giveaway-Datenbank + 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 giveaways + SET platform = %s, name = %s, game_key = %s, winner_dc_id = %s, aktiv = %s + WHERE id = %s + """, (platform, name, game_key, winner_dc_id, aktiv, giveaway_id)) + connection.commit() + + flash("Giveaway updated successfully!", "success") + return redirect(url_for("admin_giveaways")) + + # Daten des spezifischen Giveaways laden + cursor.execute("SELECT * FROM giveaways WHERE id = %s", (giveaway_id,)) + giveaway = cursor.fetchone() + + cursor.close() + connection.close() + + return render_template("edit_giveaway.html", giveaway=giveaway) + return redirect(url_for("login")) + + +@app.route("/user/giveaways", methods=["GET"]) +def user_giveaways(): + """Zeigt dem Benutzer die Giveaways, die er gewonnen hat.""" + if "discord_user" in session: + user_info = session["discord_user"] + user_id = user_info["id"] + + connection = get_giveaway_db_connection() # Verbindung zur Giveaway-Datenbank + cursor = connection.cursor(dictionary=True) + + # Suche nach Giveaways, bei denen der eingeloggte Benutzer der Gewinner ist + cursor.execute(""" + SELECT * FROM giveaways WHERE winner_dc_id = %s + """, (user_id,)) + won_giveaways = cursor.fetchall() + + cursor.close() + connection.close() + + return render_template("user_giveaways.html", user_info=user_info, giveaways=won_giveaways) + + return redirect(url_for("login")) + +@app.route("/user/giveaway/redeem/", methods=["GET", "POST"]) +def redeem_giveaway(uuid): + """Erlaubt dem Benutzer, den Giveaway-Code abzurufen.""" + if "discord_user" in session: + user_info = session["discord_user"] + user_id = user_info["id"] + + connection = get_giveaway_db_connection() # Verbindung zur Giveaway-Datenbank + cursor = connection.cursor(dictionary=True) + + # Überprüfen, ob der eingeloggte Benutzer der Gewinner ist + cursor.execute("SELECT * FROM giveaways WHERE uuid = %s AND winner_dc_id = %s", (uuid, user_id)) + giveaway = cursor.fetchone() + + if giveaway: + if request.method == "POST": + # Wenn der Benutzer den Key aufdeckt, setze `aktiv` auf TRUE + cursor.execute("UPDATE giveaways SET aktiv = TRUE WHERE uuid = %s", (uuid,)) + connection.commit() + + # Key aufdecken + return render_template("redeem_giveaway.html", giveaway=giveaway, key=giveaway["game_key"]) + + # Zeige die Seite mit dem Button an, um den Key aufzudecken + return render_template("redeem_giveaway.html", giveaway=giveaway, key=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")) + + return redirect(url_for("login")) if __name__ == "__main__": app.run(host="0.0.0.0", port=5000, debug=True)