himalaya/src/main.rs
Clément DOUIN 509b09d533
prepare v0.7.1
Those commits have been stashed then applied due to merge issue:

add ability to sync specific folders f7585eb
add expunge command 1c0b7fb
update readme links to documentation e1c8cf5
fix other doc typos 9c27165
reword title of the project 1eaac7d
reword title of the project bis a7419d6
fix broken links in changelog 26b0311
prepare v0.7.1 2b5e58e
2023-02-14 16:47:02 +01:00

456 lines
17 KiB
Rust

use anyhow::Result;
use clap::Command;
use std::{borrow::Cow, env};
use url::Url;
use himalaya::{
account, cache, compl,
config::{self, DeserializedConfig},
email, flag, folder, man, output,
printer::StdoutPrinter,
tpl,
};
use himalaya_lib::{
BackendBuilder, BackendConfig, ImapBackend, SenderBuilder, DEFAULT_INBOX_FOLDER,
};
#[cfg(feature = "imap-backend")]
use himalaya::imap;
fn create_app() -> Command {
let app = Command::new(env!("CARGO_PKG_NAME"))
.version(env!("CARGO_PKG_VERSION"))
.about(env!("CARGO_PKG_DESCRIPTION"))
.author(env!("CARGO_PKG_AUTHORS"))
.propagate_version(true)
.infer_subcommands(true)
.arg(config::args::arg())
.arg(account::args::arg())
.arg(cache::args::arg())
.args(output::args::args())
.arg(folder::args::source_arg())
.subcommand(compl::args::subcmd())
.subcommand(man::args::subcmd())
.subcommand(account::args::subcmd())
.subcommand(folder::args::subcmd())
.subcommands(email::args::subcmds());
#[cfg(feature = "imap-backend")]
let app = app.subcommands(imap::args::subcmds());
app
}
#[allow(clippy::single_match)]
fn main() -> Result<()> {
let default_env_filter = env_logger::DEFAULT_FILTER_ENV;
env_logger::init_from_env(env_logger::Env::default().filter_or(default_env_filter, "off"));
// checks mailto command before app initialization
let raw_args: Vec<String> = env::args().collect();
if raw_args.len() > 1 && raw_args[1].starts_with("mailto:") {
let url = Url::parse(&raw_args[1])?;
let config = DeserializedConfig::from_opt_path(None)?;
let (account_config, backend_config) = config.to_configs(None)?;
let mut backend = BackendBuilder::new().build(&account_config, &backend_config)?;
let mut sender = SenderBuilder::build(&account_config)?;
let mut printer = StdoutPrinter::default();
return email::handlers::mailto(
&account_config,
&mut printer,
backend.as_mut(),
sender.as_mut(),
&url,
);
}
let app = create_app();
let m = app.get_matches();
// checks completion command before configs
// https://github.com/soywod/himalaya/issues/115
match compl::args::matches(&m)? {
Some(compl::args::Cmd::Generate(shell)) => {
return compl::handlers::generate(create_app(), shell);
}
_ => (),
}
// checks completion command before configs
// https://github.com/soywod/himalaya/issues/115
match man::args::matches(&m)? {
Some(man::args::Cmd::GenerateAll(dir)) => {
return man::handlers::generate(dir, create_app());
}
_ => (),
}
// inits config
let config = DeserializedConfig::from_opt_path(config::args::parse_arg(&m))?;
let (account_config, backend_config) = config.to_configs(account::args::parse_arg(&m))?;
let folder = folder::args::parse_source_arg(&m);
// checks IMAP commands
#[cfg(feature = "imap-backend")]
if let BackendConfig::Imap(imap_config) = &backend_config {
let folder = account_config.folder_alias(folder.unwrap_or(DEFAULT_INBOX_FOLDER))?;
// FIXME: find a way to downcast `backend` instead of
// recreating an instance.
match imap::args::matches(&m)? {
Some(imap::args::Cmd::Notify(keepalive)) => {
let imap =
ImapBackend::new(Cow::Borrowed(&account_config), Cow::Borrowed(&imap_config))?;
return imap::handlers::notify(&imap, &folder, keepalive);
}
Some(imap::args::Cmd::Watch(keepalive)) => {
let imap =
ImapBackend::new(Cow::Borrowed(&account_config), Cow::Borrowed(&imap_config))?;
return imap::handlers::watch(&imap, &folder, keepalive);
}
_ => (),
}
}
// inits services
let mut sender = SenderBuilder::build(&account_config)?;
let mut printer = StdoutPrinter::try_from(&m)?;
let disable_cache = cache::args::parse_disable_cache_flag(&m);
// checks account commands
match account::args::matches(&m)? {
Some(account::args::Cmd::List(max_width)) => {
return account::handlers::list(max_width, &account_config, &config, &mut printer);
}
Some(account::args::Cmd::Sync(dry_run)) => {
let folder = match folder {
Some(folder) => Some(account_config.folder_alias(folder)?),
None => None,
};
let backend = BackendBuilder::new()
.sessions_pool_size(8)
.disable_cache(true)
.build(&account_config, &backend_config)?;
account::handlers::sync(
&account_config,
&mut printer,
backend.as_ref(),
&folder,
dry_run,
)?;
backend.close()?;
return Ok(());
}
_ => (),
}
// checks folder commands
match folder::args::matches(&m)? {
Some(folder::args::Cmd::Expunge) => {
let folder = account_config.folder_alias(folder.unwrap_or(DEFAULT_INBOX_FOLDER))?;
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return folder::handlers::expunge(&folder, &mut printer, backend.as_mut());
}
Some(folder::args::Cmd::List(max_width)) => {
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return folder::handlers::list(
max_width,
&account_config,
&mut printer,
backend.as_mut(),
);
}
_ => (),
}
// checks email commands
match email::args::matches(&m)? {
Some(email::args::Cmd::Attachments(ids)) => {
let folder = account_config.folder_alias(folder.unwrap_or(DEFAULT_INBOX_FOLDER))?;
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return email::handlers::attachments(
&account_config,
&mut printer,
backend.as_mut(),
&folder,
ids,
);
}
Some(email::args::Cmd::Copy(ids, to_folder)) => {
let folder = account_config.folder_alias(folder.unwrap_or(DEFAULT_INBOX_FOLDER))?;
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return email::handlers::copy(
&account_config,
&mut printer,
backend.as_mut(),
&folder,
to_folder,
ids,
);
}
Some(email::args::Cmd::Delete(ids)) => {
let folder = account_config.folder_alias(folder.unwrap_or(DEFAULT_INBOX_FOLDER))?;
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return email::handlers::delete(
&account_config,
&mut printer,
backend.as_mut(),
&folder,
ids,
);
}
Some(email::args::Cmd::Forward(id, headers, body)) => {
let folder = account_config.folder_alias(folder.unwrap_or(DEFAULT_INBOX_FOLDER))?;
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return email::handlers::forward(
&account_config,
&mut printer,
backend.as_mut(),
sender.as_mut(),
&folder,
id,
headers,
body,
);
}
Some(email::args::Cmd::List(max_width, page_size, page)) => {
let folder = account_config.folder_alias(folder.unwrap_or(DEFAULT_INBOX_FOLDER))?;
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return email::handlers::list(
&account_config,
&mut printer,
backend.as_mut(),
&folder,
max_width,
page_size,
page,
);
}
Some(email::args::Cmd::Move(ids, to_folder)) => {
let folder = account_config.folder_alias(folder.unwrap_or(DEFAULT_INBOX_FOLDER))?;
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return email::handlers::move_(
&account_config,
&mut printer,
backend.as_mut(),
&folder,
to_folder,
ids,
);
}
Some(email::args::Cmd::Read(ids, text_mime, sanitize, raw, headers)) => {
let folder = account_config.folder_alias(folder.unwrap_or(DEFAULT_INBOX_FOLDER))?;
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return email::handlers::read(
&account_config,
&mut printer,
backend.as_mut(),
&folder,
ids,
text_mime,
sanitize,
raw,
headers,
);
}
Some(email::args::Cmd::Reply(id, all, headers, body)) => {
let folder = account_config.folder_alias(folder.unwrap_or(DEFAULT_INBOX_FOLDER))?;
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return email::handlers::reply(
&account_config,
&mut printer,
backend.as_mut(),
sender.as_mut(),
&folder,
id,
all,
headers,
body,
);
}
Some(email::args::Cmd::Save(raw_email)) => {
let folder = account_config.folder_alias(folder.unwrap_or(DEFAULT_INBOX_FOLDER))?;
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return email::handlers::save(
&account_config,
&mut printer,
backend.as_mut(),
&folder,
raw_email,
);
}
Some(email::args::Cmd::Search(query, max_width, page_size, page)) => {
let folder = account_config.folder_alias(folder.unwrap_or(DEFAULT_INBOX_FOLDER))?;
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return email::handlers::search(
&account_config,
&mut printer,
backend.as_mut(),
&folder,
query,
max_width,
page_size,
page,
);
}
Some(email::args::Cmd::Sort(criteria, query, max_width, page_size, page)) => {
let folder = account_config.folder_alias(folder.unwrap_or(DEFAULT_INBOX_FOLDER))?;
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return email::handlers::sort(
&account_config,
&mut printer,
backend.as_mut(),
&folder,
criteria,
query,
max_width,
page_size,
page,
);
}
Some(email::args::Cmd::Send(raw_email)) => {
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return email::handlers::send(
&account_config,
&mut printer,
backend.as_mut(),
sender.as_mut(),
raw_email,
);
}
Some(email::args::Cmd::Flag(m)) => match m {
Some(flag::args::Cmd::Set(ids, ref flags)) => {
let folder = account_config.folder_alias(folder.unwrap_or(DEFAULT_INBOX_FOLDER))?;
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return flag::handlers::set(&mut printer, backend.as_mut(), &folder, ids, flags);
}
Some(flag::args::Cmd::Add(ids, ref flags)) => {
let folder = account_config.folder_alias(folder.unwrap_or(DEFAULT_INBOX_FOLDER))?;
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return flag::handlers::add(&mut printer, backend.as_mut(), &folder, ids, flags);
}
Some(flag::args::Cmd::Remove(ids, ref flags)) => {
let folder = account_config.folder_alias(folder.unwrap_or(DEFAULT_INBOX_FOLDER))?;
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return flag::handlers::remove(&mut printer, backend.as_mut(), &folder, ids, flags);
}
_ => (),
},
Some(email::args::Cmd::Tpl(m)) => match m {
Some(tpl::args::Cmd::Forward(id, headers, body)) => {
let folder = account_config.folder_alias(folder.unwrap_or(DEFAULT_INBOX_FOLDER))?;
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return tpl::handlers::forward(
&account_config,
&mut printer,
backend.as_mut(),
&folder,
id,
headers,
body,
);
}
Some(tpl::args::Cmd::Write(headers, body)) => {
return tpl::handlers::write(&account_config, &mut printer, headers, body);
}
Some(tpl::args::Cmd::Reply(id, all, headers, body)) => {
let folder = account_config.folder_alias(folder.unwrap_or(DEFAULT_INBOX_FOLDER))?;
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return tpl::handlers::reply(
&account_config,
&mut printer,
backend.as_mut(),
&folder,
id,
all,
headers,
body,
);
}
Some(tpl::args::Cmd::Save(tpl)) => {
let folder = account_config.folder_alias(folder.unwrap_or(DEFAULT_INBOX_FOLDER))?;
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return tpl::handlers::save(
&account_config,
&mut printer,
backend.as_mut(),
&folder,
tpl,
);
}
Some(tpl::args::Cmd::Send(tpl)) => {
let folder = account_config.folder_alias(folder.unwrap_or(DEFAULT_INBOX_FOLDER))?;
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return tpl::handlers::send(
&account_config,
&mut printer,
backend.as_mut(),
sender.as_mut(),
&folder,
tpl,
);
}
_ => (),
},
Some(email::args::Cmd::Write(headers, body)) => {
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return email::handlers::write(
&account_config,
&mut printer,
backend.as_mut(),
sender.as_mut(),
headers,
body,
);
}
_ => (),
}
Ok(())
}