mirror of
https://github.com/pimalaya/himalaya.git
synced 2026-06-17 05:07:55 +08:00
@@ -39,6 +39,12 @@ pub struct Config {
|
||||
pub smtp: ServerInfo,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn email_full(&self) -> String {
|
||||
format!("{} <{}>", self.name, self.email)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_xdg() -> Option<PathBuf> {
|
||||
match env::var("XDG_CONFIG_HOME") {
|
||||
Err(_) => None,
|
||||
|
||||
+36
-4
@@ -1,8 +1,15 @@
|
||||
mod config;
|
||||
mod imap;
|
||||
mod smtp;
|
||||
mod table;
|
||||
|
||||
use clap::{App, Arg, SubCommand};
|
||||
use std::io::prelude::*;
|
||||
use std::{env, fs, process};
|
||||
|
||||
fn nem_email_tpl() -> String {
|
||||
["To: ", "Subject: ", ""].join("\r\n")
|
||||
}
|
||||
|
||||
fn mailbox_arg() -> Arg<'static, 'static> {
|
||||
Arg::with_name("mailbox")
|
||||
@@ -77,6 +84,10 @@ fn main() {
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
if let Some(_) = matches.subcommand_matches("list") {
|
||||
imap::list_mailboxes(&mut imap_sess).unwrap();
|
||||
}
|
||||
|
||||
if let Some(matches) = matches.subcommand_matches("search") {
|
||||
let mbox = matches.value_of("mailbox").unwrap();
|
||||
|
||||
@@ -108,10 +119,6 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(_) = matches.subcommand_matches("list") {
|
||||
imap::list_mailboxes(&mut imap_sess).unwrap();
|
||||
}
|
||||
|
||||
if let Some(matches) = matches.subcommand_matches("read") {
|
||||
let mbox = matches.value_of("mailbox").unwrap();
|
||||
let mime = matches.value_of("mime-type").unwrap();
|
||||
@@ -120,4 +127,29 @@ fn main() {
|
||||
imap::read_email(&mut imap_sess, mbox, uid, mime).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(_) = matches.subcommand_matches("write") {
|
||||
let mut draft_path = env::temp_dir();
|
||||
draft_path.push("himalaya-draft.mail");
|
||||
|
||||
fs::File::create(&draft_path)
|
||||
.expect("Could not create draft file")
|
||||
.write(nem_email_tpl().as_bytes())
|
||||
.expect("Could not write into draft file");
|
||||
|
||||
process::Command::new(env!("EDITOR"))
|
||||
.arg(&draft_path)
|
||||
.status()
|
||||
.expect("Could not start $EDITOR");
|
||||
|
||||
let mut draft = String::new();
|
||||
fs::File::open(&draft_path)
|
||||
.expect("Could not open draft file")
|
||||
.read_to_string(&mut draft)
|
||||
.expect("Could not read draft file");
|
||||
|
||||
fs::remove_file(&draft_path).expect("Could not remove draft file");
|
||||
|
||||
smtp::send(&config, &draft.as_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
use lettre::{
|
||||
message::{header, Message, SinglePart},
|
||||
transport::smtp::{authentication::Credentials, SmtpTransport},
|
||||
Transport,
|
||||
};
|
||||
use mailparse;
|
||||
|
||||
use crate::config;
|
||||
|
||||
pub fn send(config: &config::Config, bytes: &[u8]) {
|
||||
let email_origin = mailparse::parse_mail(bytes).unwrap();
|
||||
let email = email_origin
|
||||
.headers
|
||||
.iter()
|
||||
.fold(Message::builder(), |msg, h| {
|
||||
match h.get_key().to_lowercase().as_str() {
|
||||
"to" => msg.to(h.get_value().parse().unwrap()),
|
||||
"cc" => match h.get_value().parse() {
|
||||
Err(_) => msg,
|
||||
Ok(addr) => msg.cc(addr),
|
||||
},
|
||||
"bcc" => match h.get_value().parse() {
|
||||
Err(_) => msg,
|
||||
Ok(addr) => msg.bcc(addr),
|
||||
},
|
||||
"subject" => msg.subject(h.get_value()),
|
||||
_ => msg,
|
||||
}
|
||||
})
|
||||
.from(config.email_full().parse().unwrap())
|
||||
.singlepart(
|
||||
SinglePart::builder()
|
||||
.header(header::ContentType(
|
||||
"text/plain; charset=utf-8".parse().unwrap(),
|
||||
))
|
||||
.header(header::ContentTransferEncoding::Base64)
|
||||
.body(email_origin.get_body_raw().unwrap()),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let creds = Credentials::new(config.smtp.login.clone(), config.smtp.password.clone());
|
||||
let mailer = SmtpTransport::relay(&config.smtp.host)
|
||||
.unwrap()
|
||||
.credentials(creds)
|
||||
.build();
|
||||
|
||||
println!("Sending ...");
|
||||
match mailer.send(&email) {
|
||||
Ok(_) => println!("Email sent successfully!"),
|
||||
Err(e) => panic!("Could not send email: {:?}", e),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user