Skip to main content

lb_rs/
blocking.rs

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