import time import csv import os import threading from flask import Blueprint, request, redirect, url_for, flash, render_template, send_file, current_app from flask_login import login_user, logout_user, login_required, current_user from werkzeug.utils import secure_filename from werkzeug.security import generate_password_hash, check_password_hash from .models import db, User, Job from .webcrawler import process_file # Importiere die Funktion für das Webscraping UPLOAD_FOLDER = 'uploads' RESULT_FOLDER = 'results' # Blueprint für auth erstellen bp = Blueprint('auth', __name__) @bp.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': username = request.form['username'] password = request.form['password'] user = User.query.filter_by(username=username).first() if user and check_password_hash(user.password, password): login_user(user) return redirect(url_for('auth.job_status')) flash('Login fehlgeschlagen. Überprüfen Sie Benutzername und Passwort.') return render_template('login.html') @bp.route('/signup', methods=['GET', 'POST']) def signup(): if not current_app.config['ALLOW_USER_SIGNUP']: flash("Registrierung ist derzeit deaktiviert.") return redirect(url_for('auth.login')) if request.method == 'POST': username = request.form['username'] password = generate_password_hash(request.form['password'], method='sha256') new_user = User(username=username, password=password) db.session.add(new_user) db.session.commit() flash('Benutzer erfolgreich erstellt! Sie können sich jetzt einloggen.') return redirect(url_for('auth.login')) return render_template('signup.html') @bp.route('/logout') @login_required def logout(): logout_user() return redirect(url_for('auth.login')) @bp.route('/jobs') @login_required def job_status(): jobs = Job.query.filter_by(user_id=current_user.id).all() return render_template('jobs.html', jobs=jobs) @bp.route('/upload', methods=['GET', 'POST']) @login_required def upload(): if request.method == 'POST': file = request.files['file'] filename = secure_filename(file.filename) # Überprüfen, ob eine Datei mit dem gleichen Namen bereits existiert file_path = os.path.join(current_app.config['UPLOAD_FOLDER'], filename) if os.path.exists(file_path): # Wenn eine Datei mit dem gleichen Namen existiert, einen Zeitstempel hinzufügen name, ext = os.path.splitext(filename) timestamp = time.strftime("%Y%m%d-%H%M%S") # Zeitstempel im Format JahrMonatTag-StundenMinutenSekunden filename = f"{name}_{timestamp}{ext}" file_path = os.path.join(current_app.config['UPLOAD_FOLDER'], filename) flash(f"Eine Datei mit gleichem Namen existierte bereits. Die Datei wurde als '{filename}' gespeichert.") # Speichern der Datei file.save(file_path) flash('Datei erfolgreich hochgeladen und Job gestartet') # Neuen Job erstellen new_job = Job(user_id=current_user.id, filename=filename, status="Pending") db.session.add(new_job) db.session.commit() # Debugging-Ausgabe zur Überprüfung der Thread-Erstellung print(f"Starte Scraping-Thread für Job-ID: {new_job.id}") # Starten des Scraping im Hintergrund-Thread und Übergeben des aktuellen Anwendungskontexts thread = threading.Thread(target=process_file, args=(filename, new_job.id, current_app._get_current_object())) thread.start() # Debugging-Ausgabe, nachdem der Thread gestartet wurde print(f"Thread für Job {new_job.id} erfolgreich gestartet.") return redirect(url_for('auth.job_status')) return render_template('upload.html') @bp.route('/download/', methods=['GET']) @login_required def download_result(job_id): job = Job.query.get_or_404(job_id) print(f"Job ID: {job.id} - User ID: {job.user_id} - Current User ID: {current_user.id}") # Überprüfen, ob der Job dem aktuellen Benutzer gehört if job.user_id != current_user.id: flash("Sie haben keine Berechtigung, dieses Ergebnis herunterzuladen.") return redirect(url_for('auth.job_status')) # Überprüfen, ob das Ergebnis vorhanden ist if not job.result_filename: flash("Das Ergebnis ist noch nicht verfügbar.") return redirect(url_for('auth.job_status')) # Überprüfen, ob die Datei im angegebenen Pfad existiert result_path = os.path.join(current_app.config['RESULT_FOLDER'], job.result_filename) print(f"Versuche, Datei herunterzuladen von: {result_path}") if os.path.exists(result_path): print("Datei existiert und wird zum Download bereitgestellt.") return send_file(result_path, as_attachment=True) else: print("Datei nicht gefunden. Ergebnisverzeichnis oder Pfad prüfen.") flash("Ergebnisdatei nicht gefunden.") return redirect(url_for('auth.job_status')) @bp.route('/delete_job/', methods=['POST']) @login_required def delete_job(job_id): job = Job.query.get_or_404(job_id) if job.user_id != current_user.id: flash("Sie haben keine Berechtigung, diesen Job zu löschen.") return redirect(url_for('auth.job_status')) # Löschen der Upload-Datei upload_path = os.path.join(current_app.config['UPLOAD_FOLDER'], job.filename) if os.path.exists(upload_path): os.remove(upload_path) print(f"Upload-Datei gelöscht: {upload_path}") else: print(f"Upload-Datei nicht gefunden: {upload_path}") # Löschen der Results-Datei, falls vorhanden if job.result_filename: result_path = os.path.join(current_app.config['RESULT_FOLDER'], job.result_filename) print(f"Versuche Ergebnisdatei zu löschen: {result_path}") if os.path.exists(result_path): try: os.remove(result_path) print(f"Ergebnisdatei gelöscht: {result_path}") except Exception as e: print(f"Fehler beim Löschen der Ergebnisdatei: {e}") else: print(f"Ergebnisdatei nicht gefunden im Pfad: {result_path}") # Job aus der Datenbank löschen db.session.delete(job) db.session.commit() flash("Job erfolgreich gelöscht.") return redirect(url_for('auth.job_status')) @bp.route('/admin', methods=['GET']) @login_required def admin_panel(): if not current_user.is_admin: flash("Keine Berechtigung.") return redirect(url_for('auth.job_status')) users = User.query.all() return render_template('admin_panel.html', users=users) @bp.route('/admin/create_user', methods=['POST']) @login_required def create_user(): if not current_user.is_admin: flash("Keine Berechtigung.") return redirect(url_for('auth.admin_panel')) username = request.form['username'] password = request.form['password'] is_admin = 'is_admin' in request.form # Checkbox für Adminrechte hashed_password = generate_password_hash(password, method='sha256') new_user = User(username=username, password=hashed_password, is_admin=is_admin) db.session.add(new_user) db.session.commit() flash(f"Benutzer {username} wurde erstellt.") return redirect(url_for('auth.admin_panel')) @bp.route('/admin/reset_password/', methods=['POST']) @login_required def reset_password(user_id): if not current_user.is_admin: flash("Keine Berechtigung.") return redirect(url_for('auth.admin_panel')) user = User.query.get_or_404(user_id) new_password = request.form['new_password'] user.password = generate_password_hash(new_password, method='sha256') db.session.commit() flash(f"Passwort für Benutzer {user.username} wurde zurückgesetzt.") return redirect(url_for('auth.admin_panel')) @bp.route('/admin/delete_user/', methods=['POST']) @login_required def delete_user(user_id): if not current_user.is_admin: flash("Keine Berechtigung.") return redirect(url_for('auth.admin_panel')) user = User.query.get_or_404(user_id) if user.is_admin: flash("Administratoren können nicht gelöscht werden.") return redirect(url_for('auth.admin_panel')) db.session.delete(user) db.session.commit() flash(f"Benutzer {user.username} wurde gelöscht.") return redirect(url_for('auth.admin_panel'))