Skip to main content

babelforce_manager_sdk/resources/
files.rs

1use crate::error::{map_manager_err, ManagerError};
2use crate::gen::manager::apis::configuration::Configuration;
3use crate::gen::manager::apis::file_api;
4use crate::gen::manager::models;
5use crate::http::{collect_all, fetch_page, Page};
6use crate::retry::{with_retry, RetryPolicy};
7use crate::token::SharedCfg;
8
9/// Stored files — `/api/v2/files` (recordings, prompts and backups).
10pub struct FilesResource {
11    pub(crate) cfg: SharedCfg<Configuration>,
12    pub(crate) retry: RetryPolicy,
13}
14
15impl FilesResource {
16    /// List all files (auto-paginated).
17    pub async fn list_all(&self) -> Result<Vec<models::StoredFile>, ManagerError> {
18        let cfg = self.cfg.get().await?;
19        let cfg = cfg.as_ref();
20        collect_all(&self.retry, map_manager_err, |page| async move {
21            let r = file_api::list_files(cfg, Some(page), None, None, None, None, None, None, None)
22                .await?;
23            Ok((
24                r.items,
25                r.pagination.pages.unwrap_or(1),
26                r.pagination.current.unwrap_or(1),
27            ))
28        })
29        .await
30    }
31
32    /// List one page of files, optionally narrowed to one storage type.
33    pub async fn list_page(
34        &self,
35        page: i32,
36        per_page: Option<i32>,
37        file_type: Option<models::StorageType>,
38    ) -> Result<Page<models::StoredFile>, ManagerError> {
39        let cfg = self.cfg.get().await?;
40        let cfg = cfg.as_ref();
41        fetch_page(&self.retry, map_manager_err, || async move {
42            let r = file_api::list_files(
43                cfg,
44                Some(page),
45                per_page,
46                None,
47                None,
48                file_type,
49                None,
50                None,
51                None,
52            )
53            .await?;
54            Ok((
55                r.items,
56                r.pagination.pages.unwrap_or(1),
57                r.pagination.current.unwrap_or(1),
58                r.pagination.total,
59            ))
60        })
61        .await
62    }
63
64    /// List files of a given storage type (single, non-paginated response).
65    pub async fn list_by_type(
66        &self,
67        file_type: models::StorageType,
68    ) -> Result<Vec<models::StoredFile>, ManagerError> {
69        let cfg = self.cfg.get().await?;
70        let cfg = cfg.as_ref();
71        let r = with_retry(&self.retry, true, || {
72            file_api::list_files_by_type(cfg, file_type)
73        })
74        .await
75        .map_err(map_manager_err)?;
76        Ok(r.items)
77    }
78
79    /// List all backup files.
80    pub async fn backups(&self) -> Result<Vec<models::StoredFile>, ManagerError> {
81        let cfg = self.cfg.get().await?;
82        let cfg = cfg.as_ref();
83        let r = with_retry(&self.retry, true, || file_api::list_backup_files(cfg))
84            .await
85            .map_err(map_manager_err)?;
86        Ok(r.items)
87    }
88
89    /// List all recording files.
90    pub async fn recordings(&self) -> Result<Vec<models::StoredFile>, ManagerError> {
91        let cfg = self.cfg.get().await?;
92        let cfg = cfg.as_ref();
93        let r = with_retry(&self.retry, true, || file_api::list_recording_files(cfg))
94            .await
95            .map_err(map_manager_err)?;
96        Ok(r.items)
97    }
98
99    /// List all prompt files.
100    pub async fn prompts(&self) -> Result<Vec<models::StoredFile>, ManagerError> {
101        let cfg = self.cfg.get().await?;
102        let cfg = cfg.as_ref();
103        let r = with_retry(&self.retry, true, || file_api::list_prompt_files(cfg))
104            .await
105            .map_err(map_manager_err)?;
106        Ok(r.items)
107    }
108
109    /// Get a file by id.
110    pub async fn get(&self, id: &str) -> Result<models::StoredFileItemResponse, ManagerError> {
111        let cfg = self.cfg.get().await?;
112        let cfg = cfg.as_ref();
113        with_retry(&self.retry, true, || file_api::get_file(cfg, id))
114            .await
115            .map_err(map_manager_err)
116    }
117
118    /// Delete a file by id.
119    pub async fn delete(&self, id: &str) -> Result<models::DefaultV2MessageResponse, ManagerError> {
120        let cfg = self.cfg.get().await?;
121        let cfg = cfg.as_ref();
122        with_retry(&self.retry, false, || file_api::delete_file(cfg, id))
123            .await
124            .map_err(map_manager_err)
125    }
126
127    /// Trigger a download for a file by id.
128    ///
129    /// The underlying endpoint redirects to a download link; the generated client discards the
130    /// response body, so this returns `()` once the server-side download has been triggered.
131    /// Use [`bulk_download`](Self::bulk_download) / [`bulk_download_post`](Self::bulk_download_post)
132    /// when you need the actual bytes.
133    pub async fn download(&self, id: &str) -> Result<(), ManagerError> {
134        let cfg = self.cfg.get().await?;
135        let cfg = cfg.as_ref();
136        with_retry(&self.retry, true, || file_api::download_file(cfg, id))
137            .await
138            .map_err(map_manager_err)?;
139        Ok(())
140    }
141
142    /// Bulk-delete files by id. Each `id` must be a valid UUID.
143    pub async fn bulk_delete(
144        &self,
145        ids: Vec<String>,
146    ) -> Result<models::DefaultV2MessageResponse, ManagerError> {
147        let cfg = self.cfg.get().await?;
148        let cfg = cfg.as_ref();
149        let ids = ids
150            .iter()
151            .map(|id| {
152                uuid::Uuid::parse_str(id)
153                    .map_err(|e| ManagerError::InvalidArgument(format!("id {id:?}: {e}")))
154            })
155            .collect::<Result<Vec<_>, _>>()?;
156        let body = models::FileBulkDeleteRequest { ids };
157        with_retry(&self.retry, false, || {
158            file_api::bulk_delete_files(cfg, body.clone())
159        })
160        .await
161        .map_err(map_manager_err)
162    }
163
164    /// Download multiple files as a ZIP archive (GET), returning the raw bytes.
165    pub async fn bulk_download(&self, ids: Vec<String>) -> Result<Vec<u8>, ManagerError> {
166        let cfg = self.cfg.get().await?;
167        let cfg = cfg.as_ref();
168        let ids_joined = ids.join(",");
169        let resp = file_api::get_bulk_file_download(cfg, &ids_joined)
170            .await
171            .map_err(map_manager_err)?;
172        let bytes = resp
173            .bytes()
174            .await
175            .map_err(|e| ManagerError::Network(e.to_string()))?
176            .to_vec();
177        Ok(bytes)
178    }
179
180    /// Download multiple files as a ZIP archive (POST), returning the raw bytes.
181    /// Each `id` must be a valid UUID.
182    pub async fn bulk_download_post(&self, ids: Vec<String>) -> Result<Vec<u8>, ManagerError> {
183        let cfg = self.cfg.get().await?;
184        let cfg = cfg.as_ref();
185        let ids = ids
186            .iter()
187            .map(|id| {
188                uuid::Uuid::parse_str(id)
189                    .map_err(|e| ManagerError::InvalidArgument(format!("id {id:?}: {e}")))
190            })
191            .collect::<Result<Vec<_>, _>>()?;
192        let body = models::FileBulkDownloadRequest { ids };
193        let resp = file_api::post_bulk_file_download(cfg, body)
194            .await
195            .map_err(map_manager_err)?;
196        let bytes = resp
197            .bytes()
198            .await
199            .map_err(|e| ManagerError::Network(e.to_string()))?
200            .to_vec();
201        Ok(bytes)
202    }
203}