clone all files and their content
This commit is contained in:
parent
a45c953397
commit
1042a7ea22
@ -1,9 +1,14 @@
|
|||||||
use clap::Values;
|
use clap::Values;
|
||||||
|
use std::io::Bytes;
|
||||||
|
use std::fs::OpenOptions;
|
||||||
|
use std::env;
|
||||||
|
use std::io::prelude::*;
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
use xml::reader::{EventReader, XmlEvent};
|
use xml::reader::{EventReader, XmlEvent};
|
||||||
use std::fs::{self, DirBuilder};
|
use std::fs::{File, DirBuilder};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use crate::services::list_folders::ListFolders;
|
use crate::services::list_folders::ListFolders;
|
||||||
|
use crate::services::download_files::DownloadFiles;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
pub fn clone(remote: Values<'_>) {
|
pub fn clone(remote: Values<'_>) {
|
||||||
@ -19,13 +24,23 @@ pub fn clone(remote: Values<'_>) {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
let url_without_domain = domain_regex.replace(url, "/").to_string();
|
let url_without_domain = domain_regex.replace(url, "/").to_string();
|
||||||
|
let mut it = path.iter();
|
||||||
|
it.next();
|
||||||
|
it.next();
|
||||||
|
it.next();
|
||||||
|
it.next();
|
||||||
|
it.next();
|
||||||
|
let username = it.next().unwrap();
|
||||||
|
|
||||||
let mut folders = vec![url_without_domain];
|
let mut folders = vec![url_without_domain];
|
||||||
let mut url_request;
|
let mut url_request;
|
||||||
|
let mut files: Vec<String> = vec![];
|
||||||
|
let mut first_iter = true;
|
||||||
while folders.len() > 0 {
|
while folders.len() > 0 {
|
||||||
|
let folder = folders.pop().unwrap();
|
||||||
|
|
||||||
url_request = String::from(domain.clone());
|
url_request = String::from(domain.clone());
|
||||||
url_request.push_str(folders.last().unwrap().as_str());
|
url_request.push_str(folder.as_str());
|
||||||
let mut body = Default::default();
|
let mut body = Default::default();
|
||||||
tokio::runtime::Runtime::new().unwrap().block_on(async {
|
tokio::runtime::Runtime::new().unwrap().block_on(async {
|
||||||
match call(url_request.as_str()).await {
|
match call(url_request.as_str()).await {
|
||||||
@ -41,30 +56,84 @@ pub fn clone(remote: Values<'_>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
folders.pop();
|
if first_iter {
|
||||||
if (folders.len() == 0) {
|
first_iter = false;
|
||||||
if DirBuilder::new().create(path.parent()).is_err() {
|
dbg!(path.file_name());
|
||||||
|
if DirBuilder::new().create(path.file_name().unwrap()).is_err() {
|
||||||
// todo add second parameter to save in a folder
|
// todo add second parameter to save in a folder
|
||||||
eprintln!("fatal: directory already exist");
|
eprintln!("fatal: directory already exist");
|
||||||
// destination path 'path' already exists and is not an empty directory.
|
// destination path 'path' already exists and is not an empty directory.
|
||||||
std::process::exit(1);
|
//std::process::exit(1);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
let mut path = Path::new(&folder).strip_prefix("/remote.php/dav/files/");
|
||||||
|
path = path.unwrap().strip_prefix(username);
|
||||||
|
DirBuilder::new().recursive(true).create(path.unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
let objects = get_objects_xml(body);
|
let objects = get_objects_xml(body);
|
||||||
let mut iter = objects.iter();
|
let mut iter = objects.iter();
|
||||||
iter.next(); // jump first element which the folder fetched
|
iter.next(); // jump first element which the folder fetched
|
||||||
for object in iter {
|
for object in iter {
|
||||||
dbg!(object);
|
|
||||||
if object.chars().last().unwrap() == '/' {
|
if object.chars().last().unwrap() == '/' {
|
||||||
folders.push(object.to_string());
|
folders.push(object.to_string());
|
||||||
dbg!("folder");
|
} else {
|
||||||
|
files.push(object.to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tokio::runtime::Runtime::new().unwrap().block_on(async {
|
||||||
|
download_files(domain, username.to_str().unwrap(), files);
|
||||||
|
// });
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn download_files(domain: &str, username: &str, files: Vec<String>) -> std::io::Result<()> {
|
||||||
|
dbg!("in");
|
||||||
|
let mut body: Vec<u8> = vec![];
|
||||||
|
for file in files {
|
||||||
|
let mut url_request = String::from(domain.clone());
|
||||||
|
url_request.push_str(file.as_str());
|
||||||
|
tokio::runtime::Runtime::new().unwrap().block_on(async {
|
||||||
|
match callDownload(url_request.as_str()).await {
|
||||||
|
Ok(b) => {
|
||||||
|
let mut path = Path::new(&file).strip_prefix("/remote.php/dav/files/");
|
||||||
|
path = path.unwrap().strip_prefix(username);
|
||||||
|
|
||||||
|
let pathCur = env::current_dir().unwrap();
|
||||||
|
let mut f = OpenOptions::new()
|
||||||
|
.write(true)
|
||||||
|
.create(true)
|
||||||
|
.open(pathCur.join(path.unwrap())).unwrap();
|
||||||
|
|
||||||
|
f.write_all(&b);
|
||||||
|
},
|
||||||
|
Err(MyError::IncorrectRequest(err)) => {
|
||||||
|
eprintln!("fatal: {}", err.status());
|
||||||
|
std::process::exit(1);
|
||||||
|
},
|
||||||
|
Err(MyError::EmptyError(_)) => eprintln!("Failed to get body"),
|
||||||
|
Err(MyError::RequestError(err)) => {
|
||||||
|
eprintln!("fatal: {}", err);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//f.write_all(body.clone())?;
|
||||||
|
dbg!(file);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn callDownload(url: &str) -> Result<Vec<u8>, MyError> {
|
||||||
|
let res = DownloadFiles::new(url).send().await.map_err(MyError::RequestError)?;
|
||||||
|
if res.status().is_success() {
|
||||||
|
let body = res.bytes().await.map_err(MyError::EmptyError)?;
|
||||||
|
Ok(body.to_vec())
|
||||||
|
} else {
|
||||||
|
Err(MyError::IncorrectRequest(res))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_objects_xml(xml: String) -> Vec<String> {
|
fn get_objects_xml(xml: String) -> Vec<String> {
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
pub mod api;
|
pub mod api;
|
||||||
pub mod list_folders;
|
pub mod list_folders;
|
||||||
|
pub mod download_files;
|
||||||
|
2
src/services/auth.rs
Normal file
2
src/services/auth.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
|
19
src/services/download_files.rs
Normal file
19
src/services/download_files.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
use crate::services::api::ApiBuilder;
|
||||||
|
use reqwest::{Method, IntoUrl, Response, Error};
|
||||||
|
|
||||||
|
pub struct DownloadFiles {
|
||||||
|
api_builder: ApiBuilder,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DownloadFiles {
|
||||||
|
pub fn new<U: IntoUrl>(url: U) -> Self {
|
||||||
|
DownloadFiles {
|
||||||
|
api_builder: ApiBuilder::new()
|
||||||
|
.set_request(Method::GET, url),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn send(&mut self) -> Result<Response, Error> {
|
||||||
|
self.api_builder.send().await
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user