app.py aktualisiert

This commit is contained in:
2025-08-08 08:40:10 +00:00
parent e916e4ebc1
commit 36e28be051

115
app.py
View File

@@ -1,82 +1,53 @@
from flask import Flask, render_template, request, redirect, url_for, send_from_directory, flash # app.py
from pytube import YouTube from flask import Flask, jsonify, request
import subprocess
import sys
import os import os
import re # Für das Bereinigen von Dateinamen import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
app = Flask(__name__) app = Flask(__name__)
app.secret_key = 'dein_super_geheimer_schlüssel' # Wichtig für Flash-Nachrichten
DOWNLOAD_FOLDER = 'downloads' SCRIPT_MAP = {
if not os.path.exists(DOWNLOAD_FOLDER): "run_duplicate_check": {
os.makedirs(DOWNLOAD_FOLDER) "script": "duplicate_checker.py",
"args": []
},
"run_reclassify_branches": {
"script": "brancheneinstufung.py", # oder brancheneinstufung2.py
"args": ["--mode", "reclassify_branches"]
},
"run_predict_technicians": {
"script": "brancheneinstufung.py", # oder brancheneinstufung2.py
"args": ["--mode", "predict_technicians"]
}
}
def sanitize_filename(filename): @app.route('/run-script', methods=['POST']) # <-- Der korrekte Endpunkt
"""Entfernt ungültige Zeichen aus Dateinamen.""" def run_script():
return re.sub(r'[\\/*?:"<>|]', "", filename) data = request.get_json()
action = data.get('action')
@app.route('/')
def index(): if not action or action not in SCRIPT_MAP:
try: return jsonify({"status": "error", "message": "Ungültige oder fehlende Aktion."}), 400
# Liste nur .mp4 Dateien auf
downloaded_files = [f for f in os.listdir(DOWNLOAD_FOLDER) if f.endswith('.mp4')]
except FileNotFoundError:
downloaded_files = []
return render_template('index.html', files=downloaded_files)
@app.route('/download', methods=['POST'])
def download_video():
video_url = request.form.get('youtube_url')
if not video_url:
flash('Bitte gib eine YouTube URL ein.', 'error')
return redirect(url_for('index'))
try:
yt = YouTube(video_url)
# Wähle den Stream mit der höchsten Auflösung, der progressiv ist (Audio+Video) und mp4 ist script_config = SCRIPT_MAP[action]
stream = yt.streams.filter(progressive=True, file_extension='mp4')\ script_name = script_config["script"]
.order_by('resolution')\ script_args = script_config["args"]
.desc()\
.first() if not os.path.exists(script_name):
logging.error(f"Skript '{script_name}' für Aktion '{action}' nicht gefunden.")
if not stream: return jsonify({"status": "error", "message": f"Server-Fehler: Skript '{script_name}' nicht gefunden."}), 500
flash(f'Kein passender MP4 Stream für {yt.title} gefunden.', 'error')
return redirect(url_for('index'))
# Bereinige den Titel für den Dateinamen
filename = sanitize_filename(yt.title) + ".mp4"
filepath = os.path.join(DOWNLOAD_FOLDER, filename)
# Überprüfen, ob die Datei bereits existiert
if os.path.exists(filepath):
flash(f'Video "{yt.title}" wurde bereits heruntergeladen.', 'info')
return redirect(url_for('index'))
flash(f'Starte Download für: {yt.title}...', 'info')
# Wichtig: Um Flask nicht zu blockieren, könnte man hier Threading/Async verwenden,
# aber für ein "einfaches" Skript ist dies der direkteste Weg.
# Bei langen Downloads kann der Browser einen Timeout anzeigen, obwohl der Download im Hintergrund läuft.
stream.download(output_path=DOWNLOAD_FOLDER, filename=filename)
flash(f'Video "{yt.title}" erfolgreich heruntergeladen!', 'success')
try:
logging.info(f"Starte Aktion '{action}' -> Skript: '{script_name}' mit Argumenten: {script_args}")
python_executable = sys.executable
command = [python_executable, script_name] + script_args
subprocess.Popen(command)
return jsonify({"status": "success", "message": f"Aktion '{action}' wurde erfolgreich gestartet."}), 200
except Exception as e: except Exception as e:
import traceback logging.error(f"Fehler beim Starten des Skripts für Aktion '{action}': {e}")
print("---------- ERROR DETAILS ----------") return jsonify({"status": "error", "message": str(e)}), 500
print(f"Error type: {type(e)}")
print(f"Error message: {str(e)}")
print("Traceback:")
traceback.print_exc() # Gibt den kompletten Traceback auf der Konsole aus
print("---------------------------------")
flash(f'Ein Fehler ist aufgetreten: {str(e)}', 'error')
return redirect(url_for('index'))
return redirect(url_for('index'))
@app.route('/play/<filename>')
def play_video(filename):
# send_from_directory ermöglicht das direkte Abspielen/Herunterladen der Datei
return send_from_directory(DOWNLOAD_FOLDER, filename, as_attachment=False) # as_attachment=False versucht, es im Browser abzuspielen
if __name__ == '__main__': if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5555) # host='0.0.0.0' macht es im lokalen Netzwerk erreichbar app.run(host='0.0.0.0', port=5000)