Skip to content

Commit 7454708

Browse files
authored
Merge pull request #1505 from 7sDream/feature/search
Minimalist search/filter feature
2 parents 32efd91 + 96d6909 commit 7454708

File tree

5 files changed

+210
-50
lines changed

5 files changed

+210
-50
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,15 @@ You can enable a convenient copy-pastable footer for `wget` using `--show-wget-f
118118
Afterwards, check the bottom of any rendered page.
119119
It'll have a neat `wget` command you can easily copy-paste to recursively grab the current directory.
120120

121+
### Use query parameter to do a simple filter
122+
123+
You can pass a `?search=<keyword>` query parameter to only show files and directories whose name contains the `<keyword>`, for example:
124+
125+
miniserve .
126+
# Then visit http://127.0.0.1:8080/src/?search=file
127+
128+
This filter feature is case insensitive.
129+
121130
### Take pictures and upload them from smartphones:
122131

123132
miniserve -u -m image -q
@@ -132,6 +141,7 @@ Some mobile browsers like Firefox on Android will offer to open the camera app w
132141
- Single binary drop-in with no extra dependencies required
133142
- Authentication support with username and password (and hashed password)
134143
- Mega fast and highly parallel (thanks to [Rust](https://www.rust-lang.org/) and [Actix](https://actix.rs/))
144+
- Search/filter by file or directory name
135145
- Folder download (compressed on the fly as `.tar.gz` or `.zip`)
136146
- File uploading
137147
- Directory creation

data/style.scss

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,39 @@ th span.active span {
744744
margin-top: 4rem;
745745
}
746746

747+
.title-search-box {
748+
display: flex;
749+
justify-content: space-between;
750+
align-items: center;
751+
flex-wrap: wrap;
752+
}
753+
754+
.search-box {
755+
display: flex;
756+
align-items: center;
757+
}
758+
759+
.search-box form {
760+
display: flex;
761+
align-items: center;
762+
}
763+
764+
.search-box input {
765+
padding: 0.5rem;
766+
border-radius: 0.2rem;
767+
border: 1px solid var(--upload_form_border_color);
768+
margin-right: 0.2rem;
769+
}
770+
771+
.search-box button {
772+
background: var(--upload_button_background);
773+
padding: 0.5rem;
774+
border-radius: 0.2rem;
775+
color: var(--upload_button_text_color);
776+
border: none;
777+
min-width: max-content;
778+
}
779+
747780
@media (max-width: 760px) {
748781
nav {
749782
padding: 0 2.5rem;

src/listing.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ pub struct ListingQueryParameters {
4646
pub sort: Option<SortingMethod>,
4747
pub order: Option<SortingOrder>,
4848
pub raw: Option<bool>,
49+
pub search: Option<String>,
4950
download: Option<ArchiveMethod>,
5051
}
5152

@@ -247,6 +248,13 @@ pub fn directory_listing(
247248
};
248249

249250
let query_params = extract_query_parameters(req);
251+
let search = query_params.search.as_ref().map(|s| s.to_lowercase());
252+
let matches_search = move |filename: &str| -> bool {
253+
match search {
254+
Some(ref search) => filename.to_lowercase().contains(search),
255+
None => true,
256+
}
257+
};
250258
let mut entries: Vec<Entry> = Vec::new();
251259
let mut readme: Option<(String, String)> = None;
252260
let readme_rx: Regex = Regex::new("^readme([.](md|txt))?$").unwrap();
@@ -280,6 +288,9 @@ pub fn directory_listing(
280288
let last_modification_date = metadata.modified().ok();
281289

282290
if metadata.is_dir() {
291+
if !matches_search(&file_name) {
292+
continue;
293+
}
283294
entries.push(Entry::new(
284295
file_name,
285296
EntryType::Directory,
@@ -317,14 +328,6 @@ pub fn directory_listing(
317328
}
318329
None => file_url,
319330
};
320-
entries.push(Entry::new(
321-
file_name.clone(),
322-
EntryType::File,
323-
file_link,
324-
Some(ByteSize::b(metadata.len())),
325-
last_modification_date,
326-
symlink_dest,
327-
));
328331
if conf.readme && readme_rx.is_match(&file_name.to_lowercase()) {
329332
let ext = file_name.split('.').next_back().unwrap().to_lowercase();
330333
readme = Some((
@@ -344,6 +347,17 @@ pub fn directory_listing(
344347
},
345348
));
346349
}
350+
if !matches_search(&file_name) {
351+
continue;
352+
}
353+
entries.push(Entry::new(
354+
file_name.clone(),
355+
EntryType::File,
356+
file_link,
357+
Some(ByteSize::b(metadata.len())),
358+
last_modification_date,
359+
symlink_dest,
360+
));
347361
}
348362
} else {
349363
continue;

0 commit comments

Comments
 (0)