This commit is contained in:
2025-05-18 05:21:16 -05:00
parent 132073ca19
commit c19bedc54a
65 changed files with 705 additions and 575 deletions

View File

@ -0,0 +1 @@
# search plugin initialization

15
plugins/search/forms.py Normal file
View File

@ -0,0 +1,15 @@
from flask_wtf import FlaskForm
from wtforms import StringField, SelectMultipleField, SubmitField
from wtforms.validators import Optional, Length, Regexp
class SearchForm(FlaskForm):
query = StringField(
'Search',
validators=[
Optional(),
Length(min=2, max=100, message="Search term must be between 2 and 100 characters."),
Regexp(r'^[\w\s\-]+$', message="Search can only include letters, numbers, spaces, and dashes.")
]
)
tags = SelectMultipleField('Tags', coerce=int)
submit = SubmitField('Search')

8
plugins/search/models.py Normal file
View File

@ -0,0 +1,8 @@
from app import db
class Tag(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True, nullable=False)
def __repr__(self):
return f"<Tag {self.name}>"

View File

@ -0,0 +1 @@
{ "name": "search", "version": "1.1", "description": "Updated search plugin with live Plant model integration" }

38
plugins/search/routes.py Normal file
View File

@ -0,0 +1,38 @@
from flask import Blueprint, render_template, request, jsonify
from flask_login import login_required, current_user
from app import db
from .models import Tag
from .forms import SearchForm
from plugins.plant.models import Plant
bp = Blueprint('search', __name__, template_folder='templates')
@bp.route('/search', methods=['GET', 'POST'])
@login_required
def search():
form = SearchForm()
form.tags.choices = [(tag.id, tag.name) for tag in Tag.query.order_by(Tag.name).all()]
results = []
if form.validate_on_submit():
query = db.session.query(Plant).join(PlantScientific).join(PlantCommon)
if form.query.data:
q = f"%{form.query.data}%"
query = query.filter(
db.or_(
PlantScientific.name.ilike(q),
PlantCommon.name.ilike(q),
Plant.current_status.ilike(q)
)
)
if form.tags.data:
query = query.filter(Plant.tags.any(Tag.id.in_(form.tags.data)))
query = query.filter(Plant.owner_id == current_user.id)
results = query.all()
return render_template('search/search.html', form=form, results=results)
@bp.route('/search/tags')
@login_required
def search_tags():
term = request.args.get('term', '')
tags = Tag.query.filter(Tag.name.ilike(f"%{term}%")).limit(10).all()
return jsonify([tag.name for tag in tags])

View File

@ -0,0 +1,26 @@
{% extends 'base.html' %}
{% block content %}
<h2>Search Plants</h2>
<form method="POST">
{{ form.hidden_tag() }}
<p>
{{ form.query.label }}<br>
{{ form.query(size=32) }}
</p>
<p>
{{ form.tags.label }}<br>
{{ form.tags(multiple=True) }}
</p>
<p>{{ form.submit() }}</p>
</form>
{% if results %}
<h3>Search Results</h3>
<ul>
{% for result in results %}
<li>{{ result.name }}</li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,13 @@
{% extends 'base.html' %}
{% block content %}
<h2>Search Results</h2>
{% if results %}
<ul>
{% for result in results %}
<li>{{ result.name }}</li>
{% endfor %}
</ul>
{% else %}
<p>No results found.</p>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,4 @@
{% extends 'base.html' %}
{% block content %}
<p>This page was replaced by AJAX functionality.</p>
{% endblock %}