add sanitize flag for the read command, fix #352

This commit is contained in:
Clément DOUIN 2022-10-12 15:36:36 +02:00
parent bb8f63e4b0
commit 6a15b742b0
No known key found for this signature in database
GPG key ID: 353E4A18EE0FAB72
4 changed files with 57 additions and 8 deletions

View file

@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
* Added `-s|--sanitize` flag for the `read` command.
### Changed
* Changed the behaviour of the `-t|--mime-type` argument of the `read`
command. It is less strict now: if no part is found for the given
MIME type, it will fallback to the other one. For example, giving
`-t html` will show in priority HTML parts, but if none of them are
found it will show plain parts instead (and vice versa).
* Sanitization is not done by default when using the `read` command,
the flag `-s|--sanitize` needs to be explicitly provided.
### Fixed
* Fixed empty text bodies when reading html part on plain text email
[#352].
## [0.6.0] - 2022-10-10
### Changed
@ -571,3 +591,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#340]: https://github.com/soywod/himalaya/issues/340
[#344]: https://github.com/soywod/himalaya/issues/344
[#346]: https://github.com/soywod/himalaya/issues/346
[#352]: https://github.com/soywod/himalaya/issues/352

View file

@ -21,6 +21,7 @@ const ARG_PAGE_SIZE: &str = "page-size";
const ARG_QUERY: &str = "query";
const ARG_RAW: &str = "raw";
const ARG_REPLY_ALL: &str = "reply-all";
const ARG_SANITIZE: &str = "sanitize";
const CMD_ATTACHMENTS: &str = "attachments";
const CMD_COPY: &str = "copy";
const CMD_DEL: &str = "delete";
@ -41,6 +42,7 @@ type Folder<'a> = &'a str;
type Page = usize;
type PageSize = usize;
type Query = String;
type Sanitize = bool;
type Raw = bool;
type RawEmail<'a> = &'a str;
type TextMime<'a> = &'a str;
@ -60,7 +62,7 @@ pub enum Cmd<'a> {
Forward(Id<'a>, Attachments<'a>, Encrypt),
List(table::args::MaxTableWidth, Option<PageSize>, Page),
Move(Id<'a>, Folder<'a>),
Read(Id<'a>, TextMime<'a>, Raw, Headers<'a>),
Read(Id<'a>, TextMime<'a>, Sanitize, Raw, Headers<'a>),
Reply(Id<'a>, All, Attachments<'a>, Encrypt),
Save(RawEmail<'a>),
Search(Query, table::args::MaxTableWidth, Option<PageSize>, Page),
@ -116,9 +118,10 @@ pub fn matches<'a>(m: &'a ArgMatches) -> Result<Option<Cmd<'a>>> {
debug!("read command matched");
let id = parse_id_arg(m);
let mime = parse_mime_type_arg(m);
let sanitize = parse_sanitize_flag(m);
let raw = parse_raw_flag(m);
let headers = parse_headers_arg(m);
Cmd::Read(id, mime, raw, headers)
Cmd::Read(id, mime, sanitize, raw, headers)
} else if let Some(m) = m.subcommand_matches(CMD_REPLY) {
debug!("reply command matched");
let id = parse_id_arg(m);
@ -210,9 +213,10 @@ pub fn subcmds<'a>() -> Vec<App<'a, 'a>> {
.about("Saves a raw email")
.arg(raw_arg()),
SubCommand::with_name(CMD_READ)
.about("Reads text bodies of a email")
.about("Reads text bodies of an email")
.arg(id_arg())
.arg(mime_type_arg())
.arg(sanitize_flag())
.arg(raw_flag())
.arg(headers_arg()),
SubCommand::with_name(CMD_REPLY)
@ -399,14 +403,27 @@ pub fn parse_headers_arg<'a>(matches: &'a ArgMatches<'a>) -> Vec<&'a str> {
matches.values_of(ARG_HEADERS).unwrap_or_default().collect()
}
/// Represents the sanitize flag.
pub fn sanitize_flag<'a>() -> Arg<'a, 'a> {
Arg::with_name(ARG_SANITIZE)
.help("Sanitizes text bodies")
.long("sanitize")
.short("s")
}
/// Represents the raw flag.
pub fn raw_flag<'a>() -> Arg<'a, 'a> {
Arg::with_name(ARG_RAW)
.help("Reads a raw email")
.help("Returns raw version of email")
.long("raw")
.short("r")
}
/// Represents the sanitize flag parser.
pub fn parse_sanitize_flag<'a>(matches: &'a ArgMatches<'a>) -> bool {
matches.is_present(ARG_SANITIZE)
}
/// Represents the raw flag parser.
pub fn parse_raw_flag<'a>(matches: &'a ArgMatches<'a>) -> bool {
matches.is_present(ARG_RAW)

View file

@ -5,7 +5,8 @@
use anyhow::{Context, Result};
use atty::Stream;
use himalaya_lib::{
AccountConfig, Backend, Email, Part, Parts, Sender, TextPlainPart, TplOverride,
AccountConfig, Backend, Email, Part, Parts, PartsReaderOptions, Sender, TextPlainPart,
TplOverride,
};
use log::{debug, info, trace};
use mailparse::addrparse;
@ -214,6 +215,7 @@ pub fn move_<'a, P: Printer, B: Backend<'a> + ?Sized>(
pub fn read<'a, P: Printer, B: Backend<'a> + ?Sized>(
seq: &str,
text_mime: &str,
sanitize: bool,
raw: bool,
headers: Vec<&str>,
mbox: &str,
@ -224,10 +226,18 @@ pub fn read<'a, P: Printer, B: Backend<'a> + ?Sized>(
let msg = backend.email_get(mbox, seq)?;
printer.print_struct(if raw {
// Emails don't always have valid utf8. Using "lossy" to display what we can.
// Emails do not always have valid utf8. Using "lossy" to
// display what we can.
String::from_utf8_lossy(&msg.raw).into_owned()
} else {
msg.to_readable_string(text_mime, headers, config)?
msg.to_readable(
config,
PartsReaderOptions {
plain_first: text_mime == "plain",
sanitize,
},
headers,
)?
})
}

View file

@ -161,10 +161,11 @@ fn main() -> Result<()> {
Some(email::args::Cmd::Move(seq, mbox_dst)) => {
return email::handlers::move_(seq, &folder, mbox_dst, &mut printer, backend.as_mut());
}
Some(email::args::Cmd::Read(seq, text_mime, raw, headers)) => {
Some(email::args::Cmd::Read(seq, text_mime, sanitize, raw, headers)) => {
return email::handlers::read(
seq,
text_mime,
sanitize,
raw,
headers,
&folder,