lots of things

This commit is contained in:
2025-06-06 22:02:44 -05:00
parent 9daee50a3a
commit 96c634897b
30 changed files with 1120 additions and 182 deletions

View File

@ -1,77 +1,84 @@
from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify, send_from_directory, current_app
# 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
from werkzeug.utils import secure_filename
import os
from app import db
from .models import Media, ImageHeart, FeaturedImage
from plugins.plant.models import Plant
bp = Blueprint("media", __name__, template_folder="templates")
UPLOAD_FOLDER = "static/uploads"
# 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
return (
"." in filename
and filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS
)
@bp.route("/media/upload", methods=["GET", "POST"])
@login_required
def upload_media():
if request.method == "POST":
file = request.files.get("image")
caption = request.form.get("caption")
plant_id = request.form.get("plant_id")
@bp.route("/media/", methods=["GET"])
def media_index():
"""
/media/ is not used standalone—redirect back to homepage.
"""
return redirect(url_for("core_ui.home"))
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
save_path = os.path.join(current_app.root_path, UPLOAD_FOLDER)
os.makedirs(save_path, exist_ok=True)
file.save(os.path.join(save_path, filename))
media = Media(file_url=f"{UPLOAD_FOLDER}/{filename}", caption=caption, plant_id=plant_id)
db.session.add(media)
db.session.commit()
flash("Image uploaded successfully.", "success")
return redirect(url_for("media.upload_media"))
else:
flash("Invalid file or no file uploaded.", "danger")
return render_template("media/upload.html")
@bp.route("/media/files/<path:filename>")
@bp.route("/media/files/<path:filename>", methods=["GET"])
def media_file(filename):
return send_from_directory(os.path.join(current_app.root_path, "static/uploads"), 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:image_id>", methods=["POST"])
@bp.route("/media/heart/<int:media_id>", methods=["POST"])
@login_required
def toggle_heart(image_id):
existing = ImageHeart.query.filter_by(user_id=current_user.id, submission_image_id=image_id).first()
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, submission_image_id=image_id)
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:image_id>", methods=["POST"])
@bp.route("/media/feature/<int:media_id>", methods=["POST"])
@login_required
def set_featured_image(image_id):
image = Media.query.get_or_404(image_id)
plant = image.plant
if not plant:
flash("This image is not linked to a plant.", "danger")
return redirect(request.referrer or url_for("core_ui.home"))
if current_user.id != plant.owner_id and current_user.role != "admin":
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"))
FeaturedImage.query.filter_by(submission_image_id=image_id).delete()
featured = FeaturedImage(submission_image_id=image_id, is_featured=True)
# 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")