mirror of
https://github.com/soywod/himalaya.git
synced 2024-11-22 02:50:19 +00:00
refactor configs to match new nested api from lib
This commit is contained in:
parent
8e05be7f77
commit
2e0ec913cf
23 changed files with 214 additions and 292 deletions
64
Cargo.lock
generated
64
Cargo.lock
generated
|
@ -272,7 +272,7 @@ checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.40",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -307,7 +307,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.40",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -679,7 +679,7 @@ dependencies = [
|
|||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.40",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -898,7 +898,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.40",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1192,9 +1192,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "email-lib"
|
||||
version = "0.16.0"
|
||||
version = "0.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e3f51881639d657795ea95cd2fb065b8d9249912100b297730133ffbf38e0a5"
|
||||
checksum = "743371f76482a94403ce0ab49da129065fc84cbcf9ed126524882c6ed5389efc"
|
||||
dependencies = [
|
||||
"advisory-lock",
|
||||
"anyhow",
|
||||
|
@ -1225,6 +1225,7 @@ dependencies = [
|
|||
"rustls 0.22.1",
|
||||
"rustls-native-certs",
|
||||
"secret-lib",
|
||||
"serde",
|
||||
"shellexpand-utils",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
|
@ -1269,7 +1270,7 @@ dependencies = [
|
|||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.40",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1290,7 +1291,7 @@ checksum = "f95e2801cd355d4a1a3e3953ce6ee5ae9603a5c833455343a8bfe3f44d418246"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.40",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1557,7 +1558,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.40",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2734,15 +2735,17 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "keyring-lib"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad2271300047bf0f2f4c4b6c51cbf7f848621aa373a3e80742bbdc0148110578"
|
||||
checksum = "2d5fa6d6a6a7d27d09c3e5e6c0371d97dd4cc3b0208eaba9f26dae728f1ae072"
|
||||
dependencies = [
|
||||
"keyring",
|
||||
"log",
|
||||
"once_cell",
|
||||
"secret-service",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3011,9 +3014,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "mml-lib"
|
||||
version = "1.0.2"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6bda7bfafd584f65bc7bb85a60be2a6ccf6f384f1e1d27b697d8b6524869213"
|
||||
checksum = "a5498df8f63c5c204deae46529a6cbddbe7f5cfe70723165e6fde42e8e2490df"
|
||||
dependencies = [
|
||||
"async-recursion",
|
||||
"chumsky",
|
||||
|
@ -3026,6 +3029,7 @@ dependencies = [
|
|||
"pgp-lib",
|
||||
"process-lib",
|
||||
"secret-lib",
|
||||
"serde",
|
||||
"shellexpand-utils",
|
||||
"thiserror",
|
||||
"tree_magic_mini",
|
||||
|
@ -3129,7 +3133,7 @@ checksum = "cfb77679af88f8b125209d354a202862602672222e7f2313fdd6dc349bad4712"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.40",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3641,12 +3645,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "process-lib"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "651bb0e9f091cf2ff67fbc6151d92c97bb2af864bfdbb85def0442250e10562b"
|
||||
checksum = "76cb01de71b99c9d36dacf51218b950e03f80a86ee5f910ff723a1693796bad3"
|
||||
dependencies = [
|
||||
"log",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
]
|
||||
|
@ -4152,12 +4157,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "secret-lib"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5064a00687ed7f19a36e30a8b2695739d60f3d423f229097c8d110f9f76a8a96"
|
||||
checksum = "b06c6eda723fc17a853234defb5784ec2b3377d9bce8a6577c89788f1b6dc117"
|
||||
dependencies = [
|
||||
"keyring-lib",
|
||||
"process-lib",
|
||||
"serde",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
|
@ -4226,7 +4232,7 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.40",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4258,7 +4264,7 @@ checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.40",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4490,9 +4496,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.39"
|
||||
version = "2.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
|
||||
checksum = "13fa70a4ee923979ffb522cacce59d34421ebdea5625e1073c4326ef9d2dd42e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -4588,7 +4594,7 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.40",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4664,7 +4670,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.40",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4786,7 +4792,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.40",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -5014,7 +5020,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.40",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
|
@ -5048,7 +5054,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.40",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
@ -5487,7 +5493,7 @@ checksum = "be912bf68235a88fbefd1b73415cb218405958d1655b2ece9035a19920bdf6ba"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.40",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -5507,7 +5513,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.40",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
10
Cargo.toml
10
Cargo.toml
|
@ -50,20 +50,20 @@ clap_mangen = "0.2"
|
|||
console = "0.15.2"
|
||||
dialoguer = "0.10.2"
|
||||
dirs = "4.0"
|
||||
email-lib = { version = "=0.16.0", default-features = false }
|
||||
email-lib = { version = "=0.17.1", default-features = false }
|
||||
email_address = "0.2.4"
|
||||
env_logger = "0.8"
|
||||
erased-serde = "0.3"
|
||||
indicatif = "0.17"
|
||||
keyring-lib = "=0.2.0"
|
||||
keyring-lib = "=0.3.0"
|
||||
log = "0.4"
|
||||
mail-builder = "0.3"
|
||||
md5 = "0.7.0"
|
||||
mml-lib = { version = "=1.0.2", default-features = false }
|
||||
mml-lib = { version = "=1.0.3", default-features = false }
|
||||
oauth-lib = "=0.1.0"
|
||||
once_cell = "1.16"
|
||||
process-lib = "=0.2.0"
|
||||
secret-lib = "=0.2.0"
|
||||
process-lib = "=0.3.0"
|
||||
secret-lib = "=0.3.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
shellexpand-utils = "=0.2.0"
|
||||
|
|
29
README.md
29
README.md
|
@ -85,35 +85,22 @@ Please read the [documentation](https://pimalaya.org/himalaya/cli/configuration/
|
|||
|
||||
## Contributing
|
||||
|
||||
If you find a **bug** that [does not exist yet](https://todo.sr.ht/~soywod/pimalaya), please send an email at [~soywod/pimalaya@todo.sr.ht](mailto:~soywod/pimalaya@todo.sr.ht).
|
||||
If you want to **report a bug** that [does not exist yet](https://todo.sr.ht/~soywod/pimalaya), please send an email at [~soywod/pimalaya@todo.sr.ht](mailto:~soywod/pimalaya@todo.sr.ht).
|
||||
|
||||
If you have a **question**, please send an email at [~soywod/pimalaya@lists.sr.ht](mailto:~soywod/pimalaya@lists.sr.ht).
|
||||
If you want to **propose a feature** or **fix a bug**, please send a patch at [~soywod/pimalaya@lists.sr.ht](mailto:~soywod/pimalaya@lists.sr.ht) using [git send-email](https://git-scm.com/docs/git-send-email). Follow [this guide](https://git-send-email.io/) to configure git properly.
|
||||
|
||||
If you want to **propose a feature** or **fix a bug**, please send a patch at [~soywod/pimalaya@lists.sr.ht](mailto:~soywod/pimalaya@lists.sr.ht) using [git send-email](https://git-scm.com/docs/git-send-email) (see [this guide](https://git-send-email.io/) on how to configure it).
|
||||
If you just want to **discuss** about the project, feel free to join the [Matrix](https://matrix.org/) workspace [#pimalaya.general](https://matrix.to/#/#pimalaya.general:matrix.org) or contact me directly [@soywod](https://matrix.to/#/@soywod:matrix.org). You can also use the mailing list [[send an email](mailto:~soywod/pimalaya@lists.sr.ht)|[subscribe](mailto:~soywod/pimalaya+subscribe@lists.sr.ht)|[unsubscribe](mailto:~soywod/pimalaya+unsubscribe@lists.sr.ht)].
|
||||
|
||||
If you want to **subscribe** to the mailing list, please send an email at [~soywod/pimalaya+subscribe@lists.sr.ht](mailto:~soywod/pimalaya+subscribe@lists.sr.ht).
|
||||
|
||||
If you want to **unsubscribe** to the mailing list, please send an email at [~soywod/pimalaya+unsubscribe@lists.sr.ht](mailto:~soywod/pimalaya+unsubscribe@lists.sr.ht).
|
||||
|
||||
If you want to **discuss** about the project, feel free to join the [Matrix](https://matrix.org/) workspace [#pimalaya.himalaya](https://matrix.to/#/#pimalaya.himalaya:matrix.org) or contact me directly [@soywod](https://matrix.to/#/@soywod:matrix.org).
|
||||
|
||||
## Credits
|
||||
## Sponsoring
|
||||
|
||||
[![nlnet](https://nlnet.nl/logo/banner-160x60.png)](https://nlnet.nl/project/Himalaya/index.html)
|
||||
|
||||
Special thanks to the [nlnet](https://nlnet.nl/project/Himalaya/index.html) foundation that helped Himalaya to receive financial support from the [NGI Assure](https://www.ngi.eu/ngi-projects/ngi-assure/) program of the European Commission in September, 2022.
|
||||
Special thanks to the [NLnet foundation](https://nlnet.nl/project/Himalaya/index.html) and the [European Commission](https://www.ngi.eu/) that helped the project to receive financial support from:
|
||||
|
||||
- [IMAP RFC3501](https://tools.ietf.org/html/rfc3501)
|
||||
- [Iris](https://github.com/soywod/iris.vim), the himalaya predecessor
|
||||
- [isync](https://isync.sourceforge.io/), an email synchronizer for offline usage
|
||||
- [NeoMutt](https://neomutt.org/), an email terminal user interface
|
||||
- [Alpine](http://alpine.x10host.com/alpine/alpine-info/), an other email terminal user interface
|
||||
- [mutt-wizard](https://github.com/LukeSmithxyz/mutt-wizard), a tool over NeoMutt and isync
|
||||
- [rust-imap](https://github.com/jonhoo/rust-imap), a Rust IMAP library
|
||||
- [lettre](https://github.com/lettre/lettre), a Rust mailer library
|
||||
- [mailparse](https://github.com/staktrace/mailparse), a Rust MIME email parser.
|
||||
- [NGI Assure](https://nlnet.nl/assure/) in 2022
|
||||
- [NGI Zero Untrust](https://nlnet.nl/entrust/) in 2023
|
||||
|
||||
## Sponsoring
|
||||
If you appreciate the project, feel free to donate using one of the following providers:
|
||||
|
||||
[![GitHub](https://img.shields.io/badge/-GitHub%20Sponsors-fafbfc?logo=GitHub%20Sponsors)](https://github.com/sponsors/soywod)
|
||||
[![PayPal](https://img.shields.io/badge/-PayPal-0079c1?logo=PayPal&logoColor=ffffff)](https://www.paypal.com/paypalme/soywod)
|
||||
|
|
|
@ -1,30 +1,58 @@
|
|||
[example]
|
||||
# Make this account the default one to use when no account is given to
|
||||
# commands.
|
||||
default = true
|
||||
|
||||
# The display-name and email are used to build the full email address:
|
||||
# "My example account" <example@localhost>
|
||||
# The display-name and the email are used to build the full email
|
||||
# address: "My example account" <example@localhost>
|
||||
display-name = "My example account"
|
||||
email = "example@localhost"
|
||||
|
||||
sync = true
|
||||
sync-dir = "/tmp/himalaya-sync-example"
|
||||
# The signature can be a string or a path to a file.
|
||||
signature = "Regards,"
|
||||
signature-delim = "-- \n"
|
||||
|
||||
# The default backend used for all the features like adding folders,
|
||||
# Enable the synchronization for this account. Running the command
|
||||
# `account sync example` will synchronize all folders and all emails
|
||||
# to a local Maildir at `$XDG_DATA_HOME/himalaya/example`.
|
||||
sync.enable = true
|
||||
|
||||
# Override the default Maildir path for synchronization.
|
||||
sync.dir = "/tmp/himalaya-sync-example"
|
||||
|
||||
# Default backend used for all the features like adding folders,
|
||||
# listing envelopes or copying messages.
|
||||
backend = "imap"
|
||||
|
||||
envelope.list.page-size = 10
|
||||
envelope.list.datetime-fmt = "%F %R%:z"
|
||||
|
||||
# Date are converted to the user's local timezone.
|
||||
envelope.list.datetime-local-tz = true
|
||||
|
||||
# Override the backend used for listing envelopes.
|
||||
envelope.list.backend = "imap"
|
||||
|
||||
# Override the backend used for sending messages.
|
||||
message.send.backend = "smtp"
|
||||
|
||||
# IMAP config
|
||||
imap.host = "localhost"
|
||||
imap.port = 3143
|
||||
imap.login = "example@localhost"
|
||||
imap.ssl = false
|
||||
imap.starttls = false
|
||||
imap.insecure = true
|
||||
imap.auth = "passwd"
|
||||
imap.passwd.keyring = "example-passwd"
|
||||
imap.auth = "passwd" # or oauth2
|
||||
|
||||
# Override the backend used for sending messages.
|
||||
message.send.backend = "smtp"
|
||||
# Get password from the raw string (not safe)
|
||||
# imap.passwd.raw = "password"
|
||||
|
||||
# Get password from a shell command
|
||||
imap.passwd.cmd = ["echo example-imap-password", "cat"]
|
||||
|
||||
# Get password from your system keyring using secret service
|
||||
# Keyring secrets can be (re)set with the command `account configure example`
|
||||
# imap.passwd.keyring = "example-imap-password"
|
||||
|
||||
# SMTP config
|
||||
smtp.host = "localhost"
|
||||
|
@ -32,25 +60,9 @@ smtp.port = 3025
|
|||
smtp.login = "example@localhost"
|
||||
smtp.ssl = false
|
||||
smtp.starttls = false
|
||||
smtp.insecure = true
|
||||
smtp.auth = "passwd"
|
||||
smtp.passwd.raw = "example"
|
||||
smtp.passwd.raw = "password"
|
||||
|
||||
[example-2]
|
||||
display-name = "My example account 2"
|
||||
email = "example2@localhost"
|
||||
|
||||
backend = "imap"
|
||||
|
||||
imap.host = "localhost"
|
||||
imap.port = 3143
|
||||
imap.login = "example2@localhost"
|
||||
imap.ssl = false
|
||||
imap.starttls = false
|
||||
imap.insecure = true
|
||||
imap.auth = "passwd"
|
||||
imap.passwd.raw = "example"
|
||||
|
||||
message.send.backend = "sendmail"
|
||||
|
||||
sendmail.cmd = "sendmail"
|
||||
# PGP needs to be enabled with one of those cargo feature:
|
||||
# pgp-commands, pgp-gpg or pgp-native
|
||||
# pgp.backend = "gpg"
|
||||
|
|
|
@ -44,8 +44,8 @@ impl AccountConfigureCommand {
|
|||
#[cfg(feature = "imap")]
|
||||
if let Some(ref config) = account_config.imap {
|
||||
let reset = match &config.auth {
|
||||
ImapAuthConfig::Passwd(config) => config.reset(),
|
||||
ImapAuthConfig::OAuth2(config) => config.reset(),
|
||||
ImapAuthConfig::Passwd(config) => config.reset().await,
|
||||
ImapAuthConfig::OAuth2(config) => config.reset().await,
|
||||
};
|
||||
if let Err(err) = reset {
|
||||
warn!("error while resetting imap secrets: {err}");
|
||||
|
@ -56,8 +56,8 @@ impl AccountConfigureCommand {
|
|||
#[cfg(feature = "smtp")]
|
||||
if let Some(ref config) = account_config.smtp {
|
||||
let reset = match &config.auth {
|
||||
SmtpAuthConfig::Passwd(config) => config.reset(),
|
||||
SmtpAuthConfig::OAuth2(config) => config.reset(),
|
||||
SmtpAuthConfig::Passwd(config) => config.reset().await,
|
||||
SmtpAuthConfig::OAuth2(config) => config.reset().await,
|
||||
};
|
||||
if let Err(err) = reset {
|
||||
warn!("error while resetting smtp secrets: {err}");
|
||||
|
@ -67,7 +67,7 @@ impl AccountConfigureCommand {
|
|||
|
||||
#[cfg(feature = "pgp")]
|
||||
if let Some(ref config) = account_config.pgp {
|
||||
account_config.pgp.reset().await?;
|
||||
config.reset().await?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,10 +100,11 @@ impl AccountConfigureCommand {
|
|||
}
|
||||
|
||||
#[cfg(feature = "pgp")]
|
||||
if let Some(ref config) = config.pgp {
|
||||
if let Some(ref config) = account_config.pgp {
|
||||
config
|
||||
.pgp
|
||||
.configure(&config.email, || prompt_passwd("PGP secret key password"))
|
||||
.configure(&account_config.email, || {
|
||||
prompt_passwd("PGP secret key password")
|
||||
})
|
||||
.await?;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,10 +28,7 @@ impl AccountListCommand {
|
|||
printer.print_table(
|
||||
Box::new(accounts),
|
||||
PrintTableOpts {
|
||||
format: config
|
||||
.email_reading_format
|
||||
.as_ref()
|
||||
.unwrap_or(&Default::default()),
|
||||
format: &Default::default(),
|
||||
max_width: self.table.max_width,
|
||||
},
|
||||
)
|
||||
|
|
|
@ -4,26 +4,21 @@
|
|||
//! account in the accounts section of the user configuration file.
|
||||
|
||||
#[cfg(feature = "pgp")]
|
||||
use email::account::PgpConfig;
|
||||
use email::account::config::pgp::PgpConfig;
|
||||
#[cfg(feature = "imap")]
|
||||
use email::imap::config::ImapConfig;
|
||||
#[cfg(feature = "smtp")]
|
||||
use email::smtp::config::SmtpConfig;
|
||||
use email::{
|
||||
email::config::{EmailHooks, EmailTextPlainFormat},
|
||||
folder::sync::FolderSyncStrategy,
|
||||
maildir::config::MaildirConfig,
|
||||
account::sync::config::SyncConfig, maildir::config::MaildirConfig,
|
||||
sendmail::config::SendmailConfig,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
path::PathBuf,
|
||||
};
|
||||
use std::{collections::HashSet, path::PathBuf};
|
||||
|
||||
use crate::{
|
||||
backend::BackendKind, config::prelude::*, envelope::config::EnvelopeConfig,
|
||||
flag::config::FlagConfig, folder::config::FolderConfig, message::config::MessageConfig,
|
||||
backend::BackendKind, envelope::config::EnvelopeConfig, flag::config::FlagConfig,
|
||||
folder::config::FolderConfig, message::config::MessageConfig,
|
||||
};
|
||||
|
||||
/// Represents all existing kind of account config.
|
||||
|
@ -34,93 +29,29 @@ pub struct TomlAccountConfig {
|
|||
|
||||
pub email: String,
|
||||
pub display_name: Option<String>,
|
||||
pub signature_delim: Option<String>,
|
||||
pub signature: Option<String>,
|
||||
pub signature_delim: Option<String>,
|
||||
pub downloads_dir: Option<PathBuf>,
|
||||
|
||||
pub folder_listing_page_size: Option<usize>,
|
||||
pub folder_aliases: Option<HashMap<String, String>>,
|
||||
|
||||
pub email_listing_page_size: Option<usize>,
|
||||
pub email_listing_datetime_fmt: Option<String>,
|
||||
pub email_listing_datetime_local_tz: Option<bool>,
|
||||
pub email_reading_headers: Option<Vec<String>>,
|
||||
#[serde(
|
||||
default,
|
||||
with = "OptionEmailTextPlainFormatDef",
|
||||
skip_serializing_if = "Option::is_none"
|
||||
)]
|
||||
pub email_reading_format: Option<EmailTextPlainFormat>,
|
||||
pub email_writing_headers: Option<Vec<String>>,
|
||||
pub email_sending_save_copy: Option<bool>,
|
||||
#[serde(
|
||||
default,
|
||||
with = "OptionEmailHooksDef",
|
||||
skip_serializing_if = "Option::is_none"
|
||||
)]
|
||||
pub email_hooks: Option<EmailHooks>,
|
||||
|
||||
pub sync: Option<bool>,
|
||||
pub sync_dir: Option<PathBuf>,
|
||||
#[serde(
|
||||
default,
|
||||
with = "OptionFolderSyncStrategyDef",
|
||||
skip_serializing_if = "Option::is_none"
|
||||
)]
|
||||
pub sync_folders_strategy: Option<FolderSyncStrategy>,
|
||||
|
||||
pub backend: Option<BackendKind>,
|
||||
|
||||
pub sync: Option<SyncConfig>,
|
||||
pub folder: Option<FolderConfig>,
|
||||
pub envelope: Option<EnvelopeConfig>,
|
||||
pub flag: Option<FlagConfig>,
|
||||
pub message: Option<MessageConfig>,
|
||||
|
||||
#[cfg(feature = "imap")]
|
||||
#[serde(
|
||||
default,
|
||||
with = "OptionImapConfigDef",
|
||||
skip_serializing_if = "Option::is_none"
|
||||
)]
|
||||
pub imap: Option<ImapConfig>,
|
||||
|
||||
#[serde(
|
||||
default,
|
||||
with = "OptionMaildirConfigDef",
|
||||
skip_serializing_if = "Option::is_none"
|
||||
)]
|
||||
pub maildir: Option<MaildirConfig>,
|
||||
|
||||
#[cfg(feature = "notmuch")]
|
||||
#[serde(
|
||||
default,
|
||||
with = "OptionNotmuchConfigDef",
|
||||
skip_serializing_if = "Option::is_none"
|
||||
)]
|
||||
pub notmuch: Option<NotmuchConfig>,
|
||||
|
||||
#[cfg(feature = "smtp")]
|
||||
#[serde(
|
||||
default,
|
||||
with = "OptionSmtpConfigDef",
|
||||
skip_serializing_if = "Option::is_none"
|
||||
)]
|
||||
pub smtp: Option<SmtpConfig>,
|
||||
|
||||
#[serde(
|
||||
default,
|
||||
with = "OptionSendmailConfigDef",
|
||||
skip_serializing_if = "Option::is_none"
|
||||
)]
|
||||
pub sendmail: Option<SendmailConfig>,
|
||||
|
||||
#[cfg(feature = "pgp")]
|
||||
#[serde(
|
||||
default,
|
||||
with = "OptionPgpConfigDef",
|
||||
skip_serializing_if = "Option::is_none"
|
||||
)]
|
||||
pub pgp: Option<PgpConfig>,
|
||||
|
||||
pub backend: Option<BackendKind>,
|
||||
#[cfg(feature = "maildir")]
|
||||
pub maildir: Option<MaildirConfig>,
|
||||
#[cfg(feature = "imap")]
|
||||
pub imap: Option<ImapConfig>,
|
||||
#[cfg(feature = "notmuch")]
|
||||
pub notmuch: Option<NotmuchConfig>,
|
||||
#[cfg(feature = "smtp")]
|
||||
pub smtp: Option<SmtpConfig>,
|
||||
#[cfg(feature = "sendmail")]
|
||||
pub sendmail: Option<SendmailConfig>,
|
||||
}
|
||||
|
||||
impl TomlAccountConfig {
|
||||
|
@ -207,7 +138,7 @@ impl TomlAccountConfig {
|
|||
pub fn add_raw_message_kind(&self) -> Option<&BackendKind> {
|
||||
self.message
|
||||
.as_ref()
|
||||
.and_then(|msg| msg.add.as_ref())
|
||||
.and_then(|msg| msg.write.as_ref())
|
||||
.and_then(|add| add.backend.as_ref())
|
||||
.or_else(|| self.backend.as_ref())
|
||||
}
|
||||
|
@ -223,7 +154,7 @@ impl TomlAccountConfig {
|
|||
pub fn get_messages_kind(&self) -> Option<&BackendKind> {
|
||||
self.message
|
||||
.as_ref()
|
||||
.and_then(|message| message.get.as_ref())
|
||||
.and_then(|message| message.read.as_ref())
|
||||
.and_then(|get| get.backend.as_ref())
|
||||
.or_else(|| self.backend.as_ref())
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use anyhow::{bail, Result};
|
||||
use dialoguer::{Confirm, Input};
|
||||
use email::account::sync::config::SyncConfig;
|
||||
use email_address::EmailAddress;
|
||||
|
||||
use crate::{
|
||||
|
@ -87,15 +88,20 @@ pub(crate) async fn configure() -> Result<Option<(String, TomlAccountConfig)>> {
|
|||
_ => (),
|
||||
};
|
||||
|
||||
config.sync = Some(
|
||||
Confirm::new()
|
||||
let should_configure_sync = Confirm::new()
|
||||
.with_prompt(wizard_prompt!(
|
||||
"Do you need an offline access to your account?"
|
||||
))
|
||||
.default(false)
|
||||
.interact_opt()?
|
||||
.unwrap_or_default(),
|
||||
);
|
||||
.unwrap_or_default();
|
||||
|
||||
if should_configure_sync {
|
||||
config.sync = Some(SyncConfig {
|
||||
enable: Some(true),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
||||
Ok(Some((account_name, config)))
|
||||
}
|
||||
|
|
|
@ -173,7 +173,7 @@ impl BackendBuilder {
|
|||
MaildirSessionBuilder::new(account_config.clone(), mdir_config.clone())
|
||||
}),
|
||||
maildir_for_sync: Some(MaildirConfig {
|
||||
root_dir: account_config.sync_dir()?,
|
||||
root_dir: account_config.get_sync_dir()?,
|
||||
})
|
||||
.filter(|_| is_maildir_for_sync_used)
|
||||
.map(|mdir_config| MaildirSessionBuilder::new(account_config.clone(), mdir_config)),
|
||||
|
@ -691,7 +691,7 @@ impl Backend {
|
|||
id_mapper = IdMapper::new(
|
||||
&self.backend.account_config,
|
||||
folder,
|
||||
self.backend.account_config.sync_dir()?,
|
||||
self.backend.account_config.get_sync_dir()?,
|
||||
)?;
|
||||
}
|
||||
#[cfg(feature = "notmuch")]
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
pub mod args;
|
||||
pub mod prelude;
|
||||
pub mod wizard;
|
||||
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use dialoguer::Confirm;
|
||||
use dirs::{config_dir, home_dir};
|
||||
use email::{
|
||||
account::config::AccountConfig,
|
||||
config::Config,
|
||||
email::config::{EmailHooks, EmailTextPlainFormat},
|
||||
account::config::AccountConfig, config::Config, envelope::config::EnvelopeConfig,
|
||||
folder::config::FolderConfig, message::config::MessageConfig,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use shellexpand_utils::{canonicalize, expand};
|
||||
|
@ -20,10 +18,7 @@ use std::{
|
|||
};
|
||||
use toml;
|
||||
|
||||
use crate::{
|
||||
account::config::TomlAccountConfig, backend::BackendKind, config::prelude::*, wizard_prompt,
|
||||
wizard_warn,
|
||||
};
|
||||
use crate::{account::config::TomlAccountConfig, backend::BackendKind, wizard_prompt, wizard_warn};
|
||||
|
||||
/// Represents the user config file.
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)]
|
||||
|
@ -31,32 +26,10 @@ use crate::{
|
|||
pub struct TomlConfig {
|
||||
#[serde(alias = "name")]
|
||||
pub display_name: Option<String>,
|
||||
pub signature_delim: Option<String>,
|
||||
pub signature: Option<String>,
|
||||
pub signature_delim: Option<String>,
|
||||
pub downloads_dir: Option<PathBuf>,
|
||||
|
||||
pub folder_listing_page_size: Option<usize>,
|
||||
pub folder_aliases: Option<HashMap<String, String>>,
|
||||
|
||||
pub email_listing_page_size: Option<usize>,
|
||||
pub email_listing_datetime_fmt: Option<String>,
|
||||
pub email_listing_datetime_local_tz: Option<bool>,
|
||||
pub email_reading_headers: Option<Vec<String>>,
|
||||
#[serde(
|
||||
default,
|
||||
with = "OptionEmailTextPlainFormatDef",
|
||||
skip_serializing_if = "Option::is_none"
|
||||
)]
|
||||
pub email_reading_format: Option<EmailTextPlainFormat>,
|
||||
pub email_writing_headers: Option<Vec<String>>,
|
||||
pub email_sending_save_copy: Option<bool>,
|
||||
#[serde(
|
||||
default,
|
||||
with = "OptionEmailHooksDef",
|
||||
skip_serializing_if = "Option::is_none"
|
||||
)]
|
||||
pub email_hooks: Option<EmailHooks>,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub accounts: HashMap<String, TomlAccountConfig>,
|
||||
}
|
||||
|
@ -203,7 +176,7 @@ impl TomlConfig {
|
|||
let (account_name, mut toml_account_config) =
|
||||
self.into_toml_account_config(account_name)?;
|
||||
|
||||
if let Some(true) = toml_account_config.sync {
|
||||
if let Some(true) = toml_account_config.sync.as_ref().and_then(|c| c.enable) {
|
||||
if !disable_cache {
|
||||
toml_account_config.backend = Some(BackendKind::MaildirForSync);
|
||||
}
|
||||
|
@ -211,22 +184,10 @@ impl TomlConfig {
|
|||
|
||||
let config = Config {
|
||||
display_name: self.display_name,
|
||||
signature_delim: self.signature_delim,
|
||||
signature: self.signature,
|
||||
signature_delim: self.signature_delim,
|
||||
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)| {
|
||||
(
|
||||
|
@ -235,27 +196,23 @@ impl TomlConfig {
|
|||
name,
|
||||
email: config.email,
|
||||
display_name: config.display_name,
|
||||
signature_delim: config.signature_delim,
|
||||
signature: config.signature,
|
||||
signature_delim: config.signature_delim,
|
||||
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(),
|
||||
|
||||
folder: config.folder.map(|c| FolderConfig {
|
||||
aliases: c.remote.aliases,
|
||||
list: c.list.map(|c| c.remote),
|
||||
}),
|
||||
envelope: config.envelope.map(|c| EnvelopeConfig {
|
||||
list: c.list.map(|c| c.remote),
|
||||
}),
|
||||
message: config.message.map(|c| MessageConfig {
|
||||
read: c.read.map(|c| c.remote),
|
||||
write: c.write.map(|c| c.remote),
|
||||
send: c.send.map(|c| c.remote),
|
||||
}),
|
||||
sync: config.sync,
|
||||
#[cfg(feature = "pgp")]
|
||||
pgp: config.pgp,
|
||||
},
|
||||
|
|
|
@ -58,7 +58,7 @@ impl EnvelopeListCommand {
|
|||
|
||||
let page_size = self
|
||||
.page_size
|
||||
.unwrap_or(account_config.email_listing_page_size());
|
||||
.unwrap_or(account_config.get_envelope_list_page_size());
|
||||
let page = 1.max(self.page) - 1;
|
||||
|
||||
let envelopes = backend.list_envelopes(folder, page_size, page).await?;
|
||||
|
@ -66,7 +66,7 @@ impl EnvelopeListCommand {
|
|||
printer.print_table(
|
||||
Box::new(envelopes),
|
||||
PrintTableOpts {
|
||||
format: &account_config.email_reading_format,
|
||||
format: &account_config.get_message_read_format(),
|
||||
max_width: self.table.max_width,
|
||||
},
|
||||
)?;
|
||||
|
|
|
@ -28,6 +28,9 @@ impl EnvelopeConfig {
|
|||
#[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)]
|
||||
pub struct EnvelopeListConfig {
|
||||
pub backend: Option<BackendKind>,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub remote: email::envelope::list::config::EnvelopeListConfig,
|
||||
}
|
||||
|
||||
impl EnvelopeListConfig {
|
||||
|
|
|
@ -65,12 +65,11 @@ impl AttachmentDownloadCommand {
|
|||
))?;
|
||||
|
||||
for attachment in attachments {
|
||||
let filename = attachment
|
||||
let filename: PathBuf = attachment
|
||||
.filename
|
||||
.map(PathBuf::from)
|
||||
.and_then(|f| f.file_name().map(|f| f.to_string_lossy().to_string()))
|
||||
.unwrap_or_else(|| Uuid::new_v4().to_string());
|
||||
let filepath = account_config.download_fpath(&filename)?;
|
||||
.unwrap_or_else(|| Uuid::new_v4().to_string())
|
||||
.into();
|
||||
let filepath = account_config.get_download_file_path(&filename)?;
|
||||
printer.print_log(format!("Downloading {:?}…", filepath))?;
|
||||
fs::write(&filepath, &attachment.body)
|
||||
.with_context(|| format!("cannot save attachment at {filepath:?}"))?;
|
||||
|
|
|
@ -60,7 +60,7 @@ impl MessageMailtoCommand {
|
|||
}
|
||||
}
|
||||
|
||||
match account_config.signature() {
|
||||
match account_config.find_full_signature() {
|
||||
Ok(Some(ref signature)) => builder = builder.text_body(body + "\n\n" + signature),
|
||||
Ok(None) => builder = builder.text_body(body),
|
||||
Err(err) => {
|
||||
|
@ -71,7 +71,7 @@ impl MessageMailtoCommand {
|
|||
|
||||
let tpl = account_config
|
||||
.generate_tpl_interpreter()
|
||||
.with_show_only_headers(account_config.email_writing_headers())
|
||||
.with_show_only_headers(account_config.get_message_write_headers())
|
||||
.build()
|
||||
.from_msg_builder(builder)
|
||||
.await?;
|
||||
|
|
|
@ -35,7 +35,7 @@ impl MessageSendCommand {
|
|||
let (toml_account_config, account_config) =
|
||||
config.clone().into_account_configs(account, cache)?;
|
||||
let backend = Backend::new(toml_account_config, account_config.clone(), true).await?;
|
||||
let folder = account_config.sent_folder_alias()?;
|
||||
let folder = account_config.get_sent_folder_alias()?;
|
||||
|
||||
let is_tty = io::stdin().is_terminal();
|
||||
let is_json = printer.is_json();
|
||||
|
@ -52,7 +52,7 @@ impl MessageSendCommand {
|
|||
|
||||
backend.send_raw_message(msg.as_bytes()).await?;
|
||||
|
||||
if account_config.email_sending_save_copy.unwrap_or_default() {
|
||||
if account_config.should_save_copy_sent_message() {
|
||||
backend
|
||||
.add_raw_message_with_flag(&folder, msg.as_bytes(), Flag::Seen)
|
||||
.await?;
|
||||
|
|
|
@ -5,12 +5,12 @@ use crate::backend::BackendKind;
|
|||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)]
|
||||
pub struct MessageConfig {
|
||||
pub add: Option<MessageAddConfig>,
|
||||
pub write: Option<MessageAddConfig>,
|
||||
pub send: Option<MessageSendConfig>,
|
||||
pub peek: Option<MessagePeekConfig>,
|
||||
pub get: Option<MessageGetConfig>,
|
||||
pub read: Option<MessageGetConfig>,
|
||||
pub copy: Option<MessageCopyConfig>,
|
||||
#[serde(default, rename = "move", skip_serializing_if = "Option::is_none")]
|
||||
#[serde(rename = "move")]
|
||||
pub move_: Option<MessageMoveConfig>,
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ impl MessageConfig {
|
|||
pub fn get_used_backends(&self) -> HashSet<&BackendKind> {
|
||||
let mut kinds = HashSet::default();
|
||||
|
||||
if let Some(add) = &self.add {
|
||||
if let Some(add) = &self.write {
|
||||
kinds.extend(add.get_used_backends());
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ impl MessageConfig {
|
|||
kinds.extend(peek.get_used_backends());
|
||||
}
|
||||
|
||||
if let Some(get) = &self.get {
|
||||
if let Some(get) = &self.read {
|
||||
kinds.extend(get.get_used_backends());
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,9 @@ impl MessageConfig {
|
|||
#[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)]
|
||||
pub struct MessageAddConfig {
|
||||
pub backend: Option<BackendKind>,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub remote: email::message::add_raw::config::MessageWriteConfig,
|
||||
}
|
||||
|
||||
impl MessageAddConfig {
|
||||
|
@ -66,6 +69,9 @@ impl MessageAddConfig {
|
|||
#[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)]
|
||||
pub struct MessageSendConfig {
|
||||
pub backend: Option<BackendKind>,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub remote: email::message::send_raw::config::MessageSendConfig,
|
||||
}
|
||||
|
||||
impl MessageSendConfig {
|
||||
|
@ -100,6 +106,9 @@ impl MessagePeekConfig {
|
|||
#[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)]
|
||||
pub struct MessageGetConfig {
|
||||
pub backend: Option<BackendKind>,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub remote: email::message::get::config::MessageReadConfig,
|
||||
}
|
||||
|
||||
impl MessageGetConfig {
|
||||
|
|
|
@ -60,7 +60,7 @@ impl TemplateSaveCommand {
|
|||
let mut compiler = MmlCompilerBuilder::new();
|
||||
|
||||
#[cfg(feature = "pgp")]
|
||||
compiler.set_some_pgp(config.pgp.clone());
|
||||
compiler.set_some_pgp(account_config.pgp.clone());
|
||||
|
||||
let msg = compiler.build(tpl.as_str())?.compile().await?.into_vec()?;
|
||||
backend.add_raw_message(folder, &msg).await?;
|
||||
|
|
|
@ -38,7 +38,7 @@ impl TemplateSendCommand {
|
|||
let (toml_account_config, account_config) =
|
||||
config.clone().into_account_configs(account, cache)?;
|
||||
let backend = Backend::new(toml_account_config, account_config.clone(), true).await?;
|
||||
let folder = account_config.sent_folder_alias()?;
|
||||
let folder = account_config.get_sent_folder_alias()?;
|
||||
|
||||
let is_tty = io::stdin().is_terminal();
|
||||
let is_json = printer.is_json();
|
||||
|
@ -57,13 +57,13 @@ impl TemplateSendCommand {
|
|||
let mut compiler = MmlCompilerBuilder::new();
|
||||
|
||||
#[cfg(feature = "pgp")]
|
||||
compiler.set_some_pgp(config.pgp.clone());
|
||||
compiler.set_some_pgp(account_config.pgp.clone());
|
||||
|
||||
let msg = compiler.build(tpl.as_str())?.compile().await?.into_vec()?;
|
||||
|
||||
backend.send_raw_message(&msg).await?;
|
||||
|
||||
if account_config.email_sending_save_copy.unwrap_or_default() {
|
||||
if account_config.should_save_copy_sent_message() {
|
||||
backend
|
||||
.add_raw_message_with_flag(&folder, &msg, Flag::Seen)
|
||||
.await?;
|
||||
|
|
|
@ -42,7 +42,7 @@ impl FolderListCommand {
|
|||
printer.print_table(
|
||||
Box::new(folders),
|
||||
PrintTableOpts {
|
||||
format: &account_config.email_reading_format,
|
||||
format: &account_config.get_message_read_format(),
|
||||
max_width: self.table.max_width,
|
||||
},
|
||||
)?;
|
||||
|
|
|
@ -10,6 +10,9 @@ pub struct FolderConfig {
|
|||
pub expunge: Option<FolderExpungeConfig>,
|
||||
pub purge: Option<FolderPurgeConfig>,
|
||||
pub delete: Option<FolderDeleteConfig>,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub remote: email::folder::config::FolderConfig,
|
||||
}
|
||||
|
||||
impl FolderConfig {
|
||||
|
@ -60,6 +63,9 @@ impl FolderAddConfig {
|
|||
#[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)]
|
||||
pub struct FolderListConfig {
|
||||
pub backend: Option<BackendKind>,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub remote: email::folder::list::config::FolderListConfig,
|
||||
}
|
||||
|
||||
impl FolderListConfig {
|
||||
|
|
|
@ -89,7 +89,8 @@ pub(crate) async fn configure(account_name: &str, email: &str) -> Result<Backend
|
|||
let config = match secret {
|
||||
Some(idx) if SECRETS[idx] == KEYRING => {
|
||||
Secret::new_keyring_entry(format!("{account_name}-imap-passwd"))
|
||||
.set_keyring_entry_secret(prompt_passwd("IMAP password")?)?;
|
||||
.set_keyring_entry_secret(prompt_passwd("IMAP password")?)
|
||||
.await?;
|
||||
PasswdConfig::default()
|
||||
}
|
||||
Some(idx) if SECRETS[idx] == RAW => PasswdConfig {
|
||||
|
@ -130,7 +131,8 @@ pub(crate) async fn configure(account_name: &str, email: &str) -> Result<Backend
|
|||
.with_prompt("IMAP OAuth 2.0 client secret")
|
||||
.interact()?;
|
||||
Secret::new_keyring_entry(format!("{account_name}-imap-oauth2-client-secret"))
|
||||
.set_keyring_entry_secret(&client_secret)?;
|
||||
.set_keyring_entry_secret(&client_secret)
|
||||
.await?;
|
||||
|
||||
config.auth_url = Input::with_theme(&*THEME)
|
||||
.with_prompt("IMAP OAuth 2.0 authorization URL")
|
||||
|
@ -210,11 +212,13 @@ pub(crate) async fn configure(account_name: &str, email: &str) -> Result<Backend
|
|||
.await?;
|
||||
|
||||
Secret::new_keyring_entry(format!("{account_name}-imap-oauth2-access-token"))
|
||||
.set_keyring_entry_secret(access_token)?;
|
||||
.set_keyring_entry_secret(access_token)
|
||||
.await?;
|
||||
|
||||
if let Some(refresh_token) = &refresh_token {
|
||||
Secret::new_keyring_entry(format!("{account_name}-imap-oauth2-refresh-token"))
|
||||
.set_keyring_entry_secret(refresh_token)?;
|
||||
.set_keyring_entry_secret(refresh_token)
|
||||
.await?;
|
||||
}
|
||||
|
||||
ImapAuthConfig::OAuth2(config)
|
||||
|
|
|
@ -89,7 +89,8 @@ pub(crate) async fn configure(account_name: &str, email: &str) -> Result<Backend
|
|||
let config = match secret {
|
||||
Some(idx) if SECRETS[idx] == KEYRING => {
|
||||
Secret::new_keyring_entry(format!("{account_name}-smtp-passwd"))
|
||||
.set_keyring_entry_secret(prompt_passwd("SMTP password")?)?;
|
||||
.set_keyring_entry_secret(prompt_passwd("SMTP password")?)
|
||||
.await?;
|
||||
PasswdConfig::default()
|
||||
}
|
||||
Some(idx) if SECRETS[idx] == RAW => PasswdConfig {
|
||||
|
@ -130,7 +131,8 @@ pub(crate) async fn configure(account_name: &str, email: &str) -> Result<Backend
|
|||
.with_prompt("SMTP OAuth 2.0 client secret")
|
||||
.interact()?;
|
||||
Secret::new_keyring_entry(format!("{account_name}-smtp-oauth2-client-secret"))
|
||||
.set_keyring_entry_secret(&client_secret)?;
|
||||
.set_keyring_entry_secret(&client_secret)
|
||||
.await?;
|
||||
|
||||
config.auth_url = Input::with_theme(&*THEME)
|
||||
.with_prompt("SMTP OAuth 2.0 authorization URL")
|
||||
|
@ -210,11 +212,13 @@ pub(crate) async fn configure(account_name: &str, email: &str) -> Result<Backend
|
|||
.await?;
|
||||
|
||||
Secret::new_keyring_entry(format!("{account_name}-smtp-oauth2-access-token"))
|
||||
.set_keyring_entry_secret(access_token)?;
|
||||
.set_keyring_entry_secret(access_token)
|
||||
.await?;
|
||||
|
||||
if let Some(refresh_token) = &refresh_token {
|
||||
Secret::new_keyring_entry(format!("{account_name}-smtp-oauth2-refresh-token"))
|
||||
.set_keyring_entry_secret(refresh_token)?;
|
||||
.set_keyring_entry_secret(refresh_token)
|
||||
.await?;
|
||||
}
|
||||
|
||||
SmtpAuthConfig::OAuth2(config)
|
||||
|
|
|
@ -89,8 +89,8 @@ pub async fn edit_tpl_with_editor<P: Printer>(
|
|||
|
||||
backend.send_raw_message(&email).await?;
|
||||
|
||||
if config.email_sending_save_copy.unwrap_or_default() {
|
||||
let sent_folder = config.sent_folder_alias()?;
|
||||
if config.should_save_copy_sent_message() {
|
||||
let sent_folder = config.get_sent_folder_alias()?;
|
||||
printer.print_log(format!("Adding email to the {} folder…", sent_folder))?;
|
||||
backend
|
||||
.add_raw_message_with_flag(&sent_folder, &email, Flag::Seen)
|
||||
|
|
Loading…
Reference in a new issue