mirror of
https://github.com/pimalaya/himalaya.git
synced 2026-06-18 14:07:54 +08:00
make inbox, sent and drafts folder customizable (#246)
* mbox: make inbox, sent and drafts folder customizable * msg: update send handler parameters order
This commit is contained in:
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Fixed
|
||||
|
||||
- Blur in list msg screenshot [#181]
|
||||
- Make inbox, sent and drafts folders customizable [#172]
|
||||
|
||||
## [0.5.1] - 2021-10-24
|
||||
|
||||
@@ -347,6 +348,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
[#160]: https://github.com/soywod/himalaya/issues/160
|
||||
[#162]: https://github.com/soywod/himalaya/issues/162
|
||||
[#176]: https://github.com/soywod/himalaya/issues/176
|
||||
[#172]: https://github.com/soywod/himalaya/issues/172
|
||||
[#181]: https://github.com/soywod/himalaya/issues/181
|
||||
[#185]: https://github.com/soywod/himalaya/issues/185
|
||||
[#186]: https://github.com/soywod/himalaya/issues/186
|
||||
|
||||
@@ -8,6 +8,10 @@ use crate::{
|
||||
output::run_cmd,
|
||||
};
|
||||
|
||||
pub const DEFAULT_INBOX_FOLDER: &str = "INBOX";
|
||||
pub const DEFAULT_SENT_FOLDER: &str = "Sent";
|
||||
pub const DEFAULT_DRAFT_FOLDER: &str = "Drafts";
|
||||
|
||||
/// Represent a user account.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Account {
|
||||
@@ -16,6 +20,12 @@ pub struct Account {
|
||||
pub downloads_dir: PathBuf,
|
||||
pub sig: Option<String>,
|
||||
pub default_page_size: usize,
|
||||
/// Defines the inbox folder name for this account
|
||||
pub inbox_folder: String,
|
||||
/// Defines the sent folder name for this account
|
||||
pub sent_folder: String,
|
||||
/// Defines the draft folder name for this account
|
||||
pub draft_folder: String,
|
||||
pub watch_cmds: Vec<String>,
|
||||
pub default: bool,
|
||||
pub email: String,
|
||||
@@ -134,6 +144,27 @@ impl<'a> TryFrom<(&'a Config, Option<&str>)> for Account {
|
||||
downloads_dir,
|
||||
sig,
|
||||
default_page_size,
|
||||
inbox_folder: account
|
||||
.inbox_folder
|
||||
.as_ref()
|
||||
.map(|s| s.as_str())
|
||||
.or(config.inbox_folder.as_ref().map(|s| s.as_str()))
|
||||
.unwrap_or(&DEFAULT_INBOX_FOLDER)
|
||||
.to_string(),
|
||||
sent_folder: account
|
||||
.sent_folder
|
||||
.as_ref()
|
||||
.map(|s| s.as_str())
|
||||
.or(config.sent_folder.as_ref().map(|s| s.as_str()))
|
||||
.unwrap_or(&DEFAULT_SENT_FOLDER)
|
||||
.to_string(),
|
||||
draft_folder: account
|
||||
.draft_folder
|
||||
.as_ref()
|
||||
.map(|s| s.as_str())
|
||||
.or(config.draft_folder.as_ref().map(|s| s.as_str()))
|
||||
.unwrap_or(&DEFAULT_DRAFT_FOLDER)
|
||||
.to_string(),
|
||||
watch_cmds: account
|
||||
.watch_cmds
|
||||
.as_ref()
|
||||
@@ -142,12 +173,14 @@ impl<'a> TryFrom<(&'a Config, Option<&str>)> for Account {
|
||||
.to_owned(),
|
||||
default: account.default.unwrap_or(false),
|
||||
email: account.email.to_owned(),
|
||||
|
||||
imap_host: account.imap_host.to_owned(),
|
||||
imap_port: account.imap_port,
|
||||
imap_starttls: account.imap_starttls.unwrap_or_default(),
|
||||
imap_insecure: account.imap_insecure.unwrap_or_default(),
|
||||
imap_login: account.imap_login.to_owned(),
|
||||
imap_passwd_cmd: account.imap_passwd_cmd.to_owned(),
|
||||
|
||||
smtp_host: account.smtp_host.to_owned(),
|
||||
smtp_port: account.smtp_port,
|
||||
smtp_starttls: account.smtp_starttls.unwrap_or_default(),
|
||||
|
||||
@@ -13,18 +13,27 @@ pub const DEFAULT_SIG_DELIM: &str = "-- \n";
|
||||
#[derive(Debug, Default, Clone, Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct Config {
|
||||
/// Define the full display name of the user.
|
||||
/// Defines the full display name of the user.
|
||||
pub name: String,
|
||||
/// Define the downloads directory (eg. for attachments).
|
||||
/// Defines the downloads directory (eg. for attachments).
|
||||
pub downloads_dir: Option<PathBuf>,
|
||||
/// Override the default signature delimiter "`--\n `".
|
||||
/// Overrides the default signature delimiter "`--\n `".
|
||||
pub signature_delimiter: Option<String>,
|
||||
/// Define the signature.
|
||||
/// Defines the signature.
|
||||
pub signature: Option<String>,
|
||||
/// Define the default page size for listings.
|
||||
/// Defines the default page size for listings.
|
||||
pub default_page_size: Option<usize>,
|
||||
/// Defines the inbox folder name.
|
||||
pub inbox_folder: Option<String>,
|
||||
/// Defines the sent folder name.
|
||||
pub sent_folder: Option<String>,
|
||||
/// Defines the draft folder name.
|
||||
pub draft_folder: Option<String>,
|
||||
/// Defines the notify command.
|
||||
pub notify_cmd: Option<String>,
|
||||
/// Defines the watch commands.
|
||||
pub watch_cmds: Option<Vec<String>>,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub accounts: ConfigAccountsMap,
|
||||
}
|
||||
@@ -41,15 +50,23 @@ pub struct ConfigAccountEntry {
|
||||
pub signature_delimiter: Option<String>,
|
||||
pub signature: Option<String>,
|
||||
pub default_page_size: Option<usize>,
|
||||
/// Defines a specific inbox folder name for this account.
|
||||
pub inbox_folder: Option<String>,
|
||||
/// Defines a specific sent folder name for this account.
|
||||
pub sent_folder: Option<String>,
|
||||
/// Defines a specific draft folder name for this account.
|
||||
pub draft_folder: Option<String>,
|
||||
pub watch_cmds: Option<Vec<String>>,
|
||||
pub default: Option<bool>,
|
||||
pub email: String,
|
||||
|
||||
pub imap_host: String,
|
||||
pub imap_port: u16,
|
||||
pub imap_starttls: Option<bool>,
|
||||
pub imap_insecure: Option<bool>,
|
||||
pub imap_login: String,
|
||||
pub imap_passwd_cmd: String,
|
||||
|
||||
pub smtp_host: String,
|
||||
pub smtp_port: u16,
|
||||
pub smtp_starttls: Option<bool>,
|
||||
|
||||
@@ -47,7 +47,6 @@ pub fn source_arg<'a>() -> clap::Arg<'a, 'a> {
|
||||
.long("mailbox")
|
||||
.help("Specifies the source mailbox")
|
||||
.value_name("SOURCE")
|
||||
.default_value("INBOX")
|
||||
}
|
||||
|
||||
/// Defines the target mailbox argument.
|
||||
@@ -104,7 +103,7 @@ mod tests {
|
||||
}
|
||||
|
||||
let app = get_matches_from![];
|
||||
assert_eq!(Some("INBOX"), app.value_of("mbox-source"));
|
||||
assert_eq!(None, app.value_of("mbox-source"));
|
||||
|
||||
let app = get_matches_from!["-m", "SOURCE"];
|
||||
assert_eq!(Some("SOURCE"), app.value_of("mbox-source"));
|
||||
|
||||
@@ -337,7 +337,7 @@ impl Msg {
|
||||
loop {
|
||||
match choice::post_edit() {
|
||||
Ok(PostEditChoice::Send) => {
|
||||
let mbox = Mbox::new("Sent");
|
||||
let mbox = Mbox::new(&account.sent_folder);
|
||||
let sent_msg = smtp.send_msg(&self)?;
|
||||
let flags = Flags::try_from(vec![Flag::Seen])?;
|
||||
imap.append_raw_msg_with_flags(&mbox, &sent_msg.formatted(), flags)?;
|
||||
@@ -354,12 +354,15 @@ impl Msg {
|
||||
break;
|
||||
}
|
||||
Ok(PostEditChoice::RemoteDraft) => {
|
||||
let mbox = Mbox::new("Drafts");
|
||||
let mbox = Mbox::new(&account.draft_folder);
|
||||
let flags = Flags::try_from(vec![Flag::Seen, Flag::Draft])?;
|
||||
let tpl = self.to_tpl(TplOverride::default(), account);
|
||||
imap.append_raw_msg_with_flags(&mbox, tpl.as_bytes(), flags)?;
|
||||
msg_utils::remove_local_draft()?;
|
||||
printer.print("Message successfully saved to Drafts")?;
|
||||
printer.print(format!(
|
||||
"Message successfully saved to {}",
|
||||
account.draft_folder
|
||||
))?;
|
||||
break;
|
||||
}
|
||||
Ok(PostEditChoice::Discard) => {
|
||||
|
||||
@@ -290,6 +290,7 @@ pub fn send<
|
||||
SmtpService: SmtpServiceInterface,
|
||||
>(
|
||||
raw_msg: &str,
|
||||
account: &Account,
|
||||
printer: &mut Printer,
|
||||
imap: &mut ImapService,
|
||||
smtp: &mut SmtpService,
|
||||
@@ -312,7 +313,7 @@ pub fn send<
|
||||
debug!("message sent!");
|
||||
|
||||
// Save message to sent folder
|
||||
let mbox = Mbox::new("Sent");
|
||||
let mbox = Mbox::new(&account.sent_folder);
|
||||
let flags = Flags::try_from(vec![Flag::Seen])?;
|
||||
imap.append_raw_msg_with_flags(&mbox, raw_msg.as_bytes(), flags)
|
||||
}
|
||||
|
||||
+3
-3
@@ -45,9 +45,9 @@ fn main() -> Result<()> {
|
||||
// Check 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 mbox = Mbox::new("INBOX");
|
||||
let config = Config::try_from(None)?;
|
||||
let account = Account::try_from((&config, None))?;
|
||||
let mbox = Mbox::new(&account.inbox_folder);
|
||||
let mut printer = StdoutPrinter::from(OutputFmt::Plain);
|
||||
let url = Url::parse(&raw_args[1])?;
|
||||
let mut imap = ImapService::from((&account, &mbox));
|
||||
@@ -68,9 +68,9 @@ fn main() -> Result<()> {
|
||||
}
|
||||
|
||||
// Init entities and services.
|
||||
let mbox = Mbox::new(m.value_of("mbox-source").unwrap());
|
||||
let config = Config::try_from(m.value_of("config"))?;
|
||||
let account = Account::try_from((&config, m.value_of("account")))?;
|
||||
let mbox = Mbox::new(m.value_of("mbox-source").unwrap_or(&account.inbox_folder));
|
||||
let mut printer = StdoutPrinter::try_from(m.value_of("output"))?;
|
||||
let mut imap = ImapService::from((&account, &mbox));
|
||||
let mut smtp = SmtpService::from(&account);
|
||||
@@ -150,7 +150,7 @@ fn main() -> Result<()> {
|
||||
);
|
||||
}
|
||||
Some(msg_arg::Command::Send(raw_msg)) => {
|
||||
return msg_handler::send(raw_msg, &mut printer, &mut imap, &mut smtp);
|
||||
return msg_handler::send(raw_msg, &account, &mut printer, &mut imap, &mut smtp);
|
||||
}
|
||||
Some(msg_arg::Command::Write(atts)) => {
|
||||
return msg_handler::write(atts, &account, &mut printer, &mut imap, &mut smtp);
|
||||
|
||||
+1
-1
Submodule wiki updated: ab8a6a1c40...3c74b676f0
Reference in New Issue
Block a user