mirror of
https://github.com/pimalaya/himalaya.git
synced 2026-06-17 05:07:55 +08:00
release v0.2.5
This commit is contained in:
+6
-4
@@ -1,7 +1,8 @@
|
||||
use clap::{self, App, Arg, ArgMatches, SubCommand};
|
||||
use error_chain::error_chain;
|
||||
use log::debug;
|
||||
|
||||
use crate::{config::model::Config, imap::model::ImapConnector, output::utils::print};
|
||||
use crate::{config::model::Config, imap::model::ImapConnector, info};
|
||||
|
||||
error_chain! {
|
||||
links {
|
||||
@@ -36,13 +37,14 @@ pub fn mbox_subcmds<'a>() -> Vec<App<'a, 'a>> {
|
||||
pub fn mbox_matches(matches: &ArgMatches) -> Result<bool> {
|
||||
let config = Config::new_from_file()?;
|
||||
let account = config.find_account_by_name(matches.value_of("account"))?;
|
||||
let output_fmt = matches.value_of("output").unwrap();
|
||||
let silent = matches.is_present("silent");
|
||||
|
||||
if let Some(_) = matches.subcommand_matches("mailboxes") {
|
||||
debug!("Subcommand matched: mailboxes");
|
||||
|
||||
let mut imap_conn = ImapConnector::new(&account)?;
|
||||
let mboxes = imap_conn.list_mboxes()?;
|
||||
print(&output_fmt, &silent, mboxes)?;
|
||||
info!(&mboxes);
|
||||
|
||||
imap_conn.logout();
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
+21
-18
@@ -1,13 +1,13 @@
|
||||
use clap::{self, App, Arg, ArgMatches, SubCommand};
|
||||
use error_chain::error_chain;
|
||||
use log::{debug, error, info};
|
||||
use log::{debug, error};
|
||||
use std::{fs, ops::Deref};
|
||||
|
||||
use crate::{
|
||||
config::model::Config,
|
||||
flag::model::Flag,
|
||||
imap::model::ImapConnector,
|
||||
input,
|
||||
info, input,
|
||||
mbox::cli::mbox_target_arg,
|
||||
msg::model::{Attachments, Msg, Msgs, ReadableMsg},
|
||||
smtp,
|
||||
@@ -183,7 +183,7 @@ pub fn msg_matches(matches: &ArgMatches) -> Result<()> {
|
||||
|
||||
let msgs = imap_conn.list_msgs(&mbox, &page_size, &page)?;
|
||||
let msgs = Msgs::from(&msgs);
|
||||
info!("{}", msgs);
|
||||
info!(&msgs);
|
||||
|
||||
imap_conn.logout();
|
||||
return Ok(());
|
||||
@@ -225,7 +225,7 @@ pub fn msg_matches(matches: &ArgMatches) -> Result<()> {
|
||||
|
||||
let msgs = imap_conn.search_msgs(&mbox, &query, &page_size, &page)?;
|
||||
let msgs = Msgs::from(&msgs);
|
||||
info!("{}", msgs);
|
||||
info!(&msgs);
|
||||
|
||||
imap_conn.logout();
|
||||
return Ok(());
|
||||
@@ -247,10 +247,10 @@ pub fn msg_matches(matches: &ArgMatches) -> Result<()> {
|
||||
let msg = String::from_utf8(msg)
|
||||
.chain_err(|| "Could not decode raw message as utf8 string")?;
|
||||
let msg = msg.trim_end_matches("\n");
|
||||
info!("{}", msg);
|
||||
info!(&msg);
|
||||
} else {
|
||||
let msg = ReadableMsg::from_bytes(&mime, &msg)?;
|
||||
info!("{}", msg);
|
||||
info!(&msg);
|
||||
}
|
||||
|
||||
imap_conn.logout();
|
||||
@@ -268,15 +268,18 @@ pub fn msg_matches(matches: &ArgMatches) -> Result<()> {
|
||||
let attachments = Attachments::from_bytes(&msg)?;
|
||||
debug!(
|
||||
"{} attachment(s) found for message {}",
|
||||
attachments.0.len(),
|
||||
uid
|
||||
&attachments.0.len(),
|
||||
&uid
|
||||
);
|
||||
attachments.0.iter().for_each(|attachment| {
|
||||
let filepath = config.downloads_filepath(&account, &attachment.filename);
|
||||
debug!("Downloading {}…", &attachment.filename);
|
||||
fs::write(filepath, &attachment.raw).unwrap()
|
||||
});
|
||||
info!("{} attachment(s) successfully downloaded", &uid);
|
||||
info!(&format!(
|
||||
"{} attachment(s) successfully downloaded",
|
||||
&attachments.0.len()
|
||||
));
|
||||
|
||||
imap_conn.logout();
|
||||
return Ok(());
|
||||
@@ -333,7 +336,7 @@ pub fn msg_matches(matches: &ArgMatches) -> Result<()> {
|
||||
debug!("Subcommand matched: new");
|
||||
|
||||
let tpl = Msg::build_new_tpl(&config, &account)?;
|
||||
info!("{}", tpl);
|
||||
info!(&tpl);
|
||||
}
|
||||
|
||||
if let Some(matches) = matches.subcommand_matches("reply") {
|
||||
@@ -349,7 +352,7 @@ pub fn msg_matches(matches: &ArgMatches) -> Result<()> {
|
||||
} else {
|
||||
msg.build_reply_tpl(&config, &account)?
|
||||
};
|
||||
info!("{}", tpl);
|
||||
info!(&tpl);
|
||||
|
||||
imap_conn.logout();
|
||||
}
|
||||
@@ -363,7 +366,7 @@ pub fn msg_matches(matches: &ArgMatches) -> Result<()> {
|
||||
|
||||
let msg = Msg::from(imap_conn.read_msg(&mbox, &uid)?);
|
||||
let tpl = msg.build_forward_tpl(&config, &account)?;
|
||||
info!("{}", tpl);
|
||||
info!(&tpl);
|
||||
|
||||
imap_conn.logout();
|
||||
}
|
||||
@@ -486,10 +489,10 @@ pub fn msg_matches(matches: &ArgMatches) -> Result<()> {
|
||||
let mut flags = msg.flags.deref().to_vec();
|
||||
flags.push(Flag::Seen);
|
||||
imap_conn.append_msg(target, &msg.raw, &flags)?;
|
||||
info!(
|
||||
info!(&format!(
|
||||
"Message {} successfully copied to folder `{}`",
|
||||
&uid, &target
|
||||
);
|
||||
));
|
||||
|
||||
imap_conn.logout();
|
||||
return Ok(());
|
||||
@@ -509,10 +512,10 @@ pub fn msg_matches(matches: &ArgMatches) -> Result<()> {
|
||||
flags.push(Flag::Seen);
|
||||
imap_conn.append_msg(target, &msg.raw, msg.flags.deref())?;
|
||||
imap_conn.add_flags(mbox, uid, "\\Seen \\Deleted")?;
|
||||
info!(
|
||||
info!(&format!(
|
||||
"Message {} successfully moved to folder `{}`",
|
||||
&uid, &target
|
||||
);
|
||||
));
|
||||
|
||||
imap_conn.expunge(mbox)?;
|
||||
imap_conn.logout();
|
||||
@@ -527,7 +530,7 @@ pub fn msg_matches(matches: &ArgMatches) -> Result<()> {
|
||||
debug!("UID: {}", &uid);
|
||||
|
||||
imap_conn.add_flags(mbox, uid, "\\Seen \\Deleted")?;
|
||||
info!("Message {} successfully deleted", &uid);
|
||||
info!(&format!("Message {} successfully deleted", &uid));
|
||||
|
||||
imap_conn.expunge(mbox)?;
|
||||
imap_conn.logout();
|
||||
@@ -563,7 +566,7 @@ pub fn msg_matches(matches: &ArgMatches) -> Result<()> {
|
||||
let mut imap_conn = ImapConnector::new(&account)?;
|
||||
let msgs = imap_conn.list_msgs(&mbox, &10, &0)?;
|
||||
let msgs = Msgs::from(&msgs);
|
||||
info!("{}", &msgs);
|
||||
info!(&msgs);
|
||||
|
||||
imap_conn.logout();
|
||||
Ok(())
|
||||
|
||||
+11
-1
@@ -1,8 +1,18 @@
|
||||
use std::fmt;
|
||||
|
||||
static mut OUTPUT_FMT: &'static OutputFmt = &OutputFmt::Plain;
|
||||
|
||||
pub fn set_output_fmt(output_fmt: &'static OutputFmt) {
|
||||
unsafe { OUTPUT_FMT = output_fmt }
|
||||
}
|
||||
|
||||
pub unsafe fn get_output_fmt() -> &'static OutputFmt {
|
||||
OUTPUT_FMT
|
||||
}
|
||||
|
||||
pub enum OutputFmt {
|
||||
Json,
|
||||
Plain,
|
||||
Json,
|
||||
}
|
||||
|
||||
impl From<&str> for OutputFmt {
|
||||
|
||||
+34
-10
@@ -1,11 +1,31 @@
|
||||
use error_chain::error_chain;
|
||||
use log::{Level, LevelFilter, Metadata, Record};
|
||||
use log::{self, Level, LevelFilter, Metadata, Record};
|
||||
use std::fmt;
|
||||
|
||||
use super::fmt::OutputFmt;
|
||||
use super::fmt::{set_output_fmt, OutputFmt};
|
||||
|
||||
error_chain! {}
|
||||
|
||||
// Macros
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! info {
|
||||
($t:expr) => {
|
||||
use crate::output::fmt::{get_output_fmt, OutputFmt};
|
||||
use log::info as log_info;
|
||||
unsafe {
|
||||
match get_output_fmt() {
|
||||
OutputFmt::Plain => log_info!("{}", $t.to_string()),
|
||||
OutputFmt::Json => {
|
||||
// Should be safe enough to `.unwrap()` since it's
|
||||
// formatted by Himalaya itself
|
||||
log_info!("{{\"response\":{}}}", serde_json::to_string($t).unwrap())
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Log level struct
|
||||
|
||||
pub struct LogLevel(pub LevelFilter);
|
||||
@@ -30,7 +50,7 @@ impl fmt::Display for LogLevel {
|
||||
|
||||
// Plain logger
|
||||
|
||||
struct PlainLogger;
|
||||
pub struct PlainLogger;
|
||||
|
||||
impl log::Log for PlainLogger {
|
||||
fn enabled(&self, metadata: &Metadata) -> bool {
|
||||
@@ -52,7 +72,7 @@ impl log::Log for PlainLogger {
|
||||
|
||||
// JSON logger
|
||||
|
||||
struct JsonLogger;
|
||||
pub struct JsonLogger;
|
||||
|
||||
impl log::Log for JsonLogger {
|
||||
fn enabled(&self, metadata: &Metadata) -> bool {
|
||||
@@ -64,9 +84,7 @@ impl log::Log for JsonLogger {
|
||||
if let Level::Error = record.level() {
|
||||
eprintln!("{}", record.args());
|
||||
} else {
|
||||
// Should be safe enough to `.unwrap()` since it's
|
||||
// formatted by Himalaya itself
|
||||
print!("{}", serde_json::to_string(record.args()).unwrap());
|
||||
print!("{}", record.args());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,9 +95,15 @@ impl log::Log for JsonLogger {
|
||||
// Init
|
||||
|
||||
pub fn init(fmt: &OutputFmt, level: &LogLevel) -> Result<()> {
|
||||
log::set_boxed_logger(match fmt {
|
||||
&OutputFmt::Json => Box::new(JsonLogger),
|
||||
&OutputFmt::Plain => Box::new(PlainLogger),
|
||||
log::set_logger(match fmt {
|
||||
&OutputFmt::Plain => {
|
||||
set_output_fmt(&OutputFmt::Plain);
|
||||
&PlainLogger
|
||||
}
|
||||
&OutputFmt::Json => {
|
||||
set_output_fmt(&OutputFmt::Json);
|
||||
&JsonLogger
|
||||
}
|
||||
})
|
||||
.map(|()| log::set_max_level(level.0))
|
||||
.chain_err(|| "Could not init logger")
|
||||
|
||||
+1
-18
@@ -1,8 +1,5 @@
|
||||
use error_chain::error_chain;
|
||||
use serde::{
|
||||
ser::{self, SerializeStruct},
|
||||
Serialize,
|
||||
};
|
||||
use serde::ser::{self, SerializeStruct};
|
||||
use std::{fmt, process::Command, result};
|
||||
|
||||
error_chain! {
|
||||
@@ -40,17 +37,3 @@ pub fn run_cmd(cmd: &str) -> Result<String> {
|
||||
|
||||
Ok(String::from_utf8(output.stdout)?)
|
||||
}
|
||||
|
||||
pub fn print<T: fmt::Display + Serialize>(output_type: &str, silent: &bool, item: T) -> Result<()> {
|
||||
if silent == &false {
|
||||
match output_type {
|
||||
"json" => print!(
|
||||
"{}",
|
||||
serde_json::to_string(&item).chain_err(|| "Could not decode JSON")?
|
||||
),
|
||||
"text" | _ => println!("{}", item.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user