paperless_rs/endpoint/
documents.rs

1use bytes::Bytes;
2use reqwest::Method;
3use serde::{Deserialize, Serialize};
4
5use crate::utils::pagination::Response;
6use crate::utils::Field;
7use crate::{ternary, PaperlessClient};
8
9#[derive(Serialize, Deserialize, Clone, Debug, Default)]
10pub struct Document {
11    pub id: u64,
12    pub title: String,
13    pub content: String,
14
15    pub tags: Vec<u64>,
16    pub document_type: Option<String>,
17    pub correspondent: Option<String>,
18
19    pub created: String,
20    pub created_date: Option<String>,
21    pub modified: Option<String>,
22    pub added: String,
23
24    pub archive_serial_number: Option<String>,
25    pub original_file_name: String,
26    pub archived_file_name: Option<String>,
27
28    pub notes: Vec<String>,
29    //TODO: Add permissions
30    pub custom_fields: Vec<Field>,
31
32    #[serde(rename = "__search_hit__")]
33    pub search_hit: Option<SearchHit>,
34}
35
36#[derive(Serialize, Deserialize, Clone, Debug, Default)]
37pub struct Metadata {
38    pub original_checksum: String,
39    pub original_size: String,
40    pub original_mime_type: String,
41    pub media_filename: String,
42    pub has_archive_version: bool,
43    pub original_metadata: Vec<Field>,
44
45    pub archive_checksum: Option<String>,
46    pub archive_size: Option<String>,
47    pub archive_metadata: Option<String>,
48}
49
50#[derive(Serialize, Deserialize, Clone, Debug, Default)]
51pub struct SearchHit {
52    pub rank: u64,
53    pub score: f64,
54}
55
56impl PaperlessClient {
57    pub async fn search_documents(
58        &self,
59        query: &str,
60    ) -> Result<Response<Document>, Box<dyn std::error::Error>> {
61        let formatted_query = query.replace(' ', "%20");
62        let url = format!("{}/documents/?query={}", self.base_url, formatted_query);
63
64        let request_builder = self.prepare_endpoint(Method::GET, url).await?;
65        self.call_endpoint(request_builder).await
66    }
67
68    pub async fn fetch_documents(&self) -> Result<Response<Document>, Box<dyn std::error::Error>> {
69        let url = format!("{}/documents/", self.base_url);
70
71        let request_builder = self.prepare_endpoint(Method::GET, url).await?;
72        self.call_endpoint(request_builder).await
73    }
74
75    pub async fn fetch_document(
76        &self,
77        document_id: u64,
78    ) -> Result<Document, Box<dyn std::error::Error>> {
79        let url = format!("{}/documents/{}/", self.base_url, document_id);
80
81        let request_builder = self.prepare_endpoint(Method::GET, url).await?;
82        self.call_endpoint(request_builder).await
83    }
84
85    pub async fn download_document(
86        &self,
87        document_id: u64,
88        original: bool,
89        download_path: &str,
90    ) -> Result<(), Box<dyn std::error::Error>> {
91        let url = format!("{}/documents/{}/download/", self.base_url, document_id);
92        let query_url = format!("{}{}", url, ternary!(original, "?original=true", ""));
93
94        let request_builder = self.prepare_endpoint(Method::GET, query_url).await?;
95        self.call_downloadable_endpoint(request_builder, download_path)
96            .await
97    }
98
99    pub async fn preview_document(
100        &self,
101        document_id: u64,
102        original: bool,
103    ) -> Result<Bytes, Box<dyn std::error::Error>> {
104        let url = format!("{}/documents/{}/preview/", self.base_url, document_id);
105        let query_url = format!("{}{}", url, ternary!(original, "?original=true", ""));
106
107        let request_builder = self.prepare_endpoint(Method::GET, query_url).await?;
108        self.call_binary_endpoint(request_builder).await
109    }
110
111    pub async fn fetch_document_thumbnail(
112        &self,
113        document_id: u64,
114    ) -> Result<String, Box<dyn std::error::Error>> {
115        let url = format!("{}/documents/{}/thumb/", self.base_url, document_id);
116
117        let request_builder = self.prepare_endpoint(Method::GET, url).await?;
118        self.call_endpoint(request_builder).await
119    }
120
121    pub async fn fetch_document_metadata(
122        &self,
123        document_id: u64,
124    ) -> Result<Metadata, Box<dyn std::error::Error>> {
125        let url = format!("{}/documents/{}/metadata/", self.base_url, document_id);
126
127        let request_builder = self.prepare_endpoint(Method::GET, url).await?;
128        self.call_endpoint(request_builder).await
129    }
130
131    pub async fn fetch_document_notes(
132        &self,
133        document_id: u64,
134    ) -> Result<Vec<String>, Box<dyn std::error::Error>> {
135        let url = format!("{}/documents/{}/notes/", self.base_url, document_id);
136
137        let request_builder = self.prepare_endpoint(Method::GET, url).await?;
138        self.call_endpoint(request_builder).await
139    }
140
141    pub async fn fetch_document_share_links(
142        &self,
143        document_id: u64,
144    ) -> Result<Vec<String>, Box<dyn std::error::Error>> {
145        let url = format!("{}/documents/{}/share-links/", self.base_url, document_id);
146
147        let request_builder = self.prepare_endpoint(Method::GET, url).await?;
148        self.call_endpoint(request_builder).await
149    }
150}