Allow retrieval of backup QR on context

This enables being able to get the QR code without needing to have
access to the BackupProvider itself.  This is useful for the JSON-RPC
server.
This commit is contained in:
Floris Bruynooghe
2023-02-16 16:49:20 +01:00
parent 490a14c5ef
commit c48c2af7a1
2 changed files with 39 additions and 5 deletions

View File

@@ -22,6 +22,7 @@ use crate::events::{Event, EventEmitter, EventType, Events};
use crate::key::{DcKey, SignedPublicKey};
use crate::login_param::LoginParam;
use crate::message::{self, MessageState, MsgId};
use crate::qr::Qr;
use crate::quota::QuotaInfo;
use crate::scheduler::Scheduler;
use crate::sql::Sql;
@@ -189,6 +190,10 @@ pub struct InnerContext {
pub(crate) blobdir: PathBuf,
pub(crate) sql: Sql,
pub(crate) last_smeared_timestamp: RwLock<i64>,
/// The global "ongoing" process state.
///
/// This is a global mutex-like state for operations which should be modal in the
/// clients.
running_state: RwLock<RunningState>,
/// Mutex to avoid generating the key for the user more than once.
pub(crate) generating_key_mutex: Mutex<()>,
@@ -228,6 +233,14 @@ pub struct InnerContext {
/// If debug logging is enabled, this contains all neccesary information
pub(crate) debug_logging: RwLock<Option<DebugLogging>>,
/// Qr code for currently running [`BackupProvider`].
///
/// This is only available if a backup export is currently running, it will also be
/// holding the ongoing process while running.
///
/// [`BackupProvider`]: crate::imex::BackupProvider
pub(crate) export_provider: std::sync::Mutex<Option<Qr>>,
}
#[derive(Debug)]
@@ -370,6 +383,7 @@ impl Context {
last_full_folder_scan: Mutex::new(None),
last_error: std::sync::RwLock::new("".to_string()),
debug_logging: RwLock::new(None),
export_provider: std::sync::Mutex::new(None),
};
let ctx = Context {
@@ -563,6 +577,17 @@ impl Context {
}
}
/// Returns the QR-code of the currently running [`BackupProvider`].
///
/// [`BackupProvider`]: crate::imex::BackupProvider
pub fn backup_export_qr(&self) -> Option<Qr> {
self.export_provider
.lock()
.expect("poisoned lock")
.as_ref()
.cloned()
}
/*******************************************************************************
* UI chat/message related API
******************************************************************************/

View File

@@ -118,7 +118,10 @@ impl BackupProvider {
cancel_token,
dbfile,
));
Ok(Self { handle, ticket })
let slf = Self { handle, ticket };
let qr = slf.qr();
*context.export_provider.lock().expect("poisoned lock") = Some(qr);
Ok(slf)
}
/// Creates the provider task.
@@ -128,7 +131,7 @@ impl BackupProvider {
// Generate the token up front: we also use it to encrypt the database.
let token = AuthToken::generate();
context.emit_event(SendProgress::Started.into());
export_database(context, &dbfile, token.to_string())
export_database(context, dbfile, token.to_string())
.await
.context("Database export failed")?;
context.emit_event(SendProgress::DatabaseExported.into());
@@ -171,7 +174,6 @@ impl BackupProvider {
cancel_token: Receiver<()>,
dbfile: PathBuf,
) -> Result<()> {
context.emit_event(SendProgress::ProviderListening.into());
let mut events = provider.subscribe();
let res = loop {
tokio::select! {
@@ -194,7 +196,6 @@ impl BackupProvider {
provider.shutdown();
}
Event::TransferAborted { .. } => {
context.emit_event(SendProgress::Failed.into());
provider.shutdown();
break Err(anyhow!("BackupSender transfer aborted"));
}
@@ -221,7 +222,15 @@ impl BackupProvider {
if let Err(err) = fs::remove_file(&dbfile).await {
error!(context, "Failed to remove database export: {err:#}");
}
context.emit_event(SendProgress::Completed.into());
context
.export_provider
.lock()
.expect("poisoned lock")
.take();
match &res {
Ok(_) => context.emit_event(SendProgress::Completed.into()),
Err(_) => context.emit_event(SendProgress::Failed.into()),
}
context.free_ongoing().await;
res
}