impl AppState::requeue_file

This commit is contained in:
Jörn-Michael Miehe 2025-06-18 19:40:34 +00:00
parent 79bc8e67a7
commit 3b46d228f4
6 changed files with 61 additions and 21 deletions

View file

@ -50,11 +50,6 @@
- "quiet" flag to disable output entirely - "quiet" flag to disable output entirely
- some switch to change log to "pretty-print" - some switch to change log to "pretty-print"
- client error rework
- current variants are too "low level"
- use variants like `InvalidEndpoint`, `InvalidAlias` etc.
- `Uploading::abort() -> Checked`
- hashing - hashing
- store file hashes with all `file::*` variants - store file hashes with all `file::*` variants
- check hashes on "continue" - check hashes on "continue"

View file

@ -89,10 +89,10 @@ impl AppState {
}) })
} }
fn finish_progressbar(&self) { fn end_progressbar(&self, f: impl FnOnce(&ProgressBar)) {
let mut slot = self.progress.borrow_mut(); let mut slot = self.progress.borrow_mut();
if let Some(bar) = slot.as_ref() { if let Some(bar) = slot.as_ref() {
bar.finish(); f(bar);
*slot = None; *slot = None;
} }
} }
@ -136,7 +136,7 @@ impl AppState {
} }
Err(path) => { Err(path) => {
debug!("Finished {:?}!", path.display()); debug!("Finished {:?}!", path.display());
self.finish_progressbar(); self.end_progressbar(|pb| pb.finish());
} }
} }
@ -165,6 +165,20 @@ impl AppState {
Some(self) Some(self)
} }
pub fn requeue_file(mut self) -> Option<Self> {
let Some(uploading) = self.inner.pop_file(&self.http) else {
warn!("requeue_file called on empty queue");
return None;
};
let checked = uploading.abort();
self.inner.requeue_file(checked);
self.end_progressbar(|pb| pb.abandon());
Some(self)
}
pub fn file_names(&self) -> Vec<&str> { pub fn file_names(&self) -> Vec<&str> {
self.inner.file_names() self.inner.file_names()
} }

View file

@ -118,6 +118,10 @@ impl CacheFile {
self.files.push_front(FileState::U(file)); self.files.push_front(FileState::U(file));
} }
pub fn requeue_file(&mut self, file: file::Checked) {
self.files.push_back(FileState::C(file));
}
pub fn share_notify(&self, client: &impl Client) -> sharry::Result<()> { pub fn share_notify(&self, client: &impl Client) -> sharry::Result<()> {
client.share_notify(&self.uri, &self.alias_id, &self.share_id) client.share_notify(&self.uri, &self.alias_id, &self.share_id)
} }

View file

@ -17,9 +17,9 @@ use super::{FileTrait, Uploading};
#[derive(Debug, Clone, Hash, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, Clone, Hash, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
pub struct Checked { pub struct Checked {
/// canonical path to a regular file /// canonical path to a regular file
path: PathBuf, pub(super) path: PathBuf,
/// size of that file /// size of that file
size: u64, pub(super) size: u64,
} }
impl Checked { impl Checked {

View file

@ -7,7 +7,7 @@ use std::{
use log::warn; use log::warn;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use super::{Chunk, FileTrait}; use super::{Checked, Chunk, FileTrait};
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct Uploading { pub struct Uploading {
@ -74,6 +74,13 @@ impl Uploading {
Err(self.path) Err(self.path)
} }
} }
pub fn abort(self) -> Checked {
Checked {
path: self.path,
size: self.size,
}
}
} }
impl<'t> FileTrait<'t> for Uploading { impl<'t> FileTrait<'t> for Uploading {

View file

@ -20,7 +20,8 @@ use log::{info, trace};
use appstate::AppState; use appstate::AppState;
use cli::Cli; use cli::Cli;
use output::{Log, SHRUPL, prompt_continue}; use output::{Log, SHRUPL};
use sharry::{ClientError, Parameter};
fn main() { fn main() {
let check_ctrlc = { let check_ctrlc = {
@ -52,7 +53,7 @@ fn main() {
println!("{} to {}!", style("Welcome").magenta().bold(), *SHRUPL); println!("{} to {}!", style("Welcome").magenta().bold(), *SHRUPL);
let mut state = AppState::try_resume(&args) let mut state = AppState::try_resume(&args)
.and_then(|state| prompt_continue().then_some(state)) .and_then(|state| output::prompt_continue().then_some(state))
.unwrap_or_else(|| { .unwrap_or_else(|| {
check_ctrlc(); check_ctrlc();
@ -86,17 +87,36 @@ fn main() {
match state.upload_chunk(&mut buffer) { match state.upload_chunk(&mut buffer) {
Err(e) => { Err(e) => {
// TODO better error handling (this will just retry endlessly)
// Error 404: Share might have been deleted
Log::handle(&e); Log::handle(&e);
tries += 1;
if let Some(s) = state.rewind() { match e {
tries += 1; ClientError::InvalidParameter(p) => match p {
trace!("State rewound, retrying last chunk (tried: {tries})"); // TODO Error 404: File not found
Parameter::FileID(fid) => {
// requeue file
let Some(s) = state.requeue_file() else {
Log::error("Failed to requeue file!");
};
state = s; trace!("File {fid:?} requeued (tried: {tries})");
} else { state = s;
Log::error("Failed to retry chunk!"); }
// TODO Error 404: Share might have been deleted
Parameter::ShareID(sid) => {
Log::error(format_args!("404 sid: {sid}"));
}
p => Log::error(format_args!("Unexpected {p}!")),
},
_ => {
// retry chunk
let Some(s) = state.rewind() else {
Log::error("Failed to retry chunk!");
};
trace!("State rewound, retrying last chunk (tried: {tries})");
state = s;
}
} }
} }
Ok(false) => { Ok(false) => {