[wip] implement handling "missing share"

- rework `CacheFile` API
- fix `AppState::{next_chunk, is_done}`
This commit is contained in:
Jörn-Michael Miehe 2025-06-19 10:34:28 +00:00
parent 865566ad0c
commit df055fc4e9
2 changed files with 51 additions and 39 deletions

View file

@ -9,7 +9,7 @@ use indicatif::{ProgressBar, ProgressStyle};
use log::{debug, warn}; use log::{debug, warn};
use crate::{ use crate::{
cachefile::{CacheFile, FileState}, cachefile::CacheFile,
cli::Cli, cli::Cli,
file::{self, Chunk, FileTrait}, file::{self, Chunk, FileTrait},
sharry::{self, Client}, sharry::{self, Client},
@ -89,7 +89,7 @@ impl AppState {
}) })
} }
fn end_progressbar(&self, f: impl FnOnce(&ProgressBar)) { fn drop_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() {
f(bar); f(bar);
@ -97,8 +97,8 @@ impl AppState {
} }
} }
fn next_chunk<'t>(&mut self, buffer: &'t mut [u8]) -> io::Result<Option<Chunk<'t>>> { fn next_chunk<'t>(&mut self, buffer: &'t mut [u8]) -> sharry::Result<Option<Chunk<'t>>> {
let Some(mut uploading) = self.inner.pop_file(&self.http) else { let Some(mut uploading) = self.inner.pop_uploading(&self.http)? else {
self.inner self.inner
.share_notify(&self.http) .share_notify(&self.http)
.unwrap_or_else(|e| warn!("Failed to notify the share: {e}")); .unwrap_or_else(|e| warn!("Failed to notify the share: {e}"));
@ -109,38 +109,32 @@ impl AppState {
self.get_or_create_progressbar(&uploading); self.get_or_create_progressbar(&uploading);
let chunk_res = uploading.read(buffer); let chunk = {
self.inner.push_file(uploading); let result = uploading.read(buffer);
self.inner.push_uploading(uploading);
let chunk = chunk_res?; result?
};
debug!("{chunk:?}"); debug!("{chunk:?}");
Ok(Some(chunk)) Ok(Some(chunk))
} }
fn is_done(&mut self) -> bool { fn is_done(&mut self) -> bool {
let Some(uploading) = self.inner.pop_file(&self.http) else { if let Some(path) = self.inner.check_eof() {
return true; debug!("Finished {:?}!", path.display());
}; self.drop_progressbar(ProgressBar::finish);
} else if let Some(uploading) = self.inner.peek_uploading() {
let bar = self.get_or_create_progressbar(uploading);
bar.set_position(uploading.get_offset());
// BUG in `indicatif` crate?
// `set_position` does not force an immediate redraw, so we also call `inc_length` here
bar.inc_length(0);
match uploading.check_eof() { return false;
Ok(uploading) => {
let bar = self.get_or_create_progressbar(&uploading);
bar.set_position(uploading.get_offset());
// BUG in `indicatif` crate?
// `set_position` does not force an immediate redraw, so we also call `inc_length` here
bar.inc_length(0);
drop(bar);
self.inner.push_file(uploading);
}
Err(path) => {
debug!("Finished {:?}!", path.display());
self.end_progressbar(|pb| pb.finish());
}
} }
self.inner.is_empty() self.inner.queue_empty()
} }
pub fn upload_chunk(&mut self, buffer: &mut [u8]) -> sharry::Result<bool> { pub fn upload_chunk(&mut self, buffer: &mut [u8]) -> sharry::Result<bool> {
@ -183,7 +177,7 @@ impl AppState {
let checked = uploading.abort(); let checked = uploading.abort();
self.inner.requeue_file(checked); self.inner.requeue_file(checked);
self.end_progressbar(|pb| pb.abandon()); self.drop_progressbar(|pb| pb.abandon());
Some(self) Some(self)
} }

View file

@ -78,23 +78,41 @@ impl CacheFile {
result result
} }
pub fn start_upload(&mut self, client: &impl Client) -> sharry::Result<bool> { pub fn queue_empty(&self) -> bool {
if self.uploading.is_some() { self.files.is_empty()
return Ok(true); }
}
if let Some(chk) = self.files.pop_front() { pub fn pop_uploading(
self.uploading = &mut self,
Some(chk.start_upload(client, &self.uri, &self.alias_id, &self.share_id)?); client: &impl Client,
) -> sharry::Result<Option<file::Uploading>> {
Ok(true) if let Some(upl) = self.uploading.take() {
Ok(Some(upl))
} else if let Some(chk) = self.files.pop_front() {
let upl = chk.start_upload(client, &self.uri, &self.alias_id, &self.share_id)?;
Ok(Some(upl))
} else { } else {
Ok(false) Ok(None)
} }
} }
pub fn uploading(&mut self) -> &mut Option<file::Uploading> { pub fn push_uploading(&mut self, uploading: file::Uploading) {
&mut self.uploading self.uploading.replace(uploading);
}
pub fn peek_uploading(&self) -> Option<&file::Uploading> {
self.uploading.as_ref()
}
pub fn check_eof(&mut self) -> Option<PathBuf> {
if let Some(upl) = self.uploading.take() {
match upl.check_eof() {
Ok(upl) => self.push_uploading(upl),
Err(p) => return Some(p),
}
}
None
} }
pub fn abort_upload(&mut self) { pub fn abort_upload(&mut self) {