from flask import Blueprint, render_template, request, jsonify, redirect, url_for, flash from datetime import datetime from flask_login import login_required, current_user from sqlalchemy import and_ from markupsafe import escape from werkzeug.utils import secure_filename import os from .. import db from .models import Submission, SubmissionImage core = Blueprint('core', __name__) UPLOAD_FOLDER = 'app/static/uploads' ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg'} def allowed_file(filename): return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS @core.route('/') def index(): submissions = Submission.query.order_by(Submission.timestamp.desc()).limit(6).all() use_placeholder = len(submissions) == 0 return render_template('index.html', submissions=submissions, use_placeholder=use_placeholder, current_year=datetime.now().year) @core.route('/dashboard') @login_required def user_dashboard(): return render_template('dashboard.html', current_year=datetime.now().year) @core.route('/admin') @login_required def admin_dashboard(): if current_user.role != 'admin': return render_template('unauthorized.html'), 403 return render_template('admin_dashboard.html', current_year=datetime.now().year) @core.route('/search', methods=['GET', 'POST']) def search(): query = escape(request.values.get('q', '').strip()) source = escape(request.values.get('source', '').strip()) min_price = request.values.get('min_price', type=float) max_price = request.values.get('max_price', type=float) from_date = request.values.get('from_date') to_date = request.values.get('to_date') if request.method == 'POST' and request.is_json: removed = request.json.get('remove') if removed == "Name": query = "" elif removed == "Source": source = "" elif removed == "Min Price": min_price = None elif removed == "Max Price": max_price = None elif removed == "From": from_date = None elif removed == "To": to_date = None filters = [] filter_tags = {} if query: filters.append(Submission.common_name.ilike(f"%{query}%")) filter_tags['Name'] = query if source: filters.append(Submission.source.ilike(f"%{source}%")) filter_tags['Source'] = source if min_price is not None: filters.append(Submission.price >= min_price) filter_tags['Min Price'] = f"${min_price:.2f}" if max_price is not None: filters.append(Submission.price <= max_price) filter_tags['Max Price'] = f"${max_price:.2f}" if from_date: filters.append(Submission.timestamp >= from_date) filter_tags['From'] = from_date if to_date: filters.append(Submission.timestamp <= to_date) filter_tags['To'] = to_date results = Submission.query.filter(and_(*filters)).order_by(Submission.timestamp.desc()).limit(50).all() if request.is_json: return jsonify({ "results_html": render_template("search_results.html", results=results), "tags_html": render_template("search_tags.html", filter_tags=filter_tags) }) return render_template('search.html', results=results, filter_tags=filter_tags) @core.route('/submit', methods=['GET', 'POST']) @login_required def submit(): if request.method == 'POST': common_name = escape(request.form.get('common_name', '').strip()) scientific_name = escape(request.form.get('scientific_name', '').strip()) price = request.form.get('price', type=float) source = escape(request.form.get('source', '').strip()) timestamp = request.form.get('timestamp') or datetime.utcnow() height = request.form.get('height', type=float) width = request.form.get('width', type=float) leaf_count = request.form.get('leaf_count', type=int) potting_mix = escape(request.form.get('potting_mix', '').strip()) container_size = escape(request.form.get('container_size', '').strip()) health_status = escape(request.form.get('health_status', '').strip()) notes = escape(request.form.get('notes', '').strip()) new_submission = Submission( user_id=current_user.id, common_name=common_name, scientific_name=scientific_name, price=price, source=source, timestamp=timestamp, height=height, width=width, leaf_count=leaf_count, potting_mix=potting_mix, container_size=container_size, health_status=health_status, notes=notes, ) db.session.add(new_submission) db.session.commit() files = request.files.getlist('images') for f in files[:5]: if f and allowed_file(f.filename): filename = secure_filename(f.filename) save_path = os.path.join(UPLOAD_FOLDER, filename) f.save(save_path) db.session.add(SubmissionImage(submission_id=new_submission.id, file_path=save_path)) db.session.commit() flash("Submission received!", "success") return redirect(url_for('core.index')) return render_template('submit.html')