mirror of
https://github.com/pimalaya/himalaya.git
synced 2026-06-17 13:17:55 +08:00
update pimalaya libs, prepare v0.9.0
This commit is contained in:
Vendored
+4
-4
@@ -1,13 +1,13 @@
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use log::{debug, trace};
|
||||
#[cfg(feature = "imap-backend")]
|
||||
use pimalaya_email::backend::ImapBackend;
|
||||
use email::backend::ImapBackend;
|
||||
#[cfg(feature = "notmuch-backend")]
|
||||
use pimalaya_email::backend::NotmuchBackend;
|
||||
use pimalaya_email::{
|
||||
use email::backend::NotmuchBackend;
|
||||
use email::{
|
||||
account::AccountConfig,
|
||||
backend::{Backend, MaildirBackend},
|
||||
};
|
||||
use log::{debug, trace};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
const ID_MAPPER_DB_FILE_NAME: &str = ".id-mapper.sqlite";
|
||||
|
||||
+27
-16
@@ -6,14 +6,14 @@
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use dialoguer::Confirm;
|
||||
use dirs::{config_dir, home_dir};
|
||||
use log::{debug, trace};
|
||||
use pimalaya_email::{
|
||||
use email::{
|
||||
account::AccountConfig,
|
||||
email::{EmailHooks, EmailTextPlainFormat},
|
||||
};
|
||||
use pimalaya_process::Cmd;
|
||||
use log::{debug, trace};
|
||||
use process::Cmd;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{collections::HashMap, fs, path::PathBuf, process};
|
||||
use std::{collections::HashMap, fs, path::PathBuf, process::exit};
|
||||
use toml;
|
||||
|
||||
use crate::{
|
||||
@@ -101,7 +101,7 @@ impl DeserializedConfig {
|
||||
.interact_opt()?
|
||||
.unwrap_or_default()
|
||||
{
|
||||
process::exit(0);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
wizard::configure().await?
|
||||
@@ -160,19 +160,19 @@ impl DeserializedConfig {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use pimalaya_email::{
|
||||
use email::{
|
||||
account::PasswdConfig,
|
||||
backend::{BackendConfig, MaildirConfig},
|
||||
sender::{SenderConfig, SendmailConfig},
|
||||
};
|
||||
use pimalaya_secret::Secret;
|
||||
use secret::Secret;
|
||||
|
||||
#[cfg(feature = "notmuch-backend")]
|
||||
use pimalaya_email::backend::NotmuchConfig;
|
||||
use email::backend::NotmuchConfig;
|
||||
#[cfg(feature = "imap-backend")]
|
||||
use pimalaya_email::backend::{ImapAuthConfig, ImapConfig};
|
||||
use email::backend::{ImapAuthConfig, ImapConfig};
|
||||
#[cfg(feature = "smtp-sender")]
|
||||
use pimalaya_email::sender::{SmtpAuthConfig, SmtpConfig};
|
||||
use email::sender::{SmtpAuthConfig, SmtpConfig};
|
||||
|
||||
use std::io::Write;
|
||||
use tempfile::NamedTempFile;
|
||||
@@ -463,17 +463,28 @@ mod tests {
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(config
|
||||
.unwrap_err()
|
||||
.root_cause()
|
||||
.to_string()
|
||||
.contains("missing field `sendmail-cmd`"));
|
||||
assert_eq!(
|
||||
config.unwrap(),
|
||||
DeserializedConfig {
|
||||
accounts: HashMap::from_iter([(
|
||||
"account".into(),
|
||||
DeserializedAccountConfig {
|
||||
email: "test@localhost".into(),
|
||||
sender: SenderConfig::Sendmail(SendmailConfig {
|
||||
cmd: "/usr/sbin/sendmail".into()
|
||||
}),
|
||||
..DeserializedAccountConfig::default()
|
||||
}
|
||||
)]),
|
||||
..DeserializedConfig::default()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(feature = "smtp-sender")]
|
||||
#[tokio::test]
|
||||
async fn account_smtp_sender_minimum_config() {
|
||||
use pimalaya_email::sender::SenderConfig;
|
||||
use email::sender::SenderConfig;
|
||||
|
||||
let config = make_config(
|
||||
"[account]
|
||||
|
||||
+20
-20
@@ -1,25 +1,25 @@
|
||||
#[cfg(feature = "cmds-pgp")]
|
||||
use pimalaya_email::account::CmdsPgpConfig;
|
||||
#[cfg(feature = "gpg")]
|
||||
use pimalaya_email::account::GpgConfig;
|
||||
#[cfg(feature = "native-pgp")]
|
||||
use pimalaya_email::account::{NativePgpConfig, NativePgpSecretKey, SignedSecretKey};
|
||||
#[cfg(feature = "pgp-commands")]
|
||||
use email::account::CmdsPgpConfig;
|
||||
#[cfg(feature = "pgp-gpg")]
|
||||
use email::account::GpgConfig;
|
||||
#[cfg(feature = "pgp-native")]
|
||||
use email::account::{NativePgpConfig, NativePgpSecretKey, SignedSecretKey};
|
||||
#[cfg(feature = "notmuch-backend")]
|
||||
use pimalaya_email::backend::NotmuchConfig;
|
||||
use email::backend::NotmuchConfig;
|
||||
#[cfg(feature = "imap-backend")]
|
||||
use pimalaya_email::backend::{ImapAuthConfig, ImapConfig};
|
||||
use email::backend::{ImapAuthConfig, ImapConfig};
|
||||
#[cfg(feature = "smtp-sender")]
|
||||
use pimalaya_email::sender::{SmtpAuthConfig, SmtpConfig};
|
||||
use pimalaya_email::{
|
||||
use email::sender::{SmtpAuthConfig, SmtpConfig};
|
||||
use email::{
|
||||
account::{OAuth2Config, OAuth2Method, OAuth2Scopes, PasswdConfig, PgpConfig},
|
||||
backend::{BackendConfig, MaildirConfig},
|
||||
email::{EmailHooks, EmailTextPlainFormat},
|
||||
folder::sync::FolderSyncStrategy,
|
||||
sender::{SenderConfig, SendmailConfig},
|
||||
};
|
||||
use pimalaya_keyring::Entry;
|
||||
use pimalaya_process::{Cmd, Pipeline, SingleCmd};
|
||||
use pimalaya_secret::Secret;
|
||||
use keyring::Entry;
|
||||
use process::{Cmd, Pipeline, SingleCmd};
|
||||
use secret::Secret;
|
||||
use serde::{ser::SerializeSeq, Deserialize, Serialize, Serializer};
|
||||
use std::{collections::HashSet, ops::Deref, path::PathBuf};
|
||||
|
||||
@@ -407,23 +407,23 @@ pub enum FolderSyncStrategyDef {
|
||||
pub enum PgpConfigDef {
|
||||
#[default]
|
||||
None,
|
||||
#[cfg(feature = "cmds-pgp")]
|
||||
#[cfg(feature = "pgp-commands")]
|
||||
#[serde(with = "CmdsPgpConfigDef", alias = "commands")]
|
||||
Cmds(CmdsPgpConfig),
|
||||
#[cfg(feature = "gpg")]
|
||||
#[cfg(feature = "pgp-gpg")]
|
||||
#[serde(with = "GpgConfigDef")]
|
||||
Gpg(GpgConfig),
|
||||
#[cfg(feature = "native-pgp")]
|
||||
#[cfg(feature = "pgp-native")]
|
||||
#[serde(with = "NativePgpConfigDef")]
|
||||
Native(NativePgpConfig),
|
||||
}
|
||||
|
||||
#[cfg(feature = "gpg")]
|
||||
#[cfg(feature = "pgp-gpg")]
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(remote = "GpgConfig", rename_all = "kebab-case")]
|
||||
pub struct GpgConfigDef;
|
||||
|
||||
#[cfg(feature = "cmds-pgp")]
|
||||
#[cfg(feature = "pgp-commands")]
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(remote = "CmdsPgpConfig", rename_all = "kebab-case")]
|
||||
pub struct CmdsPgpConfigDef {
|
||||
@@ -441,7 +441,7 @@ pub struct CmdsPgpConfigDef {
|
||||
verify_cmd: Option<Cmd>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "native-pgp")]
|
||||
#[cfg(feature = "pgp-native")]
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(remote = "NativePgpConfig", rename_all = "kebab-case")]
|
||||
pub struct NativePgpConfigDef {
|
||||
@@ -455,7 +455,7 @@ pub struct NativePgpConfigDef {
|
||||
key_servers: Vec<String>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "native-pgp")]
|
||||
#[cfg(feature = "pgp-native")]
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(remote = "NativePgpSecretKey", rename_all = "kebab-case")]
|
||||
pub enum NativePgpSecretKeyDef {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
//! accounts from the config file.
|
||||
|
||||
use anyhow::Result;
|
||||
use pimalaya_email::backend::BackendConfig;
|
||||
use email::backend::BackendConfig;
|
||||
use serde::Serialize;
|
||||
use std::{collections::hash_map::Iter, ops::Deref};
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
use anyhow::Result;
|
||||
use clap::{Arg, ArgAction, ArgMatches, Command};
|
||||
use email::folder::sync::FolderSyncStrategy;
|
||||
use log::info;
|
||||
use pimalaya_email::folder::sync::FolderSyncStrategy;
|
||||
use std::collections::HashSet;
|
||||
|
||||
use crate::{folder, ui::table};
|
||||
|
||||
@@ -4,17 +4,17 @@
|
||||
//! account in the accounts section of the user configuration file.
|
||||
|
||||
#[cfg(feature = "imap-backend")]
|
||||
use pimalaya_email::backend::ImapAuthConfig;
|
||||
use email::backend::ImapAuthConfig;
|
||||
#[cfg(feature = "smtp-sender")]
|
||||
use pimalaya_email::sender::SmtpAuthConfig;
|
||||
use pimalaya_email::{
|
||||
use email::sender::SmtpAuthConfig;
|
||||
use email::{
|
||||
account::{AccountConfig, PgpConfig},
|
||||
backend::BackendConfig,
|
||||
email::{EmailHooks, EmailTextPlainFormat},
|
||||
folder::sync::FolderSyncStrategy,
|
||||
sender::SenderConfig,
|
||||
};
|
||||
use pimalaya_process::Cmd;
|
||||
use process::Cmd;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{collections::HashMap, path::PathBuf};
|
||||
|
||||
|
||||
@@ -3,14 +3,11 @@
|
||||
//! This module gathers all account actions triggered by the CLI.
|
||||
|
||||
use anyhow::Result;
|
||||
use indicatif::{MultiProgress, ProgressBar, ProgressFinish, ProgressStyle};
|
||||
use log::{info, trace, warn};
|
||||
use once_cell::sync::Lazy;
|
||||
#[cfg(feature = "imap-backend")]
|
||||
use pimalaya_email::backend::ImapAuthConfig;
|
||||
use email::backend::ImapAuthConfig;
|
||||
#[cfg(feature = "smtp-sender")]
|
||||
use pimalaya_email::sender::SmtpAuthConfig;
|
||||
use pimalaya_email::{
|
||||
use email::sender::SmtpAuthConfig;
|
||||
use email::{
|
||||
account::{
|
||||
sync::{AccountSyncBuilder, AccountSyncProgressEvent},
|
||||
AccountConfig,
|
||||
@@ -18,6 +15,9 @@ use pimalaya_email::{
|
||||
backend::BackendConfig,
|
||||
sender::SenderConfig,
|
||||
};
|
||||
use indicatif::{MultiProgress, ProgressBar, ProgressFinish, ProgressStyle};
|
||||
use log::{info, trace, warn};
|
||||
use once_cell::sync::Lazy;
|
||||
use std::{collections::HashMap, sync::Mutex};
|
||||
|
||||
use crate::{
|
||||
@@ -294,7 +294,7 @@ pub async fn sync<P: Printer>(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use pimalaya_email::{account::AccountConfig, backend::ImapConfig};
|
||||
use email::{account::AccountConfig, backend::ImapConfig};
|
||||
use std::{collections::HashMap, fmt::Debug, io};
|
||||
use termcolor::ColorSpec;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//! This module gathers all IMAP handlers triggered by the CLI.
|
||||
|
||||
use anyhow::Result;
|
||||
use pimalaya_email::backend::ImapBackend;
|
||||
use email::backend::ImapBackend;
|
||||
|
||||
pub async fn notify(imap: &mut ImapBackend, folder: &str, keepalive: u64) -> Result<()> {
|
||||
imap.notify(keepalive, folder).await?;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use anyhow::Result;
|
||||
use dialoguer::{Confirm, Input, Password, Select};
|
||||
use pimalaya_email::{
|
||||
use email::{
|
||||
account::{OAuth2Config, OAuth2Method, OAuth2Scopes, PasswdConfig},
|
||||
backend::{BackendConfig, ImapAuthConfig, ImapConfig},
|
||||
};
|
||||
use pimalaya_oauth2::{AuthorizationCodeGrant, Client};
|
||||
use pimalaya_secret::Secret;
|
||||
use oauth::v2_0::{AuthorizationCodeGrant, Client};
|
||||
use secret::Secret;
|
||||
|
||||
use crate::{
|
||||
config::wizard::{prompt_passwd, THEME},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use anyhow::Result;
|
||||
use dialoguer::Input;
|
||||
use dirs::home_dir;
|
||||
use pimalaya_email::backend::{BackendConfig, MaildirConfig};
|
||||
use email::backend::{BackendConfig, MaildirConfig};
|
||||
|
||||
use crate::config::wizard::THEME;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use anyhow::Result;
|
||||
use dialoguer::Input;
|
||||
use pimalaya_email::backend::{BackendConfig, NotmuchBackend, NotmuchConfig};
|
||||
use email::backend::{BackendConfig, NotmuchBackend, NotmuchConfig};
|
||||
|
||||
use crate::config::wizard::THEME;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use anyhow::Result;
|
||||
use dialoguer::Select;
|
||||
use pimalaya_email::backend::BackendConfig;
|
||||
use email::backend::BackendConfig;
|
||||
|
||||
use crate::config::wizard::THEME;
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use atty::Stream;
|
||||
use log::{debug, trace};
|
||||
use pimalaya_email::{
|
||||
use email::{
|
||||
account::AccountConfig,
|
||||
backend::Backend,
|
||||
email::{template::FilterParts, Flag, Flags, Message, MessageBuilder},
|
||||
sender::Sender,
|
||||
};
|
||||
use log::{debug, trace};
|
||||
use std::{
|
||||
fs,
|
||||
io::{self, BufRead},
|
||||
@@ -127,7 +127,7 @@ pub async fn forward<P: Printer>(
|
||||
.with_some_body(body)
|
||||
.build()
|
||||
.await?;
|
||||
trace!("initial template: {}", *tpl);
|
||||
trace!("initial template: {tpl}");
|
||||
editor::edit_tpl_with_editor(config, printer, backend, sender, tpl).await?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -276,7 +276,7 @@ pub async fn reply<P: Printer>(
|
||||
.with_reply_all(all)
|
||||
.build()
|
||||
.await?;
|
||||
trace!("initial template: {}", *tpl);
|
||||
trace!("initial template: {tpl}");
|
||||
editor::edit_tpl_with_editor(config, printer, backend, sender, tpl).await?;
|
||||
backend
|
||||
.add_flags(&folder, vec![id], &Flags::from_iter([Flag::Answered]))
|
||||
@@ -414,7 +414,7 @@ pub async fn write<P: Printer>(
|
||||
.with_some_body(body)
|
||||
.build()
|
||||
.await?;
|
||||
trace!("initial template: {}", *tpl);
|
||||
trace!("initial template: {tpl}");
|
||||
editor::edit_tpl_with_editor(config, printer, backend, sender, tpl).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use anyhow::Result;
|
||||
use pimalaya_email::account::AccountConfig;
|
||||
use email::account::AccountConfig;
|
||||
use serde::Serialize;
|
||||
use std::ops;
|
||||
|
||||
@@ -17,7 +17,7 @@ impl Envelopes {
|
||||
pub fn from_backend(
|
||||
config: &AccountConfig,
|
||||
id_mapper: &IdMapper,
|
||||
envelopes: pimalaya_email::email::Envelopes,
|
||||
envelopes: email::email::Envelopes,
|
||||
) -> Result<Envelopes> {
|
||||
let envelopes = envelopes
|
||||
.iter()
|
||||
@@ -59,7 +59,7 @@ impl PrintTable for Envelopes {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use chrono::DateTime;
|
||||
use pimalaya_email::account::AccountConfig;
|
||||
use email::account::AccountConfig;
|
||||
use std::env;
|
||||
|
||||
use crate::{Envelopes, IdMapper};
|
||||
@@ -69,11 +69,10 @@ mod tests {
|
||||
let config = AccountConfig::default();
|
||||
let id_mapper = IdMapper::Dummy;
|
||||
|
||||
let envelopes =
|
||||
pimalaya_email::email::Envelopes::from_iter([pimalaya_email::email::Envelope {
|
||||
date: DateTime::parse_from_rfc3339("2023-06-15T09:42:00+04:00").unwrap(),
|
||||
..Default::default()
|
||||
}]);
|
||||
let envelopes = email::email::Envelopes::from_iter([email::email::Envelope {
|
||||
date: DateTime::parse_from_rfc3339("2023-06-15T09:42:00+04:00").unwrap(),
|
||||
..Default::default()
|
||||
}]);
|
||||
let envelopes = Envelopes::from_backend(&config, &id_mapper, envelopes).unwrap();
|
||||
|
||||
let expected_date = "2023-06-15 09:42+04:00";
|
||||
@@ -90,11 +89,10 @@ mod tests {
|
||||
..AccountConfig::default()
|
||||
};
|
||||
|
||||
let envelopes =
|
||||
pimalaya_email::email::Envelopes::from_iter([pimalaya_email::email::Envelope {
|
||||
date: DateTime::parse_from_rfc3339("2023-06-15T09:42:00+04:00").unwrap(),
|
||||
..Default::default()
|
||||
}]);
|
||||
let envelopes = email::email::Envelopes::from_iter([email::email::Envelope {
|
||||
date: DateTime::parse_from_rfc3339("2023-06-15T09:42:00+04:00").unwrap(),
|
||||
..Default::default()
|
||||
}]);
|
||||
let envelopes = Envelopes::from_backend(&config, &id_mapper, envelopes).unwrap();
|
||||
|
||||
let expected_date = "15/06/2023 09h42";
|
||||
@@ -114,11 +112,10 @@ mod tests {
|
||||
..AccountConfig::default()
|
||||
};
|
||||
|
||||
let envelopes =
|
||||
pimalaya_email::email::Envelopes::from_iter([pimalaya_email::email::Envelope {
|
||||
date: DateTime::parse_from_rfc3339("2023-06-15T09:42:00+04:00").unwrap(),
|
||||
..Default::default()
|
||||
}]);
|
||||
let envelopes = email::email::Envelopes::from_iter([email::email::Envelope {
|
||||
date: DateTime::parse_from_rfc3339("2023-06-15T09:42:00+04:00").unwrap(),
|
||||
..Default::default()
|
||||
}]);
|
||||
let envelopes = Envelopes::from_backend(&config, &id_mapper, envelopes).unwrap();
|
||||
|
||||
let expected_date = "15/06/2023 05h42";
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
//! This module contains the command matcher, the subcommands and the
|
||||
//! arguments related to the email flag domain.
|
||||
|
||||
use ::email::email::{Flag, Flags};
|
||||
use anyhow::Result;
|
||||
use clap::{Arg, ArgMatches, Command};
|
||||
use log::{debug, info};
|
||||
use pimalaya_email::email::{Flag, Flags};
|
||||
|
||||
use crate::email;
|
||||
|
||||
|
||||
@@ -11,9 +11,9 @@ pub enum Flag {
|
||||
Custom(String),
|
||||
}
|
||||
|
||||
impl From<&pimalaya_email::email::Flag> for Flag {
|
||||
fn from(flag: &pimalaya_email::email::Flag) -> Self {
|
||||
use pimalaya_email::email::Flag::*;
|
||||
impl From<&email::email::Flag> for Flag {
|
||||
fn from(flag: &email::email::Flag) -> Self {
|
||||
use email::email::Flag::*;
|
||||
match flag {
|
||||
Seen => Flag::Seen,
|
||||
Answered => Flag::Answered,
|
||||
|
||||
@@ -14,8 +14,8 @@ impl ops::Deref for Flags {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<pimalaya_email::email::Flags> for Flags {
|
||||
fn from(flags: pimalaya_email::email::Flags) -> Self {
|
||||
impl From<email::email::Flags> for Flags {
|
||||
fn from(flags: email::email::Flags) -> Self {
|
||||
Flags(flags.iter().map(Flag::from).collect())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use anyhow::Result;
|
||||
use pimalaya_email::{backend::Backend, email::Flags};
|
||||
use email::{backend::Backend, email::Flags};
|
||||
|
||||
use crate::{printer::Printer, IdMapper};
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ pub struct Folder {
|
||||
pub desc: String,
|
||||
}
|
||||
|
||||
impl From<&pimalaya_email::folder::Folder> for Folder {
|
||||
fn from(folder: &pimalaya_email::folder::Folder) -> Self {
|
||||
impl From<&email::folder::Folder> for Folder {
|
||||
fn from(folder: &email::folder::Folder) -> Self {
|
||||
Folder {
|
||||
name: folder.name.clone(),
|
||||
desc: folder.desc.clone(),
|
||||
|
||||
@@ -19,8 +19,8 @@ impl ops::Deref for Folders {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<pimalaya_email::folder::Folders> for Folders {
|
||||
fn from(folders: pimalaya_email::folder::Folders) -> Self {
|
||||
impl From<email::folder::Folders> for Folders {
|
||||
fn from(folders: email::folder::Folders) -> Self {
|
||||
Folders(folders.iter().map(Folder::from).collect())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
use anyhow::Result;
|
||||
use dialoguer::Confirm;
|
||||
use pimalaya_email::{account::AccountConfig, backend::Backend};
|
||||
use email::{account::AccountConfig, backend::Backend};
|
||||
use std::process;
|
||||
|
||||
use crate::{
|
||||
@@ -68,7 +68,7 @@ pub async fn delete<P: Printer>(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use async_trait::async_trait;
|
||||
use pimalaya_email::{
|
||||
use email::{
|
||||
account::AccountConfig,
|
||||
backend::Backend,
|
||||
email::{Envelope, Envelopes, Flags, Messages},
|
||||
@@ -152,10 +152,10 @@ mod tests {
|
||||
fn name(&self) -> String {
|
||||
unimplemented!();
|
||||
}
|
||||
async fn add_folder(&mut self, _: &str) -> pimalaya_email::Result<()> {
|
||||
async fn add_folder(&mut self, _: &str) -> email::Result<()> {
|
||||
unimplemented!();
|
||||
}
|
||||
async fn list_folders(&mut self) -> pimalaya_email::Result<Folders> {
|
||||
async fn list_folders(&mut self) -> email::Result<Folders> {
|
||||
Ok(Folders::from_iter([
|
||||
Folder {
|
||||
name: "INBOX".into(),
|
||||
@@ -167,16 +167,16 @@ mod tests {
|
||||
},
|
||||
]))
|
||||
}
|
||||
async fn expunge_folder(&mut self, _: &str) -> pimalaya_email::Result<()> {
|
||||
async fn expunge_folder(&mut self, _: &str) -> email::Result<()> {
|
||||
unimplemented!();
|
||||
}
|
||||
async fn purge_folder(&mut self, _: &str) -> pimalaya_email::Result<()> {
|
||||
async fn purge_folder(&mut self, _: &str) -> email::Result<()> {
|
||||
unimplemented!();
|
||||
}
|
||||
async fn delete_folder(&mut self, _: &str) -> pimalaya_email::Result<()> {
|
||||
async fn delete_folder(&mut self, _: &str) -> email::Result<()> {
|
||||
unimplemented!();
|
||||
}
|
||||
async fn get_envelope(&mut self, _: &str, _: &str) -> pimalaya_email::Result<Envelope> {
|
||||
async fn get_envelope(&mut self, _: &str, _: &str) -> email::Result<Envelope> {
|
||||
unimplemented!();
|
||||
}
|
||||
async fn list_envelopes(
|
||||
@@ -184,7 +184,7 @@ mod tests {
|
||||
_: &str,
|
||||
_: usize,
|
||||
_: usize,
|
||||
) -> pimalaya_email::Result<Envelopes> {
|
||||
) -> email::Result<Envelopes> {
|
||||
unimplemented!()
|
||||
}
|
||||
async fn search_envelopes(
|
||||
@@ -194,64 +194,31 @@ mod tests {
|
||||
_: &str,
|
||||
_: usize,
|
||||
_: usize,
|
||||
) -> pimalaya_email::Result<Envelopes> {
|
||||
) -> email::Result<Envelopes> {
|
||||
unimplemented!()
|
||||
}
|
||||
async fn add_email(
|
||||
&mut self,
|
||||
_: &str,
|
||||
_: &[u8],
|
||||
_: &Flags,
|
||||
) -> pimalaya_email::Result<String> {
|
||||
async fn add_email(&mut self, _: &str, _: &[u8], _: &Flags) -> email::Result<String> {
|
||||
unimplemented!()
|
||||
}
|
||||
async fn get_emails(
|
||||
&mut self,
|
||||
_: &str,
|
||||
_: Vec<&str>,
|
||||
) -> pimalaya_email::Result<Messages> {
|
||||
async fn get_emails(&mut self, _: &str, _: Vec<&str>) -> email::Result<Messages> {
|
||||
unimplemented!()
|
||||
}
|
||||
async fn preview_emails(
|
||||
&mut self,
|
||||
_: &str,
|
||||
_: Vec<&str>,
|
||||
) -> pimalaya_email::Result<Messages> {
|
||||
async fn preview_emails(&mut self, _: &str, _: Vec<&str>) -> email::Result<Messages> {
|
||||
unimplemented!()
|
||||
}
|
||||
async fn copy_emails(
|
||||
&mut self,
|
||||
_: &str,
|
||||
_: &str,
|
||||
_: Vec<&str>,
|
||||
) -> pimalaya_email::Result<()> {
|
||||
async fn copy_emails(&mut self, _: &str, _: &str, _: Vec<&str>) -> email::Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
async fn move_emails(
|
||||
&mut self,
|
||||
_: &str,
|
||||
_: &str,
|
||||
_: Vec<&str>,
|
||||
) -> pimalaya_email::Result<()> {
|
||||
async fn move_emails(&mut self, _: &str, _: &str, _: Vec<&str>) -> email::Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
async fn delete_emails(&mut self, _: &str, _: Vec<&str>) -> pimalaya_email::Result<()> {
|
||||
async fn delete_emails(&mut self, _: &str, _: Vec<&str>) -> email::Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
async fn add_flags(
|
||||
&mut self,
|
||||
_: &str,
|
||||
_: Vec<&str>,
|
||||
_: &Flags,
|
||||
) -> pimalaya_email::Result<()> {
|
||||
async fn add_flags(&mut self, _: &str, _: Vec<&str>, _: &Flags) -> email::Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
async fn set_flags(
|
||||
&mut self,
|
||||
_: &str,
|
||||
_: Vec<&str>,
|
||||
_: &Flags,
|
||||
) -> pimalaya_email::Result<()> {
|
||||
async fn set_flags(&mut self, _: &str, _: Vec<&str>, _: &Flags) -> email::Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
async fn remove_flags(
|
||||
@@ -259,7 +226,7 @@ mod tests {
|
||||
_: &str,
|
||||
_: Vec<&str>,
|
||||
_: &Flags,
|
||||
) -> pimalaya_email::Result<()> {
|
||||
) -> email::Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use anyhow::Result;
|
||||
use dialoguer::Input;
|
||||
use pimalaya_email::sender::{SenderConfig, SendmailConfig};
|
||||
use email::sender::{SenderConfig, SendmailConfig};
|
||||
|
||||
use crate::config::wizard::THEME;
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use anyhow::Result;
|
||||
use dialoguer::{Confirm, Input, Select};
|
||||
use pimalaya_email::{
|
||||
use email::{
|
||||
account::{OAuth2Config, OAuth2Method, OAuth2Scopes, PasswdConfig},
|
||||
sender::{SenderConfig, SmtpAuthConfig, SmtpConfig},
|
||||
};
|
||||
use pimalaya_oauth2::{AuthorizationCodeGrant, Client};
|
||||
use pimalaya_secret::Secret;
|
||||
use oauth::v2_0::{AuthorizationCodeGrant, Client};
|
||||
use secret::Secret;
|
||||
|
||||
use crate::{
|
||||
config::wizard::{prompt_passwd, THEME},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use anyhow::Result;
|
||||
use dialoguer::Select;
|
||||
use pimalaya_email::sender::SenderConfig;
|
||||
use email::sender::SenderConfig;
|
||||
|
||||
use crate::config::wizard::THEME;
|
||||
|
||||
|
||||
+20
-14
@@ -1,11 +1,12 @@
|
||||
use anyhow::{anyhow, Result};
|
||||
use atty::Stream;
|
||||
use pimalaya_email::{
|
||||
use email::{
|
||||
account::AccountConfig,
|
||||
backend::Backend,
|
||||
email::{Flag, Flags, Message, Tpl},
|
||||
email::{Flag, Flags, Message},
|
||||
sender::Sender,
|
||||
};
|
||||
use mml::MmlCompiler;
|
||||
use std::io::{stdin, BufRead};
|
||||
|
||||
use crate::{printer::Printer, IdMapper};
|
||||
@@ -76,7 +77,7 @@ pub async fn save<P: Printer>(
|
||||
folder: &str,
|
||||
tpl: String,
|
||||
) -> Result<()> {
|
||||
let email = Tpl::from(if atty::is(Stream::Stdin) || printer.is_json() {
|
||||
let mml = if atty::is(Stream::Stdin) || printer.is_json() {
|
||||
tpl.replace("\r", "")
|
||||
} else {
|
||||
stdin()
|
||||
@@ -85,11 +86,13 @@ pub async fn save<P: Printer>(
|
||||
.filter_map(Result::ok)
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n")
|
||||
})
|
||||
.with_pgp(config.pgp.clone())
|
||||
.compile()
|
||||
.await?
|
||||
.write_to_vec()?;
|
||||
};
|
||||
|
||||
let email = MmlCompiler::new()
|
||||
.with_pgp(config.pgp.clone())
|
||||
.compile(mml)
|
||||
.await?
|
||||
.write_to_vec()?;
|
||||
|
||||
let id = backend.add_email(folder, &email, &Flags::default()).await?;
|
||||
id_mapper.create_alias(id)?;
|
||||
@@ -105,7 +108,8 @@ pub async fn send<P: Printer>(
|
||||
tpl: String,
|
||||
) -> Result<()> {
|
||||
let folder = config.sent_folder_alias()?;
|
||||
let email = Tpl::from(if atty::is(Stream::Stdin) || printer.is_json() {
|
||||
|
||||
let mml = if atty::is(Stream::Stdin) || printer.is_json() {
|
||||
tpl.replace("\r", "")
|
||||
} else {
|
||||
stdin()
|
||||
@@ -114,11 +118,13 @@ pub async fn send<P: Printer>(
|
||||
.filter_map(Result::ok)
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n")
|
||||
})
|
||||
.with_pgp(config.pgp.clone())
|
||||
.compile()
|
||||
.await?
|
||||
.write_to_vec()?;
|
||||
};
|
||||
|
||||
let email = MmlCompiler::new()
|
||||
.with_pgp(config.pgp.clone())
|
||||
.compile(mml)
|
||||
.await?
|
||||
.write_to_vec()?;
|
||||
|
||||
sender.send(&email).await?;
|
||||
|
||||
|
||||
+5
-5
@@ -1,13 +1,13 @@
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use clap::Command;
|
||||
use log::{debug, warn};
|
||||
#[cfg(feature = "imap-backend")]
|
||||
use pimalaya_email::backend::ImapBackend;
|
||||
use pimalaya_email::{
|
||||
use ::email::backend::ImapBackend;
|
||||
use ::email::{
|
||||
account::{sync::AccountSyncBuilder, DEFAULT_INBOX_FOLDER},
|
||||
backend::{BackendBuilder, BackendConfig},
|
||||
sender::SenderBuilder,
|
||||
};
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use clap::Command;
|
||||
use log::{debug, warn};
|
||||
use std::env;
|
||||
use url::Url;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use anyhow::{Context, Result};
|
||||
use pimalaya_email::email::Tpl;
|
||||
|
||||
use crate::printer::WriteColor;
|
||||
|
||||
@@ -20,10 +19,3 @@ impl Print for String {
|
||||
Ok(writer.reset()?)
|
||||
}
|
||||
}
|
||||
|
||||
impl Print for Tpl {
|
||||
fn print(&self, writer: &mut dyn WriteColor) -> Result<()> {
|
||||
self.as_str().print(writer)?;
|
||||
Ok(writer.reset()?)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use anyhow::Result;
|
||||
use pimalaya_email::email::EmailTextPlainFormat;
|
||||
use email::email::EmailTextPlainFormat;
|
||||
use std::io;
|
||||
use termcolor::{self, StandardStream};
|
||||
|
||||
|
||||
+23
-20
@@ -1,42 +1,45 @@
|
||||
use anyhow::{Context, Result};
|
||||
use log::debug;
|
||||
use pimalaya_email::{
|
||||
use email::{
|
||||
account::AccountConfig,
|
||||
backend::Backend,
|
||||
email::{local_draft_path, remove_local_draft, Flag, Flags, Tpl},
|
||||
email::{local_draft_path, remove_local_draft, Flag, Flags},
|
||||
sender::Sender,
|
||||
};
|
||||
use std::{env, fs, process::Command};
|
||||
use log::debug;
|
||||
use mml::MmlCompiler;
|
||||
use process::Cmd;
|
||||
use std::{env, fs};
|
||||
|
||||
use crate::{
|
||||
printer::Printer,
|
||||
ui::choice::{self, PostEditChoice, PreEditChoice},
|
||||
};
|
||||
|
||||
pub fn open_with_tpl(tpl: Tpl) -> Result<Tpl> {
|
||||
pub async fn open_with_tpl(tpl: String) -> Result<String> {
|
||||
let path = local_draft_path();
|
||||
|
||||
debug!("create draft");
|
||||
fs::write(&path, tpl.as_bytes()).context(format!("cannot write local draft at {:?}", path))?;
|
||||
|
||||
debug!("open editor");
|
||||
Command::new(env::var("EDITOR").context(r#"cannot find "$EDITOR" env var"#)?)
|
||||
.arg(&path)
|
||||
.status()
|
||||
let editor = env::var("EDITOR").context("cannot get editor from env var")?;
|
||||
Cmd::from(format!("{editor} {}", &path.to_string_lossy()))
|
||||
.run()
|
||||
.await
|
||||
.context("cannot launch editor")?;
|
||||
|
||||
debug!("read draft");
|
||||
let content =
|
||||
fs::read_to_string(&path).context(format!("cannot read local draft at {:?}", path))?;
|
||||
|
||||
Ok(Tpl::from(content))
|
||||
Ok(content)
|
||||
}
|
||||
|
||||
pub fn open_with_local_draft() -> Result<Tpl> {
|
||||
pub async fn open_with_local_draft() -> Result<String> {
|
||||
let path = local_draft_path();
|
||||
let content =
|
||||
fs::read_to_string(&path).context(format!("cannot read local draft at {:?}", path))?;
|
||||
open_with_tpl(Tpl::from(content))
|
||||
open_with_tpl(content).await
|
||||
}
|
||||
|
||||
pub async fn edit_tpl_with_editor<P: Printer>(
|
||||
@@ -44,7 +47,7 @@ pub async fn edit_tpl_with_editor<P: Printer>(
|
||||
printer: &mut P,
|
||||
backend: &mut dyn Backend,
|
||||
sender: &mut dyn Sender,
|
||||
mut tpl: Tpl,
|
||||
mut tpl: String,
|
||||
) -> Result<()> {
|
||||
let draft = local_draft_path();
|
||||
if draft.exists() {
|
||||
@@ -52,11 +55,11 @@ pub async fn edit_tpl_with_editor<P: Printer>(
|
||||
match choice::pre_edit() {
|
||||
Ok(choice) => match choice {
|
||||
PreEditChoice::Edit => {
|
||||
tpl = open_with_local_draft()?;
|
||||
tpl = open_with_local_draft().await?;
|
||||
break;
|
||||
}
|
||||
PreEditChoice::Discard => {
|
||||
tpl = open_with_tpl(tpl)?;
|
||||
tpl = open_with_tpl(tpl).await?;
|
||||
break;
|
||||
}
|
||||
PreEditChoice::Quit => return Ok(()),
|
||||
@@ -68,16 +71,16 @@ pub async fn edit_tpl_with_editor<P: Printer>(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tpl = open_with_tpl(tpl)?;
|
||||
tpl = open_with_tpl(tpl).await?;
|
||||
}
|
||||
|
||||
loop {
|
||||
match choice::post_edit() {
|
||||
Ok(PostEditChoice::Send) => {
|
||||
printer.print_log("Sending email…")?;
|
||||
let email = tpl
|
||||
let email = MmlCompiler::new()
|
||||
.with_pgp(config.pgp.clone())
|
||||
.compile()
|
||||
.compile(tpl)
|
||||
.await?
|
||||
.write_to_vec()?;
|
||||
sender.send(&email).await?;
|
||||
@@ -93,7 +96,7 @@ pub async fn edit_tpl_with_editor<P: Printer>(
|
||||
break;
|
||||
}
|
||||
Ok(PostEditChoice::Edit) => {
|
||||
tpl = open_with_tpl(tpl)?;
|
||||
tpl = open_with_tpl(tpl).await?;
|
||||
continue;
|
||||
}
|
||||
Ok(PostEditChoice::LocalDraft) => {
|
||||
@@ -101,9 +104,9 @@ pub async fn edit_tpl_with_editor<P: Printer>(
|
||||
break;
|
||||
}
|
||||
Ok(PostEditChoice::RemoteDraft) => {
|
||||
let email = tpl
|
||||
let email = MmlCompiler::new()
|
||||
.with_pgp(config.pgp.clone())
|
||||
.compile()
|
||||
.compile(tpl)
|
||||
.await?
|
||||
.write_to_vec()?;
|
||||
backend
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
//! [builder design pattern]: https://refactoring.guru/design-patterns/builder
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use email::email::EmailTextPlainFormat;
|
||||
use log::trace;
|
||||
use pimalaya_email::email::EmailTextPlainFormat;
|
||||
use termcolor::{Color, ColorSpec};
|
||||
use terminal_size::terminal_size;
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
@@ -267,7 +267,7 @@ where
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use pimalaya_email::email::EmailTextPlainFormat;
|
||||
use email::email::EmailTextPlainFormat;
|
||||
use std::io;
|
||||
|
||||
use super::*;
|
||||
|
||||
Reference in New Issue
Block a user