Compare commits

..

No commits in common. "f05e112040331a483ac8f48fa825f86e8660c404" and "09d22a0ad921a68a1145861620ea4f536da03087" have entirely different histories.

5 changed files with 35 additions and 79 deletions

View file

@ -8,13 +8,11 @@ use console::style;
use indicatif::{ProgressBar, ProgressStyle}; use indicatif::{ProgressBar, ProgressStyle};
use log::{debug, warn}; use log::{debug, warn};
use crate::file::Chunk;
use super::{ use super::{
cachefile::CacheFile, cachefile::CacheFile,
cli::Cli, cli::Cli,
file::{self, FileTrait}, file::{self, FileTrait},
sharry::{self, Client}, sharry::{self, Client, ClientError},
}; };
pub struct AppState { pub struct AppState {
@ -106,7 +104,7 @@ impl AppState {
}) })
} }
fn finish_progressbar(&self) { fn finish_bar(&self) {
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(); bar.finish();
@ -114,7 +112,7 @@ impl AppState {
} }
} }
fn next_chunk(&mut self) -> io::Result<Option<Chunk>> { pub fn upload_chunk(&mut self) -> sharry::Result<Option<()>> {
let Some(mut uploading) = self.inner.pop_file(&self.http) else { let Some(mut uploading) = self.inner.pop_file(&self.http) else {
self.inner self.inner
.share_notify(&self.http) .share_notify(&self.http)
@ -123,23 +121,20 @@ impl AppState {
return Ok(None); return Ok(None);
}; };
debug!("{uploading:?}");
self.get_or_create_progressbar(&uploading); self.get_or_create_progressbar(&uploading);
let chunk = uploading.read(&mut self.buffer); debug!("{uploading} chunk {}", self.buffer.len());
self.inner.push_file(uploading);
let chunk = chunk?;
debug!("{chunk:?}"); let chunk = uploading
.read(&mut self.buffer)
.map_err(ClientError::from)?;
Ok(Some(chunk)) self.http.file_patch(
} chunk.get_patch_uri(),
self.inner.alias_id(),
fn is_done(&mut self) -> bool { chunk.get_offset(),
let Some(uploading) = self.inner.pop_file(&self.http) else { chunk.get_data(),
return true; )?;
};
match uploading.check_eof() { match uploading.check_eof() {
Ok(uploading) => { Ok(uploading) => {
@ -151,29 +146,15 @@ impl AppState {
drop(bar); drop(bar);
self.inner.push_file(uploading); self.inner.push_file(uploading);
Ok(Some(()))
} }
Err(path) => { Err(path) => {
debug!("Finished {:?}!", path.display()); debug!("Finished {:?}!", path.display());
self.finish_progressbar(); self.finish_bar();
Ok(self.inner.has_file().then_some(()))
} }
} }
self.inner.is_empty()
}
pub fn upload_chunk(&mut self) -> sharry::Result<bool> {
let Some(chunk) = self.next_chunk()? else {
return Ok(true);
};
self.http.file_patch(
chunk.get_patch_uri(),
self.inner.alias_id(),
chunk.get_offset(),
unsafe { chunk.get_data() },
)?;
Ok(self.is_done())
} }
pub fn file_names(&self) -> Vec<&str> { pub fn file_names(&self) -> Vec<&str> {

View file

@ -99,8 +99,8 @@ impl CacheFile {
self.files.iter().map(FileState::file_name).collect() self.files.iter().map(FileState::file_name).collect()
} }
pub fn is_empty(&self) -> bool { pub fn has_file(&self) -> bool {
self.files.is_empty() !self.files.is_empty()
} }
pub fn pop_file(&mut self, http: &impl Client) -> Option<file::Uploading> { pub fn pop_file(&mut self, http: &impl Client) -> Option<file::Uploading> {

View file

@ -1,25 +1,11 @@
use std::fmt; pub struct Chunk<'t> {
data: &'t [u8],
pub struct Chunk { patch_uri: &'t str,
data: *const [u8],
patch_uri: String,
offset: u64, offset: u64,
} }
impl fmt::Debug for Chunk { impl<'t> Chunk<'t> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub fn new(data: &'t [u8], patch_uri: &'t str, offset: u64) -> Self {
f.debug_struct("Chunk")
.field("patch_uri", &self.patch_uri)
.field("offset", &self.offset)
.field("data_len", &self.data.len())
.finish_non_exhaustive()
}
}
impl Chunk {
pub fn new(data: &[u8], patch_uri: String, offset: u64) -> Self {
let data: *const [u8] = data as *const [u8];
Self { Self {
data, data,
patch_uri, patch_uri,
@ -27,8 +13,8 @@ impl Chunk {
} }
} }
pub unsafe fn get_data(&self) -> &[u8] { pub fn get_data(&self) -> &[u8] {
unsafe { &*self.data } self.data
} }
pub fn get_length(&self) -> u64 { pub fn get_length(&self) -> u64 {
@ -41,7 +27,7 @@ impl Chunk {
} }
pub fn get_patch_uri(&self) -> &str { pub fn get_patch_uri(&self) -> &str {
&self.patch_uri self.patch_uri
} }
pub fn get_offset(&self) -> u64 { pub fn get_offset(&self) -> u64 {

View file

@ -8,16 +8,15 @@ use serde::{Deserialize, Serialize};
use super::{Chunk, FileTrait}; use super::{Chunk, FileTrait};
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Debug)]
pub struct Uploading { pub struct Uploading {
path: PathBuf, path: PathBuf,
size: u64, size: u64,
patch_uri: String, patch_uri: String,
last_offset: Option<u64>,
offset: u64, offset: u64,
} }
impl fmt::Debug for Uploading { impl fmt::Display for Uploading {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!( write!(
f, f,
@ -35,7 +34,6 @@ impl Uploading {
path, path,
size, size,
patch_uri, patch_uri,
last_offset: None,
offset: 0, offset: 0,
} }
} }
@ -44,15 +42,7 @@ impl Uploading {
self.offset self.offset
} }
pub fn rewind(self) -> Option<Self> { pub fn read<'t>(&'t mut self, buf: &'t mut [u8]) -> io::Result<Chunk<'t>> {
self.last_offset.map(|last_offset| Self {
last_offset: None,
offset: last_offset,
..self
})
}
pub fn read(&mut self, buf: &mut [u8]) -> io::Result<Chunk> {
let mut f = fs::File::open(&self.path)?; let mut f = fs::File::open(&self.path)?;
f.seek(SeekFrom::Start(self.offset))?; f.seek(SeekFrom::Start(self.offset))?;
@ -65,8 +55,7 @@ impl Uploading {
)); ));
} }
let chunk = Chunk::new(&buf[..read_len], self.patch_uri.clone(), self.offset); let chunk = Chunk::new(&buf[..read_len], &self.patch_uri, self.offset);
self.last_offset = Some(self.offset);
self.offset += chunk.get_length(); self.offset += chunk.get_length();
Ok(chunk) Ok(chunk)

View file

@ -94,7 +94,7 @@ fn main() {
"{} Failed to save {} state: {e}", "{} Failed to save {} state: {e}",
style("Warning:").red().bold(), style("Warning:").red().bold(),
style("ShrUpl").yellow().bold(), style("ShrUpl").yellow().bold(),
); )
}); });
state state
} }
@ -116,14 +116,14 @@ fn main() {
loop { loop {
match state.upload_chunk() { match state.upload_chunk() {
Err(e) => error!("error: {e:?}"), // HACK handle errors better Err(e) => error!("error: {e:?}"), // HACK handle errors better
Ok(true) => { Ok(None) => {
info!("all uploads done"); info!("all uploads done");
state.clear().unwrap_or_else(|e| { state.clear().unwrap_or_else(|e| {
eprintln!( eprintln!(
"{} Failed to remove {} state: {e}", "{} Failed to remove {} state: {e}",
style("Warning:").red().bold(), style("Warning:").red().bold(),
style("ShrUpl").yellow().bold(), style("ShrUpl").yellow().bold(),
); )
}); });
break; break;
} }
@ -135,7 +135,7 @@ fn main() {
"{} Failed to save {} state: {e}", "{} Failed to save {} state: {e}",
style("Warning:").red().bold(), style("Warning:").red().bold(),
style("ShrUpl").yellow().bold(), style("ShrUpl").yellow().bold(),
); )
}); });
check_ctrlc(); check_ctrlc();
} }