lb_rs/
blocking.rs

1use std::collections::HashMap;
2use std::path::PathBuf;
3use std::sync::Arc;
4
5use tokio::runtime::Runtime;
6use tokio::sync::broadcast::Receiver;
7use uuid::Uuid;
8
9use crate::model::account::{Account, Username};
10use crate::model::api::{
11    AccountFilter, AccountIdentifier, AccountInfo, AdminFileInfoResponse, AdminSetUserTierInfo,
12    AdminValidateAccount, AdminValidateServer, ServerIndex, StripeAccountTier, SubscriptionInfo,
13};
14use crate::model::core_config::Config;
15use crate::model::crypto::DecryptedDocument;
16use crate::model::errors::{LbResult, Warning};
17use crate::model::file::{File, ShareMode};
18use crate::model::file_metadata::{DocumentHmac, FileType};
19use crate::model::path_ops::Filter;
20use crate::service::activity::RankingWeights;
21use crate::service::events::Event;
22use crate::service::import_export::{ExportFileInfo, ImportStatus};
23use crate::service::sync::{SyncProgress, SyncStatus};
24use crate::service::usage::{UsageItemMetric, UsageMetrics};
25use crate::subscribers::search::{SearchConfig, SearchResult};
26use crate::subscribers::status::Status;
27
28#[derive(Clone)]
29pub struct Lb {
30    lb: crate::Lb,
31    rt: Arc<Runtime>,
32}
33
34impl Lb {
35    pub fn init(config: Config) -> LbResult<Self> {
36        let rt = Arc::new(Runtime::new().unwrap());
37        let lb = rt.block_on(crate::Lb::init(config))?;
38        Ok(Self { rt, lb })
39    }
40
41    pub fn create_account(
42        &self, username: &str, api_url: &str, welcome_doc: bool,
43    ) -> LbResult<Account> {
44        self.rt
45            .block_on(self.lb.create_account(username, api_url, welcome_doc))
46    }
47
48    pub fn import_account(&self, key: &str, api_url: Option<&str>) -> LbResult<Account> {
49        self.rt.block_on(self.lb.import_account(key, api_url))
50    }
51
52    pub fn export_account_private_key(&self) -> LbResult<String> {
53        self.lb.export_account_private_key_v1()
54    }
55
56    pub fn export_account_phrase(&self) -> LbResult<String> {
57        self.lb.export_account_phrase()
58    }
59
60    pub fn export_account_qr(&self) -> LbResult<Vec<u8>> {
61        self.lb.export_account_qr()
62    }
63
64    pub fn get_account(&self) -> LbResult<&Account> {
65        self.lb.get_account()
66    }
67
68    pub fn get_config(&self) -> Config {
69        self.lb.config.clone()
70    }
71
72    pub fn create_file(&self, name: &str, parent: &Uuid, file_type: FileType) -> LbResult<File> {
73        self.rt
74            .block_on(self.lb.create_file(name, parent, file_type))
75    }
76
77    pub fn safe_write(
78        &self, id: Uuid, old_hmac: Option<DocumentHmac>, content: Vec<u8>,
79    ) -> LbResult<DocumentHmac> {
80        self.rt.block_on(self.lb.safe_write(id, old_hmac, content))
81    }
82
83    pub fn write_document(&self, id: Uuid, content: &[u8]) -> LbResult<()> {
84        self.rt.block_on(self.lb.write_document(id, content))
85    }
86
87    pub fn get_root(&self) -> LbResult<File> {
88        self.rt.block_on(self.lb.root())
89    }
90
91    pub fn get_children(&self, id: &Uuid) -> LbResult<Vec<File>> {
92        self.rt.block_on(self.lb.get_children(id))
93    }
94
95    pub fn get_and_get_children_recursively(&self, id: &Uuid) -> LbResult<Vec<File>> {
96        self.rt
97            .block_on(self.lb.get_and_get_children_recursively(id))
98    }
99
100    pub fn get_file_by_id(&self, id: Uuid) -> LbResult<File> {
101        self.rt.block_on(self.lb.get_file_by_id(id))
102    }
103
104    pub fn delete_file(&self, id: &Uuid) -> LbResult<()> {
105        self.rt.block_on(self.lb.delete(id))
106    }
107
108    pub fn read_document(&self, id: Uuid, user_activity: bool) -> LbResult<DecryptedDocument> {
109        self.rt.block_on(self.lb.read_document(id, user_activity))
110    }
111
112    pub fn read_document_with_hmac(
113        &self, id: Uuid, user_activity: bool,
114    ) -> LbResult<(Option<DocumentHmac>, DecryptedDocument)> {
115        self.rt
116            .block_on(self.lb.read_document_with_hmac(id, user_activity))
117    }
118
119    pub fn list_metadatas(&self) -> LbResult<Vec<File>> {
120        self.rt.block_on(self.lb.list_metadatas())
121    }
122
123    pub fn rename_file(&self, id: &Uuid, new_name: &str) -> LbResult<()> {
124        self.rt.block_on(self.lb.rename_file(id, new_name))
125    }
126
127    pub fn move_file(&self, id: &Uuid, new_parent: &Uuid) -> LbResult<()> {
128        self.rt.block_on(self.lb.move_file(id, new_parent))
129    }
130
131    pub fn share_file(&self, id: Uuid, username: &str, mode: ShareMode) -> LbResult<()> {
132        self.rt.block_on(self.lb.share_file(id, username, mode))
133    }
134
135    pub fn get_pending_shares(&self) -> LbResult<Vec<File>> {
136        self.rt.block_on(self.lb.get_pending_shares())
137    }
138
139    pub fn get_pending_share_files(&self) -> LbResult<Vec<File>> {
140        self.rt.block_on(self.lb.get_pending_share_files())
141    }
142
143    pub fn delete_pending_share(&self, id: &Uuid) -> LbResult<()> {
144        self.rt.block_on(async { self.lb.reject_share(id).await })
145    }
146
147    pub fn create_link_at_path(&self, path_and_name: &str, target_id: Uuid) -> LbResult<File> {
148        self.rt
149            .block_on(self.lb.create_link_at_path(path_and_name, target_id))
150    }
151
152    pub fn create_at_path(&self, path_and_name: &str) -> LbResult<File> {
153        self.rt.block_on(self.lb.create_at_path(path_and_name))
154    }
155
156    pub fn get_by_path(&self, path: &str) -> LbResult<File> {
157        self.rt.block_on(self.lb.get_by_path(path))
158    }
159
160    pub fn get_path_by_id(&self, id: Uuid) -> LbResult<String> {
161        self.rt.block_on(self.lb.get_path_by_id(id))
162    }
163
164    pub fn list_paths(&self, filter: Option<Filter>) -> LbResult<Vec<String>> {
165        self.rt.block_on(self.lb.list_paths(filter))
166    }
167
168    pub fn get_local_changes(&self) -> LbResult<Vec<Uuid>> {
169        Ok(self.rt.block_on(self.lb.local_changes()))
170    }
171
172    pub fn calculate_work(&self) -> LbResult<SyncStatus> {
173        self.rt.block_on(self.lb.calculate_work())
174    }
175
176    pub fn sync(&self, f: Option<Box<dyn Fn(SyncProgress) + Send>>) -> LbResult<SyncStatus> {
177        self.rt.block_on(self.lb.sync(f))
178    }
179
180    pub fn get_last_synced(&self) -> LbResult<i64> {
181        self.rt.block_on(async {
182            let tx = self.lb.ro_tx().await;
183            let db = tx.db();
184            Ok(db.last_synced.get().copied().unwrap_or(0))
185        })
186    }
187
188    pub fn get_last_synced_human_string(&self) -> LbResult<String> {
189        self.rt.block_on(self.lb.get_last_synced_human())
190    }
191
192    pub fn get_timestamp_human_string(&self, timestamp: i64) -> String {
193        self.lb.get_timestamp_human_string(timestamp)
194    }
195
196    pub fn suggested_docs(&self, settings: RankingWeights) -> LbResult<Vec<Uuid>> {
197        self.rt.block_on(self.lb.suggested_docs(settings))
198    }
199
200    pub fn clear_suggested(&self) -> LbResult<()> {
201        self.rt.block_on(self.lb.clear_suggested())
202    }
203
204    pub fn clear_suggested_id(&self, target_id: Uuid) -> LbResult<()> {
205        self.rt.block_on(self.lb.clear_suggested_id(target_id))
206    }
207
208    // TODO: examine why the old get_usage does a bunch of things
209    pub fn get_usage(&self) -> LbResult<UsageMetrics> {
210        self.rt.block_on(self.lb.get_usage())
211    }
212
213    pub fn get_uncompressed_usage_breakdown(&self) -> LbResult<HashMap<Uuid, usize>> {
214        self.rt.block_on(self.lb.get_uncompressed_usage_breakdown())
215    }
216
217    pub fn get_uncompressed_usage(&self) -> LbResult<UsageItemMetric> {
218        self.rt.block_on(self.lb.get_uncompressed_usage())
219    }
220
221    pub fn import_files<F: Fn(ImportStatus)>(
222        &self, sources: &[PathBuf], dest: Uuid, update_status: &F,
223    ) -> LbResult<()> {
224        self.rt
225            .block_on(self.lb.import_files(sources, dest, update_status))
226    }
227
228    pub fn export_files(
229        &self, id: Uuid, dest: PathBuf, edit: bool,
230        export_progress: &Option<Box<dyn Fn(ExportFileInfo)>>,
231    ) -> LbResult<()> {
232        self.rt
233            .block_on(self.lb.export_file(id, dest, edit, export_progress))
234    }
235
236    pub fn search_file_paths(&self, input: &str) -> LbResult<Vec<SearchResult>> {
237        self.rt
238            .block_on(async { self.lb.search(input, SearchConfig::Paths).await })
239    }
240
241    pub fn search(&self, input: &str, cfg: SearchConfig) -> LbResult<Vec<SearchResult>> {
242        self.rt.block_on(self.lb.search(input, cfg))
243    }
244
245    pub fn validate(&self) -> LbResult<Vec<Warning>> {
246        self.rt.block_on(self.lb.test_repo_integrity())
247    }
248
249    pub fn upgrade_account_stripe(&self, account_tier: StripeAccountTier) -> LbResult<()> {
250        self.rt
251            .block_on(self.lb.upgrade_account_stripe(account_tier))
252    }
253
254    pub fn upgrade_account_google_play(
255        &self, purchase_token: &str, account_id: &str,
256    ) -> LbResult<()> {
257        self.rt.block_on(
258            self.lb
259                .upgrade_account_google_play(purchase_token, account_id),
260        )
261    }
262
263    pub fn upgrade_account_app_store(
264        &self, original_transaction_id: String, app_account_token: String,
265    ) -> LbResult<()> {
266        self.rt.block_on(
267            self.lb
268                .upgrade_account_app_store(original_transaction_id, app_account_token),
269        )
270    }
271
272    pub fn cancel_subscription(&self) -> LbResult<()> {
273        self.rt.block_on(self.lb.cancel_subscription())
274    }
275
276    pub fn get_subscription_info(&self) -> LbResult<Option<SubscriptionInfo>> {
277        self.rt.block_on(self.lb.get_subscription_info())
278    }
279
280    pub fn delete_account(&self) -> LbResult<()> {
281        self.rt.block_on(self.lb.delete_account())
282    }
283
284    pub fn admin_disappear_account(&self, username: &str) -> LbResult<()> {
285        self.rt.block_on(self.lb.disappear_account(username))
286    }
287
288    pub fn admin_disappear_file(&self, id: Uuid) -> LbResult<()> {
289        self.rt.block_on(self.lb.disappear_file(id))
290    }
291
292    pub fn admin_list_users(&self, filter: Option<AccountFilter>) -> LbResult<Vec<Username>> {
293        self.rt.block_on(self.lb.list_users(filter))
294    }
295
296    pub fn admin_get_account_info(&self, identifier: AccountIdentifier) -> LbResult<AccountInfo> {
297        self.rt.block_on(self.lb.get_account_info(identifier))
298    }
299
300    pub fn admin_validate_account(&self, username: &str) -> LbResult<AdminValidateAccount> {
301        self.rt.block_on(self.lb.validate_account(username))
302    }
303
304    pub fn admin_validate_server(&self) -> LbResult<AdminValidateServer> {
305        self.rt.block_on(self.lb.validate_server())
306    }
307
308    pub fn admin_file_info(&self, id: Uuid) -> LbResult<AdminFileInfoResponse> {
309        self.rt.block_on(self.lb.file_info(id))
310    }
311
312    pub fn admin_rebuild_index(&self, index: ServerIndex) -> LbResult<()> {
313        self.rt.block_on(self.lb.rebuild_index(index))
314    }
315
316    pub fn admin_set_user_tier(&self, username: &str, info: AdminSetUserTierInfo) -> LbResult<()> {
317        self.rt.block_on(self.lb.set_user_tier(username, info))
318    }
319
320    pub fn subscribe(&self) -> Receiver<Event> {
321        self.lb.subscribe()
322    }
323
324    pub fn status(&self) -> Status {
325        self.rt.block_on(self.lb.status())
326    }
327
328    pub fn debug_info(&self, os_info: String) -> String {
329        self.rt
330            .block_on(self.lb.debug_info(os_info))
331            .unwrap_or_else(|e| format!("failed to produce debug info: {:?}", e.to_string()))
332    }
333}