diff --git a/src/commands/clone.rs b/src/commands/clone.rs index c6a7431..3ea27cb 100644 --- a/src/commands/clone.rs +++ b/src/commands/clone.rs @@ -11,6 +11,7 @@ use crate::services::list_folders::ListFolders; use crate::services::download_files::DownloadFiles; use crate::store::object; use crate::commands; +use crate::utils::api::{get_local_path, get_local_path_t}; use crate::global::global::{DIR_PATH, set_dir_path}; pub fn clone(remote: Values<'_>) { @@ -99,41 +100,28 @@ pub fn clone(remote: Values<'_>) { download_files(&domain, local_path.clone(), username, dist_path_str, files); } -fn get_local_path(p: String, local_p: PathBuf, username: &str, dist_p: &str) -> PathBuf { - let mut final_p = Path::new(p.as_str()); - final_p = final_p.strip_prefix("/remote.php/dav/files/").unwrap(); - final_p = final_p.strip_prefix(username.clone()).unwrap(); - let dist_p = Path::new(dist_p).strip_prefix("/"); - final_p = final_p.strip_prefix(dist_p.unwrap()).unwrap(); - local_p.clone().join(final_p.clone()) -} - -fn write_file(path: PathBuf, content: &Vec, local_p: PathBuf) -> io::Result<()> { - let mut f = OpenOptions::new() - .write(true) - .create(true) - .open(path.clone())?; - - f.write_all(&content)?; - - let relative_p = Path::new(&path).strip_prefix(local_p).unwrap(); - object::add_blob(relative_p, "tmpdate")?; - Ok(()) -} - fn download_files(domain: &str, local_p: PathBuf, username: &str, dist_p: &str, files: Vec) { - for file in files { - let mut url_request = String::from(domain.clone()); - url_request.push_str(file.as_str()); + dbg!(local_p.clone()); + for dist_file in files { + dbg!(dist_file.clone()); tokio::runtime::Runtime::new().unwrap().block_on(async { - match DownloadFiles::new(url_request.as_str()).send_with_err().await { - Ok(b) => { - let p_to_save = get_local_path(file.clone(), local_p.clone(), username, dist_p); + let res = DownloadFiles::new() + .set_url_with_remote(dist_file.as_str()) + .save(local_p.clone()).await; - if let Err(_) = write_file(p_to_save, &b, local_p.clone()) { - eprintln!("error writing {}", file); + match res { + Ok(()) => { + + let s = &get_local_path_t(&dist_file.clone()); + let ss = s.strip_prefix("/").unwrap(); + let relative_p = Path::new(ss); + if let Err(_) = object::add_blob(relative_p, "tmpdate") { + eprintln!("error saving reference of {}", dist_file.clone()); } }, + Err(ApiError::Unexpected(_)) => { + eprintln!("error writing {}", dist_file); + }, Err(ApiError::IncorrectRequest(err)) => { eprintln!("fatal: {}", err.status()); std::process::exit(1); diff --git a/src/services/api.rs b/src/services/api.rs index 00e9ddd..3f08be5 100644 --- a/src/services/api.rs +++ b/src/services/api.rs @@ -9,6 +9,7 @@ pub enum ApiError { IncorrectRequest(reqwest::Response), EmptyError(reqwest::Error), RequestError(reqwest::Error), + Unexpected(String), } pub struct ApiBuilder { @@ -47,6 +48,17 @@ impl ApiBuilder { self } + pub fn build_request_remote(&mut self, meth: Method, path: &str) -> &mut ApiBuilder { + dotenv().ok(); + let host = env::var("HOST").unwrap(); + let mut url = String::from(host); + url.push_str("/"); + url.push_str(path); + dbg!(url.clone()); + self.request = Some(self.client.request(meth, url)); + self + } + fn set_auth(&mut self) -> &mut ApiBuilder { // todo if not exist dotenv().ok(); diff --git a/src/services/download_files.rs b/src/services/download_files.rs index 39852d1..c446eda 100644 --- a/src/services/download_files.rs +++ b/src/services/download_files.rs @@ -1,18 +1,29 @@ use crate::services::api::{ApiBuilder, ApiError}; +use std::path::PathBuf; use reqwest::{Method, IntoUrl, Response, Error}; +use crate::utils::api::get_local_path_t; +use std::fs::OpenOptions; +use std::io::{self, Write}; pub struct DownloadFiles { api_builder: ApiBuilder, + path: String, } impl DownloadFiles { - pub fn new(url: U) -> Self { + pub fn new() -> Self { DownloadFiles { - api_builder: ApiBuilder::new() - .set_request(Method::GET, url), + api_builder: ApiBuilder::new(), + path: String::from(""), } } + pub fn set_url_with_remote(&mut self, url: &str) -> &mut DownloadFiles { + self.path = get_local_path_t(url.clone()).strip_prefix("/").unwrap().to_string(); + self.api_builder.build_request_remote(Method::GET, url); + self + } + pub async fn send(&mut self) -> Result { self.api_builder.send().await } @@ -26,4 +37,28 @@ impl DownloadFiles { Err(ApiError::IncorrectRequest(res)) } } + + pub async fn save(&mut self, local_path: PathBuf) -> Result<(), ApiError> { + let p = local_path.join(PathBuf::from(self.path.clone())); + let res = self.send().await.map_err(ApiError::RequestError)?; + if res.status().is_success() { + let body = res.bytes().await.map_err(ApiError::EmptyError)?; + match DownloadFiles::write_file(p, &body.to_vec()) { + Err(_) => Err(ApiError::Unexpected(String::from(""))), + Ok(_) => Ok(()), + } + } else { + Err(ApiError::IncorrectRequest(res)) + } + } + + fn write_file(path: PathBuf, content: &Vec) -> io::Result<()> { + let mut f = OpenOptions::new() + .write(true) + .create(true) + .open(path.clone())?; + + f.write_all(&content)?; + Ok(()) + } } diff --git a/src/services/list_folders.rs b/src/services/list_folders.rs index 615220b..5764fb5 100644 --- a/src/services/list_folders.rs +++ b/src/services/list_folders.rs @@ -41,7 +41,8 @@ impl ListFolders { Err(ApiError::RequestError(err)) => { eprintln!("fatal: {}", err); std::process::exit(1); - } + }, + _ => todo!(), } } } diff --git a/src/store/object.rs b/src/store/object.rs index 2663967..9249314 100644 --- a/src/store/object.rs +++ b/src/store/object.rs @@ -84,7 +84,6 @@ pub fn rm_blob(path: &Path) -> io::Result<()> { pub fn add_blob(path: &Path, date: &str) -> io::Result<()> { let (line, hash, name) = parse_path(path.clone(), true); - // add blob reference to parent if path.iter().count() == 1 { head::add_line(line)?; diff --git a/src/utils.rs b/src/utils.rs index 68136a3..306146e 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,3 +1,4 @@ pub mod path; pub mod read; pub mod nextsyncignore; +pub mod api; diff --git a/src/utils/api.rs b/src/utils/api.rs new file mode 100644 index 0000000..82dc5c4 --- /dev/null +++ b/src/utils/api.rs @@ -0,0 +1,23 @@ +use std::path::{PathBuf, Path}; +use std::env; + +pub fn get_local_path(p: String, local_p: PathBuf, username: &str, dist_p: &str) -> PathBuf { + let mut final_p = Path::new(p.as_str()); + final_p = final_p.strip_prefix("/remote.php/dav/files/").unwrap(); + final_p = final_p.strip_prefix(username.clone()).unwrap(); + let dist_p = Path::new(dist_p).strip_prefix("/"); + final_p = final_p.strip_prefix(dist_p.unwrap()).unwrap(); + local_p.clone().join(final_p.clone()) +} + +pub fn get_local_path_t(p: &str) -> String { + dbg!(p.clone()); + let username = env::var("USERNAME").unwrap(); + let root = env::var("ROOT").unwrap(); + let mut final_p = p; + final_p = final_p.strip_prefix("/remote.php/dav/files/").unwrap(); + final_p = final_p.strip_prefix(&username).unwrap(); + final_p = final_p.strip_prefix("/").unwrap(); + final_p = final_p.strip_prefix(&root).unwrap(); + final_p.to_string() +}