add service req props

This commit is contained in:
grimhilt 2023-06-14 16:29:58 +02:00
parent 3da439ccf6
commit 51120f6268
5 changed files with 175 additions and 5 deletions

View File

@ -15,11 +15,21 @@ enum RemoveSide {
Right, Right,
} }
#[derive(PartialEq)]
#[derive(Debug)]
enum State {
Default,
New,
Renamed,
Modified,
Deleted,
}
// todo: relative path, filename, get modified // todo: relative path, filename, get modified
pub fn status() { pub fn status() {
let (staged_objs, new_objs, del_objs) = get_diff(); let (staged_objs, new_objs, del_objs) = get_diff();
dbg!(get_diff()); dbg!(get_diff());
print_status(staged_objs.clone(), del_objs.iter().map(|x| x.name.to_owned()).collect(), new_objs.clone()); print_status1(staged_objs.clone(), del_objs.iter().map(|x| x.name.to_owned()).collect(), new_objs.clone());
} }
#[derive(Debug)] #[derive(Debug)]
@ -27,6 +37,7 @@ pub struct Obj {
otype: String, otype: String,
name: String, name: String,
path: PathBuf, path: PathBuf,
state: State,
} }
pub fn get_diff() -> (Vec<String>, Vec<String>, Vec<Obj>) { pub fn get_diff() -> (Vec<String>, Vec<String>, Vec<Obj>) {
@ -89,7 +100,12 @@ pub fn get_diff() -> (Vec<String>, Vec<String>, Vec<Obj>) {
} }
let del_objs: Vec<Obj> = hashes.iter().map(|x| { let del_objs: Vec<Obj> = hashes.iter().map(|x| {
Obj {otype: x.1.otype.clone(), name: x.1.name.clone(), path: x.1.path.clone()} Obj {
otype: x.1.otype.clone(),
name: x.1.name.clone(),
path: x.1.path.clone(),
state: State::Deleted
}
}).collect(); }).collect();
(staged_objs.clone(), objs.clone(), del_objs) (staged_objs.clone(), objs.clone(), del_objs)
} }
@ -105,6 +121,7 @@ fn add_to_hashmap(lines: Lines<BufReader<File>>, hashes: &mut HashMap<String, Ob
otype: String::from(ftype), otype: String::from(ftype),
name: String::from(name), name: String::from(name),
path: p, path: p,
state: State::Default,
}); });
} }
} }
@ -121,7 +138,11 @@ fn add_to_vec(entries: Vec<PathBuf>, objects: &mut Vec<String>, root: PathBuf) {
} }
fn print_status(staged_objs: Vec<String>, del_objs: Vec<String>, new_objs: Vec<String>) { fn print_status(staged_objs: Vec<Obj>, objs: Vec<Obj>) {
}
fn print_status1(staged_objs: Vec<String>, del_objs: Vec<String>, new_objs: Vec<String>) {
if staged_objs.len() == 0 && del_objs.len() == 0 && new_objs.len() == 0 { if staged_objs.len() == 0 && del_objs.len() == 0 && new_objs.len() == 0 {
println!("Nothing to push, working tree clean"); println!("Nothing to push, working tree clean");
return; return;
@ -141,7 +162,7 @@ fn print_status(staged_objs: Vec<String>, del_objs: Vec<String>, new_objs: Vec<S
println!(" (Use\"nextsync add <file>...\" to update what will be pushed)"); println!(" (Use\"nextsync add <file>...\" to update what will be pushed)");
} }
for object in new_objs { for object in new_objs {
println!(" {} {}", String::from("added:").red(), object.red()); println!(" {} {}", String::from("new file:").red(), object.red());
} }
for object in del_objs { for object in del_objs {
println!(" {} {}", String::from("deleted:").red(), object.red()); println!(" {} {}", String::from("deleted:").red(), object.red());

View File

@ -1,3 +1,4 @@
pub mod api; pub mod api;
pub mod list_folders; pub mod list_folders;
pub mod download_files; pub mod download_files;
pub mod req_props;

View File

@ -45,6 +45,19 @@ impl ApiBuilder {
self self
} }
pub fn set_xml(&mut self, xml_payload: String) -> &mut ApiBuilder {
match self.request.take() {
None => {
eprintln!("fatal: incorrect request");
std::process::exit(1);
},
Some(req) => {
self.request = Some(req.body(xml_payload));
}
}
self
}
pub async fn send(&mut self) -> Result<Response, Error> { pub async fn send(&mut self) -> Result<Response, Error> {
self.set_auth(); self.set_auth();
match self.request.take() { match self.request.take() {

View File

@ -21,7 +21,7 @@ async fn send_propfind_request() -> Result<(), Box<dyn Error>> {
<oc:permissions/> <oc:permissions/>
<d:resourcetype/> <d:resourcetype/>
<d:getetag/> <d:getetag/>
</d:prop> ) </d:prop>
</d:propfind>"#; </d:propfind>"#;
let mut headers = HeaderMap::new(); let mut headers = HeaderMap::new();

135
src/services/req_props.rs Normal file
View File

@ -0,0 +1,135 @@
use crate::services::api::{ApiBuilder, ApiError};
use xml::reader::{EventReader, XmlEvent};
use std::io::{self, Cursor};
use reqwest::{Method, IntoUrl, Response, Error};
pub struct ReqProps {
api_builder: ApiBuilder,
xml_list: Vec<String>,
xml_payload: String,
}
impl ReqProps {
pub fn new<U: IntoUrl>(url: U) -> Self {
ReqProps {
api_builder: ApiBuilder::new()
.set_request(Method::from_bytes(b"PROPFIND").unwrap(), url),
xml_list: vec![],
xml_payload: String::new(),
}
}
pub fn getlastmodified(&mut self) -> &mut ReqProps {
self.xml_list.push(String::from("getlastmodified"));
self.xml_payload.push_str(r#"<d:getlastmodified/>"#);
self
}
pub fn getcontentlenght(&mut self) -> &mut ReqProps {
self.xml_list.push(String::from("getcontentlength"));
self.xml_payload.push_str(r#"<d:getcontentlength/>"#);
self
}
pub fn getcontenttype(&mut self) -> &mut ReqProps {
self.xml_list.push(String::from("getcontenttype"));
self.xml_payload.push_str(r#"<d:getcontenttype/>"#);
self
}
pub fn getpermissions(&mut self) -> &mut ReqProps {
self.xml_list.push(String::from("permissions"));
self.xml_payload.push_str(r#"<oc:permissions/>"#);
self
}
pub fn getressourcetype(&mut self) -> &mut ReqProps {
self.xml_list.push(String::from("resourcetype"));
self.xml_payload.push_str(r#"<d:resourcetype/>"#);
self
}
pub fn getetag(&mut self) -> &mut ReqProps {
self.xml_list.push(String::from("getetag"));
self.xml_payload.push_str(r#"<d:getetag/>"#);
self
}
fn validate_xml(&mut self) -> &mut ReqProps {
let mut xml = String::from(r#"<?xml version="1.0" encoding="UTF-8"?><d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns"><d:prop>"#);
xml.push_str(&self.xml_payload.clone());
xml.push_str(r#"</d:prop></d:propfind>"#);
self.api_builder.set_xml(xml);
self
}
pub async fn send(&mut self) -> Result<Response, Error> {
self.validate_xml();
self.api_builder.send().await
}
pub async fn send_with_err(&mut self) -> Result<String, ApiError> {
let res = self.send().await.map_err(ApiError::RequestError)?;
if res.status().is_success() {
let body = res.text().await.map_err(ApiError::EmptyError)?;
Ok(body)
} else {
Err(ApiError::IncorrectRequest(res))
}
}
pub async fn send_with_res(&mut self) -> Vec<String> {
match self.send_with_err().await {
Ok(body) => self.parse(body),
Err(ApiError::IncorrectRequest(err)) => {
eprintln!("fatal: {}", err.status());
std::process::exit(1);
},
Err(ApiError::EmptyError(_)) => {
eprintln!("Failed to get body");
vec![]
}
Err(ApiError::RequestError(err)) => {
eprintln!("fatal: {}", err);
std::process::exit(1);
}
}
}
pub fn parse(&self, xml: String) -> Vec<String> {
let cursor = Cursor::new(xml);
let parser = EventReader::new(cursor);
let mut should_get = false;
let mut values: Vec<String> = vec![];
let mut iter = self.xml_list.iter();
let mut val = iter.next();
for event in parser {
match event {
Ok(XmlEvent::StartElement { name, .. }) => {
if let Some(v) = val.clone() {
should_get = &name.local_name == v;
} else {
break;
}
}
Ok(XmlEvent::Characters(text)) => {
if !text.trim().is_empty() && should_get {
values.push(text);
val = iter.next()
}
}
Ok(XmlEvent::EndElement { .. }) => {
should_get = false;
}
Err(e) => {
eprintln!("Error: {}", e);
break;
}
_ => {}
}
}
values
}
}