mirror of
https://github.com/timvisee/ffsend.git
synced 2025-10-03 17:49:15 +02:00
Ask for archival on upload, improve upload status logging
This commit is contained in:
parent
70bbf02762
commit
b54851a37a
5 changed files with 47 additions and 21 deletions
|
@ -32,6 +32,7 @@ Features:
|
||||||
- Implement a quiet `-q` mode
|
- Implement a quiet `-q` mode
|
||||||
- Update all dependencies
|
- Update all dependencies
|
||||||
- Check all TODOs, solve them when possible
|
- Check all TODOs, solve them when possible
|
||||||
|
- Allow multi file uploads (select more than one file or directory)
|
||||||
|
|
||||||
# Future releases
|
# Future releases
|
||||||
- Color usage flag
|
- Color usage flag
|
||||||
|
|
|
@ -42,19 +42,19 @@ impl<'a> Debug<'a> {
|
||||||
|
|
||||||
// The default host
|
// The default host
|
||||||
table.add_row(Row::new(vec![
|
table.add_row(Row::new(vec![
|
||||||
Cell::new("host:"),
|
Cell::new("Host:"),
|
||||||
Cell::new(matcher_debug.host().as_str()),
|
Cell::new(matcher_debug.host().as_str()),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
// The history file
|
// The history file
|
||||||
table.add_row(Row::new(vec![
|
table.add_row(Row::new(vec![
|
||||||
Cell::new("history file:"),
|
Cell::new("History file:"),
|
||||||
Cell::new(matcher_main.history().to_str().unwrap_or("?")),
|
Cell::new(matcher_main.history().to_str().unwrap_or("?")),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
// The default host
|
// The default host
|
||||||
table.add_row(Row::new(vec![
|
table.add_row(Row::new(vec![
|
||||||
Cell::new("default expiry:"),
|
Cell::new("Default expiry:"),
|
||||||
Cell::new(&format_duration(Duration::seconds(SEND_DEFAULT_EXPIRE_TIME))),
|
Cell::new(&format_duration(Duration::seconds(SEND_DEFAULT_EXPIRE_TIME))),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
|
|
|
@ -122,14 +122,14 @@ impl<'a> Info<'a> {
|
||||||
if let Some(metadata) = metadata {
|
if let Some(metadata) = metadata {
|
||||||
// The file name
|
// The file name
|
||||||
table.add_row(Row::new(vec![
|
table.add_row(Row::new(vec![
|
||||||
Cell::new("name:"),
|
Cell::new("Name:"),
|
||||||
Cell::new(metadata.metadata().name()),
|
Cell::new(metadata.metadata().name()),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
// The file size
|
// The file size
|
||||||
let size = metadata.size();
|
let size = metadata.size();
|
||||||
table.add_row(Row::new(vec![
|
table.add_row(Row::new(vec![
|
||||||
Cell::new("size:"),
|
Cell::new("Size:"),
|
||||||
Cell::new(
|
Cell::new(
|
||||||
&if size >= 1024 {
|
&if size >= 1024 {
|
||||||
format!("{} ({} B)", format_bytes(size), size)
|
format!("{} ({} B)", format_bytes(size), size)
|
||||||
|
@ -148,13 +148,13 @@ impl<'a> Info<'a> {
|
||||||
|
|
||||||
// The download count
|
// The download count
|
||||||
table.add_row(Row::new(vec![
|
table.add_row(Row::new(vec![
|
||||||
Cell::new("downloads:"),
|
Cell::new("Downloads:"),
|
||||||
Cell::new(&format!("{} of {}", info.download_count(), info.download_limit())),
|
Cell::new(&format!("{} of {}", info.download_count(), info.download_limit())),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
// The time to live
|
// The time to live
|
||||||
table.add_row(Row::new(vec![
|
table.add_row(Row::new(vec![
|
||||||
Cell::new("expiry:"),
|
Cell::new("Expiry:"),
|
||||||
Cell::new(
|
Cell::new(
|
||||||
&if ttl_millis >= 60 * 1000 {
|
&if ttl_millis >= 60 * 1000 {
|
||||||
format!("{} ({}s)", format_duration(&ttl), ttl.num_seconds())
|
format!("{} ({}s)", format_duration(&ttl), ttl.num_seconds())
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
// TODO: remove all expect unwraps, replace them with proper errors
|
|
||||||
|
|
||||||
extern crate tempfile;
|
extern crate tempfile;
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
@ -17,6 +15,12 @@ use ffsend_api::action::upload::{
|
||||||
use ffsend_api::config::{UPLOAD_SIZE_MAX, UPLOAD_SIZE_MAX_RECOMMENDED};
|
use ffsend_api::config::{UPLOAD_SIZE_MAX, UPLOAD_SIZE_MAX_RECOMMENDED};
|
||||||
use ffsend_api::reader::ProgressReporter;
|
use ffsend_api::reader::ProgressReporter;
|
||||||
use ffsend_api::reqwest::Client;
|
use ffsend_api::reqwest::Client;
|
||||||
|
use prettytable::{
|
||||||
|
cell::Cell,
|
||||||
|
format::FormatBuilder,
|
||||||
|
row::Row,
|
||||||
|
Table,
|
||||||
|
};
|
||||||
use self::tempfile::{
|
use self::tempfile::{
|
||||||
Builder as TempBuilder,
|
Builder as TempBuilder,
|
||||||
NamedTempFile,
|
NamedTempFile,
|
||||||
|
@ -89,7 +93,7 @@ impl<'a> Upload<'a> {
|
||||||
} else if size > UPLOAD_SIZE_MAX_RECOMMENDED && !matcher_main.force() {
|
} else if size > UPLOAD_SIZE_MAX_RECOMMENDED && !matcher_main.force() {
|
||||||
// The file is larger than the recommended maximum, warn
|
// The file is larger than the recommended maximum, warn
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"the file size is {}, bigger than the recommended maximum of {}",
|
"The file size is {}, bigger than the recommended maximum of {}",
|
||||||
format_bytes(size),
|
format_bytes(size),
|
||||||
format_bytes(UPLOAD_SIZE_MAX_RECOMMENDED),
|
format_bytes(UPLOAD_SIZE_MAX_RECOMMENDED),
|
||||||
);
|
);
|
||||||
|
@ -135,9 +139,22 @@ impl<'a> Upload<'a> {
|
||||||
|
|
||||||
#[cfg(feature = "archive")]
|
#[cfg(feature = "archive")]
|
||||||
{
|
{
|
||||||
// Archive the file if specified
|
// Determine whether to archive, ask if a directory was selected
|
||||||
if matcher_upload.archive() {
|
let mut archive = matcher_upload.archive();
|
||||||
println!("Archiving file...");
|
if !archive && path.is_dir() {
|
||||||
|
if prompt_yes(
|
||||||
|
"You've selected a directory, only a single file may be uploaded.\n\
|
||||||
|
Archive the directory into a single file?",
|
||||||
|
Some(true),
|
||||||
|
&matcher_main,
|
||||||
|
) {
|
||||||
|
archive = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Archive the selected file or directory
|
||||||
|
if archive {
|
||||||
|
eprintln!("Archiving...");
|
||||||
let archive_extention = ".tar";
|
let archive_extention = ".tar";
|
||||||
|
|
||||||
// Create a new temporary file to write the archive to
|
// Create a new temporary file to write the archive to
|
||||||
|
@ -157,7 +174,6 @@ impl<'a> Upload<'a> {
|
||||||
|
|
||||||
// Select the file name to use if not set
|
// Select the file name to use if not set
|
||||||
if file_name.is_none() {
|
if file_name.is_none() {
|
||||||
// TODO: use canonical path here
|
|
||||||
file_name = Some(
|
file_name = Some(
|
||||||
path.canonicalize()
|
path.canonicalize()
|
||||||
.map_err(|err| ArchiveError::FileName(Some(err)))?
|
.map_err(|err| ArchiveError::FileName(Some(err)))?
|
||||||
|
@ -165,7 +181,7 @@ impl<'a> Upload<'a> {
|
||||||
.ok_or(ArchiveError::FileName(None))?
|
.ok_or(ArchiveError::FileName(None))?
|
||||||
.to_str()
|
.to_str()
|
||||||
.map(|s| s.to_owned())
|
.map(|s| s.to_owned())
|
||||||
.expect("failed to create string from file name")
|
.ok_or(ArchiveError::FileName(None))?
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,10 +214,19 @@ impl<'a> Upload<'a> {
|
||||||
params,
|
params,
|
||||||
).invoke(&client, &progress_reporter)?;
|
).invoke(&client, &progress_reporter)?;
|
||||||
|
|
||||||
// Get the download URL, and report it in the console
|
// Get the download URL, and report it in the console in a table
|
||||||
let url = file.download_url(true);
|
let url = file.download_url(true);
|
||||||
println!("Download URL: {}", url);
|
let mut table = Table::new();
|
||||||
println!("Owner token: {}", file.owner_token().unwrap());
|
table.set_format(FormatBuilder::new().padding(0, 2).build());
|
||||||
|
table.add_row(Row::new(vec![
|
||||||
|
Cell::new("Share URL:"),
|
||||||
|
Cell::new(url.as_str()),
|
||||||
|
]));
|
||||||
|
table.add_row(Row::new(vec![
|
||||||
|
Cell::new("Owner token:"),
|
||||||
|
Cell::new(file.owner_token().unwrap()),
|
||||||
|
]));
|
||||||
|
table.printstd();
|
||||||
|
|
||||||
// Add the file to the history manager
|
// Add the file to the history manager
|
||||||
#[cfg(feature = "history")]
|
#[cfg(feature = "history")]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
extern crate pbr;
|
extern crate pbr;
|
||||||
|
|
||||||
use std::io::Stdout;
|
use std::io::{stderr, Stderr};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use ffsend_api::reader::ProgressReporter;
|
use ffsend_api::reader::ProgressReporter;
|
||||||
|
@ -14,7 +14,7 @@ const PROGRESS_BAR_FPS_MILLIS: u64 = 200;
|
||||||
|
|
||||||
/// A progress bar reporter.
|
/// A progress bar reporter.
|
||||||
pub struct ProgressBar<'a> {
|
pub struct ProgressBar<'a> {
|
||||||
progress_bar: Option<Pbr<Stdout>>,
|
progress_bar: Option<Pbr<Stderr>>,
|
||||||
msg_progress: &'a str,
|
msg_progress: &'a str,
|
||||||
msg_finish: &'a str,
|
msg_finish: &'a str,
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ impl<'a> ProgressReporter for ProgressBar<'a> {
|
||||||
/// Start the progress with the given total.
|
/// Start the progress with the given total.
|
||||||
fn start(&mut self, total: u64) {
|
fn start(&mut self, total: u64) {
|
||||||
// Initialize the progress bar
|
// Initialize the progress bar
|
||||||
let mut progress_bar = Pbr::new(total);
|
let mut progress_bar = Pbr::on(stderr(), total);
|
||||||
progress_bar.set_max_refresh_rate(
|
progress_bar.set_max_refresh_rate(
|
||||||
Some(Duration::from_millis(PROGRESS_BAR_FPS_MILLIS))
|
Some(Duration::from_millis(PROGRESS_BAR_FPS_MILLIS))
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue