creation of a downloader

This commit is contained in:
grimhilt
2023-07-13 23:36:39 +02:00
parent 70fb733b05
commit 80d497d47c
8 changed files with 224 additions and 36 deletions

View File

@@ -4,6 +4,7 @@ use std::fs::DirBuilder;
use std::path::{Path, PathBuf};
use clap::Values;
use regex::Regex;
use crate::services::downloader::Downloader;
use crate::utils::api::ApiProps;
use crate::global::global::{DIR_PATH, set_dir_path};
use crate::services::api::ApiError;
@@ -28,7 +29,7 @@ pub fn clone(remote: Values<'_>) {
};
let api_props = ApiProps {
host: host.clone(),
username: username,
username,
root: dist_path_str.to_string(),
};
@@ -58,6 +59,7 @@ pub fn clone(remote: Values<'_>) {
let res = ReqProps::new()
.set_request(relative_s.as_str(), &api_props)
.gethref()
.getcontentlength()
.getlastmodified()
.send_req_multiple();
@@ -104,7 +106,7 @@ pub fn clone(remote: Values<'_>) {
// add tree
let path_folder = p.strip_prefix(ref_path.clone()).unwrap();
let lastmodified = folder.lastmodified.unwrap().timestamp_millis();
if let Err(err) = tree::add(path_folder.to_path_buf(), &lastmodified.to_string()) {
if let Err(err) = tree::add(path_folder.to_path_buf(), &lastmodified.to_string(), false) {
eprintln!("err: saving ref of {} ({})", path_folder.display(), err);
}
}
@@ -122,37 +124,18 @@ pub fn clone(remote: Values<'_>) {
first_iter = false;
}
download_files(ref_path.clone(), files, &api_props);
let downloader = Downloader::new()
.set_api_props(api_props.clone())
.set_files(files)
.download(ref_path.clone(), Some(&save_blob));
}
fn download_files(ref_p: PathBuf, files: Vec<ObjProps>, api_props: &ApiProps) {
for obj in files {
let relative_s = &obj.clone().relative_s.unwrap();
let res = DownloadFiles::new()
.set_url(&relative_s, api_props)
.save(ref_p.clone());
match res {
Ok(()) => {
let relative_p = PathBuf::from(&relative_s);
let lastmodified = obj.clone().lastmodified.unwrap().timestamp_millis();
if let Err(err) = blob::add(relative_p, &lastmodified.to_string()) {
eprintln!("err: saving ref of {} ({})", relative_s.clone(), err);
}
},
Err(ApiError::Unexpected(_)) => {
eprintln!("err: writing {}", relative_s);
},
Err(ApiError::IncorrectRequest(err)) => {
eprintln!("fatal: {}", err.status());
std::process::exit(1);
},
Err(ApiError::EmptyError(_)) => eprintln!("Failed to get body"),
Err(ApiError::RequestError(err)) => {
eprintln!("fatal: {}", err);
std::process::exit(1);
}
}
fn save_blob(obj: ObjProps) {
let relative_s = &obj.clone().relative_s.unwrap();
let relative_p = PathBuf::from(&relative_s);
let lastmodified = obj.clone().lastmodified.unwrap().timestamp_millis();
if let Err(err) = blob::add(relative_p, &lastmodified.to_string(), false) {
eprintln!("err: saving ref of {} ({})", relative_s.clone(), err);
}
}

View File

@@ -4,3 +4,4 @@ pub mod download_files;
pub mod req_props;
pub mod upload_file;
pub mod delete_path;
pub mod downloader;

View File

@@ -2,6 +2,7 @@ use std::env;
use dotenv::dotenv;
use reqwest::Client;
use reqwest::RequestBuilder;
use reqwest::multipart::Form;
use reqwest::{Response, Error, Method};
use reqwest::header::{HeaderValue, CONTENT_TYPE, HeaderMap, IntoHeaderName};
use crate::utils::api::ApiProps;
@@ -31,6 +32,23 @@ impl ApiBuilder {
}
}
pub fn set_url(&mut self, method: Method, url: &str) -> &mut ApiBuilder {
let remote = match config::get("remote") {
Some(r) => r,
None => {
eprintln!("fatal: unable to find a remote");
std::process::exit(1);
}
};
let (host, _, _) = get_url_props(&remote);
let mut u = String::from(host);
u.push_str(url);
self.request = Some(self.client.request(method, u));
self
}
pub fn build_request(&mut self, method: Method, path: &str) -> &mut ApiBuilder {
let remote = match config::get("remote") {
Some(r) => r,
@@ -93,6 +111,20 @@ impl ApiBuilder {
self
}
pub fn set_multipart(&mut self, form: Form) -> &mut ApiBuilder {
match self.request.take() {
None => {
eprintln!("fatal: incorrect request");
std::process::exit(1);
},
Some(req) => {
self.request = Some(req.multipart(form));
self.set_header(CONTENT_TYPE, HeaderValue::from_static("multipart/related"));
}
}
self
}
pub fn set_header<K: IntoHeaderName>(&mut self, key: K, val: HeaderValue) -> &mut ApiBuilder {
let map = self.headers.get_or_insert(HeaderMap::new());
map.insert(key, val);
@@ -110,7 +142,6 @@ impl ApiBuilder {
}
}
self
}
pub async fn send(&mut self) -> Result<Response, Error> {
@@ -122,7 +153,8 @@ impl ApiBuilder {
},
Some(req) => {
if let Some(headers) = &self.headers {
req.headers(headers.clone()).send().await.map_err(Error::from)
req.headers(headers.clone())
.send().await.map_err(Error::from)
} else {
req.send().await.map_err(Error::from)
}

View File

@@ -0,0 +1,89 @@
use std::path::PathBuf;
use crate::utils::api::ApiProps;
use crate::services::api::ApiError;
use crate::services::download_files::DownloadFiles;
use crate::services::req_props::ObjProps;
const SIZE_TO_STREAM: u64 = 2 * 1024 * 1024;
pub struct Downloader {
files: Vec<ObjProps>,
should_log: bool,
api_props: Option<ApiProps>,
}
impl Downloader {
pub fn new() -> Self {
Downloader {
files: vec![],
should_log: false,
api_props: None,
}
}
pub fn should_log(&mut self) -> &mut Downloader {
self.should_log = true;
self
}
pub fn set_api_props(&mut self, api_props: ApiProps) -> &mut Downloader {
self.api_props = Some(api_props);
self
}
pub fn set_files(&mut self, files: Vec<ObjProps>) -> &mut Downloader {
self.files = files;
self
}
pub fn add_file(&mut self, file: ObjProps) -> &mut Downloader {
self.files.push(file);
self
}
pub fn download(&mut self, ref_p: PathBuf, callback: Option<&dyn Fn(ObjProps)>) {
for file in self.files.clone() {
let relative_s = &file.clone().relative_s.unwrap();
let mut download = DownloadFiles::new();
download.set_url(&relative_s, &self.api_props.clone().unwrap());
let res = {
if let Some(size) = file.contentlength {
if size > SIZE_TO_STREAM {
download.save_stream(ref_p.clone())
} else {
download.save(ref_p.clone())
}
} else {
download.save(ref_p.clone())
}
};
match res {
Ok(()) => {
if let Some(fct) = callback {
fct(file);
}
//let relative_p = PathBuf::from(&relative_s);
//let lastmodified = obj.clone().lastmodified.unwrap().timestamp_millis();
//if let Err(err) = blob::add(relative_p, &lastmodified.to_string()) {
// eprintln!("err: saving ref of {} ({})", relative_s.clone(), err);
//}
},
Err(ApiError::Unexpected(_)) => {
eprintln!("err: writing {}", relative_s);
},
Err(ApiError::IncorrectRequest(err)) => {
eprintln!("fatal: {}", err.status());
std::process::exit(1);
},
Err(ApiError::EmptyError(_)) => eprintln!("Failed to get body"),
Err(ApiError::RequestError(err)) => {
eprintln!("fatal: {}", err);
std::process::exit(1);
}
}
}
}
}

View File

@@ -1,5 +1,4 @@
use std::io::Cursor;
use futures_util::StreamExt;
use chrono::{Utc, DateTime};
use reqwest::{Method, Response, Error};
use xml::reader::{EventReader, XmlEvent};

View File

@@ -1,5 +1,5 @@
use std::fs::File;
use std::io::{Read};
use std::io::Read;
use std::path::PathBuf;
use reqwest::{Method, Response, Error};
use crate::services::api::{ApiBuilder, ApiError};