diff options
author | metamuffin <metamuffin@disroot.org> | 2024-01-24 08:56:01 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-01-24 08:56:01 +0100 |
commit | daba95cad0d58cf9fbf460d582729857f46b5390 (patch) | |
tree | 271c2839df5eedd4b9f0d6266725cef082719b68 | |
parent | d4772cb6fb78c3d0a69371fc6cd822260b208857 (diff) | |
download | jellything-daba95cad0d58cf9fbf460d582729857f46b5390.tar jellything-daba95cad0d58cf9fbf460d582729857f46b5390.tar.bz2 jellything-daba95cad0d58cf9fbf460d582729857f46b5390.tar.zst |
add search draft
-rw-r--r-- | Cargo.lock | 7 | ||||
-rw-r--r-- | server/Cargo.toml | 1 | ||||
-rw-r--r-- | server/src/routes/mod.rs | 2 | ||||
-rw-r--r-- | server/src/routes/ui/layout.rs | 2 | ||||
-rw-r--r-- | server/src/routes/ui/mod.rs | 1 | ||||
-rw-r--r-- | server/src/routes/ui/search.rs | 74 |
6 files changed, 87 insertions, 0 deletions
@@ -738,6 +738,12 @@ dependencies = [ ] [[package]] +name = "edit-distance" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbaaaf38131deb9ca518a274a45bfdb8771f139517b073b16c2d3d32ae5037b" + +[[package]] name = "either" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1457,6 +1463,7 @@ dependencies = [ "bincode", "chashmap", "chrono", + "edit-distance", "env_logger", "futures", "glob", diff --git a/server/Cargo.toml b/server/Cargo.toml index ca8315c..32d72b9 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -22,6 +22,7 @@ base64 = "0.21.5" chrono = { version = "0.4.31", features = ["serde"] } vte = "0.13.0" chashmap = "2.2.2" +edit-distance = "2.1.0" argon2 = "0.5.2" aes-gcm-siv = "0.11.1" diff --git a/server/src/routes/mod.rs b/server/src/routes/mod.rs index d607eef..ca8c009 100644 --- a/server/src/routes/mod.rs +++ b/server/src/routes/mod.rs @@ -39,6 +39,7 @@ use ui::{ home::{r_home, r_home_unpriv}, node::{r_library_node_ext, r_library_node_filter}, player::r_player, + search::r_search, style::{r_assets_font, r_assets_js, r_assets_js_map, r_assets_style}, }; use userdata::{r_node_userdata, r_player_progress, r_player_watched}; @@ -99,6 +100,7 @@ pub fn build_rocket(database: DataAcid, federation: Federation) -> Rocket<Build> r_favicon, r_item_assets, r_person_asset, + r_search, r_all_items_filter, r_library_node_filter, r_library_node_ext, diff --git a/server/src/routes/ui/layout.rs b/server/src/routes/ui/layout.rs index faf5527..3772c06 100644 --- a/server/src/routes/ui/layout.rs +++ b/server/src/routes/ui/layout.rs @@ -13,6 +13,7 @@ use crate::{ admin::rocket_uri_macro_r_admin_dashboard, browser::rocket_uri_macro_r_all_items, node::rocket_uri_macro_r_library_node, + search::rocket_uri_macro_r_search, }, uri, }; @@ -45,6 +46,7 @@ markup::define! { @if let Some(_) = session { a.library[href=uri!(r_library_node("library"))] { "My Library" } " " a.library[href=uri!(r_all_items())] { "All Items" } " " + a.library[href=uri!(r_search(None::<&'static str>))] { "Search" } " " } div.account { @if let Some(session) = session { diff --git a/server/src/routes/ui/mod.rs b/server/src/routes/ui/mod.rs index ea78ea5..da96103 100644 --- a/server/src/routes/ui/mod.rs +++ b/server/src/routes/ui/mod.rs @@ -31,6 +31,7 @@ pub mod home; pub mod layout; pub mod node; pub mod player; +pub mod search; pub mod sort; pub mod style; diff --git a/server/src/routes/ui/search.rs b/server/src/routes/ui/search.rs new file mode 100644 index 0000000..dc90df1 --- /dev/null +++ b/server/src/routes/ui/search.rs @@ -0,0 +1,74 @@ +use super::{ + account::session::Session, + error::MyResult, + layout::{DynLayoutPage, LayoutPage}, + node::NodeCard, +}; +use edit_distance::edit_distance; +use jellybase::database::{DataAcid, ReadableTable, T_NODE, T_USER_NODE}; +use rocket::{get, State}; + +#[get("/search?<query>")] +pub async fn r_search<'a>( + session: Session, + db: &State<DataAcid>, + query: Option<&str>, +) -> MyResult<DynLayoutPage<'a>> { + let results = if let Some(query) = query { + let mut items = { + let txn = db.begin_read()?; + let nodes = txn.open_table(T_NODE)?; + let node_users = txn.open_table(T_USER_NODE)?; + let i = nodes + .iter()? + .map(|a| { + let (x, y) = a.unwrap(); + let (x, y) = (x.value().to_owned(), y.value().0); + let z = node_users + .get(&(session.user.name.as_str(), x.as_str())) + .unwrap() + .map(|z| z.value().0) + .unwrap_or_default(); + let y = y.public; + (x, y, z) + }) + .collect::<Vec<_>>(); + drop(nodes); + i + }; + + let query = query.to_lowercase(); + items.sort_by_cached_key(|(_, n, _)| { + n.title + .as_ref() + .map(|x| x.to_lowercase()) + .unwrap_or_default() + .split(" ") + .map(|tok| edit_distance(query.as_str(), tok)) + .min() + .unwrap_or(usize::MAX) + }); + + Some(items.into_iter().take(64).collect::<Vec<_>>()) + } else { + None + }; + + Ok(LayoutPage { + title: "Search".to_string(), + class: None, + content: markup::new! { + h1 { "Search" } + form[action="", method="GET"] { + input[type="text", name="query"]; + input[type="submit"]; + } + @if let Some(results) = &results { + h2 { "Results" } + ul.children {@for (id, node, udata) in results.iter() { + li { @NodeCard { id, node, udata } } + }} + } + }, + }) +} |