# plugins/submission/routes.py # Standard library from datetime import datetime # Third‐party from flask import ( Blueprint, render_template, request, redirect, url_for, flash, jsonify ) from flask_login import login_required, current_user # Application from app import db # Plugins from plugins.media.routes import _process_upload_file # Local from .models import Submission, SubmissionImage from .forms import SubmissionForm bp = Blueprint( "submission", __name__, template_folder="templates", url_prefix="/submission" ) ALLOWED_EXTENSIONS = {"png", "jpg", "jpeg", "gif", "webp"} 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 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() # Handle any uploaded images files = request.files.getlist("images") for f in files: if f and allowed_file(f.filename): media = _process_upload_file( file = f, uploader_id = current_user.id, plugin = "submission", related_id = submission.id ) img = SubmissionImage( submission_id = submission.id, file_url = media.filename, uploaded_at = media.uploaded_at ) 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/", methods=["GET"]) @bp.route("/view//", 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)