Files
natureinpots_community/plugins/submission/routes.py
2025-06-06 22:02:44 -05:00

145 lines
5.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# plugins/submission/routes.py
from flask import (
Blueprint,
render_template,
request,
redirect,
url_for,
flash,
jsonify
)
from flask_login import login_required, current_user
from app import db
from .models import Submission, SubmissionImage
from .forms import SubmissionForm
from datetime import datetime
import os
from werkzeug.utils import secure_filename
from plugins.media.utils import generate_random_filename, strip_metadata_and_save
bp = Blueprint("submission", __name__, template_folder="templates", url_prefix="/submission")
# We store only "YYYY/MM/DD/<uuid>.ext" in SubmissionImage.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("/", methods=["GET"])
@login_required
def submission_index():
return redirect(url_for("submission.new_submission"))
@bp.route("/new", methods=["GET", "POST"])
@bp.route("/new/", methods=["GET", "POST"])
@login_required
def new_submission():
form = SubmissionForm()
if form.validate_on_submit():
plant_types = {"market_price", "name_correction", "new_plant", "mutation"}
t = form.submission_type.data
# Only require plant_name if the type is plantrelated
if t in plant_types and not form.plant_name.data.strip():
flash("Common Name is required for this submission type.", "danger")
return render_template("submission/new.html", form=form)
submission = Submission(
user_id=current_user.id,
submitted_at=datetime.utcnow(),
submission_type=t,
plant_name=form.plant_name.data,
scientific_name=form.scientific_name.data,
notes=form.notes.data,
price=form.price.data if form.price.data else None,
source=form.source.data,
vendor_name=form.vendor_name.data,
rating=form.rating.data,
old_vendor=form.old_vendor.data,
new_vendor=form.new_vendor.data,
alias_reason=form.alias_reason.data,
approved=None
)
db.session.add(submission)
db.session.flush()
# date subfolder: "YYYY/MM/DD"
today = datetime.utcnow().strftime("%Y/%m/%d")
# Write into "/app/static/uploads/YYYY/MM/DD", not "/app/app/static/uploads..."
save_dir = os.path.join(os.getcwd(), BASE_UPLOAD_FOLDER, today)
os.makedirs(save_dir, exist_ok=True)
files = request.files.getlist("images")
for f in files:
if f and allowed_file(f.filename):
orig_name = secure_filename(f.filename)
rand_name = generate_random_filename(orig_name)
# Temporarily save under "/app/temp_<uuid>.ext"
temp_path = os.path.join(os.getcwd(), "temp_" + rand_name)
f.save(temp_path)
final_path = os.path.join(save_dir, rand_name)
strip_metadata_and_save(temp_path, final_path)
os.remove(temp_path)
# Store only "YYYY/MM/DD/<uuid>.ext"
rel_url = f"{today}/{rand_name}"
img = SubmissionImage(
submission_id=submission.id,
file_url=rel_url,
uploaded_at=datetime.utcnow()
)
db.session.add(img)
db.session.commit()
flash("Submission received. Thank you!", "success")
return redirect(url_for("submission.new_submission"))
return render_template("submission/new.html", form=form)
@bp.route("/list", methods=["GET"])
@bp.route("/list/", methods=["GET"])
@login_required
def list_submissions():
selected_type = request.args.get("type", None)
query = Submission.query.filter_by(user_id=current_user.id)
if selected_type:
query = query.filter_by(submission_type=selected_type)
subs = query.order_by(Submission.submitted_at.desc()).all()
all_types = [
("", "All"),
("market_price", "Market Price"),
("name_correction", "Name Correction"),
("new_plant", "New Plant Suggestion"),
("mutation", "Mutation Discovery"),
("vendor_rating", "Vendor Rating/Review"),
("vendor_alias", "Vendor Alias Submission"),
]
return render_template(
"submission/list.html",
submissions=subs,
selected_type=selected_type,
all_types=all_types
)
@bp.route("/view/<int:submission_id>", methods=["GET"])
@bp.route("/view/<int:submission_id>/", methods=["GET"])
@login_required
def view_submission(submission_id):
sub = Submission.query.get_or_404(submission_id)
if sub.user_id != current_user.id and current_user.role != "admin":
flash("Not authorized to view this submission.", "danger")
return redirect(url_for("submission.list_submissions"))
images = SubmissionImage.query.filter_by(submission_id=sub.id).all()
return render_template("submission/view.html", submission=sub, images=images)