diff --git a/src/appstate.rs b/src/appstate.rs index 4d0a64e..f817416 100644 --- a/src/appstate.rs +++ b/src/appstate.rs @@ -1,4 +1,5 @@ use std::{ + collections::VecDeque, fs, io::{self, Write}, path::{Path, PathBuf}, @@ -9,7 +10,7 @@ use serde::{Deserialize, Serialize}; use super::{ cli::Cli, - sharry::{Alias, FileChecked, FileUploading, Share}, + sharry::{Alias, ChunkState, FileChecked, FileUploading, Share, UploadError}, }; #[derive(Serialize, Deserialize, Debug)] @@ -19,7 +20,7 @@ pub struct AppState { alias: Alias, share: Share, - files: Vec, + files: VecDeque, } #[derive(Serialize, Deserialize, Debug)] @@ -68,15 +69,15 @@ impl AppState { .ok() } - pub fn from_args(args: &Cli, agent: &ureq::Agent) -> Option { + pub fn from_args(args: &Cli, http: &ureq::Agent) -> Option { let file_name = Self::cache_file(args); let alias = args.get_alias(); - let share = Share::create(agent, &alias, args.get_share_request()) + let share = Share::create(http, &alias, args.get_share_request()) .inspect_err(|e| error!("could not create Share: {e}")) .ok()?; - let files: Vec<_> = args.files.clone().into_iter().map(FileState::C).collect(); + let files: VecDeque<_> = args.files.clone().into_iter().map(FileState::C).collect(); Some(Self { file_name, @@ -86,6 +87,41 @@ impl AppState { }) } + pub fn upload_chunk( + &mut self, + http: &ureq::Agent, + chunk_size: usize, + ) -> Result, UploadError> { + let uploading = match self.files.pop_front() { + Some(FileState::C(checked)) => checked + .start_upload(http, &self.alias, &self.share) + .unwrap(), + Some(FileState::U(uploading)) => uploading, + None => { + self.share.notify(http, &self.alias).unwrap(); + + return Ok(None); + } + }; + + debug!("{uploading} chunk {chunk_size}"); + + match uploading.upload_chunk(http, &self.alias, chunk_size) { + ChunkState::Ok(upl) => { + self.files.push_front(FileState::U(upl)); + Ok(Some(())) + } + ChunkState::Err(upl, e) => { + self.files.push_front(FileState::U(upl)); + Err(e) + } + ChunkState::Finished(path) => { + debug!("Finished {:?}!", path.display()); + Ok(Some(())) + } + } + } + pub fn save(&self) -> io::Result<()> { fs::create_dir_all(Self::cache_dir())?; diff --git a/src/main.rs b/src/main.rs index 2609c20..eb52dbe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,12 +3,11 @@ mod cli; mod sharry; use clap::Parser; -use log::{debug, error, info}; +use log::{error, info}; use ureq::Agent; use appstate::AppState; use cli::Cli; -use sharry::{ChunkState, Share}; fn main() { env_logger::init(); @@ -22,7 +21,7 @@ fn main() { .build() .into(); - let state = AppState::try_resume(&args) + let mut state = AppState::try_resume(&args) .map(|state| { info!("loaded state: {state:?}"); @@ -37,34 +36,17 @@ fn main() { info!("continuing with state: {state:?}"); state.save().unwrap(); - // state.clear().unwrap(); - return; - - let alias = args.get_alias(); - let share = Share::create(&agent, &alias, args.get_share_request()).unwrap(); - info!("share: {share:?}"); - - for file in args.files { - let mut file = file.start_upload(&agent, &alias, &share).unwrap(); - info!("file: {file:?}"); - - loop { - match file.upload_chunk(&agent, &alias, args.chunk_size * 1024 * 1024) { - ChunkState::Ok(upl) => file = upl, - ChunkState::Err(upl, e) => { - error!("error: {e:?}"); - file = upl; - } - ChunkState::Finished(path) => { - info!("Finished {:?}!", path.display()); - break; - } - } - - debug!("file: {file:?}"); + loop { + match state.upload_chunk(&agent, args.chunk_size * 1024 * 1024) { + Ok(None) => break, + Err(e) => error!("error: {e:?}"), + _ => (), } - } - share.notify(&agent, &alias).unwrap(); + state.save().unwrap(); + } + info!("uploads done"); + + state.clear().unwrap(); } diff --git a/src/sharry/file/mod.rs b/src/sharry/file/mod.rs index f9d6c3b..4614561 100644 --- a/src/sharry/file/mod.rs +++ b/src/sharry/file/mod.rs @@ -2,6 +2,6 @@ mod checked; mod uploading; pub use checked::FileChecked; -pub use uploading::{ChunkState, FileUploading}; +pub use uploading::{ChunkState, FileUploading, UploadError}; use super::{Alias, Share, alias::SharryAlias}; diff --git a/src/sharry/file/uploading.rs b/src/sharry/file/uploading.rs index 7cfd393..c881bf5 100644 --- a/src/sharry/file/uploading.rs +++ b/src/sharry/file/uploading.rs @@ -1,4 +1,5 @@ use std::{ + fmt::Display, fs::File, io::{self, Read, Seek, SeekFrom}, path::PathBuf, @@ -35,6 +36,16 @@ pub enum ChunkState { Finished(PathBuf), } +impl Display for FileUploading { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "Uploading ({:?}, {}, {})", + self.path, self.size, self.offset + ) + } +} + impl FileUploading { pub(super) fn new(path: PathBuf, size: usize, uri: String) -> Self { Self {