Skip to content

Commit

Permalink
add title option (#335) and breadcrumb links in heading
Browse files Browse the repository at this point in the history
  • Loading branch information
ahti committed Sep 19, 2020
1 parent 236a8ef commit 3549d26
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 24 deletions.
5 changes: 5 additions & 0 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ struct CLIArgs {
/// because zip generation is done in memory and cannot be sent on the fly
#[structopt(short = "z", long = "enable-zip")]
enable_zip: bool,

/// Shown instead of host in page title and heading
#[structopt(short = "t", long = "title")]
title: Option<String>,
}

/// Checks wether an interface is valid, i.e. it can be parsed into an IP address
Expand Down Expand Up @@ -196,6 +200,7 @@ pub fn parse_args() -> crate::MiniserveConfig {
file_upload: args.file_upload,
tar_enabled: args.enable_tar,
zip_enabled: args.enable_zip,
title: args.title,
}
}

Expand Down
50 changes: 42 additions & 8 deletions src/listing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -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<actix_files::NamedFile> {
let path = &req.app_data::<crate::MiniserveConfig>().unwrap().path;
actix_files::NamedFile::open(path).map_err(Into::into)
Expand All @@ -142,6 +157,7 @@ pub fn directory_listing(
upload_route: String,
tar_enabled: bool,
zip_enabled: bool,
title: Option<String>,
) -> Result<ServiceResponse, io::Error> {
use actix_web::dev::BodyEncoding;
let serve_path = req.path();
Expand Down Expand Up @@ -172,13 +188,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::<Vec<_>>()
.iter()
.rev()
.enumerate()
.rev()
.map(|(i, c)| {
let link = if i == 0 {
".".into()
} else {
(0..i).map(|_| "..").collect::<Vec<_>>().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);
Expand Down Expand Up @@ -357,7 +391,7 @@ pub fn directory_listing(
file_upload,
&upload_route,
&encoded_dir,
&display_dir,
breadcrumbs,
tar_enabled,
zip_enabled,
)
Expand Down
5 changes: 5 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ pub struct MiniserveConfig {

/// If false, creation of zip archives is disabled
pub zip_enabled: bool,

/// Shown instead of host in page title and heading
pub title: Option<String>,
}

fn main() {
Expand Down Expand Up @@ -275,6 +278,7 @@ fn configure_app(app: &mut web::ServiceConfig, conf: &MiniserveConfig) {
let file_upload = conf.file_upload;
let tar_enabled = conf.tar_enabled;
let zip_enabled = conf.zip_enabled;
let title = conf.title.clone();
upload_route = if let Some(random_route) = conf.random_route.clone() {
format!("/{}/upload", random_route)
} else {
Expand Down Expand Up @@ -303,6 +307,7 @@ fn configure_app(app: &mut web::ServiceConfig, conf: &MiniserveConfig) {
u_r.clone(),
tar_enabled,
zip_enabled,
title.clone(),
)
})
.default_handler(web::to(error_404)),
Expand Down
41 changes: 25 additions & 16 deletions src/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::time::SystemTime;
use strum::IntoEnumIterator;

use crate::archive::CompressionMethod;
use crate::listing::{Entry, SortingMethod, SortingOrder};
use crate::listing::{Breadcrumb, Entry, SortingMethod, SortingOrder};
use crate::themes::ColorScheme;

/// Renders the file listing
Expand All @@ -23,7 +23,7 @@ pub fn page(
file_upload: bool,
upload_route: &str,
encoded_dir: &str,
display_dir: &str,
breadcrumbs: Vec<Breadcrumb>,
tar_enabled: bool,
zip_enabled: bool,
) -> Markup {
Expand All @@ -36,10 +36,16 @@ pub fn page(
default_color_scheme,
);

let title_path = breadcrumbs
.iter()
.map(|el| el.name.clone())
.collect::<Vec<_>>()
.join("/");

html! {
(DOCTYPE)
html {
(page_header(display_dir, color_scheme, file_upload, false))
(page_header(&title_path, color_scheme, file_upload))
body#drop-container {
@if file_upload {
div.drag-form {
Expand All @@ -51,7 +57,19 @@ pub fn page(
(color_scheme_selector(sort_method, sort_order, color_scheme, default_color_scheme, serve_path, show_qrcode))
div.container {
span#top { }
h1.title { "Index of " (display_dir) }
h1.title {
@for el in breadcrumbs {
@if el.link == "." {
// wrapped in span so the text doesn't shift slightly when it turns into a link
span { (el.name) }
} @else {
a.directory href=(parametrized_link(&el.link, sort_method, sort_order, color_scheme, default_color_scheme)) {
(el.name)
}
}
"/"
}
}
div.toolbar {
@if tar_enabled || zip_enabled {
div.download {
Expand Down Expand Up @@ -834,22 +852,13 @@ fn chevron_down() -> Markup {
}

/// Partial: page header
fn page_header(
serve_path: &str,
color_scheme: ColorScheme,
file_upload: bool,
is_error: bool,
) -> Markup {
fn page_header(title: &str, color_scheme: ColorScheme, file_upload: bool) -> Markup {
html! {
head {
meta charset="utf-8";
meta http-equiv="X-UA-Compatible" content="IE=edge";
meta name="viewport" content="width=device-width, initial-scale=1";
@if is_error {
title { (serve_path) }
} @else {
title { "Index of " (serve_path) }
}
title { (title) }
style { (css(color_scheme)) }
@if file_upload {
(PreEscaped(r#"
Expand Down Expand Up @@ -940,7 +949,7 @@ pub fn render_error(
html! {
(DOCTYPE)
html {
(page_header(&error_code.to_string(), color_scheme, false, true))
(page_header(&error_code.to_string(), color_scheme, false))
body {
div.error {
p { (error_code.to_string()) }
Expand Down

0 comments on commit 3549d26

Please sign in to comment.