from flask import Blueprint, jsonify, send_from_directory from server.database import Session from models.models import EventMedia import os # Blueprint for direct file downloads by media ID files_bp = Blueprint("files", __name__, url_prefix="/api/files") # Reuse the same media root convention as eventmedia.py BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) MEDIA_ROOT = os.path.join(BASE_DIR, "media") @files_bp.route("//", methods=["GET"]) def download_media_file(media_id: int, filename: str): """ Download the stored media file for a given EventMedia ID. URL format example: /api/files/26/LPUV4I_Folien_Nowitzki_Bewertungskriterien.pptx Behavior: - Looks up EventMedia by ID - Validates requested filename against stored metadata (best-effort) - Serves the file from server/media using the stored relative file_path """ session = Session() media = session.query(EventMedia).get(media_id) if not media: session.close() return jsonify({"error": "Not found"}), 404 # Prefer the stored relative file_path; fall back to the URL/filename rel_path = media.file_path or media.url # Basic filename consistency check to avoid leaking other files # Only enforce if media.url is present if media.url and os.path.basename(filename) != os.path.basename(media.url): session.close() return jsonify({ "error": "Filename mismatch", "expected": os.path.basename(media.url), "got": os.path.basename(filename), }), 400 abs_path = os.path.join(MEDIA_ROOT, rel_path) # Ensure file exists if not os.path.isfile(abs_path): session.close() return jsonify({"error": "File not found on server"}), 404 # Serve as attachment (download) directory = os.path.dirname(abs_path) served_name = os.path.basename(abs_path) session.close() return send_from_directory(directory, served_name, as_attachment=True)