mirror of
https://github.com/chatmail/core.git
synced 2026-04-02 05:22:14 +03:00
Compare commits
1 Commits
v1.157.2
...
simon/disa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ca294c434 |
@@ -210,16 +210,16 @@ impl CommandApi {
|
||||
/// Get a list of all configured accounts.
|
||||
async fn get_all_accounts(&self) -> Result<Vec<Account>> {
|
||||
let mut accounts = Vec::new();
|
||||
for id in self.accounts.read().await.get_all() {
|
||||
let context_option = self.accounts.read().await.get_account(id);
|
||||
if let Some(ctx) = context_option {
|
||||
accounts.push(Account::from_context(&ctx, id).await?)
|
||||
}
|
||||
let manager = self.accounts.read().await;
|
||||
for id in manager.get_all() {
|
||||
accounts.push(Account::load(&manager, id).await?)
|
||||
}
|
||||
Ok(accounts)
|
||||
}
|
||||
|
||||
/// Starts background tasks for all accounts.
|
||||
///
|
||||
/// Acounts with `disable_background_io` are not started, unless the account is the selected one
|
||||
async fn start_io_for_all_accounts(&self) -> Result<()> {
|
||||
self.accounts.write().await.start_io().await;
|
||||
Ok(())
|
||||
@@ -236,6 +236,8 @@ impl CommandApi {
|
||||
/// The `AccountsBackgroundFetchDone` event is emitted at the end even in case of timeout.
|
||||
/// Process all events until you get this one and you can safely return to the background
|
||||
/// without forgetting to create notifications caused by timing race conditions.
|
||||
///
|
||||
/// Acounts with `disable_background_io` are not fetched
|
||||
async fn accounts_background_fetch(&self, timeout_in_seconds: f64) -> Result<()> {
|
||||
self.accounts
|
||||
.write()
|
||||
@@ -245,6 +247,22 @@ impl CommandApi {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set disable_background_io for an account, when enabled,
|
||||
/// io is stopped unless the account is selected and background fetch is also disabled for the account
|
||||
///
|
||||
/// This automatically stops/starts io when account is in the background
|
||||
pub async fn set_disable_background_io(
|
||||
&self,
|
||||
account_id: u32,
|
||||
disable_background_io: bool,
|
||||
) -> Result<()> {
|
||||
self.accounts
|
||||
.write()
|
||||
.await
|
||||
.set_disable_background_io(account_id, disable_background_io)
|
||||
.await
|
||||
}
|
||||
|
||||
// ---------------------------------------------
|
||||
// Methods that work on individual accounts
|
||||
// ---------------------------------------------
|
||||
@@ -265,15 +283,8 @@ impl CommandApi {
|
||||
|
||||
/// Get top-level info for an account.
|
||||
async fn get_account_info(&self, account_id: u32) -> Result<Account> {
|
||||
let context_option = self.accounts.read().await.get_account(account_id);
|
||||
if let Some(ctx) = context_option {
|
||||
Ok(Account::from_context(&ctx, account_id).await?)
|
||||
} else {
|
||||
Err(anyhow!(
|
||||
"account with id {} doesn't exist anymore",
|
||||
account_id
|
||||
))
|
||||
}
|
||||
let manager = &self.accounts.read().await;
|
||||
Account::load(manager, account_id).await
|
||||
}
|
||||
|
||||
/// Get the combined filesize of an account in bytes
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use anyhow::Result;
|
||||
use anyhow::{anyhow, Result};
|
||||
use deltachat::config::Config;
|
||||
use deltachat::contact::{Contact, ContactId};
|
||||
use serde::Serialize;
|
||||
@@ -17,29 +17,43 @@ pub enum Account {
|
||||
// size: u32,
|
||||
profile_image: Option<String>, // TODO: This needs to be converted to work with blob http server.
|
||||
color: String,
|
||||
|
||||
/// Account IO is disabled when this account is not selected
|
||||
///
|
||||
/// this means IO is stopped unless this account is selected
|
||||
/// and background fetch is also disabled for this account
|
||||
background_io_disabled: bool,
|
||||
},
|
||||
#[serde(rename_all = "camelCase")]
|
||||
Unconfigured { id: u32 },
|
||||
}
|
||||
|
||||
impl Account {
|
||||
pub async fn from_context(ctx: &deltachat::context::Context, id: u32) -> Result<Self> {
|
||||
if ctx.is_configured().await? {
|
||||
let display_name = ctx.get_config(Config::Displayname).await?;
|
||||
let addr = ctx.get_config(Config::Addr).await?;
|
||||
let profile_image = ctx.get_config(Config::Selfavatar).await?;
|
||||
let color = color_int_to_hex_string(
|
||||
Contact::get_by_id(ctx, ContactId::SELF).await?.get_color(),
|
||||
);
|
||||
Ok(Account::Configured {
|
||||
id,
|
||||
display_name,
|
||||
addr,
|
||||
profile_image,
|
||||
color,
|
||||
})
|
||||
pub async fn load(accounts: &deltachat::accounts::Accounts, id: u32) -> Result<Self> {
|
||||
if let Some(ctx) = &accounts.get_account(id) {
|
||||
if ctx.is_configured().await? {
|
||||
let display_name = ctx.get_config(Config::Displayname).await?;
|
||||
let addr = ctx.get_config(Config::Addr).await?;
|
||||
let profile_image = ctx.get_config(Config::Selfavatar).await?;
|
||||
let color = color_int_to_hex_string(
|
||||
Contact::get_by_id(ctx, ContactId::SELF).await?.get_color(),
|
||||
);
|
||||
Ok(Account::Configured {
|
||||
id: ctx.get_id(),
|
||||
display_name,
|
||||
addr,
|
||||
profile_image,
|
||||
color,
|
||||
background_io_disabled: accounts.get_disable_background_io(id).unwrap_or(false),
|
||||
})
|
||||
} else {
|
||||
Ok(Account::Unconfigured { id })
|
||||
}
|
||||
} else {
|
||||
Ok(Account::Unconfigured { id })
|
||||
Err(anyhow!(
|
||||
"account with id {} doesn't exist anymore",
|
||||
id
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,8 +108,21 @@ impl Accounts {
|
||||
|
||||
/// Selects the given account.
|
||||
pub async fn select_account(&mut self, id: u32) -> Result<()> {
|
||||
let previous_account_id = self.config.get_selected_account();
|
||||
if let Some(true) = self.config.get_disable_background_io(previous_account_id) {
|
||||
if let Some(previous_account_ctx) = self.get_account(previous_account_id) {
|
||||
previous_account_ctx.stop_io().await;
|
||||
}
|
||||
}
|
||||
|
||||
self.config.select_account(id).await?;
|
||||
|
||||
if let Some(true) = self.config.get_disable_background_io(id) {
|
||||
if let Some(previous_account_ctx) = self.get_account(id) {
|
||||
previous_account_ctx.start_io().await;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -264,7 +277,9 @@ impl Accounts {
|
||||
/// Starts background tasks such as IMAP and SMTP loops for all accounts.
|
||||
pub async fn start_io(&mut self) {
|
||||
for account in self.accounts.values_mut() {
|
||||
account.start_io().await;
|
||||
if let Some(false) = self.config.get_disable_background_io(account.id) {
|
||||
account.start_io().await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,6 +293,33 @@ impl Accounts {
|
||||
}
|
||||
}
|
||||
|
||||
/// Set disable_background_io for an account, when enabled,
|
||||
/// io is stopped unless the account is selected and background fetch is also disabled for the account
|
||||
///
|
||||
/// This automatically stops/starts io when account is in the background
|
||||
pub async fn set_disable_background_io(
|
||||
&mut self,
|
||||
id: u32,
|
||||
disable_background_io: bool,
|
||||
) -> Result<()> {
|
||||
self.config
|
||||
.set_disable_background_io(id, disable_background_io)
|
||||
.await?;
|
||||
if let Some(account) = self.get_account(id) {
|
||||
if disable_background_io {
|
||||
account.stop_io().await;
|
||||
} else {
|
||||
account.start_io().await;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Checks if background io is disabled
|
||||
pub fn get_disable_background_io(&self, id: u32) -> Option<bool> {
|
||||
self.config.get_disable_background_io(id)
|
||||
}
|
||||
|
||||
/// Notifies all accounts that the network may have become available.
|
||||
pub async fn maybe_network(&self) {
|
||||
for account in self.accounts.values() {
|
||||
@@ -296,6 +338,8 @@ impl Accounts {
|
||||
///
|
||||
/// This is an auxiliary function and not part of public API.
|
||||
/// Use [Accounts::background_fetch] instead.
|
||||
///
|
||||
/// Acounts with `disable_background_io` are not fetched
|
||||
async fn background_fetch_without_timeout(&self) {
|
||||
async fn background_fetch_and_log_error(account: Context) {
|
||||
if let Err(error) = account.background_fetch().await {
|
||||
@@ -306,6 +350,7 @@ impl Accounts {
|
||||
join_all(
|
||||
self.accounts
|
||||
.values()
|
||||
.filter(|account| self.config.get_disable_background_io(account.id) != Some(true))
|
||||
.cloned()
|
||||
.map(background_fetch_and_log_error),
|
||||
)
|
||||
@@ -317,6 +362,8 @@ impl Accounts {
|
||||
/// The `AccountsBackgroundFetchDone` event is emitted at the end,
|
||||
/// process all events until you get this one and you can safely return to the background
|
||||
/// without forgetting to create notifications caused by timing race conditions.
|
||||
///
|
||||
/// Acounts with `disable_background_io` are not fetched
|
||||
pub async fn background_fetch(&self, timeout: std::time::Duration) {
|
||||
if let Err(_err) =
|
||||
tokio::time::timeout(timeout, self.background_fetch_without_timeout()).await
|
||||
@@ -558,6 +605,7 @@ impl Config {
|
||||
id,
|
||||
dir: target_dir,
|
||||
uuid,
|
||||
disable_background_io: false,
|
||||
});
|
||||
self.inner.next_id += 1;
|
||||
id
|
||||
@@ -620,6 +668,28 @@ impl Config {
|
||||
self.sync().await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn set_disable_background_io(&mut self, id: u32, value: bool) -> Result<()> {
|
||||
let position = self
|
||||
.inner
|
||||
.accounts
|
||||
.iter()
|
||||
.position(|e| e.id == id)
|
||||
.context("account not found")?;
|
||||
self.inner
|
||||
.accounts
|
||||
.get_mut(position)
|
||||
.context("account not found")?
|
||||
.disable_background_io = value;
|
||||
|
||||
self.sync().await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Checks if background io is disabled
|
||||
pub fn get_disable_background_io(&self, id: u32) -> Option<bool> {
|
||||
Some(self.get_account(id)?.disable_background_io)
|
||||
}
|
||||
}
|
||||
|
||||
/// Spend up to 1 minute trying to do the operation.
|
||||
@@ -666,6 +736,12 @@ struct AccountConfig {
|
||||
|
||||
/// Universally unique account identifier.
|
||||
pub uuid: Uuid,
|
||||
|
||||
/// Disable account io when it is not selected
|
||||
///
|
||||
/// this means io is stopped unless the account is selected
|
||||
/// and background fetch is also disabled for the account
|
||||
pub disable_background_io: bool,
|
||||
}
|
||||
|
||||
impl AccountConfig {
|
||||
|
||||
Reference in New Issue
Block a user