fix sync cache

This commit is contained in:
Clément DOUIN 2023-11-28 12:30:50 +01:00
parent 7629a66c9c
commit a0888067da
No known key found for this signature in database
GPG key ID: 353E4A18EE0FAB72
6 changed files with 428 additions and 266 deletions

48
Cargo.lock generated
View file

@ -984,7 +984,6 @@ dependencies = [
[[package]]
name = "email-lib"
version = "0.15.3"
source = "git+https://git.sr.ht/~soywod/pimalaya#012d31179908063affe3eec77365e5ac86c436fe"
dependencies = [
"advisory-lock",
"anyhow",
@ -2070,15 +2069,15 @@ dependencies = [
"keyring-lib",
"log",
"md5",
"mml-lib 1.0.1 (git+https://git.sr.ht/~soywod/pimalaya)",
"oauth-lib 0.1.0 (git+https://git.sr.ht/~soywod/pimalaya)",
"mml-lib 1.0.1",
"oauth-lib 0.1.0",
"once_cell",
"process-lib",
"rusqlite",
"secret-lib",
"serde",
"serde_json",
"shellexpand-utils 0.1.0 (git+https://git.sr.ht/~soywod/pimalaya)",
"shellexpand-utils 0.1.0",
"tempfile",
"termcolor",
"terminal_size",
@ -2685,6 +2684,21 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "mml-lib"
version = "1.0.1"
dependencies = [
"async-recursion",
"chumsky",
"log",
"mail-builder",
"mail-parser",
"nanohtml2text",
"shellexpand-utils 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"thiserror",
"tree_magic_mini",
]
[[package]]
name = "mml-lib"
version = "1.0.1"
@ -2707,22 +2721,6 @@ dependencies = [
"tree_magic_mini",
]
[[package]]
name = "mml-lib"
version = "1.0.1"
source = "git+https://git.sr.ht/~soywod/pimalaya#012d31179908063affe3eec77365e5ac86c436fe"
dependencies = [
"async-recursion",
"chumsky",
"log",
"mail-builder",
"mail-parser",
"nanohtml2text",
"shellexpand-utils 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"thiserror",
"tree_magic_mini",
]
[[package]]
name = "nanohtml2text"
version = "0.1.4"
@ -2848,8 +2846,6 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]]
name = "oauth-lib"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1484d9864dbf6b55b3785380631a253fa0ff7f8e1bbb078bfd7effd11283d61"
dependencies = [
"log",
"oauth2",
@ -2862,7 +2858,8 @@ dependencies = [
[[package]]
name = "oauth-lib"
version = "0.1.0"
source = "git+https://git.sr.ht/~soywod/pimalaya#012d31179908063affe3eec77365e5ac86c436fe"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1484d9864dbf6b55b3785380631a253fa0ff7f8e1bbb078bfd7effd11283d61"
dependencies = [
"log",
"oauth2",
@ -3859,8 +3856,6 @@ dependencies = [
[[package]]
name = "shellexpand-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b44114d15a72740d3049e739929d0f4af335ba2eb855ea0f1fa2bfb4d7066215"
dependencies = [
"log",
"shellexpand",
@ -3870,7 +3865,8 @@ dependencies = [
[[package]]
name = "shellexpand-utils"
version = "0.1.0"
source = "git+https://git.sr.ht/~soywod/pimalaya#012d31179908063affe3eec77365e5ac86c436fe"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b44114d15a72740d3049e739929d0f4af335ba2eb855ea0f1fa2bfb4d7066215"
dependencies = [
"log",
"shellexpand",

View file

@ -93,21 +93,21 @@ version = "1.16.0"
[dependencies.email-lib]
# version = "=0.15.3"
default-features = false
git = "https://git.sr.ht/~soywod/pimalaya"
path = "/home/soywod/sourcehut/pimalaya/email"
[dependencies.keyring-lib]
version = "=0.1.0"
[dependencies.oauth-lib]
# version = "=0.1.0"
git = "https://git.sr.ht/~soywod/pimalaya"
path = "/home/soywod/sourcehut/pimalaya/oauth"
[dependencies.process-lib]
version = "=0.1.0"
[dependencies.mml-lib]
# version = "=1.0.1"
git = "https://git.sr.ht/~soywod/pimalaya"
path = "/home/soywod/sourcehut/pimalaya/mml"
[dependencies.secret-lib]
version = "=0.1.0"
@ -121,7 +121,7 @@ version = "1.0"
[dependencies.shellexpand-utils]
# version = "=0.1.0"
git = "https://git.sr.ht/~soywod/pimalaya"
path = "/home/soywod/sourcehut/pimalaya/shellexpand-utils"
[dependencies.termcolor]
version = "1.1"

View file

@ -6,13 +6,13 @@ default = true
display-name = "My example account"
email = "example@localhost"
sync = true
sync-dir = "./.sync"
# The default backend used for all the features like adding folders,
# listing envelopes or copying messages.
backend = "imap"
# Override the backend used for sending messages.
message.send.backend = "smtp"
# IMAP config
imap.host = "localhost"
imap.port = 3143
@ -23,6 +23,9 @@ imap.insecure = true
imap.auth = "passwd"
imap.passwd.raw = "example"
# Override the backend used for sending messages.
message.send.backend = "smtp"
# SMTP config
smtp.host = "localhost"
smtp.port = 3025
@ -32,4 +35,3 @@ smtp.starttls = false
smtp.insecure = true
smtp.auth = "passwd"
smtp.passwd.raw = "example"

View file

@ -39,12 +39,12 @@ use email::{
list::{imap::ListFoldersImap, maildir::ListFoldersMaildir},
purge::imap::PurgeFolderImap,
},
maildir::{MaildirSessionBuilder, MaildirSessionSync},
maildir::{MaildirConfig, MaildirSessionBuilder, MaildirSessionSync},
sendmail::SendmailContext,
};
use serde::{Deserialize, Serialize};
use crate::config::DeserializedConfig;
use crate::{account::DeserializedAccountConfig, config::DeserializedConfig};
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
@ -61,9 +61,10 @@ pub enum BackendKind {
#[derive(Clone, Default)]
pub struct BackendContextBuilder {
sync_cache: Option<MaildirSessionBuilder>,
maildir: Option<MaildirSessionBuilder>,
#[cfg(feature = "imap-backend")]
imap: Option<ImapSessionBuilder>,
maildir: Option<MaildirSessionBuilder>,
#[cfg(feature = "smtp-sender")]
smtp: Option<SmtpClientBuilder>,
sendmail: Option<SendmailContext>,
@ -80,6 +81,10 @@ impl email::backend::BackendContextBuilder for BackendContextBuilder {
ctx.maildir = Some(maildir.build().await?);
}
if let Some(maildir) = self.sync_cache {
ctx.sync_cache = Some(maildir.build().await?);
}
#[cfg(feature = "imap-backend")]
if let Some(imap) = self.imap {
ctx.imap = Some(imap.build().await?);
@ -105,9 +110,10 @@ impl email::backend::BackendContextBuilder for BackendContextBuilder {
#[derive(Default)]
pub struct BackendContext {
pub sync_cache: Option<MaildirSessionSync>,
pub maildir: Option<MaildirSessionSync>,
#[cfg(feature = "imap-backend")]
pub imap: Option<ImapSessionSync>,
pub maildir: Option<MaildirSessionSync>,
#[cfg(feature = "smtp-sender")]
pub smtp: Option<SmtpClientSync>,
pub sendmail: Option<SendmailContext>,
@ -115,97 +121,14 @@ pub struct BackendContext {
pub struct BackendBuilder(pub email::backend::BackendBuilder<BackendContextBuilder>);
pub type Backend = email::backend::Backend<BackendContext>;
impl BackendBuilder {
pub async fn new(config: DeserializedConfig, account_name: Option<&str>) -> Result<Self> {
let (account_name, mut deserialized_account_config) = match account_name {
Some("default") | Some("") | None => config
.accounts
.iter()
.find_map(|(name, account)| {
account
.default
.filter(|default| *default == true)
.map(|_| (name.to_owned(), account.clone()))
})
.ok_or_else(|| anyhow!("cannot find default account")),
Some(name) => config
.accounts
.get(name)
.map(|account| (name.to_owned(), account.clone()))
.ok_or_else(|| anyhow!("cannot find account {name}")),
}?;
#[cfg(feature = "imap-backend")]
if let Some(imap_config) = deserialized_account_config.imap.as_mut() {
imap_config
.auth
.replace_undefined_keyring_entries(&account_name);
}
#[cfg(feature = "smtp-sender")]
if let Some(smtp_config) = deserialized_account_config.smtp.as_mut() {
smtp_config
.auth
.replace_undefined_keyring_entries(&account_name);
}
let config = Config {
display_name: config.display_name,
signature_delim: config.signature_delim,
signature: config.signature,
downloads_dir: config.downloads_dir,
folder_listing_page_size: config.folder_listing_page_size,
folder_aliases: config.folder_aliases,
email_listing_page_size: config.email_listing_page_size,
email_listing_datetime_fmt: config.email_listing_datetime_fmt,
email_listing_datetime_local_tz: config.email_listing_datetime_local_tz,
email_reading_headers: config.email_reading_headers,
email_reading_format: config.email_reading_format,
email_writing_headers: config.email_writing_headers,
email_sending_save_copy: config.email_sending_save_copy,
email_hooks: config.email_hooks,
accounts: HashMap::from_iter(config.accounts.clone().into_iter().map(
|(name, config)| {
(
name.clone(),
AccountConfig {
name,
email: config.email,
display_name: config.display_name,
signature_delim: config.signature_delim,
signature: config.signature,
downloads_dir: config.downloads_dir,
folder_listing_page_size: config.folder_listing_page_size,
folder_aliases: config.folder_aliases.unwrap_or_default(),
email_listing_page_size: config.email_listing_page_size,
email_listing_datetime_fmt: config.email_listing_datetime_fmt,
email_listing_datetime_local_tz: config.email_listing_datetime_local_tz,
email_reading_headers: config.email_reading_headers,
email_reading_format: config.email_reading_format.unwrap_or_default(),
email_writing_headers: config.email_writing_headers,
email_sending_save_copy: config.email_sending_save_copy,
email_hooks: config.email_hooks.unwrap_or_default(),
sync: config.sync,
sync_dir: config.sync_dir,
sync_folders_strategy: config.sync_folders_strategy.unwrap_or_default(),
#[cfg(feature = "pgp")]
pgp: config.pgp,
},
)
},
)),
};
let account_config = config.account(&account_name)?;
pub async fn new(
deserialized_account_config: DeserializedAccountConfig,
account_config: AccountConfig,
disable_cache: bool,
) -> Result<Self> {
let backend_ctx_builder = BackendContextBuilder {
maildir: deserialized_account_config
.maildir
@ -213,6 +136,16 @@ impl BackendBuilder {
.map(|mdir_config| {
MaildirSessionBuilder::new(account_config.clone(), mdir_config.clone())
}),
sync_cache: if account_config.sync && !disable_cache {
Some(MaildirSessionBuilder::new(
account_config.clone(),
MaildirConfig {
root_dir: account_config.sync_dir()?,
},
))
} else {
None
},
#[cfg(feature = "imap-backend")]
imap: deserialized_account_config
.imap
@ -253,6 +186,10 @@ impl BackendBuilder {
.or_else(|| deserialized_account_config.backend.as_ref());
match add_folder {
Some(_) if account_config.sync && !disable_cache => {
backend_builder = backend_builder
.with_add_folder(|ctx| ctx.sync_cache.as_ref().and_then(AddFolderMaildir::new));
}
Some(BackendKind::Maildir) => {
backend_builder = backend_builder
.with_add_folder(|ctx| ctx.maildir.as_ref().and_then(AddFolderMaildir::new));
@ -278,6 +215,11 @@ impl BackendBuilder {
.or_else(|| deserialized_account_config.backend.as_ref());
match list_folders {
Some(_) if account_config.sync && !disable_cache => {
backend_builder = backend_builder.with_list_folders(|ctx| {
ctx.sync_cache.as_ref().and_then(ListFoldersMaildir::new)
});
}
Some(BackendKind::Maildir) => {
backend_builder = backend_builder.with_list_folders(|ctx| {
ctx.maildir.as_ref().and_then(ListFoldersMaildir::new)
@ -305,6 +247,11 @@ impl BackendBuilder {
.or_else(|| deserialized_account_config.backend.as_ref());
match expunge_folder {
Some(_) if account_config.sync && !disable_cache => {
backend_builder = backend_builder.with_expunge_folder(|ctx| {
ctx.sync_cache.as_ref().and_then(ExpungeFolderMaildir::new)
});
}
Some(BackendKind::Maildir) => {
backend_builder = backend_builder.with_expunge_folder(|ctx| {
ctx.maildir.as_ref().and_then(ExpungeFolderMaildir::new)
@ -332,6 +279,12 @@ impl BackendBuilder {
.or_else(|| deserialized_account_config.backend.as_ref());
match purge_folder {
// TODO
// Some(_) if account_config.sync && !disable_cache => {
// backend_builder = backend_builder.with_purge_folder(|ctx| {
// ctx.sync_cache.as_ref().and_then(PurgeFolderMaildir::new)
// });
// }
// TODO
// Some(BackendKind::Maildir) => {
// backend_builder = backend_builder
@ -359,6 +312,11 @@ impl BackendBuilder {
.or_else(|| deserialized_account_config.backend.as_ref());
match delete_folder {
Some(_) if account_config.sync && !disable_cache => {
backend_builder = backend_builder.with_delete_folder(|ctx| {
ctx.sync_cache.as_ref().and_then(DeleteFolderMaildir::new)
});
}
Some(BackendKind::Maildir) => {
backend_builder = backend_builder.with_delete_folder(|ctx| {
ctx.maildir.as_ref().and_then(DeleteFolderMaildir::new)
@ -386,6 +344,11 @@ impl BackendBuilder {
.or_else(|| deserialized_account_config.backend.as_ref());
match get_envelope {
Some(_) if account_config.sync && !disable_cache => {
backend_builder = backend_builder.with_get_envelope(|ctx| {
ctx.sync_cache.as_ref().and_then(GetEnvelopeMaildir::new)
});
}
Some(BackendKind::Maildir) => {
backend_builder = backend_builder.with_get_envelope(|ctx| {
ctx.maildir.as_ref().and_then(GetEnvelopeMaildir::new)
@ -413,6 +376,11 @@ impl BackendBuilder {
.or_else(|| deserialized_account_config.backend.as_ref());
match list_envelopes {
Some(_) if account_config.sync && !disable_cache => {
backend_builder = backend_builder.with_list_envelopes(|ctx| {
ctx.sync_cache.as_ref().and_then(ListEnvelopesMaildir::new)
});
}
Some(BackendKind::Maildir) => {
backend_builder = backend_builder.with_list_envelopes(|ctx| {
ctx.maildir.as_ref().and_then(ListEnvelopesMaildir::new)
@ -440,6 +408,10 @@ impl BackendBuilder {
.or_else(|| deserialized_account_config.backend.as_ref());
match add_flags {
Some(_) if account_config.sync && !disable_cache => {
backend_builder = backend_builder
.with_add_flags(|ctx| ctx.sync_cache.as_ref().and_then(AddFlagsMaildir::new));
}
Some(BackendKind::Maildir) => {
backend_builder = backend_builder
.with_add_flags(|ctx| ctx.maildir.as_ref().and_then(AddFlagsMaildir::new));
@ -465,6 +437,10 @@ impl BackendBuilder {
.or_else(|| deserialized_account_config.backend.as_ref());
match set_flags {
Some(_) if account_config.sync && !disable_cache => {
backend_builder = backend_builder
.with_set_flags(|ctx| ctx.sync_cache.as_ref().and_then(SetFlagsMaildir::new));
}
Some(BackendKind::Maildir) => {
backend_builder = backend_builder
.with_set_flags(|ctx| ctx.maildir.as_ref().and_then(SetFlagsMaildir::new));
@ -490,6 +466,11 @@ impl BackendBuilder {
.or_else(|| deserialized_account_config.backend.as_ref());
match remove_flags {
Some(_) if account_config.sync && !disable_cache => {
backend_builder = backend_builder.with_remove_flags(|ctx| {
ctx.sync_cache.as_ref().and_then(RemoveFlagsMaildir::new)
});
}
Some(BackendKind::Maildir) => {
backend_builder = backend_builder.with_remove_flags(|ctx| {
ctx.maildir.as_ref().and_then(RemoveFlagsMaildir::new)
@ -539,6 +520,13 @@ impl BackendBuilder {
.or_else(|| deserialized_account_config.backend.as_ref());
match add_msg {
Some(_) if account_config.sync && !disable_cache => {
backend_builder = backend_builder.with_add_raw_message_with_flags(|ctx| {
ctx.sync_cache
.as_ref()
.and_then(AddRawMessageWithFlagsMaildir::new)
});
}
Some(BackendKind::Maildir) => {
backend_builder = backend_builder.with_add_raw_message_with_flags(|ctx| {
ctx.maildir
@ -571,6 +559,11 @@ impl BackendBuilder {
.or_else(|| deserialized_account_config.backend.as_ref());
match peek_msgs {
Some(_) if account_config.sync && !disable_cache => {
backend_builder = backend_builder.with_peek_messages(|ctx| {
ctx.sync_cache.as_ref().and_then(PeekMessagesMaildir::new)
});
}
Some(BackendKind::Maildir) => {
backend_builder = backend_builder.with_peek_messages(|ctx| {
ctx.maildir.as_ref().and_then(PeekMessagesMaildir::new)
@ -620,6 +613,11 @@ impl BackendBuilder {
.or_else(|| deserialized_account_config.backend.as_ref());
match copy_msgs {
Some(_) if account_config.sync && !disable_cache => {
backend_builder = backend_builder.with_copy_messages(|ctx| {
ctx.sync_cache.as_ref().and_then(CopyMessagesMaildir::new)
});
}
Some(BackendKind::Maildir) => {
backend_builder = backend_builder.with_copy_messages(|ctx| {
ctx.maildir.as_ref().and_then(CopyMessagesMaildir::new)
@ -647,6 +645,11 @@ impl BackendBuilder {
.or_else(|| deserialized_account_config.backend.as_ref());
match move_msgs {
Some(_) if account_config.sync && !disable_cache => {
backend_builder = backend_builder.with_move_messages(|ctx| {
ctx.sync_cache.as_ref().and_then(MoveMessagesMaildir::new)
});
}
Some(BackendKind::Maildir) => {
backend_builder = backend_builder.with_move_messages(|ctx| {
ctx.maildir.as_ref().and_then(MoveMessagesMaildir::new)
@ -668,14 +671,8 @@ impl BackendBuilder {
Ok(Self(backend_builder))
}
}
impl Deref for BackendBuilder {
type Target = email::backend::BackendBuilder<BackendContextBuilder>;
fn deref(&self) -> &Self::Target {
&self.0
pub async fn build(self) -> Result<Backend> {
self.0.build().await
}
}
pub type Backend = email::backend::Backend<BackendContext>;

View file

@ -6,7 +6,11 @@
use anyhow::{anyhow, Context, Result};
use dialoguer::Confirm;
use dirs::{config_dir, home_dir};
use email::email::{EmailHooks, EmailTextPlainFormat};
use email::{
account::AccountConfig,
config::Config,
email::{EmailHooks, EmailTextPlainFormat},
};
use log::{debug, trace};
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, fs, path::PathBuf, process::exit};
@ -98,6 +102,102 @@ impl DeserializedConfig {
.or_else(|| home_dir().map(|p| p.join(".himalayarc")))
.filter(|p| p.exists())
}
pub fn into_account_configs(
self,
account_name: Option<&str>,
) -> Result<(DeserializedAccountConfig, AccountConfig)> {
let (account_name, mut toml_account_config) = match account_name {
Some("default") | Some("") | None => self
.accounts
.iter()
.find_map(|(name, account)| {
account
.default
.filter(|default| *default == true)
.map(|_| (name.to_owned(), account.clone()))
})
.ok_or_else(|| anyhow!("cannot find default account")),
Some(name) => self
.accounts
.get(name)
.map(|account| (name.to_owned(), account.clone()))
.ok_or_else(|| anyhow!("cannot find account {name}")),
}?;
#[cfg(feature = "imap-backend")]
if let Some(imap_config) = toml_account_config.imap.as_mut() {
imap_config
.auth
.replace_undefined_keyring_entries(&account_name);
}
#[cfg(feature = "smtp-sender")]
if let Some(smtp_config) = toml_account_config.smtp.as_mut() {
smtp_config
.auth
.replace_undefined_keyring_entries(&account_name);
}
let config = Config {
display_name: self.display_name,
signature_delim: self.signature_delim,
signature: self.signature,
downloads_dir: self.downloads_dir,
folder_listing_page_size: self.folder_listing_page_size,
folder_aliases: self.folder_aliases,
email_listing_page_size: self.email_listing_page_size,
email_listing_datetime_fmt: self.email_listing_datetime_fmt,
email_listing_datetime_local_tz: self.email_listing_datetime_local_tz,
email_reading_headers: self.email_reading_headers,
email_reading_format: self.email_reading_format,
email_writing_headers: self.email_writing_headers,
email_sending_save_copy: self.email_sending_save_copy,
email_hooks: self.email_hooks,
accounts: HashMap::from_iter(self.accounts.clone().into_iter().map(
|(name, config)| {
(
name.clone(),
AccountConfig {
name,
email: config.email,
display_name: config.display_name,
signature_delim: config.signature_delim,
signature: config.signature,
downloads_dir: config.downloads_dir,
folder_listing_page_size: config.folder_listing_page_size,
folder_aliases: config.folder_aliases.unwrap_or_default(),
email_listing_page_size: config.email_listing_page_size,
email_listing_datetime_fmt: config.email_listing_datetime_fmt,
email_listing_datetime_local_tz: config.email_listing_datetime_local_tz,
email_reading_headers: config.email_reading_headers,
email_reading_format: config.email_reading_format.unwrap_or_default(),
email_writing_headers: config.email_writing_headers,
email_sending_save_copy: config.email_sending_save_copy,
email_hooks: config.email_hooks.unwrap_or_default(),
sync: config.sync.unwrap_or_default(),
sync_dir: config.sync_dir,
sync_folders_strategy: config.sync_folders_strategy.unwrap_or_default(),
#[cfg(feature = "pgp")]
pgp: config.pgp,
},
)
},
)),
};
let account_config = config.account(&account_name)?;
Ok((toml_account_config, account_config))
}
}
#[cfg(test)]

View file

@ -56,21 +56,16 @@ async fn main() -> Result<()> {
// checks mailto command before app initialization
let raw_args: Vec<String> = env::args().collect();
if raw_args.len() > 1 && raw_args[1].starts_with("mailto:") {
// let url = Url::parse(&raw_args[1])?;
// let config = DeserializedConfig::from_opt_path(None).await?;
// let account_config = config.to_account_config(None)?;
// let backend = BackendBuilder::new(account_config.clone()).build().await?;
// let mut printer = StdoutPrinter::default();
let url = Url::parse(&raw_args[1])?;
let (toml_account_config, account_config) = DeserializedConfig::from_opt_path(None)
.await?
.into_account_configs(None)?;
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), false).await?;
let backend = backend_builder.build().await?;
let mut printer = StdoutPrinter::default();
// email::handlers::mailto(
// &account_config,
// &backend,
// &mut printer,
// &url,
// )
// .await?;
return Ok(());
return email::handlers::mailto(&account_config, &backend, &mut printer, &url).await;
}
let app = create_app();
@ -93,15 +88,18 @@ async fn main() -> Result<()> {
_ => (),
}
let config = DeserializedConfig::from_opt_path(config::args::parse_arg(&m)).await?;
let maybe_account_name = account::args::parse_arg(&m);
let toml_config = DeserializedConfig::from_opt_path(config::args::parse_arg(&m)).await?;
let (toml_account_config, account_config) = toml_config
.clone()
.into_account_configs(maybe_account_name)?;
let folder = folder::args::parse_source_arg(&m);
let disable_cache = cache::args::parse_disable_cache_flag(&m);
let backend_builder = BackendBuilder::new(config.clone(), maybe_account_name).await?;
let account_config = &backend_builder.account_config;
let mut printer = StdoutPrinter::try_from(&m)?;
// FIXME
// #[cfg(feature = "imap-backend")]
// if let BackendConfig::Imap(imap_config) = &account_config.backend {
// let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER);
@ -124,10 +122,12 @@ async fn main() -> Result<()> {
match account::args::matches(&m)? {
Some(account::args::Cmd::List(max_width)) => {
account::handlers::list(max_width, &account_config, &config, &mut printer)?;
account::handlers::list(max_width, &account_config, &toml_config, &mut printer)?;
return Ok(());
}
Some(account::args::Cmd::Sync(strategy, dry_run)) => {
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), true).await?;
let sync_builder = AccountSyncBuilder::new(backend_builder.0)
.await?
.with_some_folders_strategy(strategy)
@ -148,26 +148,39 @@ async fn main() -> Result<()> {
let folder = folder
.ok_or_else(|| anyhow!("the folder argument is missing"))
.context("cannot create folder")?;
let backend = backend_builder.clone().build().await?;
folder::handlers::create(&mut printer, &backend, &folder).await?;
return Ok(());
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
return folder::handlers::create(&mut printer, &backend, &folder).await;
}
Some(folder::args::Cmd::List(max_width)) => {
let backend = backend_builder.clone().build().await?;
folder::handlers::list(&account_config, &mut printer, &backend, max_width).await?;
return Ok(());
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
return folder::handlers::list(&account_config, &mut printer, &backend, max_width)
.await;
}
Some(folder::args::Cmd::Expunge) => {
let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER);
let backend = backend_builder.clone().build().await?;
folder::handlers::expunge(&mut printer, &backend, &folder).await?;
return Ok(());
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
return folder::handlers::expunge(&mut printer, &backend, &folder).await;
}
Some(folder::args::Cmd::Delete) => {
let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER);
let backend = backend_builder.clone().build().await?;
folder::handlers::delete(&mut printer, &backend, &folder).await?;
return Ok(());
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
return folder::handlers::delete(&mut printer, &backend, &folder).await;
}
_ => (),
}
@ -176,9 +189,13 @@ async fn main() -> Result<()> {
match email::args::matches(&m)? {
Some(email::args::Cmd::Attachments(ids)) => {
let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER);
let backend = backend_builder.clone().build().await?;
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
let id_mapper = IdMapper::new(&backend, &account_config, &folder)?;
email::handlers::attachments(
return email::handlers::attachments(
&account_config,
&mut printer,
&id_mapper,
@ -186,34 +203,45 @@ async fn main() -> Result<()> {
&folder,
ids,
)
.await?;
return Ok(());
.await;
}
Some(email::args::Cmd::Copy(ids, to_folder)) => {
let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER);
let backend = backend_builder.clone().build().await?;
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
let id_mapper = IdMapper::new(&backend, &account_config, &folder)?;
email::handlers::copy(&mut printer, &id_mapper, &backend, &folder, to_folder, ids)
.await?;
return Ok(());
return email::handlers::copy(
&mut printer,
&id_mapper,
&backend,
&folder,
to_folder,
ids,
)
.await;
}
Some(email::args::Cmd::Delete(ids)) => {
let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER);
let backend = backend_builder.clone().build().await?;
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
let id_mapper = IdMapper::new(&backend, &account_config, &folder)?;
email::handlers::delete(&mut printer, &id_mapper, &backend, &folder, ids).await?;
return Ok(());
return email::handlers::delete(&mut printer, &id_mapper, &backend, &folder, ids).await;
}
Some(email::args::Cmd::Forward(id, headers, body)) => {
let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER);
let backend = backend_builder.clone().build().await?;
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
let id_mapper = IdMapper::new(&backend, &account_config, &folder)?;
email::handlers::forward(
return email::handlers::forward(
&account_config,
&mut printer,
&id_mapper,
@ -223,16 +251,17 @@ async fn main() -> Result<()> {
headers,
body,
)
.await?;
return Ok(());
.await;
}
Some(email::args::Cmd::List(max_width, page_size, page)) => {
let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER);
let backend = backend_builder.clone().build().await?;
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
let id_mapper = IdMapper::new(&backend, &account_config, &folder)?;
email::handlers::list(
return email::handlers::list(
&account_config,
&mut printer,
&id_mapper,
@ -242,26 +271,35 @@ async fn main() -> Result<()> {
page_size,
page,
)
.await?;
return Ok(());
.await;
}
Some(email::args::Cmd::Move(ids, to_folder)) => {
let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER);
let backend = backend_builder.clone().build().await?;
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
let id_mapper = IdMapper::new(&backend, &account_config, &folder)?;
email::handlers::move_(&mut printer, &id_mapper, &backend, &folder, to_folder, ids)
.await?;
return Ok(());
return email::handlers::move_(
&mut printer,
&id_mapper,
&backend,
&folder,
to_folder,
ids,
)
.await;
}
Some(email::args::Cmd::Read(ids, text_mime, raw, headers)) => {
let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER);
let backend = backend_builder.clone().build().await?;
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
let id_mapper = IdMapper::new(&backend, &account_config, &folder)?;
email::handlers::read(
return email::handlers::read(
&account_config,
&mut printer,
&id_mapper,
@ -272,16 +310,17 @@ async fn main() -> Result<()> {
raw,
headers,
)
.await?;
return Ok(());
.await;
}
Some(email::args::Cmd::Reply(id, all, headers, body)) => {
let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER);
let backend = backend_builder.clone().build().await?;
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
let id_mapper = IdMapper::new(&backend, &account_config, &folder)?;
email::handlers::reply(
return email::handlers::reply(
&account_config,
&mut printer,
&id_mapper,
@ -292,25 +331,28 @@ async fn main() -> Result<()> {
headers,
body,
)
.await?;
return Ok(());
.await;
}
Some(email::args::Cmd::Save(raw_email)) => {
let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER);
let backend = backend_builder.clone().build().await?;
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
let id_mapper = IdMapper::new(&backend, &account_config, &folder)?;
email::handlers::save(&mut printer, &id_mapper, &backend, &folder, raw_email).await?;
return Ok(());
return email::handlers::save(&mut printer, &id_mapper, &backend, &folder, raw_email)
.await;
}
Some(email::args::Cmd::Search(query, max_width, page_size, page)) => {
let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER);
let backend = backend_builder.clone().build().await?;
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
let id_mapper = IdMapper::new(&backend, &account_config, &folder)?;
email::handlers::search(
return email::handlers::search(
&account_config,
&mut printer,
&id_mapper,
@ -321,16 +363,17 @@ async fn main() -> Result<()> {
page_size,
page,
)
.await?;
return Ok(());
.await;
}
Some(email::args::Cmd::Sort(criteria, query, max_width, page_size, page)) => {
let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER);
let backend = backend_builder.clone().build().await?;
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
let id_mapper = IdMapper::new(&backend, &account_config, &folder)?;
email::handlers::sort(
return email::handlers::sort(
&account_config,
&mut printer,
&id_mapper,
@ -342,56 +385,79 @@ async fn main() -> Result<()> {
page_size,
page,
)
.await?;
return Ok(());
.await;
}
Some(email::args::Cmd::Send(raw_email)) => {
let backend = backend_builder.clone().build().await?;
email::handlers::send(&account_config, &mut printer, &backend, raw_email).await?;
return Ok(());
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
return email::handlers::send(&account_config, &mut printer, &backend, raw_email).await;
}
Some(email::args::Cmd::Flag(m)) => match m {
Some(flag::args::Cmd::Set(ids, ref flags)) => {
let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER);
let backend = backend_builder.clone().build().await?;
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
let id_mapper = IdMapper::new(&backend, &account_config, &folder)?;
flag::handlers::set(&mut printer, &id_mapper, &backend, &folder, ids, flags)
.await?;
return Ok(());
return flag::handlers::set(
&mut printer,
&id_mapper,
&backend,
&folder,
ids,
flags,
)
.await;
}
Some(flag::args::Cmd::Add(ids, ref flags)) => {
let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER);
let backend = backend_builder.clone().build().await?;
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
let id_mapper = IdMapper::new(&backend, &account_config, &folder)?;
flag::handlers::add(&mut printer, &id_mapper, &backend, &folder, ids, flags)
.await?;
return Ok(());
return flag::handlers::add(
&mut printer,
&id_mapper,
&backend,
&folder,
ids,
flags,
)
.await;
}
Some(flag::args::Cmd::Remove(ids, ref flags)) => {
let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER);
let backend = backend_builder.clone().build().await?;
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
let id_mapper = IdMapper::new(&backend, &account_config, &folder)?;
flag::handlers::remove(&mut printer, &id_mapper, &backend, &folder, ids, flags)
.await?;
return Ok(());
return flag::handlers::remove(
&mut printer,
&id_mapper,
&backend,
&folder,
ids,
flags,
)
.await;
}
_ => (),
},
Some(email::args::Cmd::Tpl(m)) => match m {
Some(tpl::args::Cmd::Forward(id, headers, body)) => {
let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER);
let backend = backend_builder.clone().build().await?;
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
let id_mapper = IdMapper::new(&backend, &account_config, &folder)?;
tpl::handlers::forward(
return tpl::handlers::forward(
&account_config,
&mut printer,
&id_mapper,
@ -401,9 +467,7 @@ async fn main() -> Result<()> {
headers,
body,
)
.await?;
return Ok(());
.await;
}
Some(tpl::args::Cmd::Write(headers, body)) => {
tpl::handlers::write(&account_config, &mut printer, headers, body).await?;
@ -411,10 +475,12 @@ async fn main() -> Result<()> {
}
Some(tpl::args::Cmd::Reply(id, all, headers, body)) => {
let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER);
let backend = backend_builder.clone().build().await?;
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
let id_mapper = IdMapper::new(&backend, &account_config, &folder)?;
tpl::handlers::reply(
return tpl::handlers::reply(
&account_config,
&mut printer,
&id_mapper,
@ -425,16 +491,16 @@ async fn main() -> Result<()> {
headers,
body,
)
.await?;
return Ok(());
.await;
}
Some(tpl::args::Cmd::Save(tpl)) => {
let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER);
let backend = backend_builder.clone().build().await?;
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
let id_mapper = IdMapper::new(&backend, &account_config, &folder)?;
tpl::handlers::save(
return tpl::handlers::save(
&account_config,
&mut printer,
&id_mapper,
@ -442,23 +508,24 @@ async fn main() -> Result<()> {
&folder,
tpl,
)
.await?;
return Ok(());
.await;
}
Some(tpl::args::Cmd::Send(tpl)) => {
let backend = backend_builder.clone().build().await?;
tpl::handlers::send(&account_config, &mut printer, &backend, tpl).await?;
return Ok(());
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
return tpl::handlers::send(&account_config, &mut printer, &backend, tpl).await;
}
_ => (),
},
Some(email::args::Cmd::Write(headers, body)) => {
let backend = backend_builder.clone().build().await?;
email::handlers::write(&account_config, &mut printer, &backend, headers, body).await?;
return Ok(());
let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), disable_cache)
.await?;
let backend = backend_builder.build().await?;
return email::handlers::write(&account_config, &mut printer, &backend, headers, body)
.await;
}
_ => (),
}