remozipsy 0.2.0

Remote Zip Sync - sync remote zip to local fs
Documentation
//! Run via `cargo run --bin remozipsy-bin --all-features -- 'https://download.veloren.net/latest/linux/x86_64/weekly'  show`
//! This bin is a bit more complicated than the examples, but it includes fancy
//! progressbars.

mod args;
mod progressbar;
mod show;

use args::Commands;
use clap::Parser;
use remozipsy::{Config, Statemachine, reqwest::ReqwestRemoteZip, tokio::TokioLocalStorage};
use show::ShowStorage;
use std::time::Duration;

pub fn main() {
    let args = args::Args::parse();

    let rt = tokio::runtime::Builder::new_multi_thread()
        .worker_threads(8)
        .enable_all()
        .build()
        .unwrap();

    let remote = ReqwestRemoteZip::with_url(args.remote_url).unwrap();
    let mut config = Config::default();
    if let Some(max_parallel_downloads) = args.max_parallel_downloads {
        config.max_parallel_downloads = max_parallel_downloads as usize
    }
    if let Some(assume_cd_contains_lh_content) = args.assume_cd_contains_lh_content {
        config.assume_cd_contains_lh_content = assume_cd_contains_lh_content
    }

    match args.command {
        Commands::Clone { output_directory } => {
            rt.block_on(tokio::fs::create_dir_all(&output_directory)).unwrap();
            let local = TokioLocalStorage::new(output_directory, Vec::new());
            let state = Statemachine::new(remote, local, config);
            rt.block_on(sync(state));
        },
        Commands::Show { print_filenames } => {
            let local = ShowStorage::default();
            let local2 = local.clone();
            let state = Statemachine::new(remote, local, config);
            rt.block_on(sync(state));

            let mut files = local2.take_content();
            files.sort_by_key(|f| f.local_unix_path.clone());
            let len = files.len();
            if print_filenames {
                for f in files {
                    println!("{}", f.local_unix_path);
                }
            }
            println!("zip contains {len} files");
        },
    }
}

async fn sync<R, F>(mut state: Statemachine<R, F>)
where
    R: remozipsy::RemoteZip + Clone + Send + 'static,
    F: remozipsy::FileSystem + Clone + Send + 'static,
{
    let mut errored = Ok(());

    let mut bar = progressbar::Bar::default();
    while let Some((progress, next_state)) = state.progress().await {
        state = next_state;
        if let Err(e) = bar.display(progress) {
            errored = Err(e);
        }

        tokio::time::sleep(Duration::from_millis(10)).await;
    }
    bar.cleanup();

    println!("Sync finished with: {errored:?}");
}