Skip to content

Commit 04d73b7

Browse files
AntosserLeoBorai
andauthored
feat: sort by date created/modified (#373)
Co-authored-by: Esteban Borai <estebanborai@gmail.com>
1 parent 9c273cf commit 04d73b7

File tree

7 files changed

+91
-63
lines changed

7 files changed

+91
-63
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ dhat-profiling = ["dhat"]
3131
anyhow = "1.0.75"
3232
async-stream = "0.3.5"
3333
async-trait = "0.1.72"
34-
chrono = "0.4.31"
34+
chrono = { version = "0.4.31", features = ["serde"] }
3535
dhat = { version = "0.2.4", optional = true }
3636
futures = "0.3.29"
3737
flate2 = "1.0.28"

src/addon/file_server/directory_entry.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use serde::Serialize;
1+
use chrono::{DateTime, Local};
2+
use serde::{Deserialize, Serialize};
23
use std::cmp::{Ord, Ordering};
34

45
/// A Directory entry used to display a File Explorer's entry.
@@ -11,8 +12,8 @@ pub struct DirectoryEntry {
1112
pub(crate) size: String,
1213
pub(crate) len: u64,
1314
pub(crate) entry_path: String,
14-
pub(crate) created_at: String,
15-
pub(crate) updated_at: String,
15+
pub(crate) date_created: Option<DateTime<Local>>,
16+
pub(crate) date_modified: Option<DateTime<Local>>,
1617
}
1718

1819
impl Ord for DirectoryEntry {
@@ -60,6 +61,14 @@ pub struct DirectoryIndex {
6061
/// Directory listing entry
6162
pub(crate) entries: Vec<DirectoryEntry>,
6263
pub(crate) breadcrumbs: Vec<BreadcrumbItem>,
63-
pub(crate) sort_by_name: bool,
64-
pub(crate) sort_by_size: bool,
64+
pub(crate) sort: Sort,
65+
}
66+
67+
#[derive(Serialize, Debug, PartialEq, Deserialize)]
68+
pub enum Sort {
69+
Directory,
70+
Name,
71+
Size,
72+
DateCreated,
73+
DateModified,
6574
}

src/addon/file_server/mod.rs

Lines changed: 54 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ mod http_utils;
44
mod query_params;
55
mod scoped_file_system;
66

7+
use chrono::{DateTime, Local};
8+
79
pub use file::{File, FILE_BUFFER_SIZE};
810
pub use scoped_file_system::{Directory, Entry, ScopedFileSystem};
911

1012
use anyhow::{Context, Result};
11-
use handlebars::Handlebars;
13+
use handlebars::{handlebars_helper, Handlebars};
1214
use http::response::Builder as HttpResponseBuilder;
1315
use http::{StatusCode, Uri};
1416
use hyper::{Body, Response};
@@ -18,10 +20,10 @@ use std::path::{Component, Path, PathBuf};
1820
use std::str::FromStr;
1921
use std::sync::Arc;
2022

21-
use crate::utils::fmt::{format_bytes, format_system_date};
23+
use crate::utils::fmt::format_bytes;
2224
use crate::utils::url_encode::{decode_uri, encode_uri, PERCENT_ENCODE_SET};
2325

24-
use self::directory_entry::{BreadcrumbItem, DirectoryEntry, DirectoryIndex};
26+
use self::directory_entry::{BreadcrumbItem, DirectoryEntry, DirectoryIndex, Sort};
2527
use self::http_utils::{make_http_file_response, CacheControlDirective};
2628
use self::query_params::{QueryParams, SortBy};
2729

@@ -58,6 +60,26 @@ impl<'a> FileServer {
5860
.register_template_string(EXPLORER_TEMPLATE, template)
5961
.unwrap();
6062

63+
handlebars_helper!(date: |d: Option<DateTime<Local>>| {
64+
match d {
65+
Some(d) => d.format("%Y/%m/%d %H:%M:%S").to_string(),
66+
None => "-".to_owned(),
67+
}
68+
});
69+
handlebars.register_helper("date", Box::new(date));
70+
71+
handlebars_helper!(sort_name: |sort: Sort| sort == Sort::Name);
72+
handlebars.register_helper("sort_name", Box::new(sort_name));
73+
74+
handlebars_helper!(sort_size: |sort: Sort| sort == Sort::Size);
75+
handlebars.register_helper("sort_size", Box::new(sort_size));
76+
77+
handlebars_helper!(sort_date_created: |sort: Sort| sort == Sort::DateCreated);
78+
handlebars.register_helper("sort_date_created", Box::new(sort_date_created));
79+
80+
handlebars_helper!(sort_date_modified: |sort: Sort| sort == Sort::DateModified);
81+
handlebars.register_helper("sort_date_modified", Box::new(sort_date_modified));
82+
6183
Arc::new(handlebars)
6284
}
6385

@@ -224,15 +246,15 @@ impl<'a> FileServer {
224246
for entry in entries {
225247
let entry = entry.context("Unable to read entry")?;
226248
let metadata = entry.metadata()?;
227-
let created_at = if let Ok(time) = metadata.created() {
228-
format_system_date(time)
249+
let date_created = if let Ok(time) = metadata.created() {
250+
Some(time.into())
229251
} else {
230-
String::default()
252+
None
231253
};
232-
let updated_at = if let Ok(time) = metadata.modified() {
233-
format_system_date(time)
254+
let date_modified = if let Ok(time) = metadata.modified() {
255+
Some(time.into())
234256
} else {
235-
String::default()
257+
None
236258
};
237259

238260
directory_entries.push(DirectoryEntry {
@@ -245,8 +267,8 @@ impl<'a> FileServer {
245267
size: format_bytes(metadata.len() as f64),
246268
len: metadata.len(),
247269
entry_path: FileServer::make_dir_entry_link(&root_dir, &entry.path()),
248-
created_at,
249-
updated_at,
270+
date_created,
271+
date_modified,
250272
});
251273
}
252274

@@ -255,25 +277,28 @@ impl<'a> FileServer {
255277
match sort_by {
256278
SortBy::Name => {
257279
directory_entries.sort_by_key(|entry| entry.display_name.clone());
258-
259-
return Ok(DirectoryIndex {
260-
entries: directory_entries,
261-
breadcrumbs,
262-
sort_by_name: true,
263-
sort_by_size: false,
264-
});
265280
}
266-
SortBy::Size => {
267-
directory_entries.sort_by_key(|entry| entry.len);
268-
269-
return Ok(DirectoryIndex {
270-
entries: directory_entries,
271-
breadcrumbs,
272-
sort_by_name: false,
273-
sort_by_size: true,
274-
});
281+
SortBy::Size => directory_entries.sort_by_key(|entry| entry.len),
282+
SortBy::DateCreated => {
283+
directory_entries.sort_by_key(|entry| entry.date_created)
275284
}
276-
}
285+
SortBy::DateModified => {
286+
directory_entries.sort_by_key(|entry| entry.date_modified)
287+
}
288+
};
289+
290+
let sort_enum = match sort_by {
291+
SortBy::Name => Sort::Name,
292+
SortBy::Size => Sort::Size,
293+
SortBy::DateCreated => Sort::DateCreated,
294+
SortBy::DateModified => Sort::DateModified,
295+
};
296+
297+
return Ok(DirectoryIndex {
298+
entries: directory_entries,
299+
breadcrumbs,
300+
sort: sort_enum,
301+
});
277302
}
278303
}
279304

@@ -282,8 +307,7 @@ impl<'a> FileServer {
282307
Ok(DirectoryIndex {
283308
entries: directory_entries,
284309
breadcrumbs,
285-
sort_by_name: false,
286-
sort_by_size: false,
310+
sort: Sort::Directory,
287311
})
288312
}
289313

