cloudreve_api/api/v4/
share.rs1use crate::api::v4::models::*;
2use crate::api::v4::uri::path_to_uri;
3use crate::api::v4::ApiV4Client;
4use crate::Error;
5use serde_json::Value;
6
7impl ApiV4Client {
9 pub async fn create_share_link(
10 &self,
11 request: &CreateShareLinkRequest,
12 ) -> Result<String, Error> {
13 let uri = path_to_uri(&request.uri);
15 let converted_request = CreateShareLinkRequest {
16 uri,
17 permissions: request.permissions.clone(),
18 is_private: request.is_private,
19 share_view: request.share_view,
20 expire: request.expire,
21 price: request.price,
22 password: request.password.clone(),
23 show_readme: request.show_readme,
24 };
25
26 let response: ApiResponse<String> = self.put("/share", &converted_request).await?;
27 response.data.ok_or_else(|| {
28 Error::InvalidResponse(format!(
29 "API returned error: code={}, msg={}",
30 response.code, response.msg
31 ))
32 })
33 }
34
35 pub async fn list_my_share_links_with_params(
36 &self,
37 page_size: u32,
38 order_by: Option<&str>,
39 order_direction: Option<&str>,
40 next_page_token: Option<&str>,
41 ) -> Result<(Vec<ShareLink>, Option<String>), Error> {
42 let mut query_params = vec![("page_size", page_size.to_string())];
43 if let Some(order_by) = order_by {
44 query_params.push(("order_by", order_by.to_string()));
45 }
46 if let Some(order_direction) = order_direction {
47 query_params.push(("order_direction", order_direction.to_string()));
48 }
49 if let Some(next_page_token) = next_page_token {
50 query_params.push(("next_page_token", next_page_token.to_string()));
51 }
52
53 let query_string = query_params
54 .iter()
55 .map(|(k, v)| format!("{}={}", k, v))
56 .collect::<Vec<_>>()
57 .join("&");
58
59 let endpoint = format!("/share?{}", query_string);
60 let response: ApiResponse<Value> = self.get(&endpoint).await?;
61
62 if let Some(data) = response.data {
63 let shares: Vec<ShareLink> =
64 serde_json::from_value(data.get("shares").unwrap_or(&Value::Array(vec![])).clone())
65 .unwrap_or_default();
66
67 let next_token = data
68 .get("pagination")
69 .and_then(|p| p.get("next_page_token"))
70 .and_then(|t| t.as_str())
71 .map(|s| s.to_string());
72
73 Ok((shares, next_token))
74 } else {
75 Err(Error::InvalidResponse(format!(
77 "API returned error: code={}, msg={}",
78 response.code, response.msg
79 )))
80 }
81 }
82
83 pub async fn list_my_share_links(&self) -> Result<Vec<ShareLink>, Error> {
84 let (shares, _) = self
85 .list_my_share_links_with_params(50, None, None, None)
86 .await?;
87 Ok(shares)
88 }
89
90 pub async fn edit_share_link(
91 &self,
92 share_id: &str,
93 request: &EditShareLinkRequest,
94 ) -> Result<ShareLink, Error> {
95 let response: ApiResponse<ShareLink> =
96 self.post(&format!("/share/{}", share_id), request).await?;
97 response.data.ok_or_else(|| {
98 Error::InvalidResponse(format!(
99 "API returned error: code={}, msg={}",
100 response.code, response.msg
101 ))
102 })
103 }
104
105 pub async fn delete_share_link(&self, share_id: &str) -> Result<(), Error> {
106 let _: ApiResponse<Value> = self.delete(&format!("/share/{}", share_id)).await?;
107 Ok(())
108 }
109
110 pub async fn get_share_link_info(
111 &self,
112 share_id: &str,
113 password: Option<&str>,
114 count_views: Option<bool>,
115 owner_extended: Option<bool>,
116 ) -> Result<ShareLink, Error> {
117 let mut query_params = Vec::new();
118 if let Some(password) = password {
119 query_params.push(format!("password={}", password));
120 }
121 if let Some(count_views) = count_views {
122 query_params.push(format!("count_views={}", count_views));
123 }
124 if let Some(owner_extended) = owner_extended {
125 query_params.push(format!("owner_extended={}", owner_extended));
126 }
127
128 let query_string = if !query_params.is_empty() {
129 format!("?{}", query_params.join("&"))
130 } else {
131 String::new()
132 };
133
134 let endpoint = format!("/share/info/{}{}", share_id, query_string);
135 let response: ApiResponse<Value> = self.get(&endpoint).await?;
136
137 if let Some(data) = response.data {
138 let share: ShareLink = serde_json::from_value(data).unwrap();
139 Ok(share)
140 } else {
141 Err(Error::InvalidResponse("No data in response".to_string()))
142 }
143 }
144
145 pub async fn report_abuse(&self, share_id: &str, reason: &str) -> Result<(), Error> {
146 let request = AbuseReportRequest { reason };
147 let _: ApiResponse<()> = self
148 .post(&format!("/share/{}/report", share_id), &request)
149 .await?;
150 Ok(())
151 }
152}