enumerate_remote function & applied to clone
This commit is contained in:
parent
30004ebd8b
commit
0832100d83
@ -6,6 +6,7 @@ use clap::Values;
|
||||
use regex::Regex;
|
||||
use crate::services::downloader::Downloader;
|
||||
use crate::utils::api::ApiProps;
|
||||
use crate::utils::remote::enumerate_remote;
|
||||
use crate::global::global::{DIR_PATH, set_dir_path};
|
||||
use crate::services::api::ApiError;
|
||||
use crate::services::req_props::{ReqProps, ObjProps};
|
||||
@ -43,84 +44,36 @@ pub fn clone(remote: Values<'_>) {
|
||||
},
|
||||
};
|
||||
|
||||
let mut folders: Vec<ObjProps> = vec![ObjProps::new()];
|
||||
let mut files: Vec<ObjProps> = vec![];
|
||||
let mut first_iter = true;
|
||||
while folders.len() > 0 {
|
||||
let folder = folders.pop().unwrap();
|
||||
// try to create root folder
|
||||
if DirBuilder::new().recursive(true).create(ref_path.clone()).is_err() {
|
||||
eprintln!("fatal: unable to create the destination directory");
|
||||
std::process::exit(1);
|
||||
} else {
|
||||
init::init();
|
||||
let mut remote_config = api_props.username.clone();
|
||||
remote_config.push_str("@");
|
||||
remote_config.push_str(api_props.host.strip_prefix("https://").unwrap());
|
||||
remote_config.push_str(&api_props.root);
|
||||
if config::set("remote", &remote_config).is_err() {
|
||||
eprintln!("err: not able to save remote");
|
||||
}
|
||||
}
|
||||
|
||||
let relative_s = match folder.relative_s {
|
||||
Some(relative_s) => relative_s,
|
||||
None => String::from(""),
|
||||
};
|
||||
let (folders, files) = enumerate_remote(|a| req(&api_props, a));
|
||||
|
||||
// request folder content
|
||||
let res = ReqProps::new()
|
||||
.set_request(relative_s.as_str(), &api_props)
|
||||
.gethref()
|
||||
.getcontentlength()
|
||||
.getlastmodified()
|
||||
.send_req_multiple();
|
||||
|
||||
let objs = match res {
|
||||
Ok(o) => o,
|
||||
Err(ApiError::IncorrectRequest(err)) => {
|
||||
eprintln!("fatal: {}", err.status());
|
||||
std::process::exit(1);
|
||||
},
|
||||
Err(ApiError::EmptyError(_)) => {
|
||||
eprintln!("Failed to get body");
|
||||
vec![]
|
||||
}
|
||||
Err(ApiError::RequestError(err)) => {
|
||||
eprintln!("fatal: {}", err);
|
||||
std::process::exit(1);
|
||||
},
|
||||
Err(ApiError::Unexpected(_)) => todo!()
|
||||
};
|
||||
|
||||
// create object
|
||||
if first_iter {
|
||||
// root folder, init and config
|
||||
if DirBuilder::new().recursive(true).create(ref_path.clone()).is_err() {
|
||||
eprintln!("fatal: unable to create the destination directory");
|
||||
std::process::exit(1);
|
||||
} else {
|
||||
init::init();
|
||||
let mut remote_config = api_props.username.clone();
|
||||
remote_config.push_str("@");
|
||||
remote_config.push_str(api_props.host.strip_prefix("https://").unwrap());
|
||||
remote_config.push_str(&api_props.root);
|
||||
if config::set("remote", &remote_config).is_err() {
|
||||
eprintln!("err: not able to save remote");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// create folder
|
||||
let p = ref_path.clone().join(Path::new(&relative_s));
|
||||
if let Err(err) = DirBuilder::new().recursive(true).create(p.clone()) {
|
||||
eprintln!("err: cannot create directory {} ({})", p.display(), err);
|
||||
}
|
||||
|
||||
// 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(), false) {
|
||||
eprintln!("err: saving ref of {} ({})", path_folder.display(), err);
|
||||
}
|
||||
for folder in folders {
|
||||
// create folder
|
||||
let p = ref_path.clone().join(Path::new(&folder.relative_s.unwrap()));
|
||||
if let Err(err) = DirBuilder::new().recursive(true).create(p.clone()) {
|
||||
eprintln!("err: cannot create directory {} ({})", p.display(), err);
|
||||
}
|
||||
|
||||
// find folders and files in response
|
||||
let mut iter = objs.iter();
|
||||
iter.next(); // jump first element which is the folder cloned
|
||||
for object in iter {
|
||||
if object.href.clone().unwrap().chars().last().unwrap() == '/' {
|
||||
folders.push(object.clone());
|
||||
} else {
|
||||
files.push(object.clone());
|
||||
}
|
||||
// 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(), false) {
|
||||
eprintln!("err: saving ref of {} ({})", path_folder.display(), err);
|
||||
}
|
||||
first_iter = false;
|
||||
}
|
||||
|
||||
let downloader = Downloader::new()
|
||||
@ -139,6 +92,15 @@ fn save_blob(obj: ObjProps) {
|
||||
}
|
||||
}
|
||||
|
||||
fn req(api_props: &ApiProps, relative_s: &str) -> Result<Vec<ObjProps>, ApiError> {
|
||||
ReqProps::new()
|
||||
.set_request(relative_s, &api_props)
|
||||
.gethref()
|
||||
.getcontentlength()
|
||||
.getlastmodified()
|
||||
.send_req_multiple()
|
||||
}
|
||||
|
||||
pub fn get_url_props(url: &str) -> (String, Option<&str>, &str) {
|
||||
let mut username = None;
|
||||
let mut domain = "";
|
||||
|
@ -37,6 +37,15 @@ impl ObjProps {
|
||||
contentlength: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_dir(&self) -> bool {
|
||||
if let Some(href) = &self.href {
|
||||
href.chars().last().unwrap() == '/'
|
||||
} else {
|
||||
eprintln!("err: cannot determine object type wihout href");
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ReqProps {
|
||||
@ -81,6 +90,7 @@ impl ReqProps {
|
||||
}
|
||||
|
||||
pub fn gethref(&mut self) -> &mut ReqProps {
|
||||
// not an actual property but used to prevent getting anything else
|
||||
self.xml_balises.push(String::from("href"));
|
||||
self
|
||||
}
|
||||
@ -127,6 +137,7 @@ impl ReqProps {
|
||||
}
|
||||
|
||||
fn validate_xml(&mut self) -> &mut ReqProps {
|
||||
self.gethref();
|
||||
let mut xml = String::from(r#"<?xml version="1.0" encoding="UTF-8"?><d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns"><d:prop>"#);
|
||||
xml.push_str(&self.xml_payload.clone());
|
||||
xml.push_str(r#"</d:prop></d:propfind>"#);
|
||||
|
@ -3,3 +3,4 @@ pub mod read;
|
||||
pub mod nextsyncignore;
|
||||
pub mod api;
|
||||
pub mod time;
|
||||
pub mod remote;
|
||||
|
50
src/utils/remote.rs
Normal file
50
src/utils/remote.rs
Normal file
@ -0,0 +1,50 @@
|
||||
use crate::services::{req_props::ObjProps, api::ApiError};
|
||||
|
||||
pub fn enumerate_remote(req: impl Fn(&str) -> Result<Vec<ObjProps>, ApiError>) -> (Vec<ObjProps>, Vec<ObjProps>) {
|
||||
let mut folders: Vec<ObjProps> = vec![ObjProps::new()];
|
||||
let mut all_folders: Vec<ObjProps> = vec![];
|
||||
let mut files: Vec<ObjProps> = vec![];
|
||||
|
||||
while folders.len() > 0 {
|
||||
let folder = folders.pop().unwrap();
|
||||
|
||||
let relative_s = match folder.relative_s {
|
||||
Some(relative_s) => relative_s,
|
||||
None => String::from(""),
|
||||
};
|
||||
|
||||
// request folder content
|
||||
let res = req(relative_s.as_str());
|
||||
|
||||
let objs = match res {
|
||||
Ok(o) => o,
|
||||
Err(ApiError::IncorrectRequest(err)) => {
|
||||
eprintln!("fatal: {}", err.status());
|
||||
std::process::exit(1);
|
||||
},
|
||||
Err(ApiError::EmptyError(_)) => {
|
||||
eprintln!("Failed to get body");
|
||||
vec![]
|
||||
}
|
||||
Err(ApiError::RequestError(err)) => {
|
||||
eprintln!("fatal: {}", err);
|
||||
std::process::exit(1);
|
||||
},
|
||||
Err(ApiError::Unexpected(_)) => todo!()
|
||||
};
|
||||
|
||||
// find folders and files in response
|
||||
let mut iter = objs.iter();
|
||||
iter.next(); // jump first element which is the folder cloned
|
||||
for object in iter {
|
||||
if object.is_dir() {
|
||||
folders.push(object.clone());
|
||||
all_folders.push(object.clone());
|
||||
} else {
|
||||
files.push(object.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(all_folders, files)
|
||||
}
|
Loading…
Reference in New Issue
Block a user