improve mailbox alias management

This commit is contained in:
Clément DOUIN 2022-03-09 12:30:10 +01:00
parent 1f01202262
commit 811ea45610
No known key found for this signature in database
GPG key ID: 353E4A18EE0FAB72
2 changed files with 37 additions and 25 deletions

View file

@ -5,7 +5,7 @@
use anyhow::{anyhow, Context, Result};
use log::{debug, info, trace};
use std::{convert::TryInto, fs, path::PathBuf};
use std::{convert::TryInto, env, fs, path::PathBuf};
use crate::{
backends::{Backend, IdMapper, MaildirEnvelopes, MaildirFlags, MaildirMboxes},
@ -41,33 +41,32 @@ impl<'a> MaildirBackend<'a> {
/// Creates a maildir instance from a string slice.
pub fn get_mdir_from_dir(&self, dir: &str) -> Result<maildir::Maildir> {
let dir = self.account_config.get_mbox_alias(dir)?;
// If the dir points to the inbox folder, creates a maildir
// instance from the root folder.
if dir.to_lowercase() == "inbox" {
self.validate_mdir_path(self.mdir.path().to_owned())
.map(maildir::Maildir::from)
} else {
// If the dir is a valid maildir path, creates a maildir
// instance from it. Checks for absolute path first,
self.validate_mdir_path(dir.into())
// then for relative path,
.or_else(|_| self.validate_mdir_path(self.mdir.path().join(dir)))
.or_else(|_| {
// otherwise creates a maildir instance from a
// maildir subdirectory by adding a "." in front
// of the name as described in the spec:
// https://cr.yp.to/proto/maildir.html.
let dir = self
.account_config
.mailboxes
.get(dir)
.map(|s| s.as_str())
.unwrap_or(dir);
let path = self.mdir.path().join(format!(".{}", dir));
self.validate_mdir_path(path)
})
.map(maildir::Maildir::from)
if &dir == "inbox" {
return self
.validate_mdir_path(self.mdir.path().to_owned())
.map(maildir::Maildir::from);
}
// If the dir is a valid maildir path, creates a maildir
// instance from it. First checks for absolute path,
self.validate_mdir_path((&dir).into())
// then for relative path to `maildir-dir`,
.or_else(|_| self.validate_mdir_path(self.mdir.path().join(&dir)))
// and finally for relative path to the current directory.
.or_else(|_| self.validate_mdir_path(env::current_dir()?.join(&dir)))
.or_else(|_| {
// Otherwise creates a maildir instance from a maildir
// subdirectory by adding a "." in front of the name
// as described in the [spec].
//
// [spec]: http://www.courier-mta.org/imap/README.maildirquota.html
self.validate_mdir_path(self.mdir.path().join(format!(".{}", dir)))
})
.map(maildir::Maildir::from)
}
}

View file

@ -317,6 +317,19 @@ impl<'a> AccountConfig {
run_cmd(&cmd).context("cannot run notify cmd")?;
Ok(())
}
/// Gets the mailbox alias if exists, otherwise returns the
/// mailbox. Also tries to expand shell variables.
pub fn get_mbox_alias(&self, mbox: &str) -> Result<String> {
let mbox = self
.mailboxes
.get(&mbox.trim().to_lowercase())
.map(|s| s.as_str())
.unwrap_or(mbox);
shellexpand::full(mbox)
.map(String::from)
.with_context(|| format!("cannot expand mailbox path {:?}", mbox))
}
}
/// Represents all existing kind of account (backend).