wip: main business logic

This commit is contained in:
Jörn-Michael Miehe 2025-06-05 01:13:54 +00:00
parent a91d9afb66
commit 9208a7dfcf
4 changed files with 65 additions and 36 deletions

View file

@ -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<FileState>,
files: VecDeque<FileState>,
}
#[derive(Serialize, Deserialize, Debug)]
@ -68,15 +69,15 @@ impl AppState {
.ok()
}
pub fn from_args(args: &Cli, agent: &ureq::Agent) -> Option<Self> {
pub fn from_args(args: &Cli, http: &ureq::Agent) -> Option<Self> {
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<Option<()>, 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())?;

View file

@ -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();
}

View file

@ -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};

View file

@ -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 {