use crate::Error;
use crate::api::v3::ApiV3Client;
use crate::api::v3::models::*;
impl ApiV3Client {
pub async fn search_files(&self, keyword: &str, path: &str) -> Result<DirectoryList, Error> {
let scope = if path.is_empty() { "/" } else { path };
let endpoint = format!(
"/file/search/keywords/{}?path={}",
urlencoding::encode(keyword),
urlencoding::encode(scope)
);
let response: ApiResponse<DirectoryList> = self.get(&endpoint).await?;
match response.data {
Some(list) => Ok(list),
None => Err(Error::Api {
code: response.code,
message: response.msg,
}),
}
}
pub async fn upload_file(
&self,
request: &UploadFileRequest<'_>,
) -> Result<UploadSession, Error> {
let response: ApiResponse<UploadSession> = self.put("/file/upload", request).await?;
match response.data {
Some(session) => Ok(session),
None => Err(Error::Api {
code: response.code,
message: response.msg,
}),
}
}
pub async fn upload_chunk(
&self,
session_id: &str,
chunk_index: u32,
data: Vec<u8>,
) -> Result<(), Error> {
let url = self.get_url(&format!("/file/upload/{}/{}", session_id, chunk_index));
let mut request = self.http_client.post(&url).body(data);
if let Some(cookie) = &self.session_cookie {
request = request.header("Cookie", format!("cloudreve-session={}", cookie));
}
let response = request.send().await?;
let status = response.status();
let raw_text = response.text().await.unwrap_or_default();
if let Ok(api_response) = serde_json::from_str::<ApiResponse<serde_json::Value>>(&raw_text)
{
return match api_response.code {
0 => Ok(()),
code => Err(Error::Api {
code,
message: api_response.msg,
}),
};
}
if status.is_success() {
Ok(())
} else {
Err(Error::Api {
code: status.as_u16() as i32,
message: format!("Upload failed with status: {}", status),
})
}
}
pub async fn update_file_content(&self, id: &str, content: Vec<u8>) -> Result<(), Error> {
let url = self.get_url(&format!("/file/update/{}", urlencoding::encode(id)));
let mut request = self
.http_client
.put(&url)
.header("Content-Type", "application/octet-stream")
.header("Content-Length", content.len().to_string())
.body(content);
if let Some(cookie) = &self.session_cookie {
request = request.header("Cookie", format!("cloudreve-session={}", cookie));
}
let response = request.send().await?;
let status = response.status();
let raw_text = response.text().await.unwrap_or_default();
if let Ok(api_response) = serde_json::from_str::<ApiResponse<serde_json::Value>>(&raw_text)
{
return match api_response.code {
0 => Ok(()),
code => Err(Error::Api {
code,
message: api_response.msg,
}),
};
}
Err(Error::Api {
code: status.as_u16() as i32,
message: raw_text.trim().to_string(),
})
}
pub async fn delete_upload_session(&self, session_id: &str) -> Result<(), Error> {
let response: ApiResponse<()> = self
.delete(&format!("/file/upload/{}", urlencoding::encode(session_id)))
.await?;
match response.code {
0 => Ok(()),
code => Err(Error::Api {
code,
message: response.msg,
}),
}
}
pub async fn delete_all_upload_sessions(&self) -> Result<(), Error> {
let response: ApiResponse<()> = self.delete("/file/upload").await?;
match response.code {
0 => Ok(()),
code => Err(Error::Api {
code,
message: response.msg,
}),
}
}
pub async fn download_file(&self, id: &str) -> Result<DownloadUrl, Error> {
let response: ApiResponse<String> = self
.put(&format!("/file/download/{}", id), &serde_json::json!({}))
.await?;
match response.data {
Some(url_path) => Ok(DownloadUrl { url: url_path }),
None => Err(Error::Api {
code: response.code,
message: response.msg,
}),
}
}
pub async fn get_file_source(
&self,
request: &FileSourceRequest,
) -> Result<Vec<FileSource>, Error> {
let response: ApiResponse<Vec<FileSource>> = self.post("/file/source", request).await?;
match response.data {
Some(sources) => Ok(sources),
None => Err(Error::Api {
code: response.code,
message: response.msg,
}),
}
}
pub async fn preview_file(&self, id: &str) -> Result<Vec<u8>, Error> {
self.fetch_binary(&format!("/file/preview/{}", urlencoding::encode(id)))
.await
}
pub async fn get_thumbnail(&self, id: &str) -> Result<Vec<u8>, Error> {
self.fetch_binary(&format!("/file/thumb/{}", urlencoding::encode(id)))
.await
}
async fn fetch_binary(&self, endpoint: &str) -> Result<Vec<u8>, Error> {
let url = self.get_url(endpoint);
let mut request = self.http_client.get(&url);
if let Some(cookie) = &self.session_cookie {
request = request.header("Cookie", format!("cloudreve-session={}", cookie));
}
let response = request.send().await?;
let status = response.status();
let bytes = response.bytes().await?.to_vec();
if let Ok(api_response) = serde_json::from_slice::<ApiResponse<serde_json::Value>>(&bytes)
&& api_response.code != 0
{
return Err(Error::Api {
code: api_response.code,
message: api_response.msg,
});
}
if !status.is_success() {
return Err(Error::Api {
code: status.as_u16() as i32,
message: String::from_utf8_lossy(&bytes).trim().to_string(),
});
}
Ok(bytes)
}
pub async fn create_file(&self, request: &CreateFileRequest<'_>) -> Result<(), Error> {
let response: ApiResponse<()> = self.post("/file/create", request).await?;
if response.code == 0 {
Ok(())
} else {
Err(Error::Api {
code: response.code,
message: response.msg,
})
}
}
}