Compare commits

..

No commits in common. "487a94f8293891375c43aafaeb30227baf41ae78" and "33d35aba496cd3003e4e83137f164ee2d5d82ef7" have entirely different histories.

6 changed files with 43 additions and 108 deletions

View File

@ -20,9 +20,7 @@ pub async fn exec(args: CloneArgs, config: Config) {
.set_path(url_props.path.to_string()) .set_path(url_props.path.to_string())
// .set_depth(args.depth) // .set_depth(args.depth)
.get_properties(vec![]) .get_properties(vec![])
.enumerate().await else { todo!() }; .enumerate().await else { todo!()};
dbg!(&files);
dbg!(&folders);
for folder in folders { for folder in folders {
// create folder // create folder

View File

@ -2,16 +2,15 @@ use super::{
req_props::{Props, ReqProps, Response}, req_props::{Props, ReqProps, Response},
service::Service, service::Service,
}; };
use crate::utils::path;
use std::sync::Arc; use std::sync::Arc;
use tokio::{sync::Mutex, task::JoinSet}; use tokio::sync::Mutex;
pub const DEFAULT_DEPTH: u16 = 3; pub const DEFAULT_DEPTH: usize = 3;
pub struct Enumerator<'a> { pub struct Enumerator<'a> {
service: &'a Service, service: &'a Service,
path: String, path: String,
depth: u16, depth: usize,
properties: Vec<Props>, properties: Vec<Props>,
} }
@ -30,7 +29,7 @@ impl<'a> Enumerator<'a> {
self self
} }
pub fn set_depth(mut self, depth: u16) -> Self { pub fn set_depth(mut self, depth: usize) -> Self {
self.depth = depth; self.depth = depth;
self self
} }
@ -45,55 +44,44 @@ impl<'a> Enumerator<'a> {
let files = Arc::new(Mutex::new(Vec::new())); let files = Arc::new(Mutex::new(Vec::new()));
let folders = Arc::new(Mutex::new(Vec::new())); let folders = Arc::new(Mutex::new(Vec::new()));
let service = Arc::from(self.service.clone()); let service = Arc::from(self.service.clone());
let tasks_active = Arc::new(Mutex::new(0));
tx.send(self.path.clone()); tx.send(self.path.clone());
let mut taskSet = JoinSet::new(); let mut handles = vec![];
loop { while let Some(path) = rx.recv().await {
if let Ok(path) = rx.try_recv() { let tx_clone = tx.clone();
let current_depth = path::get_depth(&path); let files_clone = Arc::clone(&files);
*tasks_active.lock().await += 1; let folders_clone = Arc::clone(&folders);
let tx_clone = tx.clone(); let service_clone = Arc::clone(&service);
let files_clone = Arc::clone(&files); let properties = self.properties.clone();
let folders_clone = Arc::clone(&folders);
let service_clone = Arc::clone(&service);
let properties = self.properties.clone();
let depth = self.depth.clone();
let tasks_active_clone = Arc::clone(&tasks_active);
let task = taskSet.spawn(async move { let handle = tokio::task::spawn_blocking(move || async move {
let res = ReqProps::new(&service_clone) let res = ReqProps::new(&service_clone)
.set_path(path.clone()) .set_path(path)
.set_depth(depth) // .set_depth(self.depth)
.get_properties(properties) .get_properties(properties)
.send() .send()
.await .await
.unwrap(); .unwrap();
for obj in res.responses { for obj in res.responses {
if obj.is_dir() { if obj.is_dir() {
// Avoid enumerating the same folder multiple times todo!("Deal to have good href");
if obj.abs_path() != &path { tx_clone.send(obj.href.clone());
// depth deeper than current + self.depth folders_clone.lock().await.push(obj);
if obj.path_depth() >= current_depth + depth { } else {
tx_clone.send(obj.abs_path().to_owned()).unwrap(); files_clone.lock().await.push(obj);
}
folders_clone.lock().await.push(obj);
}
} else {
files_clone.lock().await.push(obj);
}
} }
*tasks_active_clone.lock().await -= 1; }
}); });
} else if *tasks_active.lock().await <= 0 { handles.push(handle);
break;
}
} }
taskSet.join_all().await; // Wait for all tasks to complete
for handle in handles {
handle.await;
}
Ok(( Ok((
Arc::try_unwrap(files).unwrap().into_inner(), Arc::try_unwrap(files).unwrap().into_inner(),

View File

@ -1,6 +1,5 @@
use crate::services::service::{Request, Service}; use crate::services::service::{Request, Service};
use crate::store::object::Obj; use crate::store::object::Obj;
use crate::utils::path;
use serde::Deserialize; use serde::Deserialize;
use serde_xml_rs::from_str; use serde_xml_rs::from_str;
@ -50,27 +49,7 @@ pub struct Response {
impl Response { impl Response {
pub fn is_dir(&self) -> bool { pub fn is_dir(&self) -> bool {
self.href.ends_with("/") todo!("is dir reponse")
}
pub fn abs_path(&self) -> &str {
let path = self
.href
.strip_prefix("/remote.php/dav/files")
.expect(&format!(
"Unexpected result when requesting props. Cannot strip from {}",
self.href
));
if path.ends_with('/') {
path.strip_suffix('/').expect("Checked before")
} else {
path
}
}
pub fn path_depth(&self) -> u16 {
path::get_depth(self.abs_path())
} }
} }
@ -108,11 +87,6 @@ impl<'a> ReqProps<'a> {
self self
} }
pub fn set_depth(mut self, depth: u16) -> Self {
self.request.headers.insert("Depth", depth.into());
self
}
pub fn get_properties(mut self, properties: Vec<Props>) -> Self { pub fn get_properties(mut self, properties: Vec<Props>) -> Self {
self.properties.extend(properties); self.properties.extend(properties);
self self

View File

@ -1,6 +1,6 @@
use crate::commands::clone::UrlProps; use crate::commands::clone::UrlProps;
use reqwest::{header::HeaderMap, Method, Url}; use reqwest::{header::HeaderMap, Method, Url};
use reqwest::{Client, ClientBuilder, RequestBuilder}; use reqwest::{Client, ClientBuilder};
const USER_AGENT: &str = "Nextsync"; const USER_AGENT: &str = "Nextsync";
@ -36,37 +36,29 @@ impl ClientConfig {
#[derive(Clone)] #[derive(Clone)]
pub struct Service { pub struct Service {
/// http[s]://host.xz/remote.php/dav/files
url_base: String, url_base: String,
} }
impl From<&UrlProps<'_>> for Service { impl From<&UrlProps<'_>> for Service {
fn from(url_props: &UrlProps) -> Self { fn from(url_props: &UrlProps) -> Self {
todo!("Auth");
let mut url_base = if url_props.is_secure { let mut url_base = if url_props.is_secure {
String::from("https://") String::from("https://")
} else { } else {
String::from("http://") String::from("http://")
}; };
url_base.push_str(url_props.domain); url_base.push_str(url_props.domain);
url_base.push_str("/remote.php/dav/files");
Service { url_base } Service { url_base }
} }
} }
impl Service {
fn authenticate(&self, request: RequestBuilder) -> RequestBuilder {
request
.bearer_auth("rK5ud2NmrR8p586Th7v272HRgUcZcEKIEluOGjzQQRj7gWMMAISFTiJcFnnmnNiu2VVlENks")
}
}
pub struct Request<'a> { pub struct Request<'a> {
service: &'a Service, service: &'a Service,
client: ClientConfig, client: ClientConfig,
method: Option<Method>, method: Option<Method>,
url: Option<String>, url: Option<String>,
pub headers: HeaderMap, headers: HeaderMap,
body: Option<String>, body: Option<String>,
} }
@ -89,19 +81,7 @@ impl<'a> Request<'a> {
} }
pub async fn send(&mut self) -> Result<reqwest::Response, reqwest::Error> { pub async fn send(&mut self) -> Result<reqwest::Response, reqwest::Error> {
self.service todo!()
.authenticate(
self.client
.build()
.request(self.method.clone().expect("Method must be set"), {
let mut url = self.service.url_base.clone();
url.push_str(&self.url.clone().expect("An url must be set"));
url
})
.headers(self.headers.clone()),
)
.send()
.await
// let mut url = self // let mut url = self
// .config // .config
// .clone() // .clone()
@ -115,6 +95,7 @@ impl<'a> Request<'a> {
// self.client // self.client
// .build() // .build()
// .request(self.method.clone().expect("Method must be set"), url) // .request(self.method.clone().expect("Method must be set"), url)
// .bearer_auth("rK5ud2NmrR8p586Th7v272HRgUcZcEKIEluOGjzQQRj7gWMMAISFTiJcFnnmnNiu2VVlENks")
// .send() // .send()
// .await // .await
} }

View File

@ -1,4 +1,4 @@
use clap::{Arg, ArgAction, ArgMatches, Command}; use clap::{Arg, ArgMatches, Command};
use crate::commands; use crate::commands;
use crate::config::config::Config; use crate::config::config::Config;
@ -22,9 +22,8 @@ pub fn create() -> Command {
) )
.arg( .arg(
Arg::new("force_insecure") Arg::new("force_insecure")
.short('f')
.long("force-insecure") .long("force-insecure")
.action(ArgAction::SetTrue) .short('f')
.help("Force the connection to nextcloud to be in http (not https)") .help("Force the connection to nextcloud to be in http (not https)")
) )
.arg( .arg(
@ -49,7 +48,7 @@ pub async fn handler(args: &ArgMatches) {
commands::clone::CloneArgs { commands::clone::CloneArgs {
remote: remote.to_string(), remote: remote.to_string(),
depth: args.get_one::<String>("depth").cloned(), depth: args.get_one::<String>("depth").cloned(),
force_insecure: *args.get_one::<bool>("force_insecure").unwrap(), force_insecure: args.contains_id("force_insecure"),
}, },
Config::from(args.get_one::<String>("directory")), Config::from(args.get_one::<String>("directory")),
) )

View File

@ -54,8 +54,3 @@ pub fn normalize_path<P: AsRef<Path>>(path: P) -> PathBuf {
} }
normalized normalized
} }
/// Calculate depth of a path
pub fn get_depth(path: &str) -> u16 {
path.split("/").count() as u16
}