mirror of
https://github.com/pimalaya/himalaya.git
synced 2026-06-17 13:17:55 +08:00
refactor: remove composer and reader
Composers and readers did not work as expected. It is just not possible for himalaya to spawn a command that spawns $EDITOR, piping and redirection cannot satisfy all the needs. Either the $EDITOR does not spawn (hangs over), either himalaya does not collect any output from edition. The simplest way is to use an intermediate temp file, or use process substitution. For eg., using mml: mml compose >(himalaya message send) You can also write into a file then feed himalaya with it.
This commit is contained in:
+12
-6
@@ -19,6 +19,7 @@ use anyhow::Result;
|
||||
use clap::Subcommand;
|
||||
use pimalaya_cli::printer::Printer;
|
||||
|
||||
use crate::account::context::Account;
|
||||
use crate::imap::{
|
||||
client::ImapClient, envelope::cli::ImapEnvelopeCommand, flag::cli::ImapFlagCommand,
|
||||
id::ImapIdCommand, mailbox::cli::ImapMailboxCommand, message::cli::ImapMessageCommand,
|
||||
@@ -46,14 +47,19 @@ pub enum ImapCommand {
|
||||
}
|
||||
|
||||
impl ImapCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: ImapClient) -> Result<()> {
|
||||
pub fn execute(
|
||||
self,
|
||||
printer: &mut impl Printer,
|
||||
account: &mut Account,
|
||||
client: &mut ImapClient,
|
||||
) -> Result<()> {
|
||||
match self {
|
||||
Self::Id(cmd) => cmd.execute(printer, client),
|
||||
Self::Id(cmd) => cmd.execute(printer, account, client),
|
||||
|
||||
Self::Envelopes(cmd) => cmd.execute(printer, client),
|
||||
Self::Flags(cmd) => cmd.execute(printer, client),
|
||||
Self::Mailboxes(cmd) => cmd.execute(printer, client),
|
||||
Self::Messages(cmd) => cmd.execute(printer, client),
|
||||
Self::Envelopes(cmd) => cmd.execute(printer, account, client),
|
||||
Self::Flags(cmd) => cmd.execute(printer, account, client),
|
||||
Self::Mailboxes(cmd) => cmd.execute(printer, account, client),
|
||||
Self::Messages(cmd) => cmd.execute(printer, account, client),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-13
@@ -15,12 +15,12 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! Himalaya wrapper around [`io_imap::client::ImapClientStd`] that
|
||||
//! bundles the merged [`Account`] alongside the live IMAP client.
|
||||
//! Himalaya wrapper around [`io_imap::client::ImapClientStd`].
|
||||
//!
|
||||
//! This is what every IMAP-specific subcommand receives: the dispatch
|
||||
//! layer (`crate::cli`) opens the session up front via
|
||||
//! [`build_imap_client`] and hands the ready-to-use wrapper down.
|
||||
//! [`build_imap_client`] and hands the ready-to-use wrapper down,
|
||||
//! together with the merged [`Account`] as a sibling argument.
|
||||
|
||||
use std::{
|
||||
ops::{Deref, DerefMut},
|
||||
@@ -40,23 +40,21 @@ use crate::{
|
||||
|
||||
pub struct ImapClient {
|
||||
inner: Inner,
|
||||
pub account: Account,
|
||||
}
|
||||
|
||||
impl ImapClient {
|
||||
/// Opens the IMAP connection (TCP/TLS/STARTTLS, greeting, SASL)
|
||||
/// then wraps the resulting client alongside `account`. The
|
||||
/// capability list reported by the connect handshake is discarded;
|
||||
/// IMAP-specific subcommands that need it should call
|
||||
/// Opens the IMAP connection (TCP/TLS/STARTTLS, greeting, SASL).
|
||||
/// The capability list reported by the connect handshake is
|
||||
/// discarded; IMAP-specific subcommands that need it should call
|
||||
/// [`Inner::capability`] explicitly.
|
||||
pub fn new(config: ImapConfig, account: Account) -> Result<Self> {
|
||||
pub fn new(config: ImapConfig) -> Result<Self> {
|
||||
let mut tls: Tls = config.tls.into();
|
||||
tls.rustls.alpn = vec!["imap".into()];
|
||||
let sasl: Option<Sasl> = config.sasl.map(Sasl::try_from).transpose()?;
|
||||
let auto_id = resolve_auto_id_params(&config.id)?;
|
||||
let server = parse_imap_server(&config.server)?;
|
||||
let (inner, _capability) = Inner::connect(&server, &tls, config.starttls, sasl, auto_id)?;
|
||||
Ok(Self { inner, account })
|
||||
Ok(Self { inner })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,11 +90,13 @@ impl DerefMut for ImapClient {
|
||||
|
||||
/// Loads the configuration, picks the active account, builds the
|
||||
/// merged [`Account`] then opens the IMAP session. Bails when the
|
||||
/// account has no `[imap]` block.
|
||||
/// account has no `[imap]` block. Returns the live client paired
|
||||
/// with the merged account so subcommands receive both as sibling
|
||||
/// arguments.
|
||||
pub fn build_imap_client(
|
||||
config_paths: &[PathBuf],
|
||||
account_name: Option<&str>,
|
||||
) -> Result<ImapClient> {
|
||||
) -> Result<(Account, ImapClient)> {
|
||||
let mut config = load_or_wizard(config_paths)?;
|
||||
let (name, mut ac) = config
|
||||
.take_account(account_name)?
|
||||
@@ -106,5 +106,6 @@ pub fn build_imap_client(
|
||||
.take()
|
||||
.ok_or_else(|| anyhow!("IMAP config is missing for account `{name}`"))?;
|
||||
let account = Account::from(config).merge(Account::from(ac));
|
||||
ImapClient::new(imap_config, account)
|
||||
let client = ImapClient::new(imap_config)?;
|
||||
Ok((account, client))
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ use anyhow::Result;
|
||||
use clap::Subcommand;
|
||||
use pimalaya_cli::printer::Printer;
|
||||
|
||||
use crate::account::context::Account;
|
||||
use crate::imap::{
|
||||
client::ImapClient,
|
||||
envelope::{
|
||||
@@ -43,12 +44,17 @@ pub enum ImapEnvelopeCommand {
|
||||
}
|
||||
|
||||
impl ImapEnvelopeCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: ImapClient) -> Result<()> {
|
||||
pub fn execute(
|
||||
self,
|
||||
printer: &mut impl Printer,
|
||||
account: &mut Account,
|
||||
client: &mut ImapClient,
|
||||
) -> Result<()> {
|
||||
match self {
|
||||
Self::Get(cmd) => cmd.execute(printer, client),
|
||||
Self::List(cmd) => cmd.execute(printer, client),
|
||||
Self::Search(cmd) => cmd.execute(printer, client),
|
||||
Self::Sort(cmd) => cmd.execute(printer, client),
|
||||
Self::Get(cmd) => cmd.execute(printer, account, client),
|
||||
Self::List(cmd) => cmd.execute(printer, account, client),
|
||||
Self::Search(cmd) => cmd.execute(printer, account, client),
|
||||
Self::Sort(cmd) => cmd.execute(printer, account, client),
|
||||
Self::Thread(cmd) => cmd.execute(printer, client),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ use io_imap::types::{
|
||||
use pimalaya_cli::printer::Printer;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::account::context::Account;
|
||||
use crate::imap::{
|
||||
client::ImapClient,
|
||||
envelope::list::{decode_mime, format_address},
|
||||
@@ -54,7 +55,12 @@ pub struct ImapEnvelopeGetCommand {
|
||||
}
|
||||
|
||||
impl ImapEnvelopeGetCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(
|
||||
self,
|
||||
printer: &mut impl Printer,
|
||||
account: &mut Account,
|
||||
client: &mut ImapClient,
|
||||
) -> Result<()> {
|
||||
let mailbox = self.mailbox_name.inner.try_into()?;
|
||||
|
||||
if !self.mailbox_no_select.inner {
|
||||
@@ -76,7 +82,7 @@ impl ImapEnvelopeGetCommand {
|
||||
};
|
||||
|
||||
let table = EnvelopeTable {
|
||||
preset: client.account.table_preset().to_string(),
|
||||
preset: account.table_preset().to_string(),
|
||||
envelope: items.into(),
|
||||
};
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ use pimalaya_cli::printer::Printer;
|
||||
use rfc2047_decoder::{Decoder, RecoverStrategy};
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::account::context::Account;
|
||||
use crate::imap::{
|
||||
client::ImapClient,
|
||||
mailbox::arg::{MailboxNameOptionalFlag, MailboxNoSelectFlag},
|
||||
@@ -67,7 +68,12 @@ pub struct ImapEnvelopeListCommand {
|
||||
}
|
||||
|
||||
impl ImapEnvelopeListCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(
|
||||
self,
|
||||
printer: &mut impl Printer,
|
||||
account: &mut Account,
|
||||
client: &mut ImapClient,
|
||||
) -> Result<()> {
|
||||
let mailbox = self.mailbox_name.inner.try_into()?;
|
||||
|
||||
let exists = if self.mailbox_no_select.inner {
|
||||
@@ -100,13 +106,13 @@ impl ImapEnvelopeListCommand {
|
||||
let data = client.fetch(sequence_set, item_names, !self.sequence && has_sequence)?;
|
||||
|
||||
let table = EnvelopesTable {
|
||||
preset: client.account.table_preset().to_string(),
|
||||
arrangement: client.account.table_arrangement(),
|
||||
preset: account.table_preset().to_string(),
|
||||
arrangement: account.table_arrangement(),
|
||||
colors: EnvelopeColors {
|
||||
id: client.account.envelopes_list_table_id_color(),
|
||||
subject: client.account.envelopes_list_table_subject_color(),
|
||||
from: client.account.envelopes_list_table_from_color(),
|
||||
date: client.account.envelopes_list_table_date_color(),
|
||||
id: account.envelopes_list_table_id_color(),
|
||||
subject: account.envelopes_list_table_subject_color(),
|
||||
from: account.envelopes_list_table_from_color(),
|
||||
date: account.envelopes_list_table_date_color(),
|
||||
},
|
||||
envelopes: map_envelopes_table_entries(data),
|
||||
};
|
||||
|
||||
@@ -28,6 +28,7 @@ use io_imap::types::{
|
||||
use pimalaya_cli::printer::Printer;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::account::context::Account;
|
||||
use crate::imap::{
|
||||
client::ImapClient,
|
||||
mailbox::arg::{MailboxNameOptionalFlag, MailboxNoSelectFlag},
|
||||
@@ -75,7 +76,12 @@ pub struct ImapEnvelopeSearchCommand {
|
||||
}
|
||||
|
||||
impl ImapEnvelopeSearchCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(
|
||||
self,
|
||||
printer: &mut impl Printer,
|
||||
account: &mut Account,
|
||||
client: &mut ImapClient,
|
||||
) -> Result<()> {
|
||||
let mailbox = self.mailbox_name.inner.try_into()?;
|
||||
|
||||
if !self.mailbox_no_select.inner {
|
||||
@@ -86,9 +92,9 @@ impl ImapEnvelopeSearchCommand {
|
||||
let ids = client.search(criteria, !self.seq)?;
|
||||
|
||||
let table = SearchTable {
|
||||
preset: client.account.table_preset().to_string(),
|
||||
arrangement: client.account.table_arrangement(),
|
||||
id_color: client.account.envelopes_list_table_id_color(),
|
||||
preset: account.table_preset().to_string(),
|
||||
arrangement: account.table_arrangement(),
|
||||
id_color: account.envelopes_list_table_id_color(),
|
||||
ids: ids
|
||||
.into_iter()
|
||||
.map(|id| SearchResult { id: id.get() })
|
||||
|
||||
@@ -27,6 +27,7 @@ use io_imap::types::{
|
||||
use pimalaya_cli::printer::Printer;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::account::context::Account;
|
||||
use crate::imap::{
|
||||
client::ImapClient, envelope::search::parse_query, mailbox::arg::MailboxNameOptionalArg,
|
||||
};
|
||||
@@ -68,7 +69,12 @@ pub struct ImapEnvelopeSortCommand {
|
||||
}
|
||||
|
||||
impl ImapEnvelopeSortCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(
|
||||
self,
|
||||
printer: &mut impl Printer,
|
||||
account: &mut Account,
|
||||
client: &mut ImapClient,
|
||||
) -> Result<()> {
|
||||
let mailbox = self.mailbox_name.inner.try_into()?;
|
||||
|
||||
client.select(mailbox)?;
|
||||
@@ -82,7 +88,7 @@ impl ImapEnvelopeSortCommand {
|
||||
|
||||
let ids = client.sort(sort_criteria, search_criteria, !self.seq)?;
|
||||
|
||||
let id_color = client.account.envelopes_list_table_id_color();
|
||||
let id_color = account.envelopes_list_table_id_color();
|
||||
let table = SortResultsTable::new(ids, !self.seq, id_color);
|
||||
|
||||
printer.out(table)?;
|
||||
|
||||
@@ -62,7 +62,7 @@ pub struct ImapEnvelopeThreadCommand {
|
||||
}
|
||||
|
||||
impl ImapEnvelopeThreadCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: &mut ImapClient) -> Result<()> {
|
||||
let mailbox = self.mailbox_name.inner.try_into()?;
|
||||
|
||||
if !self.mailbox_no_select.inner {
|
||||
@@ -76,7 +76,7 @@ impl ImapEnvelopeThreadCommand {
|
||||
|
||||
let all_ids = collect_thread_ids(&threads);
|
||||
let subjects = if !all_ids.is_empty() {
|
||||
fetch_subjects(&mut client, &all_ids, !self.seq)?
|
||||
fetch_subjects(client, &all_ids, !self.seq)?
|
||||
} else {
|
||||
HashMap::new()
|
||||
};
|
||||
|
||||
@@ -52,7 +52,7 @@ pub struct ImapFlagAddCommand {
|
||||
}
|
||||
|
||||
impl ImapFlagAddCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: &mut ImapClient) -> Result<()> {
|
||||
let mailbox = self.mailbox_name.inner.try_into()?;
|
||||
|
||||
if !self.mailbox_no_select.inner {
|
||||
|
||||
@@ -19,6 +19,7 @@ use anyhow::Result;
|
||||
use clap::Subcommand;
|
||||
use pimalaya_cli::printer::Printer;
|
||||
|
||||
use crate::account::context::Account;
|
||||
use crate::imap::{
|
||||
client::ImapClient,
|
||||
flag::{
|
||||
@@ -40,9 +41,14 @@ pub enum ImapFlagCommand {
|
||||
}
|
||||
|
||||
impl ImapFlagCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: ImapClient) -> Result<()> {
|
||||
pub fn execute(
|
||||
self,
|
||||
printer: &mut impl Printer,
|
||||
account: &mut Account,
|
||||
client: &mut ImapClient,
|
||||
) -> Result<()> {
|
||||
match self {
|
||||
Self::List(cmd) => cmd.execute(printer, client),
|
||||
Self::List(cmd) => cmd.execute(printer, account, client),
|
||||
Self::Add(cmd) => cmd.execute(printer, client),
|
||||
Self::Set(cmd) => cmd.execute(printer, client),
|
||||
Self::Remove(cmd) => cmd.execute(printer, client),
|
||||
|
||||
@@ -24,6 +24,7 @@ use io_imap::types::flag::{Flag, FlagPerm};
|
||||
use pimalaya_cli::printer::Printer;
|
||||
use serde::{Serialize, Serializer};
|
||||
|
||||
use crate::account::context::Account;
|
||||
use crate::imap::{client::ImapClient, mailbox::arg::MailboxNameArg};
|
||||
|
||||
/// List available IMAP flags for the given mailbox.
|
||||
@@ -38,7 +39,12 @@ pub struct ImapFlagListCommand {
|
||||
}
|
||||
|
||||
impl ImapFlagListCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(
|
||||
self,
|
||||
printer: &mut impl Printer,
|
||||
account: &mut Account,
|
||||
client: &mut ImapClient,
|
||||
) -> Result<()> {
|
||||
let mailbox = self.mailbox_name.inner.try_into()?;
|
||||
|
||||
let data = client.select(mailbox)?;
|
||||
@@ -46,8 +52,8 @@ impl ImapFlagListCommand {
|
||||
let permanent_flags = data.permanent_flags.unwrap_or_default();
|
||||
|
||||
let table = FlagsTable {
|
||||
preset: client.account.table_preset().to_string(),
|
||||
arrangement: client.account.table_arrangement(),
|
||||
preset: account.table_preset().to_string(),
|
||||
arrangement: account.table_arrangement(),
|
||||
flags,
|
||||
permanent_flags,
|
||||
};
|
||||
|
||||
@@ -52,7 +52,7 @@ pub struct ImapFlagRemoveCommand {
|
||||
}
|
||||
|
||||
impl ImapFlagRemoveCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: &mut ImapClient) -> Result<()> {
|
||||
let mailbox = self.mailbox_name.inner.try_into()?;
|
||||
|
||||
if !self.mailbox_no_select.inner {
|
||||
|
||||
@@ -52,7 +52,7 @@ pub struct ImapFlagSetCommand {
|
||||
}
|
||||
|
||||
impl ImapFlagSetCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: &mut ImapClient) -> Result<()> {
|
||||
let mailbox = self.mailbox_name.inner.try_into()?;
|
||||
|
||||
if !self.mailbox_no_select.inner {
|
||||
|
||||
+8
-2
@@ -27,6 +27,7 @@ use io_imap::types::{
|
||||
use pimalaya_cli::printer::Printer;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::account::context::Account;
|
||||
use crate::{config::ImapIdConfig, imap::client::ImapClient};
|
||||
|
||||
/// Get information about the IMAP server.
|
||||
@@ -44,7 +45,12 @@ pub struct ImapIdCommand {
|
||||
}
|
||||
|
||||
impl ImapIdCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(
|
||||
self,
|
||||
printer: &mut impl Printer,
|
||||
account: &mut Account,
|
||||
client: &mut ImapClient,
|
||||
) -> Result<()> {
|
||||
let mut params: HashMap<IString<'static>, NString<'static>> = HashMap::new();
|
||||
for key in ["name", "version", "vendor", "support-url"] {
|
||||
let (k, v) = build_canned_pair(key)?;
|
||||
@@ -58,7 +64,7 @@ impl ImapIdCommand {
|
||||
let params = client.id(Some(params.into_iter().collect()))?;
|
||||
|
||||
let table = ServerIdTable {
|
||||
preset: client.account.table_preset().to_string(),
|
||||
preset: account.table_preset().to_string(),
|
||||
server_id: params
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
|
||||
@@ -19,6 +19,7 @@ use anyhow::Result;
|
||||
use clap::Subcommand;
|
||||
use pimalaya_cli::printer::Printer;
|
||||
|
||||
use crate::account::context::Account;
|
||||
use crate::imap::{
|
||||
client::ImapClient,
|
||||
mailbox::{
|
||||
@@ -55,17 +56,22 @@ pub enum ImapMailboxCommand {
|
||||
}
|
||||
|
||||
impl ImapMailboxCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: ImapClient) -> Result<()> {
|
||||
pub fn execute(
|
||||
self,
|
||||
printer: &mut impl Printer,
|
||||
account: &mut Account,
|
||||
client: &mut ImapClient,
|
||||
) -> Result<()> {
|
||||
match self {
|
||||
Self::Close(cmd) => cmd.execute(printer, client),
|
||||
Self::Create(cmd) => cmd.execute(printer, client),
|
||||
Self::Delete(cmd) => cmd.execute(printer, client),
|
||||
Self::Expunge(cmd) => cmd.execute(printer, client),
|
||||
Self::List(cmd) => cmd.execute(printer, client),
|
||||
Self::List(cmd) => cmd.execute(printer, account, client),
|
||||
Self::Purge(cmd) => cmd.execute(printer, client),
|
||||
Self::Rename(cmd) => cmd.execute(printer, client),
|
||||
Self::Select(cmd) => cmd.execute(printer, client),
|
||||
Self::Status(cmd) => cmd.execute(printer, client),
|
||||
Self::Status(cmd) => cmd.execute(printer, account, client),
|
||||
Self::Subscribe(cmd) => cmd.execute(printer, client),
|
||||
Self::Unselect(cmd) => cmd.execute(printer, client),
|
||||
Self::Unsubscribe(cmd) => cmd.execute(printer, client),
|
||||
|
||||
@@ -34,7 +34,7 @@ use crate::imap::client::ImapClient;
|
||||
pub struct ImapMailboxCloseCommand;
|
||||
|
||||
impl ImapMailboxCloseCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: &mut ImapClient) -> Result<()> {
|
||||
client.close()?;
|
||||
printer.out(Message::new("Mailbox successfully closed"))
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ pub struct ImapMailboxCreateCommand {
|
||||
}
|
||||
|
||||
impl ImapMailboxCreateCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: &mut ImapClient) -> Result<()> {
|
||||
let mailbox = self.mailbox_name.inner.try_into()?;
|
||||
client.create(mailbox)?;
|
||||
printer.out(Message::new("Mailbox successfully created"))
|
||||
|
||||
@@ -32,7 +32,7 @@ pub struct ImapMailboxDeleteCommand {
|
||||
}
|
||||
|
||||
impl ImapMailboxDeleteCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: &mut ImapClient) -> Result<()> {
|
||||
let mailbox = self.mailbox_name.inner.try_into()?;
|
||||
client.delete(mailbox)?;
|
||||
printer.out(Message::new("Mailbox successfully deleted"))
|
||||
|
||||
@@ -37,7 +37,7 @@ pub struct ImapMailboxExpungeCommand {
|
||||
}
|
||||
|
||||
impl ImapMailboxExpungeCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: &mut ImapClient) -> Result<()> {
|
||||
let mailbox = self.mailbox_name.inner.try_into()?;
|
||||
|
||||
if !self.mailbox_no_select.inner {
|
||||
|
||||
@@ -25,6 +25,7 @@ use io_imap::types::{core::QuotedChar, flag::FlagNameAttribute, mailbox::Mailbox
|
||||
use pimalaya_cli::printer::Printer;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::account::context::Account;
|
||||
use crate::imap::client::ImapClient;
|
||||
|
||||
/// List, search and filter mailboxes.
|
||||
@@ -48,7 +49,12 @@ pub struct ImapMailboxListCommand {
|
||||
}
|
||||
|
||||
impl ImapMailboxListCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(
|
||||
self,
|
||||
printer: &mut impl Printer,
|
||||
account: &mut Account,
|
||||
client: &mut ImapClient,
|
||||
) -> Result<()> {
|
||||
let reference = self.reference.try_into()?;
|
||||
let pattern = self.pattern.try_into()?;
|
||||
|
||||
@@ -59,8 +65,8 @@ impl ImapMailboxListCommand {
|
||||
};
|
||||
|
||||
let table = MailboxesTable {
|
||||
preset: client.account.table_preset().to_string(),
|
||||
name_color: client.account.mailboxes_list_table_name_color(),
|
||||
preset: account.table_preset().to_string(),
|
||||
name_color: account.mailboxes_list_table_name_color(),
|
||||
mailboxes: mailboxes.into_iter().map(From::from).collect(),
|
||||
};
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ pub struct ImapMailboxPurgeCommand {
|
||||
}
|
||||
|
||||
impl ImapMailboxPurgeCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: &mut ImapClient) -> Result<()> {
|
||||
let mailbox = self.mailbox_name.inner.try_into()?;
|
||||
|
||||
if !self.mailbox_no_select.inner {
|
||||
|
||||
@@ -36,7 +36,7 @@ pub struct ImapMailboxRenameCommand {
|
||||
}
|
||||
|
||||
impl ImapMailboxRenameCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: &mut ImapClient) -> Result<()> {
|
||||
let from = self.mailbox_source_name.inner.try_into()?;
|
||||
let to = self.mailbox_dest_name.inner.try_into()?;
|
||||
client.rename(from, to)?;
|
||||
|
||||
@@ -36,7 +36,7 @@ pub struct ImapMailboxSelectCommand {
|
||||
}
|
||||
|
||||
impl ImapMailboxSelectCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: &mut ImapClient) -> Result<()> {
|
||||
let mailbox = self.mailbox_name.inner.try_into()?;
|
||||
client.select(mailbox)?;
|
||||
printer.out(Message::new("Mailbox successfully selected"))
|
||||
|
||||
@@ -24,6 +24,7 @@ use io_imap::types::status::{StatusDataItem, StatusDataItemName};
|
||||
use pimalaya_cli::printer::Printer;
|
||||
use serde::{Serialize, Serializer};
|
||||
|
||||
use crate::account::context::Account;
|
||||
use crate::imap::{client::ImapClient, mailbox::arg::MailboxNameArg};
|
||||
|
||||
/// Get the status of the given mailbox.
|
||||
@@ -37,7 +38,12 @@ pub struct ImapMailboxStatusCommand {
|
||||
}
|
||||
|
||||
impl ImapMailboxStatusCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(
|
||||
self,
|
||||
printer: &mut impl Printer,
|
||||
account: &mut Account,
|
||||
client: &mut ImapClient,
|
||||
) -> Result<()> {
|
||||
let mailbox = self.mailbox_name.inner.try_into()?;
|
||||
let item_names = vec![
|
||||
StatusDataItemName::Messages,
|
||||
@@ -50,7 +56,7 @@ impl ImapMailboxStatusCommand {
|
||||
let items = client.status(mailbox, item_names)?;
|
||||
|
||||
let table = MailboxStatusTable {
|
||||
preset: client.account.table_preset().to_string(),
|
||||
preset: account.table_preset().to_string(),
|
||||
status: items.into(),
|
||||
};
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ pub struct ImapMailboxSubscribeCommand {
|
||||
}
|
||||
|
||||
impl ImapMailboxSubscribeCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: &mut ImapClient) -> Result<()> {
|
||||
let mailbox = self.mailbox_name.inner.try_into()?;
|
||||
client.subscribe(mailbox)?;
|
||||
printer.out(Message::new("Mailbox successfully subscribed"))
|
||||
|
||||
@@ -33,7 +33,7 @@ use crate::imap::client::ImapClient;
|
||||
pub struct ImapMailboxUnselectCommand;
|
||||
|
||||
impl ImapMailboxUnselectCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: &mut ImapClient) -> Result<()> {
|
||||
client.unselect()?;
|
||||
printer.out(Message::new("Mailbox successfully unselected"))
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ pub struct ImapMailboxUnsubscribeCommand {
|
||||
}
|
||||
|
||||
impl ImapMailboxUnsubscribeCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: &mut ImapClient) -> Result<()> {
|
||||
let mailbox = self.mailbox_name.inner.try_into()?;
|
||||
client.unsubscribe(mailbox)?;
|
||||
printer.out(Message::new("Mailbox successfully unsubscribed"))
|
||||
|
||||
@@ -19,6 +19,7 @@ use anyhow::Result;
|
||||
use clap::Subcommand;
|
||||
use pimalaya_cli::printer::Printer;
|
||||
|
||||
use crate::account::context::Account;
|
||||
use crate::imap::{
|
||||
client::ImapClient,
|
||||
message::{
|
||||
@@ -43,12 +44,17 @@ pub enum ImapMessageCommand {
|
||||
}
|
||||
|
||||
impl ImapMessageCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: ImapClient) -> Result<()> {
|
||||
pub fn execute(
|
||||
self,
|
||||
printer: &mut impl Printer,
|
||||
account: &mut Account,
|
||||
client: &mut ImapClient,
|
||||
) -> Result<()> {
|
||||
match self {
|
||||
Self::Save(cmd) => cmd.execute(printer, client),
|
||||
Self::Get(cmd) => cmd.execute(printer, client),
|
||||
Self::Read(cmd) => cmd.execute(printer, client),
|
||||
Self::Export(cmd) => cmd.execute(printer, client),
|
||||
Self::Export(cmd) => cmd.execute(printer, account, client),
|
||||
Self::Copy(cmd) => cmd.execute(printer, client),
|
||||
Self::Move(cmd) => cmd.execute(printer, client),
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ pub struct ImapMessageCopyCommand {
|
||||
}
|
||||
|
||||
impl ImapMessageCopyCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: &mut ImapClient) -> Result<()> {
|
||||
let mailbox = self.mailbox_name.inner.try_into()?;
|
||||
|
||||
if !self.mailbox_no_select.inner {
|
||||
|
||||
@@ -27,6 +27,7 @@ use io_imap::types::fetch::{MacroOrMessageDataItemNames, MessageDataItem, Messag
|
||||
use mail_parser::{MessageParser, MimeHeaders};
|
||||
use pimalaya_cli::printer::{Message, Printer};
|
||||
|
||||
use crate::account::context::Account;
|
||||
use crate::imap::{client::ImapClient, mailbox::arg::MailboxNameOptionalFlag};
|
||||
|
||||
/// Export type for message export.
|
||||
@@ -73,7 +74,12 @@ pub struct ImapMessageExportCommand {
|
||||
}
|
||||
|
||||
impl ImapMessageExportCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(
|
||||
self,
|
||||
printer: &mut impl Printer,
|
||||
account: &mut Account,
|
||||
client: &mut ImapClient,
|
||||
) -> Result<()> {
|
||||
let mailbox = self.mailbox_name.inner.try_into()?;
|
||||
|
||||
client.select(mailbox)?;
|
||||
@@ -133,9 +139,7 @@ impl ImapMessageExportCommand {
|
||||
|
||||
// Generate filename from subject or message-id
|
||||
let filename = generate_eml_filename(&message, self.id);
|
||||
let dir = self
|
||||
.directory
|
||||
.unwrap_or_else(|| client.account.downloads_dir());
|
||||
let dir = self.directory.unwrap_or_else(|| account.downloads_dir());
|
||||
|
||||
if !dir.exists() {
|
||||
fs::create_dir_all(&dir)?;
|
||||
|
||||
@@ -49,7 +49,7 @@ pub struct ImapMessageGetCommand {
|
||||
}
|
||||
|
||||
impl ImapMessageGetCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: &mut ImapClient) -> Result<()> {
|
||||
let mailbox = self.mailbox_name.inner.try_into()?;
|
||||
if self.id == 0 {
|
||||
bail!("ID must be non-zero");
|
||||
|
||||
@@ -49,7 +49,7 @@ pub struct ImapMessageMoveCommand {
|
||||
}
|
||||
|
||||
impl ImapMessageMoveCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: &mut ImapClient) -> Result<()> {
|
||||
let mailbox = self.mailbox_name.inner.try_into()?;
|
||||
|
||||
if !self.mailbox_no_select.inner {
|
||||
|
||||
@@ -54,7 +54,7 @@ pub struct ImapMessageReadCommand {
|
||||
}
|
||||
|
||||
impl ImapMessageReadCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: &mut ImapClient) -> Result<()> {
|
||||
let mailbox = self.mailbox_name.inner.try_into()?;
|
||||
|
||||
if !self.mailbox_no_select.inner {
|
||||
|
||||
@@ -46,7 +46,7 @@ pub struct ImapMessageSaveCommand {
|
||||
}
|
||||
|
||||
impl ImapMessageSaveCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, mut client: ImapClient) -> Result<()> {
|
||||
pub fn execute(self, printer: &mut impl Printer, client: &mut ImapClient) -> Result<()> {
|
||||
let mailbox: Mailbox<'static> = self.mailbox.inner.try_into()?;
|
||||
let message = self.message.parse()?;
|
||||
let message = Literal::try_from(message)?;
|
||||
|
||||
Reference in New Issue
Block a user