From 746535b7645b6aeb6eb58dced984530744fef161 Mon Sep 17 00:00:00 2001 From: Lukas Stabe Date: Thu, 24 Sep 2020 05:22:45 +0200 Subject: add title option (#335) and breadcrumb links in heading --- src/listing.rs | 50 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 8 deletions(-) (limited to 'src/listing.rs') diff --git a/src/listing.rs b/src/listing.rs index a70e237..7f09fa4 100644 --- a/src/listing.rs +++ b/src/listing.rs @@ -8,7 +8,7 @@ use percent_encoding::{percent_decode_str, utf8_percent_encode, AsciiSet, CONTRO use qrcodegen::{QrCode, QrCodeEcc}; use serde::Deserialize; use std::io; -use std::path::{Path, PathBuf}; +use std::path::{Component, Path, PathBuf}; use std::time::SystemTime; use strum_macros::{Display, EnumString}; @@ -123,6 +123,21 @@ impl Entry { } } +/// One entry in the path to the listed directory +pub struct Breadcrumb { + /// Name of directory + pub name: String, + + /// Link to get to directory, relative to listed directory + pub link: String, +} + +impl Breadcrumb { + fn new(name: String, link: String) -> Self { + Breadcrumb { name, link } + } +} + pub async fn file_handler(req: HttpRequest) -> Result { let path = &req.app_data::().unwrap().path; actix_files::NamedFile::open(path).map_err(Into::into) @@ -143,6 +158,7 @@ pub fn directory_listing( upload_route: String, tar_enabled: bool, zip_enabled: bool, + title: Option, ) -> Result { use actix_web::dev::BodyEncoding; let serve_path = req.path(); @@ -173,13 +189,31 @@ pub fn directory_listing( .display() .to_string(); - let display_dir = { + let connection_info = actix_web::dev::ConnectionInfo::get(req.head(), req.app_config()); + let title = title.unwrap_or_else(|| connection_info.host().into()); + + let breadcrumbs = { let decoded = percent_decode_str(&encoded_dir).decode_utf8_lossy(); - if is_root { - decoded.to_string() - } else { - format!("{}/", decoded) - } + let components = Path::new(&*decoded).components(); + components + .collect::>() + .iter() + .rev() + .enumerate() + .rev() + .map(|(i, c)| { + let link = if i == 0 { + ".".into() + } else { + (0..i).map(|_| "..").collect::>().join("/") + }; + match c { + Component::RootDir => Breadcrumb::new(title.clone(), link), + Component::Normal(s) => Breadcrumb::new(s.to_string_lossy().into(), link), + _ => panic!(""), + } + }) + .collect() }; let query_params = extract_query_parameters(req); @@ -360,7 +394,7 @@ pub fn directory_listing( &upload_route, &favicon_route, &encoded_dir, - &display_dir, + breadcrumbs, tar_enabled, zip_enabled, ) -- cgit v1.2.3 From c2fb51e902a4b0d213fd272ca045a533b99b93cb Mon Sep 17 00:00:00 2001 From: Lukas Stabe Date: Thu, 24 Sep 2020 04:00:23 +0200 Subject: use req.connection_info() and build breadcrumbs iteratively --- src/listing.rs | 61 ++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 25 deletions(-) (limited to 'src/listing.rs') diff --git a/src/listing.rs b/src/listing.rs index 7f09fa4..66f0b0a 100644 --- a/src/listing.rs +++ b/src/listing.rs @@ -179,41 +179,52 @@ pub fn directory_listing( } let base = Path::new(serve_path); - let random_route = format!("/{}", random_route.unwrap_or_default()); - let is_root = base.parent().is_none() || Path::new(&req.path()) == Path::new(&random_route); + let random_route_abs = format!("/{}", random_route.clone().unwrap_or_default()); + let is_root = base.parent().is_none() || Path::new(&req.path()) == Path::new(&random_route_abs); - let encoded_dir = match base.strip_prefix(random_route) { + let encoded_dir = match base.strip_prefix(random_route_abs) { Ok(c_d) => Path::new("/").join(c_d), Err(_) => base.to_path_buf(), } .display() .to_string(); - let connection_info = actix_web::dev::ConnectionInfo::get(req.head(), req.app_config()); - let title = title.unwrap_or_else(|| connection_info.host().into()); - let breadcrumbs = { + let title = title.unwrap_or_else(|| req.connection_info().host().into()); + let decoded = percent_decode_str(&encoded_dir).decode_utf8_lossy(); - let components = Path::new(&*decoded).components(); - components - .collect::>() - .iter() - .rev() - .enumerate() - .rev() - .map(|(i, c)| { - let link = if i == 0 { - ".".into() - } else { - (0..i).map(|_| "..").collect::>().join("/") - }; - match c { - Component::RootDir => Breadcrumb::new(title.clone(), link), - Component::Normal(s) => Breadcrumb::new(s.to_string_lossy().into(), link), - _ => panic!(""), + + let mut res: Vec = Vec::new(); + let mut link_accumulator = + "/".to_string() + &(random_route.map(|r| r + "/").unwrap_or_default()); + + let mut components = Path::new(&*decoded).components().peekable(); + + while let Some(c) = components.next() { + let name; + + match c { + Component::RootDir => { + name = title.clone(); + } + Component::Normal(s) => { + name = s.to_string_lossy().to_string(); + link_accumulator + .push_str(&(utf8_percent_encode(&name, FRAGMENT).to_string() + "/")); } - }) - .collect() + _ => panic!(), + }; + + res.push(Breadcrumb::new( + name, + if components.peek().is_some() { + link_accumulator.clone() + } else { + ".".to_string() + }, + )); + } + res }; let query_params = extract_query_parameters(req); -- cgit v1.2.3 From 5040271655042298bd0854e0feff4e8b50e4163a Mon Sep 17 00:00:00 2001 From: Lukas Stabe Date: Thu, 24 Sep 2020 04:02:59 +0200 Subject: use unreachable instead of panic for unreachable case --- src/listing.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/listing.rs') diff --git a/src/listing.rs b/src/listing.rs index 66f0b0a..f45c493 100644 --- a/src/listing.rs +++ b/src/listing.rs @@ -212,7 +212,7 @@ pub fn directory_listing( link_accumulator .push_str(&(utf8_percent_encode(&name, FRAGMENT).to_string() + "/")); } - _ => panic!(), + _ => unreachable!(), }; res.push(Breadcrumb::new( -- cgit v1.2.3 From d450712d2c869816a946abdeb0a1f91efd489082 Mon Sep 17 00:00:00 2001 From: Lukas Stabe Date: Thu, 24 Sep 2020 04:09:22 +0200 Subject: use format! instead of + --- src/listing.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/listing.rs') diff --git a/src/listing.rs b/src/listing.rs index f45c493..d14a188 100644 --- a/src/listing.rs +++ b/src/listing.rs @@ -196,7 +196,7 @@ pub fn directory_listing( let mut res: Vec = Vec::new(); let mut link_accumulator = - "/".to_string() + &(random_route.map(|r| r + "/").unwrap_or_default()); + format!("/{}", random_route.map(|r| r + "/").unwrap_or_default()); let mut components = Path::new(&*decoded).components().peekable(); -- cgit v1.2.3