PCv5/app/routes/search.py

117 lines
4.1 KiB
Python
Raw Normal View History

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
2023-08-10 10:06:26 +02:00
from app.models.program import Program
2019-02-03 16:20:05 +01:00
from app.utils.render import render
from sqlalchemy import text, func, Date
from flask import request
2023-08-09 18:26:38 +02:00
from flask_sqlalchemy import Pagination
2019-02-03 16:20:05 +01:00
2023-08-09 18:26:38 +02:00
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):
2023-08-08 23:39:11 +02:00
return func.websearch_to_tsquery('french', search).op('||')(func.websearch_to_tsquery('english', search))
def to_tsvector_multilang(text):
2023-08-08 23:39:11 +02:00
return func.to_tsvector('french', text).op('||')(func.to_tsvector('english', text))
2023-08-09 18:26:38 +02:00
@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)
2023-08-10 10:06:26 +02:00
# Topics are sorted first in results
2023-08-09 18:26:38 +02:00
topic_query = db.session.query(Topic).where(
to_tsvector_multilang(Topic.title).bool_op('@@')(tsquery)
).group_by(
Topic.id,
Post.id
)
2023-08-10 10:06:26 +02:00
# 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
2023-08-10 10:06:26 +02:00
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
)
2023-09-26 23:52:13 +02:00
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()
)
2023-08-10 10:06:26 +02:00
results = list(topic_query) + list(program_query) + list(comment_query)
2023-08-09 18:26:38 +02:00
results = paginate(results, page, SEARCH_RESULTS_PER_PAGE)
return render('search.html', form=form, results=results)