diff options
Diffstat (limited to 'server/src/routes')
| -rw-r--r-- | server/src/routes/mod.rs | 8 | ||||
| -rw-r--r-- | server/src/routes/search.rs | 76 |
2 files changed, 54 insertions, 30 deletions
diff --git a/server/src/routes/mod.rs b/server/src/routes/mod.rs index 959971a..05b8025 100644 --- a/server/src/routes/mod.rs +++ b/server/src/routes/mod.rs @@ -16,6 +16,7 @@ pub mod items; pub mod node; pub mod player; pub mod playersync; +pub mod search; pub mod stream; pub mod style; pub mod userdata; @@ -44,7 +45,7 @@ use self::{ stream::r_stream, style::{r_assets_css, r_assets_font, r_assets_js, r_assets_js_map}, }; -use crate::State; +use crate::{State, routes::search::r_search}; use rocket::{ Build, Config, Rocket, catchers, fairing::AdHoc, fs::FileServer, http::Header, routes, shield::Shield, @@ -102,9 +103,9 @@ pub(super) fn build_rocket(state: Arc<State>) -> Rocket<Build> { r_admin_log_stream, r_admin_log, r_admin_new_user, - r_admin_users, - r_admin_user, r_admin_user_remove, + r_admin_user, + r_admin_users, r_api_root, r_assets_css, r_assets_font, @@ -119,6 +120,7 @@ pub(super) fn build_rocket(state: Arc<State>) -> Rocket<Build> { r_node, r_player, r_playersync, + r_search, r_stream, r_version, // Compat diff --git a/server/src/routes/search.rs b/server/src/routes/search.rs index 8ec2697..8726b8e 100644 --- a/server/src/routes/search.rs +++ b/server/src/routes/search.rs @@ -3,35 +3,57 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2026 metamuffin <metamuffin.org> */ + +use std::{borrow::Cow, time::Instant}; + use super::error::MyResult; use crate::request_info::RequestInfo; -use anyhow::anyhow; -use rocket::{Either, get, response::content::RawHtml, serde::json::Json}; +use jellycommon::{ + jellyobject::{EMPTY, Path}, + *, +}; +use jellydb::{Filter, Query, Sort}; +use jellyui::components::items::Items; +use log::info; +use rocket::{get, response::content::RawHtml}; + +#[get("/search?<q>")] +pub async fn r_search(ri: RequestInfo<'_>, q: Option<&str>) -> MyResult<RawHtml<String>> { + ri.require_user()?; + + let q = q.unwrap(); + + let mut items = Vec::new(); + let t = Instant::now(); + ri.state.database.transaction(&mut |txn| { + let rows = txn + .query(Query { + filter: Filter::Match(Path(vec![NO_VISIBILITY.0]), VISI_VISIBLE.into()), + sort: Sort::TextSearch(Path(vec![NO_TITLE.0]), q.to_owned()), + ..Default::default() + })? + .take(64) + .collect::<Result<Vec<_>, _>>()?; -#[get("/search?<query>&<page>")] -pub async fn r_search( - ri: RequestInfo<'_>, - query: Option<&str>, - page: Option<usize>, -) -> MyResult<RawHtml<String>> { - // let r = query - // .map(|query| search(&ri.session, query, page)) - // .transpose()?; + items.clear(); + for (r, _is) in rows { + let node = txn.get(r)?.unwrap(); + items.push(node); + } + Ok(()) + })?; + info!("search {q:?} took {:?}", t.elapsed()); - // Ok(if ri.accept.is_json() { - // let Some(r) = r else { - // Err(anyhow!("no query"))? - // }; - // Either::Right(Json(r)) - // } else { - // Either::Left(RawHtml(render_page( - // &SearchPage { - // lang: &ri.lang, - // query: &query.map(|s| s.to_string()), - // r, - // }, - // ri.render_info(), - // ))) - // }) - todo!() + Ok(ri.respond_ui(&Items { + items: &items + .iter() + .map(|node| Nku { + node: Cow::Borrowed(node), + userdata: Cow::Borrowed(EMPTY), + role: None, + }) + .collect::<Vec<_>>(), + ri: &ri.render_info(), + cont: None, + })) } |