diff --git a/Cargo.toml b/Cargo.toml index eb50c7f..f2b67b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nexy" -version = "0.4.1" +version = "0.5.0" edition = "2024" license = "MIT" readme = "README.md" @@ -13,4 +13,5 @@ repository = "https://github.com/YGGverse/nexy" anyhow = "1.0" chrono = "^0.4.20" clap = { version = "4.5", features = ["derive"] } -urlencoding = "2.1" \ No newline at end of file +regex = "1.11" +urlencoding = "2.1" diff --git a/README.md b/README.md index 2bf1c52..4d942d0 100644 --- a/README.md +++ b/README.md @@ -36,125 +36,128 @@ nexy -p /path/to/public_dir ### Options ``` bash --a, --access-log - Absolute path to the access log file + -a, --access-log + Absolute path to the access log file --b, --bind - Bind server(s) `host:port` to listen incoming connections + -b, --bind + Bind server(s) `host:port` to listen incoming connections - * use `[host]:port` notation for IPv6 + * use `[host]:port` notation for IPv6 - [default: 127.0.0.1:1900 [::1]:1900] + [default: 127.0.0.1:1900 [::1]:1900] --d, --debug - Print debug information + -d, --debug + Print debug information --p, --public - Absolute path to the public files directory + -p, --public + Absolute path to the public files directory ---show-hidden - Show hidden entries (in the directory listing) + --show-hidden + Show hidden entries (in the directory listing) - * Important: this option does not prevent access to hidden files! + * Important: this option does not prevent access to hidden files! ---template-access-denied - Absolute path to the `Access denied` template file + --template-access-denied + Absolute path to the `Access denied` template file - * this template file can be in binary format (e.g. image) + * this template file can be in binary format (e.g. image) ---template-internal-server-error - Absolute path to the `Internal server error` template file + --template-internal-server-error + Absolute path to the `Internal server error` template file - * this template file can be in binary format (e.g. image) + * this template file can be in binary format (e.g. image) ---template-not-found - Absolute path to the `Not found` template file + --template-not-found + Absolute path to the `Not found` template file - * this template file can be in binary format (e.g. image) + * this template file can be in binary format (e.g. image) ---template-welcome - Absolute path to the `Welcome` template file. Unlike `template-index`, this applies only to the `public` location + --template-welcome + Absolute path to the `Welcome` template file. Unlike `template-index`, this applies only to the `public` location - * this template file expects pattern and cannot be in binary format + * this template file expects pattern and cannot be in binary format - **Patterns** * `{list}` - entries list for the `public` directory * `{hosts}` - unique visitors count * `{hits}` - requests count + **Patterns** * `{list}` - entries list for the `public` directory * `{hosts}` - unique visitors count * `{hits}` - requests count ---template-index - Absolute path to the `Index` template file for each directory + --template-index + Absolute path to the `Index` template file for each directory - * this template file expects pattern and cannot be in binary format + * this template file expects pattern and cannot be in binary format - **Patterns** * `{list}` - entries list for the current directory * `{hosts}` - unique visitors count * `{hits}` - requests count + **Patterns** * `{list}` - entries list for the current directory * `{hosts}` - unique visitors count * `{hits}` - requests count ---list-dir-show-count - Show files count in dir (as the alternative text for navigation links) + --list-dir-show-count + Show files count in dir (as the alternative text for navigation links) ---list-dir-show-accessed - Show directory accessed time + --list-dir-show-accessed + Show directory accessed time ---list-dir-show-created - Show directory created time + --list-dir-show-created + Show directory created time ---list-dir-show-modified - Show directory modified time + --list-dir-show-modified + Show directory modified time ---list-dir-sort-by-accessed - Sort dirs by time accessed (name by default) + --list-dir-sort-by-accessed + Sort dirs by time accessed (name by default) ---list-dir-sort-by-created - Sort dirs by time created (name by default) + --list-dir-sort-by-created + Sort dirs by time created (name by default) ---list-dir-sort-by-modified - Sort dirs by time modified (name by default) + --list-dir-sort-by-modified + Sort dirs by time modified (name by default) ---list-dir-sort-by-count - Sort dirs by count (name by default) + --list-dir-sort-by-count + Sort dirs by count (name by default) ---list-dir-reverse - Sort directories in list DESC (ASC by default) + --list-dir-reverse + Sort directories in list DESC (ASC by default) ---list-file-show-size - Show file size in list (as the alternative text for navigation links) + --list-file-show-size + Show file size in list (as the alternative text for navigation links) ---list-file-show-accessed - Show file accessed time + --list-file-show-accessed + Show file accessed time ---list-file-show-created - Show file created time + --list-file-show-created + Show file created time ---list-file-show-modified - Show file modified time + --list-file-show-modified + Show file modified time ---list-file-sort-by-accessed - Sort files by time accessed (name by default) + --list-file-sort-by-accessed + Sort files by time accessed (name by default) ---list-file-sort-by-created - Sort files by time created (name by default) + --list-file-sort-by-created + Sort files by time created (name by default) ---list-file-sort-by-modified - Sort files by time modified (name by default) + --list-file-sort-by-modified + Sort files by time modified (name by default) ---list-file-sort-by-size - Sort files by size (name by default) + --list-file-sort-by-size + Sort files by size (name by default) ---list-file-reverse - Sort files in list DESC (ASC by default) + --list-file-reverse + Sort files in list DESC (ASC by default) ---list-time-format - Time format for listing items + --list-file-slash + Append trailing slash to files match regex pattern(s) - * use escape notation for `%` e.g. `"%%Y-%%m-%%d %%H:%%M:%%S"` + --list-time-format + Time format for listing items - [default: "%Y/%m/%d"] + * use escape notation for `%` e.g. `"%%Y-%%m-%%d %%H:%%M:%%S"` --r, --read-chunk - Optimize memory usage on reading large files or stream + [default: %Y/%m/%d] - [default: 1024] + -r, --read-chunk + Optimize memory usage on reading large files or stream --h, --help - Print help (see a summary with '-h') + [default: 1024] --V, --version - Print version + -h, --help + Print help (see a summary with '-h') + + -V, --version + Print version ``` diff --git a/src/config.rs b/src/config.rs index cb2fe55..268681a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -147,6 +147,10 @@ pub struct Config { #[arg(long, default_value_t = false)] pub list_file_reverse: bool, + /// Append trailing slash to files match regex pattern(s) + #[arg(long)] + pub list_file_slash: Vec, + /// Time format for listing items /// /// * use escape notation for `%` e.g. `"%%Y-%%m-%%d %%H:%%M:%%S"` diff --git a/src/session/public.rs b/src/session/public.rs index 4eeffb5..5343989 100644 --- a/src/session/public.rs +++ b/src/session/public.rs @@ -240,9 +240,17 @@ impl Public { if fc.alt.is_size { a.push(b(file.meta.size())) } + if !l.ends_with('/') { + for p in &fc.append_slash { + if p.is_match(&l) { + l.push('/'); + break; + } + } + } if !a.is_empty() { l.push(' '); - l.push_str(&a.join(", ")); + l.push_str(&a.join(", ")) } l }) diff --git a/src/session/public/list_config.rs b/src/session/public/list_config.rs index a093f20..233d56f 100644 --- a/src/session/public/list_config.rs +++ b/src/session/public/list_config.rs @@ -2,6 +2,8 @@ //! valid listing configuration from the plain `clap` arguments list. //! This feature is evolving, and it may require refactoring in the future. +use regex::Regex; + pub struct Time { pub is_accessed: bool, pub is_created: bool, @@ -35,6 +37,7 @@ pub struct Dir { } pub struct File { pub alt: FileAlt, + pub append_slash: Vec, pub is_reverse: bool, pub sort: FileSort, } @@ -103,6 +106,13 @@ impl ListConfig { is_size: config.list_file_show_size, }, is_reverse: config.list_file_reverse, + append_slash: { + let mut p = Vec::with_capacity(config.list_file_slash.len()); + for pattern in &config.list_file_slash { + p.push(Regex::new(pattern)?) + } + p + }, sort: FileSort { time: Time { is_accessed: config.list_file_sort_by_accessed,