diff --git a/.gitignore b/.gitignore index e4a6d9f..f2d0780 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# Cargo config directory +.cargo/ + # Cargo build directory target/ debug/ diff --git a/CHANGELOG.md b/CHANGELOG.md index dcf94f1..00c3c61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.6.1] - 2022-10-12 + +### 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 @@ -22,6 +44,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * This repository only contains the CLI source code (it was not possible to move it to sourcehut because of cross platform builds) +* [**BREAKING**] Renamed `-m|--mailbox` to `-f|--folder` + * [**BREAKING**] Refactored config system [#344]. The configuration has been rethought in order to be more intuitive @@ -412,7 +436,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Password from command [#22] * Set up README [#20] -[unreleased]: https://github.com/soywod/himalaya/compare/v0.6.0...HEAD +[unreleased]: https://github.com/soywod/himalaya/compare/v0.6.1...HEAD +[0.6.1]: https://github.com/soywod/himalaya/compare/v0.6.0...v0.6.1 [0.6.0]: https://github.com/soywod/himalaya/compare/v0.5.10...v0.6.0 [0.5.10]: https://github.com/soywod/himalaya/compare/v0.5.9...v0.5.10 [0.5.9]: https://github.com/soywod/himalaya/compare/v0.5.8...v0.5.9 @@ -569,3 +594,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 diff --git a/Cargo.lock b/Cargo.lock index 5bf988b..5e42379 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,19 +3,28 @@ version = 3 [[package]] -name = "aho-corasick" -version = "0.7.18" +name = "ahash" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217" +dependencies = [ + "const-random", +] + +[[package]] +name = "aho-corasick" +version = "0.7.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" dependencies = [ "memchr 2.5.0", ] [[package]] name = "ammonia" -version = "3.2.0" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5ed2509ee88cc023cccee37a6fab35826830fe8b748b3869790e7720c2c4a74" +checksum = "4b477377562f3086b7778d241786e9406b883ccfaa03557c0fe0924b9349f13a" dependencies = [ "html5ever", "maplit", @@ -24,6 +33,15 @@ dependencies = [ "url", ] +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "ansi_term" version = "0.12.1" @@ -35,9 +53,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.58" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704" +checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" [[package]] name = "atty" @@ -86,6 +104,12 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40e38929add23cdf8a366df9b0e088953150724bcbe5fc330b0d8eb3b328eec8" +[[package]] +name = "bumpalo" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" + [[package]] name = "cc" version = "1.0.73" @@ -116,17 +140,28 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.19" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" dependencies = [ - "libc", + "iana-time-zone", + "js-sys", "num-integer", "num-traits", "time", + "wasm-bindgen", "winapi", ] +[[package]] +name = "chumsky" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d02796e4586c6c41aeb68eae9bfb4558a522c35f1430c14b40136c3706e09e4" +dependencies = [ + "ahash", +] + [[package]] name = "clap" version = "2.34.0" @@ -150,6 +185,38 @@ dependencies = [ "bitflags", ] +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "const-random" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f590d95d011aa80b063ffe3253422ed5aa462af4e9867d43ce8337562bac77c4" +dependencies = [ + "const-random-macro", + "proc-macro-hack", +] + +[[package]] +name = "const-random-macro" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "615f6e27d000a2bffbc7f2f6a8669179378fa27ee4d0a509e985dfc0a7defb40" +dependencies = [ + "getrandom", + "lazy_static", + "proc-macro-hack", + "tiny-keccak", +] + [[package]] name = "convert_case" version = "0.5.0" @@ -172,6 +239,56 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "cxx" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f39818dcfc97d45b03953c1292efc4e80954e1583c4aa770bac1383e2310a4" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e580d70777c116df50c390d1211993f62d40302881e54d4b79727acb83d0199" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56a46460b88d1cec95112c8c363f0e2c39afdb237f60583b0b36343bf627ea9c" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "747b608fecf06b0d72d440f27acc99288207324b793be2c17991839f3d4995ea" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "darling" version = "0.10.2" @@ -214,20 +331,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" [[package]] -name = "dirs-next" -version = "2.0.0" +name = "dirs" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" dependencies = [ - "cfg-if 1.0.0", - "dirs-sys-next", + "dirs-sys", ] [[package]] -name = "dirs-sys-next" -version = "0.1.2" +name = "dirs-sys" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" dependencies = [ "libc", "redox_users", @@ -246,9 +362,9 @@ dependencies = [ [[package]] name = "email_address" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8684b7c9cb4857dfa1e5b9629ef584ba618c9b93bae60f58cb23f4f271d0468e" +checksum = "b1b32a7a2580c4473f10f66b512c34bdd7d33c5e3473227ca833abdb5afe4809" [[package]] name = "encoding_rs" @@ -274,18 +390,18 @@ dependencies = [ [[package]] name = "erased-serde" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81d013529d5574a60caeda29e179e695125448e5de52e3874f7b4c1d7360e18e" +checksum = "54558e0ba96fbe24280072642eceb9d7d442e32c7ec0ea9e7ecd7b4ea2cf4e11" dependencies = [ "serde", ] [[package]] name = "fastrand" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" dependencies = [ "instant", ] @@ -319,11 +435,10 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" dependencies = [ - "matches", "percent-encoding", ] @@ -366,27 +481,27 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" [[package]] name = "futures-io" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" [[package]] name = "futures-task" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" +checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" [[package]] name = "futures-util" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" dependencies = [ "futures-core", "futures-io", @@ -420,9 +535,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hermit-abi" @@ -435,29 +550,18 @@ dependencies = [ [[package]] name = "himalaya" -version = "0.6.0" +version = "0.6.1" dependencies = [ - "ammonia", "anyhow", "atty", "chrono", "clap", - "convert_case", "env_logger", "erased-serde", "himalaya-lib", - "html-escape", - "imap", - "imap-proto", "lettre", "log", - "maildir", "mailparse", - "md5", - "native-tls", - "notmuch", - "regex", - "rfc2047-decoder", "serde", "serde_json", "shellexpand", @@ -465,7 +569,6 @@ dependencies = [ "termcolor", "terminal_size", "toml", - "tree_magic", "unicode-width", "url", "uuid", @@ -473,9 +576,7 @@ dependencies = [ [[package]] name = "himalaya-lib" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33465f9a8c4dd3db2838c299bc897d4c29acd56ec1713f81a4666ef800abb1e4" +version = "0.4.0" dependencies = [ "ammonia", "chrono", @@ -496,6 +597,7 @@ dependencies = [ "shellexpand", "thiserror", "tree_magic", + "utf7-imap", "uuid", ] @@ -545,6 +647,30 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "iana-time-zone" +version = "0.1.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5a6ef98976b22b3b7f2f3a806f858cb862044cfa66805aa3ad84cb3d3b785ed" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fde6edd6cef363e9359ed3c98ba64590ba9eecba2293eb5a723ab32aee8926aa" +dependencies = [ + "cxx", + "cxx-build", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -562,6 +688,16 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "imap" version = "3.0.0-alpha.4" @@ -608,9 +744,18 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" + +[[package]] +name = "js-sys" +version = "0.3.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +dependencies = [ + "wasm-bindgen", +] [[package]] name = "lazy_static" @@ -631,7 +776,7 @@ dependencies = [ "futures-util", "hostname", "httpdate", - "idna", + "idna 0.2.3", "mime", "native-tls", "nom 7.1.1", @@ -643,9 +788,18 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.126" +version = "0.2.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c" + +[[package]] +name = "link-cplusplus" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" +dependencies = [ + "cc", +] [[package]] name = "lock_api" @@ -658,9 +812,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" dependencies = [ "autocfg", "scopeguard", @@ -853,15 +1007,15 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.12.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" +checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" [[package]] name = "openssl" -version = "0.10.40" +version = "0.10.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb81a6430ac911acb25fe5ac8f1d2af1b4ea8a4fdfda0f1ee4292af2e2d8eb0e" +checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13" dependencies = [ "bitflags", "cfg-if 1.0.0", @@ -891,9 +1045,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.74" +version = "0.9.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "835363342df5fba8354c5b453325b110ffd54044e588c539cf2f20a8014e4cb1" +checksum = "5230151e44c0f05157effb743e8d517472843121cf9243e8b81393edb5acd9ce" dependencies = [ "autocfg", "cc", @@ -918,7 +1072,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ - "lock_api 0.4.7", + "lock_api 0.4.9", "parking_lot_core 0.9.3", ] @@ -944,16 +1098,16 @@ checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.2.13", + "redox_syscall 0.2.16", "smallvec", "windows-sys", ] [[package]] name = "percent-encoding" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "petgraph" @@ -1034,19 +1188,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] -name = "proc-macro2" -version = "1.0.40" +name = "proc-macro-hack" +version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro2" +version = "1.0.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" dependencies = [ "proc-macro2", ] @@ -1086,9 +1246,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] @@ -1101,9 +1261,9 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_syscall" -version = "0.2.13" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags", ] @@ -1115,15 +1275,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ "getrandom", - "redox_syscall 0.2.13", + "redox_syscall 0.2.16", "thiserror", ] [[package]] name = "regex" -version = "1.5.6" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" +checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" dependencies = [ "aho-corasick", "memchr 2.5.0", @@ -1132,9 +1292,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.26" +version = "0.6.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" +checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" [[package]] name = "remove_dir_all" @@ -1147,20 +1307,23 @@ dependencies = [ [[package]] name = "rfc2047-decoder" -version = "0.1.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ecf2ba387f446155e26796aabb727e9ae1427dd13ac9cc21773a3fbda19d77" +checksum = "11347d014ae34e1d367aaf9191c37bf071b161e2e1c09c8559c7717e87030e11" dependencies = [ "base64", "charset", + "chumsky", + "memchr 2.5.0", "quoted_printable", + "thiserror", ] [[package]] name = "ryu" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" [[package]] name = "schannel" @@ -1179,10 +1342,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] -name = "security-framework" -version = "2.6.1" +name = "scratch" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" +checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" + +[[package]] +name = "security-framework" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" dependencies = [ "bitflags", "core-foundation", @@ -1203,18 +1372,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.138" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1578c6245786b9d168c5447eeacfb96856573ca56c9d68fdcf394be134882a47" +checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.138" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "023e9b1467aef8a10fb88f25611870ada9800ef7e22afce356bb0d2387b6f27c" +checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" dependencies = [ "proc-macro2", "quote", @@ -1223,9 +1392,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.82" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" +checksum = "41feea4228a6f1cd09ec7a3593a682276702cd67b5273544757dae23c096f074" dependencies = [ "itoa", "ryu", @@ -1234,11 +1403,11 @@ dependencies = [ [[package]] name = "shellexpand" -version = "2.1.0" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83bdb7831b2d85ddf4a7b148aa19d0587eddbe8671a436b7bd1182eaad0f2829" +checksum = "7ccc8076840c4da029af4f87e4e8daeb0fca6b87bbb02e10cb60b791450e11e4" dependencies = [ - "dirs-next", + "dirs", ] [[package]] @@ -1249,21 +1418,24 @@ checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" [[package]] name = "slab" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] [[package]] name = "smallvec" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "socket2" -version = "0.4.4" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" dependencies = [ "libc", "winapi", @@ -1309,9 +1481,9 @@ checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" [[package]] name = "syn" -version = "1.0.98" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" +checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1" dependencies = [ "proc-macro2", "quote", @@ -1333,7 +1505,7 @@ dependencies = [ "cfg-if 1.0.0", "fastrand", "libc", - "redox_syscall 0.2.13", + "redox_syscall 0.2.16", "remove_dir_all", "winapi", ] @@ -1379,18 +1551,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.31" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.31" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" dependencies = [ "proc-macro2", "quote", @@ -1408,6 +1580,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -1453,34 +1634,33 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.1" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" [[package]] name = "unicode-normalization" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] [[package]] name = "unicode-width" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" [[package]] name = "url" -version = "2.2.2" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" dependencies = [ "form_urlencoded", - "idna", - "matches", + "idna 0.3.0", "percent-encoding", ] @@ -1490,6 +1670,17 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf7-imap" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e326365261fc2761f0809dfb6032810534a0427bbd8f0edf546f6afeef89f5d" +dependencies = [ + "base64", + "encoding_rs", + "regex", +] + [[package]] name = "utf8-width" version = "0.1.6" @@ -1529,6 +1720,60 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index 93c0668..ed6c52c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "himalaya" description = "Command-line interface for email management." -version = "0.6.0" +version = "0.6.1" authors = ["soywod "] edition = "2021" license = "MIT" @@ -16,47 +16,31 @@ priority = "optional" section = "mail" [features] -imap-backend = ["imap", "imap-proto"] -maildir-backend = ["maildir", "md5"] -notmuch-backend = ["himalaya-lib/notmuch-backend", "maildir-backend", "notmuch"] +imap-backend = ["himalaya-lib/imap-backend"] +maildir-backend = ["himalaya-lib/maildir-backend"] +notmuch-backend = ["himalaya-lib/notmuch-backend"] default = ["imap-backend", "maildir-backend"] [dev-dependencies] tempfile = "3.3.0" [dependencies] -ammonia = "3.1.2" anyhow = "1.0.44" atty = "0.2.14" chrono = "0.4.19" clap = { version = "2.33.3", default-features = false, features = ["suggestions", "color"] } -convert_case = "0.5.0" env_logger = "0.8.3" erased-serde = "0.3.18" -# himalaya-lib = { version = "=0.3.1", git = "https://git.sr.ht/~soywod/himalaya-lib", branch = "develop" } -himalaya-lib = "=0.3.1" -html-escape = "0.2.9" +himalaya-lib = "=0.4.0" lettre = { version = "=0.10.0-rc.7", features = ["serde"] } log = "0.4.14" mailparse = "0.13.6" -native-tls = "0.2.8" -regex = "1.5.4" -rfc2047-decoder = "0.1.2" serde = { version = "1.0.118", features = ["derive"] } serde_json = "1.0.61" shellexpand = "2.1.0" termcolor = "1.1" terminal_size = "0.1.15" toml = "0.5.8" -tree_magic = "0.2.3" unicode-width = "0.1.7" url = "2.2.2" uuid = { version = "0.8", features = ["v4"] } - -# Optional dependencies: - -imap = { version = "=3.0.0-alpha.4", optional = true } -imap-proto = { version = "0.14.3", optional = true } -maildir = { version = "0.6.1", optional = true } -md5 = { version = "0.7.0", optional = true } -notmuch = { version = "0.7.1", optional = true } diff --git a/README.md b/README.md index a5112a8..f80550c 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,8 @@ before the `v1.0.0`.* ## Installation -[![homebrew](https://img.shields.io/homebrew/v/himalaya?color=success&style=flat-square)](https://formulae.brew.sh/formula/himalaya) -[![crates](https://img.shields.io/crates/v/himalaya?color=success&style=flat-square)](https://crates.io/crates/himalaya) +[![Packaging +status](https://repology.org/badge/vertical-allrepos/himalaya.svg)](https://repology.org/project/himalaya/versions) ```sh curl -sSL https://raw.githubusercontent.com/soywod/himalaya/master/install.sh | PREFIX=~/.local sh diff --git a/src/config/prelude.rs b/src/config/prelude.rs index dbb6a5f..0aae942 100644 --- a/src/config/prelude.rs +++ b/src/config/prelude.rs @@ -18,6 +18,8 @@ struct SmtpConfigDef { pub host: String, #[serde(rename = "smtp-port")] pub port: u16, + #[serde(rename = "smtp-ssl")] + pub ssl: Option, #[serde(rename = "smtp-starttls")] pub starttls: Option, #[serde(rename = "smtp-insecure")] @@ -36,6 +38,8 @@ pub struct ImapConfigDef { pub host: String, #[serde(rename = "imap-port")] pub port: u16, + #[serde(rename = "imap-ssl")] + pub ssl: Option, #[serde(rename = "imap-starttls")] pub starttls: Option, #[serde(rename = "imap-insecure")] diff --git a/src/domain/email/args.rs b/src/domain/email/args.rs index 99dfcba..ec2b643 100644 --- a/src/domain/email/args.rs +++ b/src/domain/email/args.rs @@ -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, 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, Page), @@ -116,9 +118,10 @@ pub fn matches<'a>(m: &'a ArgMatches) -> Result>> { 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> { .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) diff --git a/src/domain/email/handlers.rs b/src/domain/email/handlers.rs index b632907..e4be121 100644 --- a/src/domain/email/handlers.rs +++ b/src/domain/email/handlers.rs @@ -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; @@ -93,7 +94,7 @@ pub fn forward<'a, P: Printer, B: Backend<'a> + ?Sized, S: Sender + ?Sized>( .into_forward(config)? .add_attachments(attachments_paths)? .encrypt(encrypt); - editor::edit_msg_with_editor( + editor::edit_email_with_editor( msg, TplOverride::default(), config, @@ -184,7 +185,7 @@ pub fn mailto<'a, P: Printer, B: Backend<'a> + ?Sized, S: Sender + ?Sized>( }; trace!("message: {:?}", msg); - editor::edit_msg_with_editor( + editor::edit_email_with_editor( msg, TplOverride::default(), config, @@ -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, + )? }) } @@ -248,7 +258,7 @@ pub fn reply<'a, P: Printer, B: Backend<'a> + ?Sized, S: Sender + ?Sized>( .into_reply(all, config)? .add_attachments(attachments_paths)? .encrypt(encrypt); - editor::edit_msg_with_editor( + editor::edit_email_with_editor( msg, TplOverride::default(), config, @@ -341,7 +351,7 @@ pub fn sort<'a, P: Printer, B: Backend<'a> + ?Sized>( /// Send a raw message. pub fn send<'a, P: Printer, B: Backend<'a> + ?Sized, S: Sender + ?Sized>( - raw_msg: &str, + raw_email: &str, config: &AccountConfig, printer: &mut P, backend: &mut B, @@ -357,8 +367,8 @@ pub fn send<'a, P: Printer, B: Backend<'a> + ?Sized, S: Sender + ?Sized>( let sent_folder = config.folder_alias("sent")?; debug!("sent folder: {:?}", sent_folder); - let raw_msg = if is_tty || is_json { - raw_msg.replace("\r", "").replace("\n", "\r\n") + let raw_email = if is_tty || is_json { + raw_email.replace("\r", "").replace("\n", "\r\n") } else { io::stdin() .lock() @@ -367,10 +377,10 @@ pub fn send<'a, P: Printer, B: Backend<'a> + ?Sized, S: Sender + ?Sized>( .collect::>() .join("\r\n") }; - trace!("raw message: {:?}", raw_msg); - let msg = Email::from_tpl(&raw_msg)?; - sender.send(&config, &msg)?; - backend.email_add(&sent_folder, raw_msg.as_bytes(), "seen")?; + trace!("raw message: {:?}", raw_email); + let email = Email::from_tpl(&raw_email)?; + sender.send(&email)?; + backend.email_add(&sent_folder, raw_email.as_bytes(), "seen")?; Ok(()) } @@ -384,9 +394,9 @@ pub fn write<'a, P: Printer, B: Backend<'a> + ?Sized, S: Sender + ?Sized>( backend: &mut B, sender: &mut S, ) -> Result<()> { - let msg = Email::default() + let email = Email::default() .add_attachments(attachments_paths)? .encrypt(encrypt); - editor::edit_msg_with_editor(msg, tpl, config, printer, backend, sender)?; + editor::edit_email_with_editor(email, tpl, config, printer, backend, sender)?; Ok(()) } diff --git a/src/domain/tpl/handlers.rs b/src/domain/tpl/handlers.rs index 0fcb078..0c2f0a7 100644 --- a/src/domain/tpl/handlers.rs +++ b/src/domain/tpl/handlers.rs @@ -71,16 +71,15 @@ pub fn save<'a, P: Printer, B: Backend<'a> + ?Sized>( .collect::>() .join("\n") }; - let msg = Email::from_tpl(&tpl)?.add_attachments(attachments_paths)?; - let raw_msg = msg.into_sendable_msg(config)?.formatted(); - backend.email_add(mbox, &raw_msg, "seen")?; + let email = Email::from_tpl(&tpl)?.add_attachments(attachments_paths)?; + let raw_email = email.into_sendable(config)?.formatted(); + backend.email_add(mbox, &raw_email, "seen")?; printer.print_struct("Template successfully saved") } /// Sends a message based on a template. pub fn send<'a, P: Printer, B: Backend<'a> + ?Sized, S: Sender + ?Sized>( mbox: &str, - account: &AccountConfig, attachments_paths: Vec<&str>, tpl: &str, printer: &mut P, @@ -97,8 +96,8 @@ pub fn send<'a, P: Printer, B: Backend<'a> + ?Sized, S: Sender + ?Sized>( .collect::>() .join("\n") }; - let msg = Email::from_tpl(&tpl)?.add_attachments(attachments_paths)?; - let sent_msg = sender.send(account, &msg)?; + let email = Email::from_tpl(&tpl)?.add_attachments(attachments_paths)?; + let sent_msg = sender.send(&email)?; backend.email_add(mbox, &sent_msg, "seen")?; printer.print_struct("Template successfully sent") } diff --git a/src/main.rs b/src/main.rs index de4360a..e9a54bf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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, @@ -302,7 +303,6 @@ fn main() -> Result<()> { Some(tpl::args::Cmd::Send(atts, tpl)) => { return tpl::handlers::send( &folder, - &account_config, atts, tpl, &mut printer, diff --git a/src/ui/editor.rs b/src/ui/editor.rs index 0557028..e78ac4c 100644 --- a/src/ui/editor.rs +++ b/src/ui/editor.rs @@ -37,14 +37,18 @@ pub fn open_with_draft() -> Result { open_with_tpl(tpl) } -fn _edit_msg_with_editor(msg: &Email, tpl: TplOverride, config: &AccountConfig) -> Result { - let tpl = msg.to_tpl(tpl, config)?; +fn _edit_email_with_editor( + email: &Email, + tpl: TplOverride, + config: &AccountConfig, +) -> Result { + let tpl = email.to_tpl(tpl, config)?; let tpl = open_with_tpl(tpl)?; - Email::from_tpl(&tpl).context("cannot parse message from template") + Email::from_tpl(&tpl).context("cannot parse email from template") } -pub fn edit_msg_with_editor<'a, P: Printer, B: Backend<'a> + ?Sized, S: Sender + ?Sized>( - mut msg: Email, +pub fn edit_email_with_editor<'a, P: Printer, B: Backend<'a> + ?Sized, S: Sender + ?Sized>( + mut email: Email, tpl: TplOverride, config: &AccountConfig, printer: &mut P, @@ -60,11 +64,11 @@ pub fn edit_msg_with_editor<'a, P: Printer, B: Backend<'a> + ?Sized, S: Sender + Ok(choice) => match choice { PreEditChoice::Edit => { let tpl = open_with_draft()?; - msg.merge_with(Email::from_tpl(&tpl)?); + email.merge_with(Email::from_tpl(&tpl)?); break; } PreEditChoice::Discard => { - msg.merge_with(_edit_msg_with_editor(&msg, tpl.clone(), config)?); + email.merge_with(_edit_email_with_editor(&email, tpl.clone(), config)?); break; } PreEditChoice::Quit => return Ok(()), @@ -76,35 +80,35 @@ pub fn edit_msg_with_editor<'a, P: Printer, B: Backend<'a> + ?Sized, S: Sender + } } } else { - msg.merge_with(_edit_msg_with_editor(&msg, tpl.clone(), config)?); + email.merge_with(_edit_email_with_editor(&email, tpl.clone(), config)?); } loop { match choice::post_edit() { Ok(PostEditChoice::Send) => { - printer.print_str("Sending message…")?; - let sent_msg: Vec = sender.send(config, &msg)?; + printer.print_str("Sending email…")?; + let sent_email: Vec = sender.send(&email)?; let sent_folder = config.folder_alias("sent")?; - printer.print_str(format!("Adding message to the {:?} folder…", sent_folder))?; - backend.email_add(&sent_folder, &sent_msg, "seen")?; + printer.print_str(format!("Adding email to the {:?} folder…", sent_folder))?; + backend.email_add(&sent_folder, &sent_email, "seen")?; remove_local_draft()?; printer.print_struct("Done!")?; break; } Ok(PostEditChoice::Edit) => { - msg.merge_with(_edit_msg_with_editor(&msg, tpl.clone(), config)?); + email.merge_with(_edit_email_with_editor(&email, tpl.clone(), config)?); continue; } Ok(PostEditChoice::LocalDraft) => { - printer.print_struct("Message successfully saved locally")?; + printer.print_struct("Email successfully saved locally")?; break; } Ok(PostEditChoice::RemoteDraft) => { - let tpl = msg.to_tpl(TplOverride::default(), config)?; - let draft_folder = config.folder_alias("draft")?; + let tpl = email.to_tpl(TplOverride::default(), config)?; + let draft_folder = config.folder_alias("drafts")?; backend.email_add(&draft_folder, tpl.as_bytes(), "seen draft")?; remove_local_draft()?; - printer.print_struct(format!("Message successfully saved to {}", draft_folder))?; + printer.print_struct(format!("Email successfully saved to {}", draft_folder))?; break; } Ok(PostEditChoice::Discard) => {