Skip to main content

cloudreve_api/api/v4/
share.rs

1use crate::Error;
2use crate::api::v4::ApiV4Client;
3use crate::api::v4::models::*;
4use crate::api::v4::uri::path_to_uri;
5use serde_json::Value;
6
7/// Share management methods
8impl ApiV4Client {
9    pub async fn create_share_link(
10        &self,
11        request: &CreateShareLinkRequest,
12    ) -> Result<String, Error> {
13        // Convert URI format internally
14        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            // Return error if API returned an error response
76            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}