1use crate::Error;
4use crate::api::v3::ApiV3Client;
5use crate::api::v3::models::*;
6
7impl ApiV3Client {
8 pub async fn search_files(&self, keyword: &str, path: &str) -> Result<DirectoryList, Error> {
13 let scope = if path.is_empty() { "/" } else { path };
14 let endpoint = format!(
15 "/file/search/keywords/{}?path={}",
16 urlencoding::encode(keyword),
17 urlencoding::encode(scope)
18 );
19 let response: ApiResponse<DirectoryList> = self.get(&endpoint).await?;
20 match response.data {
21 Some(list) => Ok(list),
22 None => Err(Error::Api {
23 code: response.code,
24 message: response.msg,
25 }),
26 }
27 }
28
29 pub async fn upload_file(
30 &self,
31 request: &UploadFileRequest<'_>,
32 ) -> Result<UploadSession, Error> {
33 let response: ApiResponse<UploadSession> = self.put("/file/upload", request).await?;
34 match response.data {
35 Some(session) => Ok(session),
36 None => Err(Error::Api {
37 code: response.code,
38 message: response.msg,
39 }),
40 }
41 }
42
43 pub async fn upload_chunk(
44 &self,
45 session_id: &str,
46 chunk_index: u32,
47 data: Vec<u8>,
48 ) -> Result<(), Error> {
49 let url = self.get_url(&format!("/file/upload/{}/{}", session_id, chunk_index));
50 let mut request = self.http_client.post(&url).body(data);
51
52 if let Some(cookie) = &self.session_cookie {
53 request = request.header("Cookie", format!("cloudreve-session={}", cookie));
54 }
55
56 let response = request.send().await?;
57 let status = response.status();
58 let raw_text = response.text().await.unwrap_or_default();
59
60 if let Ok(api_response) = serde_json::from_str::<ApiResponse<serde_json::Value>>(&raw_text)
61 {
62 return match api_response.code {
63 0 => Ok(()),
64 code => Err(Error::Api {
65 code,
66 message: api_response.msg,
67 }),
68 };
69 }
70
71 if status.is_success() {
72 Ok(())
73 } else {
74 Err(Error::Api {
75 code: status.as_u16() as i32,
76 message: format!("Upload failed with status: {}", status),
77 })
78 }
79 }
80
81 pub async fn update_file_content(&self, id: &str, content: Vec<u8>) -> Result<(), Error> {
90 let url = self.get_url(&format!("/file/update/{}", urlencoding::encode(id)));
91 let mut request = self
92 .http_client
93 .put(&url)
94 .header("Content-Type", "application/octet-stream")
95 .header("Content-Length", content.len().to_string())
96 .body(content);
97
98 if let Some(cookie) = &self.session_cookie {
99 request = request.header("Cookie", format!("cloudreve-session={}", cookie));
100 }
101
102 let response = request.send().await?;
103 let status = response.status();
104 let raw_text = response.text().await.unwrap_or_default();
105
106 if let Ok(api_response) = serde_json::from_str::<ApiResponse<serde_json::Value>>(&raw_text)
107 {
108 return match api_response.code {
109 0 => Ok(()),
110 code => Err(Error::Api {
111 code,
112 message: api_response.msg,
113 }),
114 };
115 }
116
117 Err(Error::Api {
118 code: status.as_u16() as i32,
119 message: raw_text.trim().to_string(),
120 })
121 }
122
123 pub async fn delete_upload_session(&self, session_id: &str) -> Result<(), Error> {
135 let response: ApiResponse<()> = self
136 .delete(&format!("/file/upload/{}", urlencoding::encode(session_id)))
137 .await?;
138 match response.code {
139 0 => Ok(()),
140 code => Err(Error::Api {
141 code,
142 message: response.msg,
143 }),
144 }
145 }
146
147 pub async fn delete_all_upload_sessions(&self) -> Result<(), Error> {
155 let response: ApiResponse<()> = self.delete("/file/upload").await?;
156 match response.code {
157 0 => Ok(()),
158 code => Err(Error::Api {
159 code,
160 message: response.msg,
161 }),
162 }
163 }
164
165 pub async fn download_file(&self, id: &str) -> Result<DownloadUrl, Error> {
166 let response: ApiResponse<String> = self
168 .put(&format!("/file/download/{}", id), &serde_json::json!({}))
169 .await?;
170 match response.data {
171 Some(url_path) => Ok(DownloadUrl { url: url_path }),
172 None => Err(Error::Api {
173 code: response.code,
174 message: response.msg,
175 }),
176 }
177 }
178
179 pub async fn get_file_source(
180 &self,
181 request: &FileSourceRequest,
182 ) -> Result<Vec<FileSource>, Error> {
183 let response: ApiResponse<Vec<FileSource>> = self.post("/file/source", request).await?;
184 match response.data {
185 Some(sources) => Ok(sources),
186 None => Err(Error::Api {
187 code: response.code,
188 message: response.msg,
189 }),
190 }
191 }
192
193 pub async fn preview_file(&self, id: &str) -> Result<Vec<u8>, Error> {
200 self.fetch_binary(&format!("/file/preview/{}", urlencoding::encode(id)))
201 .await
202 }
203
204 pub async fn get_thumbnail(&self, id: &str) -> Result<Vec<u8>, Error> {
208 self.fetch_binary(&format!("/file/thumb/{}", urlencoding::encode(id)))
209 .await
210 }
211
212 async fn fetch_binary(&self, endpoint: &str) -> Result<Vec<u8>, Error> {
217 let url = self.get_url(endpoint);
218 let mut request = self.http_client.get(&url);
219 if let Some(cookie) = &self.session_cookie {
220 request = request.header("Cookie", format!("cloudreve-session={}", cookie));
221 }
222
223 let response = request.send().await?;
224 let status = response.status();
225 let bytes = response.bytes().await?.to_vec();
226
227 if let Ok(api_response) = serde_json::from_slice::<ApiResponse<serde_json::Value>>(&bytes)
228 && api_response.code != 0
229 {
230 return Err(Error::Api {
231 code: api_response.code,
232 message: api_response.msg,
233 });
234 }
235
236 if !status.is_success() {
237 return Err(Error::Api {
238 code: status.as_u16() as i32,
239 message: String::from_utf8_lossy(&bytes).trim().to_string(),
240 });
241 }
242
243 Ok(bytes)
244 }
245
246 pub async fn create_file(&self, request: &CreateFileRequest<'_>) -> Result<(), Error> {
247 let response: ApiResponse<()> = self.post("/file/create", request).await?;
248 if response.code == 0 {
249 Ok(())
250 } else {
251 Err(Error::Api {
252 code: response.code,
253 message: response.msg,
254 })
255 }
256 }
257}