mirror of
https://github.com/chatmail/core.git
synced 2026-05-05 14:26:30 +03:00
Store relative accounts path in accounts.toml
This makes it possible to move accounts dir, especially useful for bots.
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
add the new recipients as group members #3781
|
add the new recipients as group members #3781
|
||||||
- Remove `pytest-async` plugin #3846
|
- Remove `pytest-async` plugin #3846
|
||||||
- Only send the message about ephemeral timer change if the chat is promoted #3847
|
- Only send the message about ephemeral timer change if the chat is promoted #3847
|
||||||
|
- Use relative paths in `accounts.toml` #3838
|
||||||
|
|
||||||
### API-Changes
|
### API-Changes
|
||||||
|
|
||||||
|
|||||||
@@ -14,9 +14,7 @@ class Rpc:
|
|||||||
if accounts_dir:
|
if accounts_dir:
|
||||||
kwargs["env"] = {
|
kwargs["env"] = {
|
||||||
**kwargs.get("env", os.environ),
|
**kwargs.get("env", os.environ),
|
||||||
"DC_ACCOUNTS_PATH": os.path.abspath(
|
"DC_ACCOUNTS_PATH": str(accounts_dir),
|
||||||
os.path.expanduser(str(accounts_dir))
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self._kwargs = kwargs
|
self._kwargs = kwargs
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ impl Accounts {
|
|||||||
let events = Events::new();
|
let events = Events::new();
|
||||||
let stockstrings = StockStrings::new();
|
let stockstrings = StockStrings::new();
|
||||||
let accounts = config
|
let accounts = config
|
||||||
.load_accounts(&events, &stockstrings)
|
.load_accounts(&events, &stockstrings, &dir)
|
||||||
.await
|
.await
|
||||||
.context("failed to load accounts")?;
|
.context("failed to load accounts")?;
|
||||||
|
|
||||||
@@ -107,10 +107,11 @@ impl Accounts {
|
|||||||
///
|
///
|
||||||
/// Returns account ID.
|
/// Returns account ID.
|
||||||
pub async fn add_account(&mut self) -> Result<u32> {
|
pub async fn add_account(&mut self) -> Result<u32> {
|
||||||
let account_config = self.config.new_account(&self.dir).await?;
|
let account_config = self.config.new_account().await?;
|
||||||
|
let dbfile = account_config.dbfile(&self.dir);
|
||||||
|
|
||||||
let ctx = Context::new(
|
let ctx = Context::new(
|
||||||
&account_config.dbfile(),
|
&dbfile,
|
||||||
account_config.id,
|
account_config.id,
|
||||||
self.events.clone(),
|
self.events.clone(),
|
||||||
self.stockstrings.clone(),
|
self.stockstrings.clone(),
|
||||||
@@ -123,10 +124,10 @@ impl Accounts {
|
|||||||
|
|
||||||
/// Adds a new closed account.
|
/// Adds a new closed account.
|
||||||
pub async fn add_closed_account(&mut self) -> Result<u32> {
|
pub async fn add_closed_account(&mut self) -> Result<u32> {
|
||||||
let account_config = self.config.new_account(&self.dir).await?;
|
let account_config = self.config.new_account().await?;
|
||||||
|
|
||||||
let ctx = Context::new_closed(
|
let ctx = Context::new_closed(
|
||||||
&account_config.dbfile(),
|
&account_config.dbfile(&self.dir),
|
||||||
account_config.id,
|
account_config.id,
|
||||||
self.events.clone(),
|
self.events.clone(),
|
||||||
self.stockstrings.clone(),
|
self.stockstrings.clone(),
|
||||||
@@ -147,6 +148,8 @@ impl Accounts {
|
|||||||
drop(ctx);
|
drop(ctx);
|
||||||
|
|
||||||
if let Some(cfg) = self.config.get_account(id) {
|
if let Some(cfg) = self.config.get_account(id) {
|
||||||
|
let account_path = self.dir.join(cfg.dir);
|
||||||
|
|
||||||
// Spend up to 1 minute trying to remove the files.
|
// Spend up to 1 minute trying to remove the files.
|
||||||
// Files may remain locked up to 30 seconds due to r2d2 bug:
|
// Files may remain locked up to 30 seconds due to r2d2 bug:
|
||||||
// https://github.com/sfackler/r2d2/issues/99
|
// https://github.com/sfackler/r2d2/issues/99
|
||||||
@@ -154,7 +157,7 @@ impl Accounts {
|
|||||||
loop {
|
loop {
|
||||||
counter += 1;
|
counter += 1;
|
||||||
|
|
||||||
if let Err(err) = fs::remove_dir_all(&cfg.dir)
|
if let Err(err) = fs::remove_dir_all(&account_path)
|
||||||
.await
|
.await
|
||||||
.context("failed to remove account data")
|
.context("failed to remove account data")
|
||||||
{
|
{
|
||||||
@@ -187,16 +190,16 @@ impl Accounts {
|
|||||||
// create new account
|
// create new account
|
||||||
let account_config = self
|
let account_config = self
|
||||||
.config
|
.config
|
||||||
.new_account(&self.dir)
|
.new_account()
|
||||||
.await
|
.await
|
||||||
.context("failed to create new account")?;
|
.context("failed to create new account")?;
|
||||||
|
|
||||||
let new_dbfile = account_config.dbfile();
|
let new_dbfile = account_config.dbfile(&self.dir);
|
||||||
let new_blobdir = Context::derive_blobdir(&new_dbfile);
|
let new_blobdir = Context::derive_blobdir(&new_dbfile);
|
||||||
let new_walfile = Context::derive_walfile(&new_dbfile);
|
let new_walfile = Context::derive_walfile(&new_dbfile);
|
||||||
|
|
||||||
let res = {
|
let res = {
|
||||||
fs::create_dir_all(&account_config.dir)
|
fs::create_dir_all(self.dir.join(&account_config.dir))
|
||||||
.await
|
.await
|
||||||
.context("failed to create dir")?;
|
.context("failed to create dir")?;
|
||||||
fs::rename(&dbfile, &new_dbfile)
|
fs::rename(&dbfile, &new_dbfile)
|
||||||
@@ -358,8 +361,17 @@ impl Config {
|
|||||||
|
|
||||||
/// Read a configuration from the given file into memory.
|
/// Read a configuration from the given file into memory.
|
||||||
pub async fn from_file(file: PathBuf) -> Result<Self> {
|
pub async fn from_file(file: PathBuf) -> Result<Self> {
|
||||||
|
let dir = file.parent().context("can't get config file directory")?;
|
||||||
let bytes = fs::read(&file).await.context("failed to read file")?;
|
let bytes = fs::read(&file).await.context("failed to read file")?;
|
||||||
let inner: InnerConfig = toml::from_slice(&bytes).context("failed to parse config")?;
|
let mut inner: InnerConfig = toml::from_slice(&bytes).context("failed to parse config")?;
|
||||||
|
|
||||||
|
// Previous versions of the core stored absolute paths in account config.
|
||||||
|
// Convert them to relative paths.
|
||||||
|
for account in &mut inner.accounts {
|
||||||
|
if let Ok(new_dir) = account.dir.strip_prefix(dir) {
|
||||||
|
account.dir = new_dir.to_path_buf();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Config { file, inner })
|
Ok(Config { file, inner })
|
||||||
}
|
}
|
||||||
@@ -372,12 +384,13 @@ impl Config {
|
|||||||
&self,
|
&self,
|
||||||
events: &Events,
|
events: &Events,
|
||||||
stockstrings: &StockStrings,
|
stockstrings: &StockStrings,
|
||||||
|
dir: &Path,
|
||||||
) -> Result<BTreeMap<u32, Context>> {
|
) -> Result<BTreeMap<u32, Context>> {
|
||||||
let mut accounts = BTreeMap::new();
|
let mut accounts = BTreeMap::new();
|
||||||
|
|
||||||
for account_config in &self.inner.accounts {
|
for account_config in &self.inner.accounts {
|
||||||
let ctx = Context::new(
|
let ctx = Context::new(
|
||||||
&account_config.dbfile(),
|
&account_config.dbfile(dir),
|
||||||
account_config.id,
|
account_config.id,
|
||||||
events.clone(),
|
events.clone(),
|
||||||
stockstrings.clone(),
|
stockstrings.clone(),
|
||||||
@@ -386,7 +399,7 @@ impl Config {
|
|||||||
.with_context(|| {
|
.with_context(|| {
|
||||||
format!(
|
format!(
|
||||||
"failed to create context from file {:?}",
|
"failed to create context from file {:?}",
|
||||||
account_config.dbfile()
|
account_config.dbfile(dir)
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@@ -396,12 +409,12 @@ impl Config {
|
|||||||
Ok(accounts)
|
Ok(accounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new account in the given root directory.
|
/// Creates a new account in the account manager directory.
|
||||||
async fn new_account(&mut self, dir: &Path) -> Result<AccountConfig> {
|
async fn new_account(&mut self) -> Result<AccountConfig> {
|
||||||
let id = {
|
let id = {
|
||||||
let id = self.inner.next_id;
|
let id = self.inner.next_id;
|
||||||
let uuid = Uuid::new_v4();
|
let uuid = Uuid::new_v4();
|
||||||
let target_dir = dir.join(uuid.to_string());
|
let target_dir = PathBuf::from(uuid.to_string());
|
||||||
|
|
||||||
self.inner.accounts.push(AccountConfig {
|
self.inner.accounts.push(AccountConfig {
|
||||||
id,
|
id,
|
||||||
@@ -473,14 +486,16 @@ struct AccountConfig {
|
|||||||
/// Unique id.
|
/// Unique id.
|
||||||
pub id: u32,
|
pub id: u32,
|
||||||
/// Root directory for all data for this account.
|
/// Root directory for all data for this account.
|
||||||
|
///
|
||||||
|
/// The path is relative to the account manager directory.
|
||||||
pub dir: std::path::PathBuf,
|
pub dir: std::path::PathBuf,
|
||||||
pub uuid: Uuid,
|
pub uuid: Uuid,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AccountConfig {
|
impl AccountConfig {
|
||||||
/// Get the canoncial dbfile name for this configuration.
|
/// Get the canoncial dbfile name for this configuration.
|
||||||
pub fn dbfile(&self) -> std::path::PathBuf {
|
pub fn dbfile(&self, accounts_dir: &Path) -> std::path::PathBuf {
|
||||||
self.dir.join(DB_NAME)
|
accounts_dir.join(&self.dir).join(DB_NAME)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user