mirror of
https://github.com/soywod/himalaya.git
synced 2024-09-04 18:21:11 +00:00
make smtp service lazy with instance()
This commit is contained in:
parent
979c6ef1c9
commit
07833c2fc7
68
src/domain/smtp.rs
Normal file
68
src/domain/smtp.rs
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
use anyhow::Result;
|
||||||
|
use lettre::{
|
||||||
|
self,
|
||||||
|
transport::smtp::{
|
||||||
|
client::{Tls, TlsParameters},
|
||||||
|
SmtpTransport,
|
||||||
|
},
|
||||||
|
Transport,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::domain::account::entity::Account;
|
||||||
|
|
||||||
|
pub trait SmtpServiceInterface {
|
||||||
|
fn send(&mut self, msg: &lettre::Message) -> Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct SmtpService<'a> {
|
||||||
|
account: &'a Account,
|
||||||
|
transport: Option<SmtpTransport>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> SmtpService<'a> {
|
||||||
|
pub fn new(account: &'a Account) -> Result<Self> {
|
||||||
|
Ok(Self {
|
||||||
|
account,
|
||||||
|
transport: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transport(&mut self) -> Result<&SmtpTransport> {
|
||||||
|
if let Some(ref transport) = self.transport {
|
||||||
|
Ok(transport)
|
||||||
|
} else {
|
||||||
|
let builder = if self.account.smtp_starttls {
|
||||||
|
SmtpTransport::starttls_relay(&self.account.smtp_host)
|
||||||
|
} else {
|
||||||
|
SmtpTransport::relay(&self.account.smtp_host)
|
||||||
|
}?;
|
||||||
|
|
||||||
|
let tls = TlsParameters::builder(self.account.smtp_host.to_owned())
|
||||||
|
.dangerous_accept_invalid_hostnames(self.account.smtp_insecure)
|
||||||
|
.dangerous_accept_invalid_certs(self.account.smtp_insecure)
|
||||||
|
.build()?;
|
||||||
|
let tls = if self.account.smtp_starttls {
|
||||||
|
Tls::Required(tls)
|
||||||
|
} else {
|
||||||
|
Tls::Wrapper(tls)
|
||||||
|
};
|
||||||
|
|
||||||
|
self.transport = Some(
|
||||||
|
builder
|
||||||
|
.tls(tls)
|
||||||
|
.port(self.account.smtp_port)
|
||||||
|
.credentials(self.account.smtp_creds()?)
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(self.transport.as_ref().unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> SmtpServiceInterface for SmtpService<'a> {
|
||||||
|
fn send(&mut self, msg: &lettre::Message) -> Result<()> {
|
||||||
|
self.transport()?.send(msg)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +0,0 @@
|
||||||
//! Modules related to SMTP.
|
|
||||||
|
|
||||||
pub mod service;
|
|
|
@ -1,51 +0,0 @@
|
||||||
use anyhow::Result;
|
|
||||||
use lettre::{
|
|
||||||
self,
|
|
||||||
transport::{smtp::client::Tls, smtp::client::TlsParameters, smtp::SmtpTransport},
|
|
||||||
Transport,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::domain::account::entity::Account;
|
|
||||||
|
|
||||||
pub trait SMTPServiceInterface {
|
|
||||||
fn send(&self, msg: &lettre::Message) -> Result<()>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SMTPService<'a> {
|
|
||||||
account: &'a Account,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> SMTPService<'a> {
|
|
||||||
pub fn new(account: &'a Account) -> Result<Self> {
|
|
||||||
Ok(Self { account })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> SMTPServiceInterface for SMTPService<'a> {
|
|
||||||
fn send(&self, msg: &lettre::Message) -> Result<()> {
|
|
||||||
let smtp_relay = if self.account.smtp_starttls {
|
|
||||||
SmtpTransport::starttls_relay
|
|
||||||
} else {
|
|
||||||
SmtpTransport::relay
|
|
||||||
};
|
|
||||||
|
|
||||||
let tls = TlsParameters::builder(self.account.smtp_host.to_string())
|
|
||||||
.dangerous_accept_invalid_hostnames(self.account.smtp_insecure)
|
|
||||||
.dangerous_accept_invalid_certs(self.account.smtp_insecure)
|
|
||||||
.build()?;
|
|
||||||
let tls = if self.account.smtp_starttls {
|
|
||||||
Tls::Required(tls)
|
|
||||||
} else {
|
|
||||||
Tls::Wrapper(tls)
|
|
||||||
};
|
|
||||||
|
|
||||||
smtp_relay(&self.account.smtp_host)?
|
|
||||||
.port(self.account.smtp_port)
|
|
||||||
.tls(tls)
|
|
||||||
.credentials(self.account.smtp_creds()?)
|
|
||||||
.build()
|
|
||||||
.send(msg)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -43,4 +43,5 @@ pub mod msg;
|
||||||
pub mod output;
|
pub mod output;
|
||||||
|
|
||||||
pub mod domain;
|
pub mod domain;
|
||||||
|
pub mod infra;
|
||||||
pub mod ui;
|
pub mod ui;
|
||||||
|
|
|
@ -8,7 +8,7 @@ use himalaya::{
|
||||||
comp,
|
comp,
|
||||||
config::cli::config_args,
|
config::cli::config_args,
|
||||||
ctx::Ctx,
|
ctx::Ctx,
|
||||||
domain::{account::entity::Account, config::entity::Config, smtp::service::SMTPService},
|
domain::{account::entity::Account, config::entity::Config, smtp::SmtpService},
|
||||||
flag, imap, mbox, msg,
|
flag, imap, mbox, msg,
|
||||||
output::{cli::output_args, model::Output},
|
output::{cli::output_args, model::Output},
|
||||||
};
|
};
|
||||||
|
@ -73,7 +73,7 @@ fn main() -> Result<()> {
|
||||||
|
|
||||||
let account_name = arg_matches.value_of("account");
|
let account_name = arg_matches.value_of("account");
|
||||||
let account = Account::try_from((&config, account_name))?;
|
let account = Account::try_from((&config, account_name))?;
|
||||||
let smtp_service = SMTPService::new(&account)?;
|
let smtp_service = SmtpService::new(&account)?;
|
||||||
debug!("account name: {}", account_name.unwrap_or("default"));
|
debug!("account name: {}", account_name.unwrap_or("default"));
|
||||||
trace!("account: {:?}", account);
|
trace!("account: {:?}", account);
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ use super::{
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
ctx::Ctx,
|
ctx::Ctx,
|
||||||
domain::{account::entity::Account, smtp},
|
domain::{account::entity::Account, smtp::*},
|
||||||
flag::model::Flags,
|
flag::model::Flags,
|
||||||
imap::model::ImapConnector,
|
imap::model::ImapConnector,
|
||||||
input,
|
input,
|
||||||
|
@ -127,10 +127,10 @@ pub fn subcmds<'a>() -> Vec<clap::App<'a, 'a>> {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn matches<SMTP: smtp::service::SMTPServiceInterface>(
|
pub fn matches<SmtpService: SmtpServiceInterface>(
|
||||||
ctx: &Ctx,
|
ctx: &Ctx,
|
||||||
account: &Account,
|
account: &Account,
|
||||||
smtp: SMTP,
|
smtp: SmtpService,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
match ctx.arg_matches.subcommand() {
|
match ctx.arg_matches.subcommand() {
|
||||||
("attachments", Some(matches)) => msg_matches_attachments(&ctx, &account, &matches),
|
("attachments", Some(matches)) => msg_matches_attachments(&ctx, &account, &matches),
|
||||||
|
@ -399,11 +399,11 @@ fn msg_matches_attachments(
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn msg_matches_write<'a, SMTP: smtp::service::SMTPServiceInterface>(
|
fn msg_matches_write<SmtpService: SmtpServiceInterface>(
|
||||||
ctx: &Ctx,
|
ctx: &Ctx,
|
||||||
account: &Account,
|
account: &Account,
|
||||||
matches: &clap::ArgMatches,
|
matches: &clap::ArgMatches,
|
||||||
smtp: SMTP,
|
smtp: SmtpService,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
debug!("write command matched");
|
debug!("write command matched");
|
||||||
|
|
||||||
|
@ -438,11 +438,11 @@ fn msg_matches_write<'a, SMTP: smtp::service::SMTPServiceInterface>(
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn msg_matches_reply<'a, SMTP: smtp::service::SMTPServiceInterface>(
|
fn msg_matches_reply<SmtpService: SmtpServiceInterface>(
|
||||||
ctx: &Ctx,
|
ctx: &Ctx,
|
||||||
account: &Account,
|
account: &Account,
|
||||||
matches: &clap::ArgMatches,
|
matches: &clap::ArgMatches,
|
||||||
smtp: SMTP,
|
smtp: SmtpService,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
debug!("reply command matched");
|
debug!("reply command matched");
|
||||||
|
|
||||||
|
@ -473,11 +473,11 @@ fn msg_matches_reply<'a, SMTP: smtp::service::SMTPServiceInterface>(
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn msg_matches_mailto<'a, SMTP: smtp::service::SMTPServiceInterface>(
|
pub fn msg_matches_mailto<SmtpService: SmtpServiceInterface>(
|
||||||
ctx: &Ctx,
|
ctx: &Ctx,
|
||||||
account: &Account,
|
account: &Account,
|
||||||
url: &Url,
|
url: &Url,
|
||||||
smtp: SMTP,
|
smtp: SmtpService,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
debug!("mailto command matched");
|
debug!("mailto command matched");
|
||||||
|
|
||||||
|
@ -525,11 +525,11 @@ pub fn msg_matches_mailto<'a, SMTP: smtp::service::SMTPServiceInterface>(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn msg_matches_forward<'a, SMTP: smtp::service::SMTPServiceInterface>(
|
fn msg_matches_forward<SmtpService: SmtpServiceInterface>(
|
||||||
ctx: &Ctx,
|
ctx: &Ctx,
|
||||||
account: &Account,
|
account: &Account,
|
||||||
matches: &clap::ArgMatches,
|
matches: &clap::ArgMatches,
|
||||||
smtp: SMTP,
|
smtp: SmtpService,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
debug!("forward command matched");
|
debug!("forward command matched");
|
||||||
|
|
||||||
|
@ -639,11 +639,11 @@ fn msg_matches_delete(ctx: &Ctx, account: &Account, matches: &clap::ArgMatches)
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn msg_matches_send<'a, SMTP: smtp::service::SMTPServiceInterface>(
|
fn msg_matches_send<SmtpService: SmtpServiceInterface>(
|
||||||
ctx: &Ctx,
|
ctx: &Ctx,
|
||||||
account: &Account,
|
account: &Account,
|
||||||
matches: &clap::ArgMatches,
|
matches: &clap::ArgMatches,
|
||||||
smtp: SMTP,
|
mut smtp: SmtpService,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
debug!("send command matched");
|
debug!("send command matched");
|
||||||
|
|
||||||
|
@ -849,11 +849,11 @@ fn tpl_matches_forward(ctx: &Ctx, account: &Account, matches: &clap::ArgMatches)
|
||||||
|
|
||||||
/// This function opens the prompt to do some actions to the msg like sending, editing it again and
|
/// This function opens the prompt to do some actions to the msg like sending, editing it again and
|
||||||
/// so on.
|
/// so on.
|
||||||
fn msg_interaction<SMTP: smtp::service::SMTPServiceInterface>(
|
fn msg_interaction<SmtpService: SmtpServiceInterface>(
|
||||||
ctx: &Ctx,
|
ctx: &Ctx,
|
||||||
msg: &mut Msg,
|
msg: &mut Msg,
|
||||||
imap_conn: &mut ImapConnector,
|
imap_conn: &mut ImapConnector,
|
||||||
smtp: SMTP,
|
mut smtp: SmtpService,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
// let the user change the body a little bit first, before opening the prompt
|
// let the user change the body a little bit first, before opening the prompt
|
||||||
msg.edit_body()?;
|
msg.edit_body()?;
|
||||||
|
|
Loading…
Reference in a new issue