lb_rs/
blocking.rs

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