PCv5/app/routes/search.py

117 lines
4.1 KiB
Python

from app import app, db
from app.forms.search import AdvancedSearchForm, SearchForm
from app.models.post import Post
from app.models.comment import Comment
from app.models.topic import Topic
from app.models.forum import Forum
from app.models.program import Program
from app.utils.render import render
from sqlalchemy import text, func, Date
from flask import request
from flask_sqlalchemy import Pagination
SEARCH_RESULTS_PER_PAGE = 20
def paginate(data, page, per_page):
# Based on page and per_page info, calculate start and end index of items to keep
start_index = (page - 1) * per_page
end_index = start_index + per_page
# Get the paginated list of items
items = data[start_index:end_index]
# Create Pagination object
return Pagination(None, page, per_page, len(data), items)
def websearch_to_tsquery_multilang(search):
return func.websearch_to_tsquery('french', search).op('||')(func.websearch_to_tsquery('english', search))
def to_tsvector_multilang(text):
return func.to_tsvector('french', text).op('||')(func.to_tsvector('english', text))
@app.route('/rechercher/')
@app.route('/rechercher/<int:page>/')
def search(page=1):
form = AdvancedSearchForm(request.args)
results = list()
if form.validate():
tsquery = websearch_to_tsquery_multilang(form.q.data)
# Topics are sorted first in results
topic_query = db.session.query(Topic).where(
to_tsvector_multilang(Topic.title).bool_op('@@')(tsquery)
).group_by(
Topic.id,
Post.id
)
# Programms follow directly in the results
program_query = db.session.query(Program).where(
to_tsvector_multilang(Program.name).bool_op('@@')(tsquery)
).group_by(
Program.id,
Post.id
)
# Comments are less important than topics and programs
comment_query = db.session.query(Comment).where(
to_tsvector_multilang(Comment.text).bool_op('@@')(tsquery)
).group_by(
Comment.id,
Post.id
)
if (form.date.data):
topic_query = topic_query.where(
Topic.date_created.cast(Date) == form.date.data
)
program_query = program_query.where(
Program.date_created.cast(Date) == form.date.data
)
comment_query = comment_query.where(
Comment.date_created.cast(Date) == form.date.data
)
if (form.sortBy.data == "Date croissante"):
topic_query = topic_query.order_by(
Topic.date_created.asc()
)
program_query = program_query.order_by(
Program.date_created.asc()
)
comment_query = comment_query.order_by(
Post.date_created.asc()
)
elif (form.sortBy.data == "Date décroissante"):
topic_query = topic_query.order_by(
Topic.date_created.desc()
)
program_query = program_query.order_by(
Program.date_created.desc()
)
comment_query = comment_query.order_by(
Post.date_created.desc()
)
elif (form.sortBy.data == "Alphabétique croissant"):
topic_query = topic_query.order_by(
Topic.title.asc()
)
program_query = program_query.order_by(
Program.name.asc()
)
comment_query = comment_query.order_by(
Comment.text.asc()
)
elif (form.sortBy.data == "Alphabétique décroissant"):
topic_query = topic_query.order_by(
Topic.title.desc()
)
program_query = program_query.order_by(
Program.name.desc()
)
comment_query = comment_query.order_by(
Comment.text.desc()
)
results = list(topic_query) + list(program_query) + list(comment_query)
results = paginate(results, page, SEARCH_RESULTS_PER_PAGE)
return render('search.html', form=form, results=results)