use std::path::Path;
use reqwest::{Client, Response};
use base64::{Engine as _, engine::general_purpose};
use crate::models::structs::{ChildAssociationEntry, NodeBodyUpdate, NodeEntry};
use anyhow::Result;
use serde_json::json;
use tokio::fs::File;
use tokio::io::AsyncReadExt;
use crate::alfresco::params::QueryParamsBuilder;
pub struct NodesApi {
pub base_url: String,
pub client: Client,
}
impl NodesApi {
pub fn new(base_url: &str, client: Client) -> Self {
NodesApi {
base_url: format!("{}/alfresco/api/-default-/public/alfresco/versions/1", base_url),
client,
}
}
pub async fn get_node(&self, ticket: &String, node_id: &String, include: Option<&Vec<String>>, relative_path: Option<&String>, fields: Option<&Vec<String>>) -> Result<NodeEntry> {
let formatted_url = format!("{}/nodes/{}", self.base_url, node_id);
let ticket_b64 = general_purpose::STANDARD.encode(ticket);
let mut params_builder = QueryParamsBuilder::new()
.set_relative_path(relative_path);
if let Some(field_list) = fields {
for field in field_list {
params_builder = params_builder.push_field(Some(field));
}
}
if let Some(include_list) = include {
for include in include_list {
params_builder = params_builder.push_include(Some(include));
}
}
let raw_response = self.client.get(&formatted_url)
.header("Authorization", format!("Basic {}", ticket_b64))
.query(¶ms_builder.build())
.send()
.await?;
let parsed = raw_response.json::<NodeEntry>().await?;
Ok(parsed)
}
pub async fn update_node(&self, ticket: &String, node_id: &String, include: Option<&Vec<String>>, fields: Option<&Vec<String>>, body: NodeBodyUpdate) -> Result<NodeEntry> {
let formatted_url = format!("{}/nodes/{}", self.base_url, node_id);
let ticket_b64 = general_purpose::STANDARD.encode(ticket);
let mut params_builder = QueryParamsBuilder::new();
if let Some(field_list) = fields {
for field in field_list {
params_builder = params_builder.push_field(Some(field));
}
}
if let Some(include_list) = include {
for include in include_list {
params_builder = params_builder.push_include(Some(include));
}
}
let raw_response: Response = self.client.put(&formatted_url)
.header("Authorization", format!("Basic {}", ticket_b64))
.query(¶ms_builder.build())
.json(&body)
.send()
.await?;
let parsed = raw_response.json::<NodeEntry>().await?;
Ok(parsed)
}
pub async fn upload_file(&self, ticket: &String, parent_id: &String, file_path: &String, overwrite: &bool, relative_path: Option<&String>) -> Result<NodeEntry> {
let formatted_url = format!("{}/nodes/{}/children", self.base_url, parent_id);
let ticket_b64 = general_purpose::STANDARD.encode(ticket);
let mut file = File::open(file_path).await?;
let mut buffer = Vec::new();
file.read_to_end(&mut buffer).await?;
let path = Path::new(file_path);
let file_name = path.file_name().unwrap().to_owned().into_string().unwrap();
println!("{:?}", &file_name);
let file_part = reqwest::multipart::Part::bytes(buffer).file_name(file_name.clone());
let mut form = reqwest::multipart::Form::new()
.part("filedata", file_part)
.text("overwrite", overwrite.to_string())
.text("name", file_name.clone())
.text("nodeType", "cm:content")
.text("renditions", "doclib");
if relative_path.is_some() {
form = form.text("relativePath", relative_path.unwrap().clone());
}
let raw_response = self.client.post(&formatted_url)
.header("Authorization", format!("Basic {}", ticket_b64))
.multipart(form)
.send()
.await?;
let parsed = raw_response.json::<NodeEntry>().await?;
Ok(parsed)
}
pub async fn create_secondary_children(&self, ticket: &String, parent_id: &String, child_id: &String, assoc_type: &String, fields: Option<&Vec<String>>) -> Result<ChildAssociationEntry> {
let formatted_url = format!("{}/nodes/{}/secondary-children", self.base_url, parent_id);
let ticket_b64 = general_purpose::STANDARD.encode(ticket);
let mut params_builder = QueryParamsBuilder::new();
if let Some(field_list) = fields {
for field in field_list {
params_builder = params_builder.push_field(Some(field));
}
}
let raw_response = self.client.post(&formatted_url)
.header("Authorization", format!("Basic {}", ticket_b64))
.json(&json!({
"childId": child_id,
"assocType": assoc_type,
}))
.send()
.await?;
let parsed = raw_response.json::<ChildAssociationEntry>().await?;
Ok(parsed)
}
}