alfresco_sdk/alfresco/core_api/nodes/
mod.rs

1use std::path::Path;
2use reqwest::{Client, Response};
3use base64::{Engine as _, engine::general_purpose};
4use crate::models::structs::{ChildAssociationEntry, NodeBodyUpdate, NodeEntry};
5
6use anyhow::Result;
7use serde_json::json;
8use tokio::fs::File;
9use tokio::io::AsyncReadExt;
10use crate::alfresco::params::QueryParamsBuilder;
11
12pub struct NodesApi {
13    pub base_url: String,
14    pub client: Client,
15}
16
17impl NodesApi {
18    pub fn new(base_url: &str, client: Client) -> Self {
19        NodesApi {
20            base_url: format!("{}/alfresco/api/-default-/public/alfresco/versions/1", base_url),
21            client,
22        }
23    }
24
25    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> {
26        let formatted_url = format!("{}/nodes/{}", self.base_url, node_id);
27        let ticket_b64 = general_purpose::STANDARD.encode(ticket);
28
29        let mut params_builder = QueryParamsBuilder::new()
30            .set_relative_path(relative_path);
31
32        if let Some(field_list) = fields {
33            for field in field_list {
34                params_builder = params_builder.push_field(Some(field));
35            }
36        }
37
38        if let Some(include_list) = include {
39            for include in include_list {
40                params_builder = params_builder.push_include(Some(include));
41            }
42        }
43
44        let raw_response = self.client.get(&formatted_url)
45            .header("Authorization", format!("Basic {}", ticket_b64))
46            .query(&params_builder.build())
47            .send()
48            .await?;
49
50        let parsed = raw_response.json::<NodeEntry>().await?;
51
52        Ok(parsed)
53    }
54
55    pub async fn update_node(&self, ticket: &String, node_id: &String, include: Option<&Vec<String>>, fields: Option<&Vec<String>>, body: NodeBodyUpdate) -> Result<NodeEntry> {
56        let formatted_url = format!("{}/nodes/{}", self.base_url, node_id);
57        let ticket_b64 = general_purpose::STANDARD.encode(ticket);
58
59        let mut params_builder = QueryParamsBuilder::new();
60
61        if let Some(field_list) = fields {
62            for field in field_list {
63                params_builder = params_builder.push_field(Some(field));
64            }
65        }
66
67        if let Some(include_list) = include {
68            for include in include_list {
69                params_builder = params_builder.push_include(Some(include));
70            }
71        }
72
73        let raw_response: Response = self.client.put(&formatted_url)
74            .header("Authorization", format!("Basic {}", ticket_b64))
75            .query(&params_builder.build())
76            .json(&body)
77            .send()
78            .await?;
79
80        let parsed = raw_response.json::<NodeEntry>().await?;
81        // let parsed = raw_response.text().await?;
82        Ok(parsed)
83    }
84
85    pub async fn upload_file(&self, ticket: &String, parent_id: &String, file_path: &String, overwrite: &bool, relative_path: Option<&String>) -> Result<NodeEntry> {
86        let formatted_url = format!("{}/nodes/{}/children", self.base_url, parent_id);
87        let ticket_b64 = general_purpose::STANDARD.encode(ticket);
88
89        let mut file = File::open(file_path).await?;
90        let mut buffer = Vec::new();
91        file.read_to_end(&mut buffer).await?;
92
93        let path = Path::new(file_path);
94        let file_name = path.file_name().unwrap().to_owned().into_string().unwrap();
95        let file_part = reqwest::multipart::Part::bytes(buffer).file_name(file_name.clone());
96
97        let mut form = reqwest::multipart::Form::new()
98            .part("filedata", file_part)
99            .text("overwrite", overwrite.to_string())
100            .text("name", file_name.clone())
101            .text("nodeType", "cm:content")
102            .text("renditions", "doclib");
103
104        if relative_path.is_some() {
105            form = form.text("relativePath", relative_path.unwrap().clone());
106        }
107
108        let raw_response = self.client.post(&formatted_url)
109            .header("Authorization", format!("Basic {}", ticket_b64))
110            .multipart(form)
111            .send()
112            .await?;
113
114
115        let parsed = raw_response.json::<NodeEntry>().await?;
116
117        Ok(parsed)
118    }
119
120    pub async fn create_secondary_children(&self, ticket: &String, parent_id: &String, child_id: &String, assoc_type: &String, fields: Option<&Vec<String>>) -> Result<ChildAssociationEntry> {
121        let formatted_url = format!("{}/nodes/{}/secondary-children", self.base_url, parent_id);
122        let ticket_b64 = general_purpose::STANDARD.encode(ticket);
123
124        let mut params_builder = QueryParamsBuilder::new();
125
126        if let Some(field_list) = fields {
127            for field in field_list {
128                params_builder = params_builder.push_field(Some(field));
129            }
130        }
131
132        let raw_response = self.client.post(&formatted_url)
133            .header("Authorization", format!("Basic {}", ticket_b64))
134            .json(&json!({
135                "childId": child_id,
136                "assocType": assoc_type,
137            }))
138            .send()
139            .await?;
140
141        let parsed = raw_response.json::<ChildAssociationEntry>().await?;
142
143        Ok(parsed)
144    }
145
146}