mirror of
https://github.com/timvisee/ffsend.git
synced 2025-10-06 10:39:57 +02:00
Complete upload progress bar implementation, simplify with arc/mutex
This commit is contained in:
parent
030454cc10
commit
b57e85a8ec
4 changed files with 29 additions and 20 deletions
|
@ -1,6 +1,7 @@
|
|||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use mime_guess::{get_mime_type, Mime};
|
||||
use openssl::symm::encrypt_aead;
|
||||
|
@ -24,8 +25,7 @@ use reader::{
|
|||
use file::file::File as SendFile;
|
||||
use file::metadata::{Metadata, XFileMetadata};
|
||||
|
||||
type EncryptedReader =
|
||||
ProgressReader<'static, BufReader<EncryptedFileReaderTagged>>;
|
||||
type EncryptedReader = ProgressReader<BufReader<EncryptedFileReaderTagged>>;
|
||||
pub type Result<T> = ::std::result::Result<T, UploadError>;
|
||||
|
||||
/// A file upload action to a Send server.
|
||||
|
@ -50,7 +50,7 @@ impl Upload {
|
|||
pub fn invoke(
|
||||
self,
|
||||
client: &Client,
|
||||
reporter: Box<ProgressReporter + 'static>,
|
||||
reporter: Arc<Mutex<ProgressReporter>>,
|
||||
) -> Result<SendFile> {
|
||||
// Create file data, generate a key
|
||||
let file = FileData::from(Box::new(&self.path))?;
|
||||
|
@ -58,8 +58,8 @@ impl Upload {
|
|||
|
||||
// Crpate metadata and a file reader
|
||||
let metadata = self.create_metadata(&key, &file)?;
|
||||
// TODO: do not use leak, as it might cause memory leaks
|
||||
let reader = self.create_reader(&key, Box::leak(reporter))?;
|
||||
let reader = self.create_reader(&key, reporter.clone())?;
|
||||
let reader_len = reader.len().unwrap();
|
||||
|
||||
// Create the request to send
|
||||
let req = self.create_request(
|
||||
|
@ -69,10 +69,18 @@ impl Upload {
|
|||
reader,
|
||||
);
|
||||
|
||||
// Start the reporter
|
||||
reporter.lock()
|
||||
.expect("unable to start progress, failed to get lock")
|
||||
.start(reader_len);
|
||||
|
||||
// Execute the request
|
||||
let result = self.execute_request(req, client, &key);
|
||||
|
||||
// TODO: finish the progress bar
|
||||
// Mark the reporter as finished
|
||||
reporter.lock()
|
||||
.expect("unable to finish progress, failed to get lock")
|
||||
.finish();
|
||||
|
||||
result
|
||||
}
|
||||
|
@ -112,7 +120,7 @@ impl Upload {
|
|||
fn create_reader(
|
||||
&self,
|
||||
key: &KeySet,
|
||||
reporter: &'static mut ProgressReporter,
|
||||
reporter: Arc<Mutex<ProgressReporter>>,
|
||||
) -> Result<EncryptedReader> {
|
||||
// Open the file
|
||||
let file = match File::open(self.path.as_path()) {
|
||||
|
@ -139,8 +147,7 @@ impl Upload {
|
|||
.expect("failed to create progress reader");
|
||||
|
||||
// Initialize and attach the reporter
|
||||
reporter.start(reader.len().unwrap());
|
||||
reader.set_reporter(&mut *reporter);
|
||||
reader.set_reporter(reporter);
|
||||
|
||||
Ok(reader)
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ use std::io::{
|
|||
Error as IoError,
|
||||
Read,
|
||||
};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use openssl::symm::{
|
||||
Cipher,
|
||||
|
@ -236,7 +237,7 @@ unsafe impl Send for EncryptedFileReaderTagged {}
|
|||
///
|
||||
/// The reader will only start producing `None` if the wrapped reader is doing
|
||||
/// so.
|
||||
pub struct ProgressReader<'a, R> {
|
||||
pub struct ProgressReader<R> {
|
||||
/// The wrapped reader.
|
||||
inner: R,
|
||||
|
||||
|
@ -247,10 +248,10 @@ pub struct ProgressReader<'a, R> {
|
|||
progress: u64,
|
||||
|
||||
/// A reporter, to report the progress status to.
|
||||
reporter: Option<&'a mut ProgressReporter>,
|
||||
reporter: Option<Arc<Mutex<ProgressReporter>>>,
|
||||
}
|
||||
|
||||
impl<'a, R: Read> ProgressReader<'a, R> {
|
||||
impl<R: Read> ProgressReader<R> {
|
||||
/// Wrap the given reader with an exact length, in a progress reader.
|
||||
pub fn new(inner: R) -> Result<Self, IoError>
|
||||
where
|
||||
|
@ -277,7 +278,7 @@ impl<'a, R: Read> ProgressReader<'a, R> {
|
|||
}
|
||||
|
||||
/// Set the reporter to report the status to.
|
||||
pub fn set_reporter(&mut self, reporter: &'a mut ProgressReporter) {
|
||||
pub fn set_reporter(&mut self, reporter: Arc<Mutex<ProgressReporter>>) {
|
||||
self.reporter = Some(reporter);
|
||||
}
|
||||
|
||||
|
@ -287,7 +288,7 @@ impl<'a, R: Read> ProgressReader<'a, R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, R: Read> Read for ProgressReader<'a, R> {
|
||||
impl<R: Read> Read for ProgressReader<R> {
|
||||
/// Read from the encrypted file, and then the encryption tag.
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
|
||||
// Read from the wrapped reader, increase the progress
|
||||
|
@ -301,14 +302,16 @@ impl<'a, R: Read> Read for ProgressReader<'a, R> {
|
|||
|
||||
// Report
|
||||
if let Some(reporter) = self.reporter.as_mut() {
|
||||
reporter.progress(self.progress);
|
||||
reporter.lock()
|
||||
.expect("failed to update progress, unable to lock reproter")
|
||||
.progress(self.progress);
|
||||
}
|
||||
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, R: Read> ExactLengthReader for ProgressReader<'a, R> {
|
||||
impl<R: Read> ExactLengthReader for ProgressReader<R> {
|
||||
// Return the specified length.
|
||||
fn len(&self) -> Result<u64, io::Error> {
|
||||
Ok(self.len)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use ffsend_api::action::upload::Upload as ApiUpload;
|
||||
use ffsend_api::reqwest::Client;
|
||||
|
@ -34,7 +34,7 @@ impl<'a> Upload<'a> {
|
|||
let client = Client::new();
|
||||
|
||||
// Create a progress bar reporter
|
||||
let bar = Box::new(ProgressBar::new());
|
||||
let bar = Arc::new(Mutex::new(ProgressBar::new()));
|
||||
|
||||
// Execute an upload action
|
||||
// TODO: do not unwrap, but return an error
|
||||
|
|
|
@ -42,7 +42,6 @@ impl ProgressReporter for ProgressBar {
|
|||
fn finish(&mut self) {
|
||||
self.bar.as_mut()
|
||||
.expect("progress bar not yet instantiated")
|
||||
// TODO: print a proper message here
|
||||
.finish_print("DONE");
|
||||
.finish_print("File uploaded");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue