#[allow(unused)] use env_logger::{Env, Target}; #[allow(unused)] use log::{debug, error, info, log_enabled, warn}; use reqwest; use std::collections::HashMap; #[allow(unused)] use std::io::{self, BufReader, Write}; #[allow(unused)] use yaserde_derive::{YaDeserialize, YaSerialize}; use yaserde::de::from_str; #[allow(unused)] fn publicise() {} #[derive(Default, PartialEq, Debug, YaDeserialize)] #[yaserde( rename = "multistatus", prefix = "d", namespace = "d: DAV:", namespace = "nc: http://nextcloud.org/ns", namespace = "oc: http://owncloud.org/ns", namespace = "s: http://sabredav.org/ns" )] pub struct Multistatus { #[yaserde(prefix = "d")] response: Vec, } #[derive(Default, PartialEq, Debug, YaDeserialize)] #[yaserde(rename = "response", prefix = "d", namespace = "d: DAV:")] pub struct NextcloudResponse { #[yaserde(prefix = "d")] // href: Option, href: String, #[yaserde(prefix = "d")] propstat: Vec, } #[derive(Default, PartialEq, Debug, YaDeserialize)] #[yaserde(rename = "propstat", prefix = "d", namespace = "d: DAV:")] pub struct Propstat { #[yaserde(prefix = "d")] prop: Option, #[yaserde(prefix = "d")] status: Option, } #[derive(Default, PartialEq, Debug, YaDeserialize)] #[yaserde( rename = "prop", namespace = "d: DAV:", namespace = "oc: http://owncloud.org/ns" )] pub struct Prop { #[yaserde(prefix = "d", rename = "getlastmodified")] get_last_modified: Option, #[yaserde(prefix = "oc")] permissions: Option, #[yaserde(prefix = "d", rename = "resourcetype")] resource_type: Option, #[yaserde(prefix = "d", rename = "getetag")] get_etag: Option, #[yaserde(prefix = "d", rename = "getcontentlength")] get_content_length: Option, #[yaserde(prefix = "d", rename = "getcontenttype")] get_content_type: Option, #[yaserde(prefix = "oc", rename = "share-types")] share_types: Vec, } #[derive(Default, PartialEq, Debug, YaDeserialize)] #[yaserde(rename = "share-types", namespace = "oc: http://owncloud.org/ns")] pub struct ShareType { #[yaserde(rename = "share-type", prefix = "oc")] share_type: u8, } #[derive(Default, PartialEq, Debug, YaDeserialize)] #[yaserde(rename = "resourcetype", namespace = "d: DAV:")] pub struct ResourceType { #[yaserde(prefix = "d")] collection: Vec, } #[derive(Default, PartialEq, Debug, YaDeserialize)] #[yaserde(rename = "collection", namespace = "d: DAV:")] pub struct Collection { #[yaserde(prefix = "d")] collection: Option, } async fn get_folder_contents(url_tail: &String) -> Result> { debug!("Entering: get_folder_contents()"); let password = get_password().unwrap().trim().to_string(); debug!("Received password: {}[END]", password); let root_url = "https://theadamcooper.com"; let method = reqwest::Method::from_bytes(b"PROPFIND").unwrap(); let client = reqwest::Client::new(); let url = format!("{}{}", root_url, url_tail); debug!("url: {}", url); let body = String::from( r#" "#, ); let response_text = client .request(method, url) .basic_auth("adam", Some(password)) .body(body) .send() .await? .text() .await?; debug!("{:?}", response_text); Ok(response_text) } #[tokio::main] async fn traverse(mut result: Multistatus) { debug!("Entering: traverse()"); // Initialize the indexed "pointer" let mut current_index: usize = 0; let mut already_visited: bool; // Initialize the hashmap of visited items (by etag?) let mut visited_items = HashMap::new(); if let Some(prop) = &mut result.response[0].propstat[0].prop { if let Some(etag) = &prop.get_etag { visited_items.insert(etag, true); } else { current_index += 1; } } else { current_index += 1; } // Depth first traversal while current_index < (&mut result.response).len() { match &mut result.response[current_index].propstat[0].prop { Some(prop) => { match &prop.get_etag { Some(etag) => { }, _ => println!("Something's happening.") } }, _ => println!("Something's happening.") } } } fn get_password() -> Result { print!("Nextcloud password: "); io::stdout().flush().unwrap(); let mut buffer = String::new(); let stdin = io::stdin(); match stdin.read_line(&mut buffer) { Ok(_) => Ok(buffer), Err(error) => Err(error), } } #[allow(unused)] fn indent(size: usize) -> String { const INDENT: &'static str = " "; (0..size) .map(|_| INDENT) .fold(String::with_capacity(size * INDENT.len()), |r, s| r + s) } #[tokio::main] async fn main() -> std::io::Result<()> { // use yaserde::de::from_str; env_logger::Builder::from_env(Env::default().default_filter_or("trace")) .target(Target::Stdout) .init(); println!("Publicise it!"); let folder_contents: String = // get_folder_contents("/nextcloud/remote.php/dav/files/adam/test_public/2019_test_public") get_folder_contents(&String::from("/nextcloud/remote.php/dav/files/adam/test_public")) .await .unwrap(); debug!("{:?}", folder_contents); let mut result: Multistatus = from_str(&folder_contents).unwrap(); println!("{:?}", result); traverse(result); Ok(()) }