aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--README.md12
-rw-r--r--src/args.rs20
-rw-r--r--src/config.rs27
-rw-r--r--src/listing.rs12
-rw-r--r--src/renderer.rs4
-rw-r--r--tests/navigation.rs30
-rw-r--r--tests/utils/mod.rs16
7 files changed, 116 insertions, 5 deletions
diff --git a/README.md b/README.md
index 7136627..b3c832a 100644
--- a/README.md
+++ b/README.md
@@ -210,6 +210,18 @@ Options:
[env: MINISERVE_HIDDEN=]
+ -S, --default-sorting-method
+ Default sort method for file list
+
+ [env: MINISERVE_DEFAULT_SORTING_METHOD=]
+ [possible values: name, date, size]
+
+ -O, --default-sorting-order
+ Default sort order for file list
+
+ [env: MINISERVE_DEFAULT_SORTING_ORDER=]
+ [possible values: asc, desc]
+
-c, --color-scheme <COLOR_SCHEME>
Default color scheme
diff --git a/src/args.rs b/src/args.rs
index c5c268f..e400c8a 100644
--- a/src/args.rs
+++ b/src/args.rs
@@ -113,6 +113,26 @@ pub struct CliArgs {
#[arg(short = 'H', long = "hidden", env = "MINISERVE_HIDDEN")]
pub hidden: bool,
+ /// Default sorting method for file list
+ #[arg(
+ short = 'S',
+ long = "default-sorting-method",
+ default_value = "",
+ ignore_case = true,
+ env = "MINISERVE_DEFAULT_SORTING_METHOD"
+ )]
+ pub default_sorting_method: String,
+
+ /// Default sorting order for file list
+ #[arg(
+ short = 'O',
+ long = "default-sorting-order",
+ default_value = "",
+ ignore_case = true,
+ env = "MINISERVE_DEFAULT_SORTING_ORDER"
+ )]
+ pub default_sorting_order: String,
+
/// Default color scheme
#[arg(
short = 'c',
diff --git a/src/config.rs b/src/config.rs
index 1ef9eca..491ac40 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -15,6 +15,7 @@ use crate::{
args::{parse_auth, CliArgs, MediaType},
auth::RequiredAuth,
file_utils::sanitize_path,
+ listing::{SortingMethod, SortingOrder},
renderer::ThemeSlug,
};
@@ -50,6 +51,12 @@ pub struct MiniserveConfig {
/// Show hidden files
pub show_hidden: bool,
+ /// Default sorting method
+ pub default_sorting_method: Option<SortingMethod>,
+
+ /// Default sorting order
+ pub default_sorting_order: Option<SortingOrder>,
+
/// Route prefix; Either empty or prefixed with slash
pub route_prefix: String,
@@ -265,6 +272,24 @@ impl MiniserveConfig {
.transpose()?
.unwrap_or_default();
+ let default_sorting_method: Option<SortingMethod> = match args
+ .default_sorting_method
+ .to_owned()
+ .parse::<SortingMethod>()
+ {
+ Ok(value) => Some(value),
+ Err(_) => None,
+ };
+
+ let default_sorting_order: Option<SortingOrder> = match args
+ .default_sorting_order
+ .to_owned()
+ .parse::<SortingOrder>()
+ {
+ Ok(value) => Some(value),
+ Err(_) => None,
+ };
+
Ok(MiniserveConfig {
verbose: args.verbose,
path: args.path.unwrap_or_else(|| PathBuf::from(".")),
@@ -274,6 +299,8 @@ impl MiniserveConfig {
path_explicitly_chosen,
no_symlinks: args.no_symlinks,
show_hidden: args.hidden,
+ default_sorting_method,
+ default_sorting_order,
route_prefix,
favicon_route,
css_route,
diff --git a/src/listing.rs b/src/listing.rs
index 6e75b0e..40c5a77 100644
--- a/src/listing.rs
+++ b/src/listing.rs
@@ -223,7 +223,7 @@ pub fn directory_listing(
res
};
- let query_params = extract_query_parameters(req);
+ let mut query_params = extract_query_parameters(req);
let mut entries: Vec<Entry> = Vec::new();
let mut readme: Option<(String, String)> = None;
@@ -299,6 +299,14 @@ pub fn directory_listing(
}
}
+ if query_params.sort.is_none() {
+ query_params.sort = conf.default_sorting_method
+ }
+
+ if query_params.order.is_none() {
+ query_params.order = conf.default_sorting_order
+ }
+
match query_params.sort.unwrap_or(SortingMethod::Name) {
SortingMethod::Name => entries.sort_by(|e1, e2| {
alphanumeric_sort::compare_str(e1.name.to_lowercase(), e2.name.to_lowercase())
@@ -319,7 +327,7 @@ pub fn directory_listing(
}),
};
- if let Some(SortingOrder::Descending) = query_params.order {
+ if let Some(SortingOrder::Ascending) = query_params.order {
entries.reverse()
}
diff --git a/src/renderer.rs b/src/renderer.rs
index 5a591f0..3b62704 100644
--- a/src/renderer.rs
+++ b/src/renderer.rs
@@ -459,7 +459,7 @@ fn build_link(
) -> Markup {
let mut link = format!("?sort={name}&order=asc");
let mut help = format!("Sort by {name} in ascending order");
- let mut chevron = chevron_up();
+ let mut chevron = chevron_down();
let mut class = "";
if let Some(method) = sort_method {
@@ -469,7 +469,7 @@ fn build_link(
if order.to_string() == "asc" {
link = format!("?sort={name}&order=desc");
help = format!("Sort by {name} in descending order");
- chevron = chevron_down();
+ chevron = chevron_up();
}
}
}
diff --git a/tests/navigation.rs b/tests/navigation.rs
index 3bd7415..34eee2f 100644
--- a/tests/navigation.rs
+++ b/tests/navigation.rs
@@ -1,12 +1,13 @@
mod fixtures;
mod utils;
-use fixtures::{server, Error, TestServer, DEEPLY_NESTED_FILE, DIRECTORIES};
+use fixtures::{server, Error, TestServer, FILES, DEEPLY_NESTED_FILE, DIRECTORIES};
use pretty_assertions::{assert_eq, assert_ne};
use rstest::rstest;
use select::document::Document;
use std::process::{Command, Stdio};
use utils::get_link_from_text;
+use utils::get_link_hrefs_from_text_with_prefix;
#[rstest(
input,
@@ -147,3 +148,30 @@ fn can_navigate_using_breadcrumbs(
Ok(())
}
+
+#[rstest]
+#[case(server(&["--default-sorting-method", "date", "--default-sorting-order", "desc"]))]
+#[case(server(&["--default-sorting-method", "date", "--default-sorting-order", "asc"]))]
+/// We can specify the default sorting order
+fn can_specify_default_sorting_order(#[case] server: TestServer) -> Result<(), Error> {
+ let slash = String::from("/");
+ let base_url = server.url();
+ let nested_url = base_url.join(&slash)?;
+
+ let resp = reqwest::blocking::get(nested_url.as_str())?;
+ let body = resp.error_for_status()?;
+ let parsed = Document::from_read(body)?;
+
+ let links = get_link_hrefs_from_text_with_prefix(&parsed, "/");
+ let first_created_file = slash + FILES.first().unwrap();
+
+ if links.first().unwrap() == &first_created_file {
+ assert_eq!("/very/?sort=date&order=asc", links.last().unwrap());
+ }
+
+ if links.last().unwrap() == &first_created_file {
+ assert_eq!("/very/?sort=date&order=desc", links.first().unwrap());
+ }
+
+ Ok(())
+}
diff --git a/tests/utils/mod.rs b/tests/utils/mod.rs
index 734d33b..64433fc 100644
--- a/tests/utils/mod.rs
+++ b/tests/utils/mod.rs
@@ -12,3 +12,19 @@ pub fn get_link_from_text(document: &Document, text: &str) -> Option<String> {
.next()?;
Some(a_elem.attr("href")?.to_string())
}
+
+/// Return the href attributes of all links that start with the specified prefix `text`.
+pub fn get_link_hrefs_from_text_with_prefix(document: &Document, text: &str) -> Vec<String> {
+ let mut vec: Vec<String> = Vec::new();
+
+ let a_elem = document.find(Name("a"));
+
+ for element in a_elem {
+ let str = element.attr("href").unwrap_or("");
+ if str.to_string().starts_with(text) {
+ vec.push(str.to_string());
+ }
+ }
+
+ return vec;
+}