1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//! Aria2-related API endpoints for Cloudreve API v3
use crate::Error;
use crate::api::v3::ApiV3Client;
use crate::api::v3::models::*;
impl ApiV3Client {
/// Create one or more aria2 offline-download tasks.
///
/// Cloudreve v3 returns the created tasks in `data` (an array of objects whose exact
/// shape varies by version, e.g. with/without `gid`), so we accept any JSON payload.
/// Callers only need success/failure here — use [`Self::list_downloading`] to follow
/// the new tasks afterwards.
pub async fn create_download(&self, request: &Aria2CreateRequest<'_>) -> Result<(), Error> {
let response: ApiResponse<serde_json::Value> = self.post("/aria2/url", request).await?;
if response.code == 0 {
Ok(())
} else {
Err(Error::Api {
code: response.code,
message: response.msg,
})
}
}
/// List in-flight aria2 tasks (`GET /aria2/downloading`).
///
/// Cloudreve v3 returns a flat array (no pagination wrapper). When there are no active
/// downloads the response carries `code: 0, data: null`, which deserialises to an empty
/// vector here.
pub async fn list_downloading(&self) -> Result<Vec<Aria2DownloadingTask>, Error> {
let response: ApiResponse<Vec<Aria2DownloadingTask>> =
self.get("/aria2/downloading").await?;
if response.code != 0 {
return Err(Error::Api {
code: response.code,
message: response.msg,
});
}
Ok(response.data.unwrap_or_default())
}
/// List finished aria2 tasks (`GET /aria2/finished`).
///
/// Cloudreve v3's response is a flat array; the legacy `/aria2/finished/:page` path
/// segment was removed years ago and no longer exists on supported servers. Returns
/// an empty vector when the server replies with `data: null`.
pub async fn list_finished(&self) -> Result<Vec<Aria2FinishedTask>, Error> {
let response: ApiResponse<Vec<Aria2FinishedTask>> = self.get("/aria2/finished").await?;
if response.code != 0 {
return Err(Error::Api {
code: response.code,
message: response.msg,
});
}
Ok(response.data.unwrap_or_default())
}
/// Cancel an aria2 task by GID.
pub async fn delete_task(&self, gid: &str) -> Result<(), Error> {
let response: ApiResponse<()> = self.delete(&format!("/aria2/task/{}", gid)).await?;
if response.code == 0 {
Ok(())
} else {
Err(Error::Api {
code: response.code,
message: response.msg,
})
}
}
}