2018-12-02 17:37:51 +01:00
|
|
|
use chrono::offset::Utc;
|
2018-12-06 18:54:16 +01:00
|
|
|
use rocket::request::Form;
|
2018-12-02 17:37:51 +01:00
|
|
|
|
2020-01-21 07:02:03 +01:00
|
|
|
use crate::routes::Page;
|
|
|
|
use crate::template_utils::{IntoContext, Ructe};
|
2021-01-30 13:44:29 +01:00
|
|
|
use plume_models::{db_conn::DbConn, search::Query, PlumeRocket};
|
2019-03-20 17:56:17 +01:00
|
|
|
use std::str::FromStr;
|
2018-12-02 17:37:51 +01:00
|
|
|
|
2018-12-06 18:54:16 +01:00
|
|
|
#[derive(Default, FromForm)]
|
|
|
|
pub struct SearchQuery {
|
2018-12-02 17:37:51 +01:00
|
|
|
q: Option<String>,
|
|
|
|
title: Option<String>,
|
|
|
|
subtitle: Option<String>,
|
|
|
|
content: Option<String>,
|
|
|
|
instance: Option<String>,
|
|
|
|
author: Option<String>,
|
|
|
|
tag: Option<String>,
|
|
|
|
blog: Option<String>,
|
|
|
|
lang: Option<String>,
|
|
|
|
license: Option<String>,
|
|
|
|
after: Option<String>,
|
|
|
|
before: Option<String>,
|
|
|
|
page: Option<Page>,
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! param_to_query {
|
|
|
|
( $query:ident, $parsed_query:ident; normal: $($field:ident),*; date: $($date:ident),*) => {
|
|
|
|
$(
|
2018-12-12 00:51:45 +01:00
|
|
|
let mut rest = $query.$field.as_ref().map(String::as_str).unwrap_or_default();
|
|
|
|
while !rest.is_empty() {
|
|
|
|
let (token, r) = Query::get_first_token(rest);
|
|
|
|
rest = r;
|
|
|
|
$parsed_query.$field(token, None);
|
2018-12-02 17:37:51 +01:00
|
|
|
}
|
|
|
|
)*
|
|
|
|
$(
|
2018-12-06 18:54:16 +01:00
|
|
|
if let Some(ref field) = $query.$date {
|
2018-12-02 17:37:51 +01:00
|
|
|
let mut rest = field.as_str();
|
|
|
|
while !rest.is_empty() {
|
|
|
|
use chrono::naive::NaiveDate;
|
|
|
|
let (token, r) = Query::get_first_token(rest);
|
|
|
|
rest = r;
|
|
|
|
if let Ok(token) = NaiveDate::parse_from_str(token, "%Y-%m-%d") {
|
|
|
|
$parsed_query.$date(&token);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-06 18:54:16 +01:00
|
|
|
#[get("/search?<query..>")]
|
2021-01-30 13:44:29 +01:00
|
|
|
pub fn search(query: Option<Form<SearchQuery>>, conn: DbConn, rockets: PlumeRocket) -> Ructe {
|
2019-04-01 20:28:23 +02:00
|
|
|
let query = query.map(Form::into_inner).unwrap_or_default();
|
2018-12-13 22:20:19 +01:00
|
|
|
let page = query.page.unwrap_or_default();
|
2019-03-20 17:56:17 +01:00
|
|
|
let mut parsed_query =
|
2021-11-27 23:53:13 +01:00
|
|
|
Query::from_str(query.q.as_deref().unwrap_or_default()).unwrap_or_default();
|
2018-12-02 17:37:51 +01:00
|
|
|
|
|
|
|
param_to_query!(query, parsed_query; normal: title, subtitle, content, tag,
|
|
|
|
instance, author, blog, lang, license;
|
|
|
|
date: before, after);
|
|
|
|
|
2018-12-06 18:54:16 +01:00
|
|
|
let str_query = parsed_query.to_string();
|
2018-12-02 17:37:51 +01:00
|
|
|
|
2018-12-06 18:54:16 +01:00
|
|
|
if str_query.is_empty() {
|
|
|
|
render!(search::index(
|
2021-01-30 13:44:29 +01:00
|
|
|
&(&conn, &rockets).to_context(),
|
2023-01-06 15:38:38 +01:00
|
|
|
&format!("{}", Utc::now().date_naive().format("%Y-%m-d"))
|
2018-12-06 18:54:16 +01:00
|
|
|
))
|
|
|
|
} else {
|
2019-04-30 12:04:25 +02:00
|
|
|
let res = rockets
|
|
|
|
.searcher
|
|
|
|
.search_document(&conn, parsed_query, page.limits());
|
2018-12-13 22:20:19 +01:00
|
|
|
let next_page = if res.is_empty() { 0 } else { page.0 + 1 };
|
2018-12-06 18:54:16 +01:00
|
|
|
render!(search::result(
|
2021-01-30 13:44:29 +01:00
|
|
|
&(&conn, &rockets).to_context(),
|
2018-12-06 18:54:16 +01:00
|
|
|
&str_query,
|
|
|
|
res,
|
|
|
|
page.0,
|
|
|
|
next_page
|
|
|
|
))
|
|
|
|
}
|
2018-12-02 17:37:51 +01:00
|
|
|
}
|