86 lines
2.7 KiB
Python
86 lines
2.7 KiB
Python
# plugins/media/routes.py
|
||
|
||
from flask import (
|
||
Blueprint,
|
||
redirect,
|
||
url_for,
|
||
request,
|
||
flash,
|
||
send_from_directory,
|
||
current_app,
|
||
jsonify
|
||
)
|
||
from flask_login import current_user, login_required
|
||
import os
|
||
from app import db
|
||
from .models import Media, ImageHeart, FeaturedImage
|
||
|
||
bp = Blueprint("media", __name__, template_folder="templates")
|
||
|
||
# We store only "YYYY/MM/DD/<uuid>.ext" in Media.file_url.
|
||
# All files live under "/app/static/uploads/YYYY/MM/DD/<uuid>.ext" in the container.
|
||
BASE_UPLOAD_FOLDER = "static/uploads"
|
||
ALLOWED_EXTENSIONS = {"png", "jpg", "jpeg", "gif"}
|
||
|
||
def allowed_file(filename):
|
||
return (
|
||
"." in filename
|
||
and filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS
|
||
)
|
||
|
||
@bp.route("/media/", methods=["GET"])
|
||
def media_index():
|
||
"""
|
||
/media/ is not used stand‐alone—redirect back to homepage.
|
||
"""
|
||
return redirect(url_for("core_ui.home"))
|
||
|
||
@bp.route("/media/files/<path:filename>", methods=["GET"])
|
||
def media_file(filename):
|
||
"""
|
||
Serve files from "/app/static/uploads/<filename>".
|
||
Example: GET /media/files/2025/06/07/abcdef1234abcd.jpg
|
||
"""
|
||
# Use os.getcwd() to guarantee "/app/static/uploads" (not "/app/app/static/uploads")
|
||
full_dir = os.path.join(os.getcwd(), BASE_UPLOAD_FOLDER)
|
||
return send_from_directory(full_dir, filename)
|
||
|
||
@bp.route("/media/heart/<int:media_id>", methods=["POST"])
|
||
@login_required
|
||
def toggle_heart(media_id):
|
||
"""
|
||
Add/remove a "heart" from an image.
|
||
"""
|
||
existing = ImageHeart.query.filter_by(
|
||
user_id=current_user.id, media_id=media_id
|
||
).first()
|
||
|
||
if existing:
|
||
db.session.delete(existing)
|
||
db.session.commit()
|
||
return jsonify({"status": "unhearted"})
|
||
else:
|
||
heart = ImageHeart(user_id=current_user.id, media_id=media_id)
|
||
db.session.add(heart)
|
||
db.session.commit()
|
||
return jsonify({"status": "hearted"})
|
||
|
||
@bp.route("/media/feature/<int:media_id>", methods=["POST"])
|
||
@login_required
|
||
def set_featured_image(media_id):
|
||
"""
|
||
Toggle featured status on a media item. Only the uploader or an admin may do so.
|
||
"""
|
||
media = Media.query.get_or_404(media_id)
|
||
if (current_user.id != media.uploader_id) and (current_user.role != "admin"):
|
||
flash("Not authorized to set featured image.", "danger")
|
||
return redirect(request.referrer or url_for("core_ui.home"))
|
||
|
||
# Remove any existing featured entries for this media
|
||
FeaturedImage.query.filter_by(media_id=media_id).delete()
|
||
featured = FeaturedImage(media_id=media_id, is_featured=True)
|
||
db.session.add(featured)
|
||
db.session.commit()
|
||
flash("Image set as featured.", "success")
|
||
return redirect(request.referrer or url_for("core_ui.home"))
|