use crate::services::service::{Request, Service}; use crate::store::{ object::Obj, structs::{to_obj_path, ObjPath}, }; use crate::utils::path; use serde::Deserialize; use serde_xml_rs::from_str; use std::path::PathBuf; #[derive(Clone)] pub enum Props { CreationDate, LastModified, ETag, ContentType, RessourceType, ContentLength, ContentLanguage, DisplayName, FileId, Permissions, Size, HasPreview, Favorite, CommentsUnread, OwnerDisplayName, ShareTypes, ContainedFolderCount, ContainedFileCountm, } #[derive(Deserialize, Debug)] struct Propstat { #[serde(rename = "prop")] prop: Prop, } #[derive(Deserialize, Debug)] struct Prop { #[serde(rename = "getlastmodified")] last_modified: Option, #[serde(rename = "getcontentlength")] content_length: Option, } #[derive(Deserialize, Debug)] pub struct Response { #[serde(rename = "href")] pub href: String, #[serde(rename = "propstat")] propstat: Propstat, } impl Response { pub fn is_dir(&self) -> bool { self.href.ends_with("/") } 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 obj_path(&self, ) -> ObjPath { let mut path = self.abs_path(); // TODO path = path.strip_prefix("/admin/tmp_test/").unwrap(); to_obj_path(&PathBuf::from(path)) } pub fn path_depth(&self) -> u16 { path::get_depth(self.abs_path()) } } #[derive(Deserialize, Debug)] pub struct Multistatus { #[serde(rename = "response")] pub responses: Vec, } impl From<&Props> for &str { fn from(variant: &Props) -> Self { match variant { Props::CreationDate => "", Props::LastModified => "", _ => todo!("Props conversion not implemented"), } } } pub struct ReqProps<'a> { request: Request<'a>, properties: Vec, } impl<'a> ReqProps<'a> { pub fn new(service: &'a Service) -> Self { ReqProps { request: Request::new(service), properties: Vec::new(), } } pub fn set_path(mut self, path: String) -> Self { self.request.propfind(path); 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) -> Self { self.properties.extend(properties); self } pub fn get_property(&mut self, property: Props) { self.properties.push(property); } fn get_body(&self) -> String { let mut xml = String::from( r#""#, ); for property in &self.properties { xml.push_str(property.into()); } xml.push_str(r#""#); xml } pub async fn send(&mut self) -> Result { let res = self.request.send().await; let xml = res.unwrap().text().await?; let multistatus: Multistatus = from_str(&xml).expect("Failed to unwrap xml response from req_props"); Ok(multistatus) } } // impl From for ReqProps<'_> { // fn from(obj: Obj) -> Self { // ReqProps::new(obj.get_obj_path().to_str().unwrap()) // } // }