From aed09ac9d857838234cb5f761033e22dd4139b3c Mon Sep 17 00:00:00 2001 From: Adam Cooper Date: Fri, 7 Jan 2022 09:20:17 -0500 Subject: [PATCH] [wip] No compilation errors --- .gitignore | 1 + Cargo.lock | 42 +++++++++++++- Cargo.toml | 3 +- src/main.rs | 164 ++++++++++++++++++++++++++++++++++++---------------- 4 files changed, 159 insertions(+), 51 deletions(-) diff --git a/.gitignore b/.gitignore index c0c260e..9afe259 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target .env Cargo.lock +example*.xml diff --git a/Cargo.lock b/Cargo.lock index 73e1573..8a877a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -214,6 +214,15 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "hermit-abi" version = "0.1.19" @@ -570,7 +579,8 @@ dependencies = [ "log", "reqwest", "tokio", - "xml-rs", + "yaserde", + "yaserde_derive", ] [[package]] @@ -948,6 +958,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" + [[package]] name = "unicode-xid" version = "0.2.2" @@ -1109,3 +1125,27 @@ name = "xml-rs" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" + +[[package]] +name = "yaserde" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2776ec5bb20e76d89268e87e1ea66c078b94f55e9771e4d648adda3019f87fc" +dependencies = [ + "log", + "xml-rs", +] + +[[package]] +name = "yaserde_derive" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c0b0a4701f203ebaecce4971a6bb8575aa07b617bdc39ddfc6ffeff3a38530d" +dependencies = [ + "heck", + "log", + "proc-macro2", + "quote", + "syn", + "xml-rs", +] diff --git a/Cargo.toml b/Cargo.toml index 21da9e2..0f72641 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,4 +11,5 @@ env_logger = "0.8.4" log = "0.4.0" reqwest = { version = "0.11", features = ["json"] } tokio = { version = "1", features = ["full"] } -xml-rs = "0.8.4" +yaserde = "0.7.1" +yaserde_derive = "0.7.1" diff --git a/src/main.rs b/src/main.rs index 0c5a1b2..c9f66cc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,29 +1,115 @@ -extern crate xml; - #[allow(unused)] -// use dotenv::dotenv; -use env_logger::{ Env, Target }; +use env_logger::{Env, Target}; #[allow(unused)] -use log::{debug, info, log_enabled, warn, error}; +use log::{debug, error, info, log_enabled, warn}; use reqwest; #[allow(unused)] use std::io::{self, BufReader, Write}; #[allow(unused)] -use xml::reader::{EventReader, XmlEvent}; - +use yaserde_derive::{YaDeserialize, YaSerialize}; #[allow(unused)] -fn publicise() { +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, } -async fn get_folder_contents(password: String, url_tail: &str) -> Result> { +#[derive(Default, PartialEq, Debug, YaDeserialize)] +#[yaserde(rename = "response", prefix = "d", namespace = "d: DAV:")] +pub struct NextcloudResponse { + #[yaserde(prefix = "d")] + href: Option, + #[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, +} + +/* + + /nextcloud/remote.php/dav/files/adam/test_public/2021_test_public/ + + + Tue, 14 Dec 2021 03:46:36 GMT + RGDNVCK + + + + "61b8139c1beb0" + + HTTP/1.1 200 OK + + + + + + + HTTP/1.1 404 Not Found + + +*/ +#[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, +} + +#[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( + password: String, + url_tail: &str, +) -> Result> { debug!("Entering: get_folder_contents()"); 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 body = String::from( + r#" @@ -34,8 +120,10 @@ async fn get_folder_contents(password: String, url_tail: &str) -> Result - "#); - let response_text = client.request(method, url) + "#, + ); + let response_text = client + .request(method, url) .basic_auth("adam", Some(password)) .body(body) .send() @@ -57,55 +145,33 @@ fn get_password() -> Result { } } +#[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) -} - -fn parse_xml(xml_string: String) { - let xml_str = &xml_string; - let parser = EventReader::from_str(xml_str); - let mut depth = 0; - let mut resourcetype_element = false; - let mut share_type_element = false; - for e in parser { - match e { - Ok(XmlEvent::StartElement { name, .. }) => { - println!("{}+{}", indent(depth), name); - depth += 1; - if name.local_name.matches("resourcetype").collect::>().len() > 0 { - println!("{} Element: resourcetype", indent(depth)); - resourcetype_element = true; - } - } - Ok(XmlEvent::Characters(s)) => { - println!("{} {}", indent(depth), s); - } - Ok(XmlEvent::EndElement { name }) => { - depth -= 1; - println!("{}-{}", indent(depth), name); - } - Err(e) => { - println!("Error: {}", e); - break; - } - _ => {} - } - } + (0..size) + .map(|_| INDENT) + .fold(String::with_capacity(size * INDENT.len()), |r, s| r + s) } #[tokio::main] async fn main() -> std::io::Result<()> { - env_logger::Builder::from_env(Env::default().default_filter_or("trace")).target(Target::Stdout).init(); + use yaserde::de::from_str; + + env_logger::Builder::from_env(Env::default().default_filter_or("trace")) + .target(Target::Stdout) + .init(); println!("Publicise it!"); let password = get_password().unwrap().trim().to_string(); debug!("Received password: {}[END]", password); - let folder_contents = get_folder_contents(password, "/nextcloud/remote.php/dav/files/adam/test_public").await.unwrap(); + let folder_contents = + get_folder_contents(password, "/nextcloud/remote.php/dav/files/adam/test_public/2019_test_public") + .await + .unwrap(); debug!("{:?}", folder_contents); - parse_xml(folder_contents); + let result: Multistatus = from_str(&folder_contents).unwrap(); + println!("{:?}", result); Ok(()) }