Compare commits
No commits in common. "f05e112040331a483ac8f48fa825f86e8660c404" and "09d22a0ad921a68a1145861620ea4f536da03087" have entirely different histories.
f05e112040
...
09d22a0ad9
5 changed files with 35 additions and 79 deletions
|
|
@ -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> {
|
||||||
|
|
|
||||||
|
|
@ -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> {
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue