import os from flask import g, request, jsonify, url_for import auth from core.flask_app import app @app.route("/assets/upload", methods=["POST"]) def upload_user_asset(): """"Mes assets" (voir auth/user_assets_dir.py) : mirroir de routes/uploads/upload_file.py, mais stocké PAR COMPTE plutôt que par jeu, pour être réutilisable dans n'importe quel projet du même compte. Écriture disque + ligne base factorisées dans auth.save_user_asset (partagé avec la génération IA, voir ai/tools.py::_dispatch_add_generated_image).""" f = request.files.get("file") if not f or not f.filename: return jsonify({"error": "Aucun fichier reçu"}), 400 ext = "".join(c for c in os.path.splitext(f.filename)[1].lower() if c.isalnum() or c == ".")[:10] content = f.read() file_kind = auth.user_asset_kind(f.filename) # Un son ne doit jamais dépasser 3 minutes (demande explicite, voir # auth/validate_audio_duration.py) — vérifié sur le CONTENU réel du # fichier (mutagen lit ses métadonnées), jamais sur une durée # annoncée par le client, qui ne serait pas fiable. if file_kind == "audio": error = auth.validate_audio_duration(content) if error: return jsonify({"error": error}), 400 # Une vidéo ne doit jamais dépasser 5 minutes, et SEUL le format MP4 # est accepté (demande explicite) — mutagen (qui lit déjà la durée # d'un son ci-dessus) ne sait fiablement lire la durée que du # conteneur MP4/MOV, jamais de webm/avi ; sans cette restriction, # d'autres extensions passeraient la limite de durée sans jamais être # vérifiées. if file_kind == "video": if ext != ".mp4": return jsonify({"error": "Seul le format MP4 est accepté pour une vidéo."}), 400 error = auth.validate_video_duration(content, filename=f.filename) if error: return jsonify({"error": error}), 400 # "decor"/"fond" (demande explicite : "un bouton d'import séparé pour # les images de fond et les objets") — décide comment un clic sur la # tuile pose l'objet (voir screens/scenes/add_scene_object.py). Sans # objet ("son"/"vidéo"), le champ n'a pas de sens : jamais transmis. scene_kind = None if file_kind == "image": scene_kind = request.form.get("scene_kind") if scene_kind not in ("decor", "fond"): scene_kind = "decor" user_id = g.current_user["id"] asset_id, filename = auth.save_user_asset(user_id, content, ext, original_name=f.filename, source="upload", scene_kind=scene_kind) return jsonify({ "id": asset_id, "url": url_for("serve_user_asset", user_id=user_id, filename=filename), })