src/addon/file_server/query_params.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use std::str::FromStr;
66
pub enum SortBy {
77
Name,
88
Size,
9+
DateCreated,
10+
DateModified,
911
}
1012

1113
impl FromStr for SortBy {
@@ -16,8 +18,10 @@ impl FromStr for SortBy {
1618
let lower = lower.as_str();
1719

1820
match lower {
19-
"name" => Ok(SortBy::Name),
20-
"size" => Ok(SortBy::Size),
21+
"name" => Ok(Self::Name),
22+
"size" => Ok(Self::Size),
23+
"date_created" => Ok(Self::DateCreated),
24+
"date_modified" => Ok(Self::DateModified),
2125
_ => Err(Error::msg("Value doesnt correspond")),
2226
}
2327
}

src/addon/file_server/template/explorer.hbs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -190,18 +190,27 @@
190190
<ul id="explorer">
191191
<li class="hrow">
192192
<span class="hcol icon-col"></span>
193-
{{#if sort_by_name}}
193+
{{#if (sort_name sort)}}
194194
<a class="hcol" href="?sort_by=">Name&nbsp;↓</a>
195195
{{else}}
196196
<a class="hcol" href="?sort_by=name">Name</a>
197197
{{/if}}
198-
{{#if sort_by_size}}
198+
{{#if (sort_size sort)}}
199199
<a class="hcol" href="?sort_by=">Size&nbsp;↓</a>
200200
{{else}}
201201
<a class="hcol" href="?sort_by=size">Size</a>
202202
{{/if}}
203-
<a class="hcol">Date created</a>
204-
<a class="hcol">Date modified</a>
203+
{{#if (sort_date_created sort)}}
204+
<a class="hcol" href="?sort_by=">Date created&nbsp;↓</a>
205+
{{else}}
206+
<a class="hcol" href="?sort_by=date_created">Date created</a>
207+
{{/if}}
208+
{{#if (sort_date_modified sort)}}
209+
<a class="hcol" href="?sort_by=">Date modified&nbsp;↓</a>
210+
{{else}}
211+
<a class="hcol" href="?sort_by=date_modified">Date modified</a>
212+
{{/if}}
213+
205214
</li>
206215
{{#each entries}}
207216
<li class="brow">
@@ -215,8 +224,8 @@
215224
</span>
216225
<span class="bcol">{{display_name}}</span>
217226
<span class="bcol">{{size}}</span>
218-
<span class="bcol">{{created_at}}</span>
219-
<span class="bcol">{{updated_at}}</span>
227+
<span class="bcol">{{date date_created}}</span>
228+
<span class="bcol">{{date date_modified}}</span>
220229
</a>
221230
</li>
222231
{{/each}}

src/utils/fmt.rs

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
use chrono::prelude::*;
2-
use chrono::{DateTime, Local};
3-
use std::time::SystemTime;
4-
51
/// Byte size units
62
const BYTE_SIZE_UNIT: [&str; 9] = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
73

@@ -18,21 +14,6 @@ pub fn format_bytes(bytes: f64) -> String {
1814
format!("{:.2} {}", value, BYTE_SIZE_UNIT[i as usize])
1915
}
2016

21-
/// Formats a `SystemTime` into a YYYY/MM/DD HH:MM:SS time `String`
22-
pub fn format_system_date(system_time: SystemTime) -> String {
23-
let datetime: DateTime<Local> = DateTime::from(system_time);
24-
25-
format!(
26-
"{}/{:0>2}/{:0>2} {:0>2}:{:0>2}:{:0>2}",
27-
datetime.year(),
28-
datetime.month(),
29-
datetime.day(),
30-
datetime.hour(),
31-
datetime.minute(),
32-
datetime.second()
33-
)
34-
}
35-
3617
#[cfg(test)]
3718
mod tests {
3819
use std::vec;

0 commit comments

Comments
 (0)