Skip to content

Commit

Permalink
adjust api, test commands with a greenmail instance
Browse files Browse the repository at this point in the history
  • Loading branch information
soywod committed Dec 9, 2023
1 parent ef3214f commit 04e721d
Show file tree
Hide file tree
Showing 31 changed files with 150 additions and 112 deletions.
23 changes: 21 additions & 2 deletions config.sample.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ display-name = "My example account"
email = "example@localhost"

sync = true
sync-dir = "./.sync"
sync-dir = "/tmp/himalaya-sync-example"

# The default backend used for all the features like adding folders,
# listing envelopes or copying messages.
Expand All @@ -21,7 +21,7 @@ imap.ssl = false
imap.starttls = false
imap.insecure = true
imap.auth = "passwd"
imap.passwd.raw = "example"
imap.passwd.keyring = "example-passwd"

# Override the backend used for sending messages.
message.send.backend = "smtp"
Expand All @@ -35,3 +35,22 @@ smtp.starttls = false
smtp.insecure = true
smtp.auth = "passwd"
smtp.passwd.raw = "example"

[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"
4 changes: 2 additions & 2 deletions src/account/arg/name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ pub struct AccountNameArg {
}

/// The account name flag parser.
#[derive(Debug, Parser)]
#[derive(Debug, Default, Parser)]
pub struct AccountNameFlag {
/// Override the default account.
///
/// An account name corresponds to an entry in the table at the
/// root level of your TOML configuration file.
#[arg(long = "account", short = 'a', global = true)]
#[arg(long = "account", short = 'a')]
#[arg(name = "account_name", value_name = "NAME")]
pub name: Option<String>,
}
4 changes: 2 additions & 2 deletions src/account/command/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use self::{
///
/// An account is a set of settings, identified by an account
/// name. Settings are directly taken from your TOML configuration
/// file.
/// file. This subcommand allows you to manage them.
#[derive(Debug, Subcommand)]
pub enum AccountSubcommand {
#[command(alias = "cfg")]
Expand All @@ -24,7 +24,7 @@ pub enum AccountSubcommand {
#[command(alias = "lst")]
List(AccountListCommand),

#[command()]
#[command(alias = "synchronize", alias = "synchronise")]
Sync(AccountSyncCommand),
}

Expand Down
2 changes: 1 addition & 1 deletion src/account/command/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const SUB_PROGRESS_DONE_STYLE: Lazy<ProgressStyle> = Lazy::new(|| {
/// Synchronize an account.
///
/// This command allows you to synchronize all folders and emails
/// (including envelopes and messages) of an account into a local
/// (including envelopes and messages) of a given account into a local
/// Maildir folder.
#[derive(Debug, Parser)]
pub struct AccountSyncCommand {
Expand Down
5 changes: 4 additions & 1 deletion src/account/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,10 @@ impl From<Iter<'_, String, TomlAccountConfig>> for Accounts {
Account::new(name, &backends, account.default.unwrap_or_default())
})
.collect();
accounts.sort_by(|a, b| b.name.partial_cmp(&a.name).unwrap());

// sort accounts by name
accounts.sort_by(|a, b| a.name.partial_cmp(&b.name).unwrap());

Self(accounts)
}
}
2 changes: 1 addition & 1 deletion src/cache/arg/disable.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use clap::Parser;

/// The disable cache flag parser.
#[derive(Debug, Parser)]
#[derive(Debug, Default, Parser)]
pub struct CacheDisableFlag {
/// Disable any sort of cache.
///
Expand Down
1 change: 1 addition & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ pub enum HimalayaCommand {
Account(AccountSubcommand),

#[command(subcommand)]
#[command(visible_alias = "mailbox", aliases = ["mailboxes", "mboxes", "mbox"])]
#[command(alias = "folders")]
Folder(FolderSubcommand),

Expand Down
4 changes: 2 additions & 2 deletions src/email/envelope/flag/command/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
cache::arg::disable::CacheDisableFlag,
config::TomlConfig,
flag::arg::ids_and_flags::{into_tuple, IdsAndFlagsArgs},
folder::arg::name::FolderNameArg,
folder::arg::name::FolderNameOptionalFlag,
printer::Printer,
};

Expand All @@ -19,7 +19,7 @@ use crate::{
#[derive(Debug, Parser)]
pub struct FlagAddCommand {
#[command(flatten)]
pub folder: FolderNameArg,
pub folder: FolderNameOptionalFlag,

#[command(flatten)]
pub args: IdsAndFlagsArgs,
Expand Down
4 changes: 2 additions & 2 deletions src/email/envelope/flag/command/remove.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
cache::arg::disable::CacheDisableFlag,
config::TomlConfig,
flag::arg::ids_and_flags::{into_tuple, IdsAndFlagsArgs},
folder::arg::name::FolderNameArg,
folder::arg::name::FolderNameOptionalFlag,
printer::Printer,
};

Expand All @@ -19,7 +19,7 @@ use crate::{
#[derive(Debug, Parser)]
pub struct FlagRemoveCommand {
#[command(flatten)]
pub folder: FolderNameArg,
pub folder: FolderNameOptionalFlag,

#[command(flatten)]
pub args: IdsAndFlagsArgs,
Expand Down
4 changes: 2 additions & 2 deletions src/email/envelope/flag/command/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
cache::arg::disable::CacheDisableFlag,
config::TomlConfig,
flag::arg::ids_and_flags::{into_tuple, IdsAndFlagsArgs},
folder::arg::name::FolderNameArg,
folder::arg::name::FolderNameOptionalFlag,
printer::Printer,
};

Expand All @@ -19,7 +19,7 @@ use crate::{
#[derive(Debug, Parser)]
pub struct FlagSetCommand {
#[command(flatten)]
pub folder: FolderNameArg,
pub folder: FolderNameOptionalFlag,

#[command(flatten)]
pub args: IdsAndFlagsArgs,
Expand Down
2 changes: 1 addition & 1 deletion src/email/message/arg/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::ops::Deref;
pub struct MessageRawBodyArg {
/// Prefill the template with a custom body.
#[arg(trailing_var_arg = true)]
#[arg(name = "body-raw")]
#[arg(name = "body_raw", value_name = "BODY")]
pub raw: Vec<String>,
}

Expand Down
17 changes: 17 additions & 0 deletions src/email/message/arg/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
use clap::Parser;

pub mod body;
pub mod header;
pub mod reply;

/// The raw message argument parser.
#[derive(Debug, Parser)]
pub struct MessageRawArg {
/// The raw message, including headers and body.
#[arg(trailing_var_arg = true)]
#[arg(name = "message_raw", value_name = "MESSAGE")]
pub raw: Vec<String>,
}

impl MessageRawArg {
pub fn raw(self) -> String {
self.raw.join(" ").replace("\r", "").replace("\n", "\r\n")
}
}
6 changes: 3 additions & 3 deletions src/email/message/attachment/command/download.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use uuid::Uuid;

use crate::{
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::CacheDisableFlag,
config::TomlConfig, envelope::arg::ids::EnvelopeIdsArgs, folder::arg::name::FolderNameArg,
printer::Printer,
config::TomlConfig, envelope::arg::ids::EnvelopeIdsArgs,
folder::arg::name::FolderNameOptionalFlag, printer::Printer,
};

/// Download all attachments for the given message.
Expand All @@ -17,7 +17,7 @@ use crate::{
#[derive(Debug, Parser)]
pub struct AttachmentDownloadCommand {
#[command(flatten)]
pub folder: FolderNameArg,
pub folder: FolderNameOptionalFlag,

#[command(flatten)]
pub envelopes: EnvelopeIdsArgs,
Expand Down
6 changes: 3 additions & 3 deletions src/email/message/command/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use log::info;

use crate::{
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::CacheDisableFlag,
config::TomlConfig, envelope::arg::ids::EnvelopeIdsArgs, folder::arg::name::FolderNameArg,
printer::Printer,
config::TomlConfig, envelope::arg::ids::EnvelopeIdsArgs,
folder::arg::name::FolderNameOptionalFlag, printer::Printer,
};

/// Mark as deleted a message from a folder.
Expand All @@ -17,7 +17,7 @@ use crate::{
#[derive(Debug, Parser)]
pub struct MessageDeleteCommand {
#[command(flatten)]
pub folder: FolderNameArg,
pub folder: FolderNameOptionalFlag,

#[command(flatten)]
pub envelopes: EnvelopeIdsArgs,
Expand Down
21 changes: 3 additions & 18 deletions src/email/message/command/forward.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
use anyhow::{anyhow, Result};
use atty::Stream;
use clap::Parser;
use log::info;
use std::io::{self, BufRead};

use crate::{
account::arg::name::AccountNameFlag,
backend::Backend,
cache::arg::disable::CacheDisableFlag,
config::TomlConfig,
envelope::arg::ids::EnvelopeIdArg,
folder::arg::name::FolderNameArg,
folder::arg::name::FolderNameOptionalFlag,
message::arg::{body::MessageRawBodyArg, header::HeaderRawArgs},
printer::Printer,
ui::editor,
Expand All @@ -25,7 +23,7 @@ use crate::{
#[derive(Debug, Parser)]
pub struct MessageForwardCommand {
#[command(flatten)]
pub folder: FolderNameArg,
pub folder: FolderNameOptionalFlag,

#[command(flatten)]
pub envelope: EnvelopeIdArg,
Expand Down Expand Up @@ -55,19 +53,6 @@ impl MessageForwardCommand {
config.clone().into_account_configs(account, cache)?;
let backend = Backend::new(toml_account_config, account_config.clone(), true).await?;

let is_tty = atty::is(Stream::Stdin);
let is_json = printer.is_json();
let body = if !self.body.is_empty() && (is_tty || is_json) {
self.body.raw()
} else {
io::stdin()
.lock()
.lines()
.filter_map(Result::ok)
.collect::<Vec<String>>()
.join("\r\n")
};

let id = self.envelope.id;
let tpl = backend
.get_messages(folder, &[id])
Expand All @@ -76,7 +61,7 @@ impl MessageForwardCommand {
.ok_or(anyhow!("cannot find message"))?
.to_forward_tpl_builder(&account_config)
.with_headers(self.headers.raw)
.with_body(body)
.with_body(self.body.raw())
.build()
.await?;
editor::edit_tpl_with_editor(&account_config, printer, &backend, tpl).await
Expand Down
23 changes: 19 additions & 4 deletions src/email/message/command/mailto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ use log::{debug, info};
use mail_builder::MessageBuilder;
use url::Url;

use crate::{backend::Backend, config::TomlConfig, printer::Printer, ui::editor};
use crate::{
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::CacheDisableFlag,
config::TomlConfig, printer::Printer, ui::editor,
};

/// Parse and edit a message from a mailto URL string.
///
Expand All @@ -17,19 +20,31 @@ pub struct MessageMailtoCommand {
/// The mailto url.
#[arg()]
pub url: Url,

#[command(flatten)]
pub cache: CacheDisableFlag,

#[command(flatten)]
pub account: AccountNameFlag,
}

impl MessageMailtoCommand {
pub fn new(url: &str) -> Result<Self> {
let url = Url::parse(url)?;
Ok(Self { url })
Ok(Self {
url: Url::parse(url)?,
cache: Default::default(),
account: Default::default(),
})
}

pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing message mailto command");

let account = self.account.name.as_ref().map(String::as_str);
let cache = self.cache.disable;

let (toml_account_config, account_config) =
config.clone().into_account_configs(None, false)?;
config.clone().into_account_configs(account, cache)?;
let backend = Backend::new(toml_account_config, account_config.clone(), true).await?;

let mut builder = MessageBuilder::new().to(self.url.path());
Expand Down
8 changes: 5 additions & 3 deletions src/email/message/command/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,32 +32,34 @@ pub enum MessageSubcommand {
#[command(arg_required_else_help = true)]
Read(MessageReadCommand),

#[command(alias = "add", alias = "create", alias = "new", alias = "compose")]
#[command(aliases = ["add", "create", "new", "compose"])]
Write(MessageWriteCommand),

#[command()]
Reply(MessageReplyCommand),

#[command(alias = "fwd")]
#[command(aliases = ["fwd", "fd"])]
Forward(MessageForwardCommand),

#[command()]
Mailto(MessageMailtoCommand),

#[command(arg_required_else_help = true)]
#[command(alias = "add", alias = "create")]
Save(MessageSaveCommand),

#[command(arg_required_else_help = true)]
Send(MessageSendCommand),

#[command(arg_required_else_help = true)]
#[command(aliases = ["cpy", "cp"])]
Copy(MessageCopyCommand),

#[command(arg_required_else_help = true)]
#[command(alias = "mv")]
Move(MessageMoveCommand),

#[command(arg_required_else_help = true)]
#[command(aliases = ["remove", "rm"])]
Delete(MessageDeleteCommand),
}

Expand Down
6 changes: 3 additions & 3 deletions src/email/message/command/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use mml::message::FilterParts;

use crate::{
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::CacheDisableFlag,
config::TomlConfig, envelope::arg::ids::EnvelopeIdsArgs, folder::arg::name::FolderNameArg,
printer::Printer,
config::TomlConfig, envelope::arg::ids::EnvelopeIdsArgs,
folder::arg::name::FolderNameOptionalFlag, printer::Printer,
};

/// Read a message.
Expand All @@ -15,7 +15,7 @@ use crate::{
#[derive(Debug, Parser)]
pub struct MessageReadCommand {
#[command(flatten)]
pub folder: FolderNameArg,
pub folder: FolderNameOptionalFlag,

#[command(flatten)]
pub envelopes: EnvelopeIdsArgs,
Expand Down
Loading

0 comments on commit 04e721d

Please sign in to comment.