Render file expiry time and secret in history view
This commit is contained in:
parent
cb0638c5c9
commit
a6186975b2
3 changed files with 80 additions and 3 deletions
|
@ -6,9 +6,8 @@ use url::{
|
|||
ParseError as UrlParseError,
|
||||
Url,
|
||||
};
|
||||
use self::chrono::{DateTime, Utc};
|
||||
use self::chrono::{DateTime, Duration, Utc};
|
||||
use self::regex::Regex;
|
||||
use time::Duration;
|
||||
use url_serde;
|
||||
|
||||
use config::SEND_DEFAULT_EXPIRE_TIME;
|
||||
|
@ -157,6 +156,23 @@ impl RemoteFile {
|
|||
&self.id
|
||||
}
|
||||
|
||||
/// Get the duration the file will expire after,
|
||||
/// if an expiry time is known.
|
||||
/// Otherwise `None` is returned.
|
||||
pub fn expire_duration(&self) -> Option<Duration> {
|
||||
self.expire_at.as_ref().map(|time| {
|
||||
// Get the current time
|
||||
let now = Utc::now();
|
||||
|
||||
// Return the duration if not expired, otherwise return zero
|
||||
if time > &now {
|
||||
*time - now
|
||||
} else {
|
||||
Duration::zero()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Set the time this file will expire at.
|
||||
/// None may be given if the expire time is unknown.
|
||||
pub fn set_expire_at(&mut self, expire_at: Option<DateTime<Utc>>) {
|
||||
|
|
|
@ -18,6 +18,7 @@ use history::{
|
|||
History as HistoryManager,
|
||||
LoadError as HistoryLoadError,
|
||||
};
|
||||
use util::format_duration;
|
||||
|
||||
/// A history action.
|
||||
pub struct History<'a> {
|
||||
|
@ -61,14 +62,23 @@ impl<'a> History<'a> {
|
|||
Cell::new("#"),
|
||||
Cell::new("FILE ID"),
|
||||
Cell::new("URL"),
|
||||
Cell::new("EXPIRY"),
|
||||
]));
|
||||
|
||||
// Add an entry for each file
|
||||
for (i, file) in history.files().iter().enumerate() {
|
||||
// Build the expiry time string
|
||||
let expiry = match file.expire_duration() {
|
||||
Some(ref expire) => format_duration(expire),
|
||||
None => "?".into(),
|
||||
};
|
||||
|
||||
// Add the row
|
||||
table.add_row(Row::new(vec![
|
||||
Cell::new(&format!("{}", i + 1)),
|
||||
Cell::new(file.id()),
|
||||
Cell::new(file.download_url(false).as_str()),
|
||||
Cell::new(file.download_url(true).as_str()),
|
||||
Cell::new(&expiry),
|
||||
]));
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ use self::colored::*;
|
|||
use failure::{err_msg, Fail};
|
||||
use ffsend_api::url::Url;
|
||||
use rpassword::prompt_password_stderr;
|
||||
use time::Duration;
|
||||
|
||||
use cmd::matcher::MainMatcher;
|
||||
|
||||
|
@ -442,6 +443,56 @@ pub fn format_bytes(bytes: u64) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
/// Format the given duration in a human readable format.
|
||||
/// This method builds a string of time components to represent
|
||||
/// the given duration.
|
||||
///
|
||||
/// The following time units are used:
|
||||
/// - `w`: weeks
|
||||
/// - `d`: days
|
||||
/// - `h`: hours
|
||||
/// - `m`: minutes
|
||||
/// - `s`: seconds
|
||||
///
|
||||
/// Only the two most significant units are returned.
|
||||
/// If the duration is zero seconds or less `now` is returned.
|
||||
///
|
||||
/// The following time strings may be produced:
|
||||
/// - `8w6d`
|
||||
/// - `23h14m`
|
||||
/// - `9m55s`
|
||||
/// - `1s`
|
||||
/// - `now`
|
||||
pub fn format_duration(duration: &Duration) -> String {
|
||||
// Get the total number of seconds, return immediately if zero or less
|
||||
let mut secs = duration.num_seconds();
|
||||
if secs <= 0 {
|
||||
return "now".into();
|
||||
}
|
||||
|
||||
// Build a list of time units, define a list for time components
|
||||
let mut components = Vec::new();
|
||||
let units = [
|
||||
(1 * 60 * 60 * 24 * 7, "w"),
|
||||
(1 * 60 * 60 * 24, "d"),
|
||||
(1 * 60 * 60, "h"),
|
||||
(1 * 60, "m"),
|
||||
(1, "s"),
|
||||
];
|
||||
|
||||
// Fill the list of time components based on the units which fit
|
||||
for unit in units.iter() {
|
||||
if secs >= unit.0 {
|
||||
components.push(format!("{}{}", secs / unit.0, unit.1));
|
||||
secs %= unit.0;
|
||||
}
|
||||
}
|
||||
|
||||
// Show only the two most significant components and join them in a string
|
||||
components.truncate(2);
|
||||
components.join("")
|
||||
}
|
||||
|
||||
/// Get the name of the executable that was invoked.
|
||||
pub fn exe_name() -> String {
|
||||
current_exe()
|
||||
|
|
Loading…
Reference in a new issue