From 6ef6f1c31feee0ff7078367e71276e6676f0b350 Mon Sep 17 00:00:00 2001 From: Luke Hsiao Date: Wed, 6 Sep 2023 16:56:57 -0600 Subject: [PATCH] refactor: switch to `feed-rs` This library has a simpler API that unifies Atom and RSS, and is more maintained. As a side-effect, it also allows us to resolve our chrono security advisories. Unfortunately, since we are no longer responsible for parsing the date, we cannot support invalid, naive dates. Ref: https://github.com/feed-rs/feed-rs --- Cargo.lock | 638 +++++++++++++++++++---------------------------------- Cargo.toml | 14 +- src/lib.rs | 247 +++++++++------------ 3 files changed, 333 insertions(+), 566 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 19872e5..7660199 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8f9420f797f2d9e935edf629310eb938a0d839f984e25327f3c7eed22300c" +checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" dependencies = [ "memchr", ] @@ -70,9 +70,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" +checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea" [[package]] name = "anstyle-parse" @@ -104,32 +104,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" - -[[package]] -name = "atom_syndication" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a9a7ab83635ff7a3b04856f4ad95324dccc9b947ab1e790fc5c769ee6d6f60c" -dependencies = [ - "derive_builder 0.5.1", - "failure", - "quick-xml 0.12.4", -] - -[[package]] -name = "atom_syndication" -version = "0.9.1" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d5016bf52ff4f3ed28bf3ec1fed96b53daf4b137d5e6b9f97a8cfae7b57a3a2" -dependencies = [ - "chrono", - "derive_builder 0.9.0", - "diligent-date-parser", - "quick-xml 0.20.0", -] +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "autocfg" @@ -139,9 +116,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", @@ -163,9 +140,9 @@ dependencies = [ [[package]] name = "base64" -version = "0.21.2" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53" [[package]] name = "bitflags" @@ -175,9 +152,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" [[package]] name = "block-buffer" @@ -190,9 +167,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.6.0" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05" +checksum = "4c2f7349907b712260e64b0afe2f84692af14a454be26187d9df565c7f69266a" dependencies = [ "memchr", "serde", @@ -206,9 +183,9 @@ checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" [[package]] name = "cc" -version = "1.0.82" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "libc", ] @@ -221,40 +198,37 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ed24df0632f708f5f6d8082675bef2596f7084dee3dd55f632290bf35bfe0f" +checksum = "d87d9d13be47a5b7c3907137f1290b0459a7f80efb26be8c52afb11963bccb02" dependencies = [ "android-tzdata", "iana-time-zone", - "js-sys", "num-traits", "serde", - "time", - "wasm-bindgen", - "windows-targets 0.48.1", + "windows-targets 0.48.5", ] [[package]] name = "chrono-tz" -version = "0.6.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58549f1842da3080ce63002102d5bc954c7bc843d4f47818e642abdc36253552" +checksum = "f1369bc6b9e9a7dfdae2055f6ec151fe9c554a9d23d357c0237cee2e25eaabb7" dependencies = [ "chrono", "chrono-tz-build", - "phf", + "phf 0.11.2", ] [[package]] name = "chrono-tz-build" -version = "0.0.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db058d493fb2f65f41861bfed7e3fe6335264a9f0f92710cab5bdf01fef09069" +checksum = "e2f5ebdc942f57ed96d560a6d1a459bae5851102a25d5bf89dc04ae453e31ecf" dependencies = [ "parse-zoneinfo", - "phf", - "phf_codegen", + "phf 0.11.2", + "phf_codegen 0.11.2", ] [[package]] @@ -286,7 +260,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim 0.10.0", + "strsim", "terminal_size 0.2.6", ] @@ -298,15 +272,15 @@ checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" dependencies = [ "heck", "proc-macro2", - "quote 1.0.32", - "syn 2.0.28", + "quote", + "syn 2.0.31", ] [[package]] name = "clap_lex" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" +checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" [[package]] name = "colorchoice" @@ -404,87 +378,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "darling" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote 1.0.32", - "strsim 0.9.3", - "syn 1.0.109", -] - -[[package]] -name = "darling_macro" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" -dependencies = [ - "darling_core", - "quote 1.0.32", - "syn 1.0.109", -] - -[[package]] -name = "derive_builder" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c998e6ab02a828dd9735c18f154e14100e674ed08cb4e1938f0e4177543f439" -dependencies = [ - "derive_builder_core 0.2.0", - "quote 0.3.15", - "syn 0.11.11", -] - -[[package]] -name = "derive_builder" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2658621297f2cf68762a6f7dc0bb7e1ff2cfd6583daef8ee0fed6f7ec468ec0" -dependencies = [ - "darling", - "derive_builder_core 0.9.0", - "proc-macro2", - "quote 1.0.32", - "syn 1.0.109", -] - -[[package]] -name = "derive_builder_core" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "735e24ee9e5fa8e16b86da5007856e97d592e11867e45d76e0c0d0a164a0b757" -dependencies = [ - "quote 0.3.15", - "syn 0.11.11", -] - -[[package]] -name = "derive_builder_core" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2791ea3e372c8495c0bc2033991d76b512cd799d07491fbd6890124db9458bef" -dependencies = [ - "darling", - "proc-macro2", - "quote 1.0.32", - "syn 1.0.109", -] - [[package]] name = "deunicode" version = "0.4.4" @@ -501,15 +394,6 @@ dependencies = [ "crypto-common", ] -[[package]] -name = "diligent-date-parser" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6cf7fe294274a222363f84bcb63cdea762979a0443b4cf1f4f8fd17c86b1182" -dependencies = [ - "chrono", -] - [[package]] name = "either" version = "1.9.0" @@ -524,18 +408,18 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.32" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ "cfg-if", ] [[package]] name = "errno" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" dependencies = [ "errno-dragonfly", "libc", @@ -553,32 +437,28 @@ dependencies = [ ] [[package]] -name = "failure" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" -dependencies = [ - "backtrace", - "failure_derive", -] - -[[package]] -name = "failure_derive" -version = "0.1.8" +name = "feed-rs" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" +checksum = "9dbec361cb401c1b86aea784fb809073733da06b1a1fd794222e7bf9845db327" dependencies = [ - "proc-macro2", - "quote 1.0.32", - "syn 1.0.109", - "synstructure", + "chrono", + "lazy_static", + "mime", + "quick-xml", + "regex", + "serde", + "serde_json", + "siphasher", + "url", + "uuid", ] [[package]] name = "flate2" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" +checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" dependencies = [ "crc32fast", "miniz_oxide", @@ -627,14 +507,14 @@ checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", ] [[package]] name = "gimli" -version = "0.27.3" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "globset" @@ -691,7 +571,7 @@ dependencies = [ "mac", "markup5ever", "proc-macro2", - "quote 1.0.32", + "quote", "syn 1.0.109", ] @@ -727,12 +607,6 @@ dependencies = [ "cc", ] -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "idna" version = "0.4.0" @@ -801,7 +675,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix 0.38.7", + "rustix 0.38.11", "windows-sys 0.48.0", ] @@ -891,8 +765,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016" dependencies = [ "log", - "phf", - "phf_codegen", + "phf 0.10.1", + "phf_codegen 0.10.0", "string_cache", "string_cache_codegen", "tendril", @@ -909,9 +783,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" [[package]] name = "memoffset" @@ -950,10 +824,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" dependencies = [ "proc-macro2", - "quote 1.0.32", - "syn 2.0.28", + "quote", + "syn 2.0.31", ] +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + [[package]] name = "miniz_oxide" version = "0.7.1" @@ -1006,9 +886,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "object" -version = "0.31.1" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] @@ -1028,6 +908,7 @@ dependencies = [ "chrono", "clap", "clap-verbosity-flag", + "feed-rs", "html-escape", "indicatif", "log", @@ -1035,7 +916,6 @@ dependencies = [ "rayon", "serde", "serde_json", - "syndication", "tera", "thiserror", "tracing", @@ -1076,7 +956,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets 0.48.1", + "windows-targets 0.48.5", ] [[package]] @@ -1096,19 +976,20 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pest" -version = "2.7.2" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1acb4a4365a13f749a93f1a094a7805e5cfa0955373a9de860d962eaa3a5fe5a" +checksum = "d7a4d085fd991ac8d5b05a147b437791b4260b76326baf0fc60cf7c9c27ecd33" dependencies = [ + "memchr", "thiserror", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.2" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "666d00490d4ac815001da55838c500eafb0320019bbaa44444137c48b443a853" +checksum = "a2bee7be22ce7918f641a33f08e3f43388c7656772244e2bbb2477f44cc9021a" dependencies = [ "pest", "pest_generator", @@ -1116,22 +997,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.2" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ca01446f50dbda87c1786af8770d535423fa8a53aec03b8f4e3d7eb10e0929" +checksum = "d1511785c5e98d79a05e8a6bc34b4ac2168a0e3e92161862030ad84daa223141" dependencies = [ "pest", "pest_meta", "proc-macro2", - "quote 1.0.32", - "syn 2.0.28", + "quote", + "syn 2.0.31", ] [[package]] name = "pest_meta" -version = "2.7.2" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56af0a30af74d0445c0bf6d9d051c979b516a1a5af790d251daee76005420a48" +checksum = "b42f0394d3123e33353ca5e1e89092e533d2cc490389f2bd6131c43c634ebc5f" dependencies = [ "once_cell", "pest", @@ -1144,7 +1025,16 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" dependencies = [ - "phf_shared", + "phf_shared 0.10.0", +] + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_shared 0.11.2", ] [[package]] @@ -1153,8 +1043,18 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" dependencies = [ - "phf_generator", - "phf_shared", + "phf_generator 0.10.0", + "phf_shared 0.10.0", +] + +[[package]] +name = "phf_codegen" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +dependencies = [ + "phf_generator 0.11.2", + "phf_shared 0.11.2", ] [[package]] @@ -1163,7 +1063,17 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" dependencies = [ - "phf_shared", + "phf_shared 0.10.0", + "rand", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared 0.11.2", "rand", ] @@ -1174,20 +1084,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" dependencies = [ "siphasher", - "uncased", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", ] [[package]] name = "pin-project-lite" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "portable-atomic" -version = "1.4.2" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f32154ba0af3a075eefa1eda8bb414ee928f62303a54ea85b8d6638ff1a6ee9e" +checksum = "31114a898e107c51bb1609ffaf55a0e011cf6a4d7f1170d0015a165082c0338b" [[package]] name = "ppv-lite86" @@ -1212,21 +1130,9 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d8065cbb01701c11cc195cde85cbf39d1c6a80705b67a157ebb3042e0e5777f" -dependencies = [ - "encoding_rs", - "failure", - "log", - "memchr", -] - -[[package]] -name = "quick-xml" -version = "0.20.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26aab6b48e2590e4a64d1ed808749ba06257882b461d01ca71baeb747074a6dd" +checksum = "ffc053f057dd768a56f62cd7e434c42c831d296968997e9ac1f76ea7c2d14c41" dependencies = [ "encoding_rs", "memchr", @@ -1234,15 +1140,9 @@ dependencies = [ [[package]] name = "quote" -version = "0.3.15" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" - -[[package]] -name = "quote" -version = "1.0.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -1310,14 +1210,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.3" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" +checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.3.6", - "regex-syntax 0.7.4", + "regex-automata 0.3.8", + "regex-syntax 0.7.5", ] [[package]] @@ -1331,13 +1231,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.6" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" +checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.4", + "regex-syntax 0.7.5", ] [[package]] @@ -1348,9 +1248,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "ring" @@ -1367,17 +1267,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "rss" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e70d6ae72f8a4333af8ce9dce58942020528430eb0d46ee2fcb5e8d4d16377" -dependencies = [ - "atom_syndication 0.9.1", - "derive_builder 0.9.0", - "quick-xml 0.20.0", -] - [[package]] name = "rustc-demangle" version = "0.1.23" @@ -1400,11 +1289,11 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.7" +version = "0.38.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "172891ebdceb05aa0005f533a6cbfca599ddd7d966f6f5d4d9b2e70478e70399" +checksum = "c0c3dde1fc030af041adc40e79c0e7fbcf431dd24870053d187d7c66e4b87453" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.0", "errno", "libc", "linux-raw-sys 0.4.5", @@ -1413,21 +1302,21 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.6" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1feddffcfcc0b33f5c6ce9a29e341e4cd59c3f78e7ee45f4a40c038b1d6cbb" +checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" dependencies = [ "log", "ring", - "rustls-webpki 0.101.3", + "rustls-webpki 0.101.4", "sct", ] [[package]] name = "rustls-webpki" -version = "0.100.1" +version = "0.100.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" +checksum = "e98ff011474fa39949b7e5c0428f9b4937eda7da7848bbb947786b7be0b27dab" dependencies = [ "ring", "untrusted", @@ -1435,9 +1324,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.101.3" +version = "0.101.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261e9e0888cba427c3316e6322805653c9425240b6fd96cee7cb671ab70ab8d0" +checksum = "7d93931baf2d282fff8d3a532bbfd7653f734643161b87e3e01e59a04439bf0d" dependencies = [ "ring", "untrusted", @@ -1490,15 +1379,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", - "quote 1.0.32", - "syn 2.0.28", + "quote", + "syn 2.0.31", ] [[package]] name = "serde_json" -version = "1.0.104" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" +checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" dependencies = [ "itoa", "ryu", @@ -1527,9 +1416,9 @@ dependencies = [ [[package]] name = "siphasher" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" [[package]] name = "slug" @@ -1567,7 +1456,7 @@ dependencies = [ "new_debug_unreachable", "once_cell", "parking_lot", - "phf_shared", + "phf_shared 0.10.0", "precomputed-hash", "serde", ] @@ -1578,18 +1467,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" dependencies = [ - "phf_generator", - "phf_shared", + "phf_generator 0.10.0", + "phf_shared 0.10.0", "proc-macro2", - "quote 1.0.32", + "quote", ] -[[package]] -name = "strsim" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" - [[package]] name = "strsim" version = "0.10.0" @@ -1624,17 +1507,6 @@ dependencies = [ "is-terminal", ] -[[package]] -name = "syn" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" -dependencies = [ - "quote 0.3.15", - "synom", - "unicode-xid 0.0.4", -] - [[package]] name = "syn" version = "1.0.109" @@ -1642,52 +1514,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", - "quote 1.0.32", + "quote", "unicode-ident", ] [[package]] name = "syn" -version = "2.0.28" +version = "2.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" dependencies = [ "proc-macro2", - "quote 1.0.32", + "quote", "unicode-ident", ] -[[package]] -name = "syndication" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c441f801a54249fe9c74fc03691c6d0f9de2b6ad2f1bf2fb12eb92bd376d3552" -dependencies = [ - "atom_syndication 0.6.0", - "rss", -] - -[[package]] -name = "synom" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" -dependencies = [ - "unicode-xid 0.0.4", -] - -[[package]] -name = "synstructure" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" -dependencies = [ - "proc-macro2", - "quote 1.0.32", - "syn 1.0.109", - "unicode-xid 0.2.4", -] - [[package]] name = "tendril" version = "0.4.3" @@ -1701,9 +1542,9 @@ dependencies = [ [[package]] name = "tera" -version = "1.19.0" +version = "1.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5ab29bb4f3e256ae6ad5c3e2775aa1f8829f2c0c101fc407bfd3a6df15c60c5" +checksum = "970dff17c11e884a4a09bc76e3a17ef71e01bb13447a11e85226e254fe6d10b8" dependencies = [ "chrono", "chrono-tz", @@ -1718,7 +1559,6 @@ dependencies = [ "serde", "serde_json", "slug", - "thread_local", "unic-segment", ] @@ -1755,44 +1595,34 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.47" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f" +checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.47" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b" +checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", - "quote 1.0.32", - "syn 2.0.28", + "quote", + "syn 2.0.31", ] [[package]] name = "thread_local" -version = "1.1.4" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" dependencies = [ + "cfg-if", "once_cell", ] -[[package]] -name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] - [[package]] name = "tinyvec" version = "1.6.0" @@ -1827,8 +1657,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", - "quote 1.0.32", - "syn 2.0.28", + "quote", + "syn 2.0.31", ] [[package]] @@ -1882,15 +1712,6 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" -[[package]] -name = "uncased" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b9bc53168a4be7402ab86c3aad243a84dd7381d09be0eddc81280c1da95ca68" -dependencies = [ - "version_check", -] - [[package]] name = "unic-char-property" version = "0.9.0" @@ -1974,18 +1795,6 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" -[[package]] -name = "unicode-xid" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" - -[[package]] -name = "unicode-xid" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" - [[package]] name = "untrusted" version = "0.7.1" @@ -2003,16 +1812,16 @@ dependencies = [ "log", "once_cell", "rustls", - "rustls-webpki 0.100.1", + "rustls-webpki 0.100.2", "url", "webpki-roots", ] [[package]] name = "url" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" dependencies = [ "form_urlencoded", "idna", @@ -2038,6 +1847,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "uuid" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" +dependencies = [ + "getrandom", +] + [[package]] name = "valuable" version = "0.1.0" @@ -2052,20 +1870,14 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "walkdir" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" dependencies = [ "same-file", "winapi-util", ] -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -2092,8 +1904,8 @@ dependencies = [ "log", "once_cell", "proc-macro2", - "quote 1.0.32", - "syn 2.0.28", + "quote", + "syn 2.0.31", "wasm-bindgen-shared", ] @@ -2103,7 +1915,7 @@ version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ - "quote 1.0.32", + "quote", "wasm-bindgen-macro-support", ] @@ -2114,8 +1926,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", - "quote 1.0.32", - "syn 2.0.28", + "quote", + "syn 2.0.31", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2142,7 +1954,7 @@ version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" dependencies = [ - "rustls-webpki 0.100.1", + "rustls-webpki 0.100.2", ] [[package]] @@ -2182,7 +1994,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.48.1", + "windows-targets 0.48.5", ] [[package]] @@ -2200,7 +2012,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.1", + "windows-targets 0.48.5", ] [[package]] @@ -2220,17 +2032,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] @@ -2241,9 +2053,9 @@ checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" @@ -2253,9 +2065,9 @@ checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" @@ -2265,9 +2077,9 @@ checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" @@ -2277,9 +2089,9 @@ checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" @@ -2289,9 +2101,9 @@ checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" @@ -2301,9 +2113,9 @@ checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" @@ -2313,6 +2125,6 @@ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/Cargo.toml b/Cargo.toml index f2a3b53..0832f4e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,21 +14,21 @@ categories = ["command-line-utilities"] [dependencies] ammonia = "3.3.0" -anyhow = "1.0.72" -chrono = { version = "0.4.28", features = ["serde"] } +anyhow = "1.0.75" +chrono = { version = "0.4.29", default-features = false, features = ["serde", "clock"] } clap = { version = "4.4.2", features = ["derive", "wrap_help", "cargo"] } clap-verbosity-flag = "2.0.1" +feed-rs = "1.3.0" html-escape = "0.2.13" indicatif = { version = "0.17.6", features = ["rayon"] } log = "0.4.20" miette = { version = "5.10.0", features = ["fancy"] } rayon = "1.7.0" serde = { version = "1.0.188", features = ["derive"] } -serde_json = "1.0.104" -syndication = "0.5.0" -tera = "1.19.0" -thiserror = "1.0.47" +serde_json = "1.0.105" +tera = "1.19.1" +thiserror = "1.0.48" tracing = "0.1.37" tracing-subscriber = { version = "0.3.17", features = ["env-filter", "fmt"] } ureq = "2.7.1" -url = { version = "2.4.0", features = ["serde"] } +url = { version = "2.4.1", features = ["serde"] } diff --git a/src/lib.rs b/src/lib.rs index fe65d8c..b1afe95 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,20 +6,17 @@ use std::{ time::Duration, }; -use chrono::{ - naive::{NaiveDate, NaiveDateTime}, - DateTime, FixedOffset, Local, TimeZone, -}; +use chrono::{naive::NaiveDate, DateTime, Utc}; use clap::{builder::ValueHint, crate_name, crate_version, Parser}; use clap_verbosity_flag::{Verbosity, WarnLevel}; +use feed_rs::{model::Feed, parser}; use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; use miette::{Diagnostic, NamedSource, SourceSpan}; use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator}; use serde::Serialize; -use syndication::Feed; use tera::Tera; use thiserror::Error; -use tracing::{debug, info, warn}; +use tracing::{debug, warn}; use ureq::{Agent, AgentBuilder}; use url::Url; @@ -31,6 +28,9 @@ pub enum OpenringError { DateError, #[error("No feed urls were provided. Provide feeds with -s or -S .")] FeedMissing, + #[error("The feed at `{0}` has a bad a title (e.g., missing link or title).")] + #[diagnostic(code(openring::feed_title_error))] + FeedBadTitle(String), #[error("Failed to parse naive date.")] NaiveDateError(#[from] chrono::ParseError), #[error(transparent)] @@ -110,7 +110,7 @@ pub struct Article { summary: String, source_link: Url, source_title: String, - date: DateTime, + date: DateTime, } fn parse_naive_date(input: &str) -> Result { @@ -178,7 +178,7 @@ fn get_feeds_from_urls(urls: Vec) -> Result> { pb.inc(1); if let Some(feed_str) = body { - match feed_str.parse::() { + match parser::parse(feed_str.as_bytes()) { Ok(feed) => { pb.finish_and_clear(); Some((feed, url.clone())) @@ -206,23 +206,6 @@ fn get_feeds_from_urls(urls: Vec) -> Result> { Ok(feeds) } -// Parse the date, falling back to naive parsing if necessary. -fn parse_date(date: &str) -> Result> { - date.parse::>() - .or_else(|_| DateTime::parse_from_rfc2822(date)) - .or_else(|_| DateTime::parse_from_rfc3339(date)) - .or_else(|_| { - debug!(?date, "attempting to parse non-standard date"); - let naive_dt = NaiveDateTime::parse_from_str(date, "%Y-%m-%dT%H:%M:%S")?; - let fixed_offset = - FixedOffset::east_opt(Local::now().offset().local_minus_utc()).unwrap(); - fixed_offset - .from_local_datetime(&naive_dt) - .earliest() - .ok_or(OpenringError::DateError) - }) -} - pub fn run(args: Args) -> Result<()> { debug!(?args); let mut urls = args.url; @@ -241,137 +224,109 @@ pub fn run(args: Args) -> Result<()> { let template = fs::read_to_string(&args.template_file)?; let mut context = tera::Context::new(); + // Grab articles from all the feeds let mut articles = Vec::new(); for (feed, url) in feeds { - match feed { - Feed::RSS(c) => { - let items = if c.items().len() >= args.per_source { - &c.items()[0..args.per_source] - } else { - c.items() - }; - let source_link = Url::parse(c.link())?; - let source_title = c.title().to_string(); - for item in items { - if let (Some(link), Some(title), Some(date)) = - (item.link(), item.title(), item.pub_date()) - { - let date = parse_date(date)?; - // Skip articles after args.before, if present - if let Some(before) = args.before { - if date.date_naive() > before { - continue; - } - } + let entries = if feed.entries.len() >= args.per_source { + &feed.entries[0..args.per_source] + } else { + &feed.entries + }; - let summary = match item.description() { - Some(s) => s.to_string(), - None => match item.content() { - Some(s) => s.to_string(), - None => { - warn!(?link, ?source_link, "Skipping link from feed: no summary or content provided in feed."); - continue; - } - }, - }; - let mut safe_summary = String::new(); - html_escape::decode_html_entities_to_string( - ammonia::clean(&summary), - &mut safe_summary, - ); - articles.push(Article { - link: Url::parse(link)?, - title: title.to_string(), - summary: safe_summary.trim().to_string(), - source_link: source_link.clone(), - source_title: source_title.clone(), - date, - }); - } else { - debug!(?item, "Skipping. Must have link, title, and date"); + if feed.title.is_none() { + return Err(OpenringError::FeedBadTitle(url.to_string())); + } + let source_title = feed.title.clone().unwrap().content; + let source_link = match &feed.title.as_ref().unwrap().src { + None => { + // Then, look for links + match feed + .links + .iter() + .find(|l| { + if let Some(rel) = &l.rel { + rel == "alternate" + } else { + false + } + }) + .map(|l| &l.href) + { + None => { + // If an alternate link is missing just grab one of them + match feed.links.into_iter().next().map(|l| l.href) { + Some(s) => Url::parse(&s)?, + None => return Err(OpenringError::FeedBadTitle(url.to_string())), + } } + Some(s) => Url::parse(s)?, } } - Feed::Atom(ref f) => { - let items = &f.entries()[0..args.per_source]; - let feed_links = f.links(); - if !feed_links.is_empty() { - debug!(?feed_links); - - let source_link = Url::parse( - f.links() - .iter() - .find(|l| l.rel() == "alternate") - .unwrap() - .href(), - )?; - let source_title = f.title().to_string(); - for item in items { - if !item.links().is_empty() { - let date = parse_date(item.updated()).or_else(|_| { - debug!("using published date, rather than last updated date"); - if let Some(date) = item.published() { - parse_date(date).map_err(|e| { - let feed_src = feed.to_string(); - let start = feed_src.find(date).unwrap(); - let len = date.len(); - ChronoError { - src: NamedSource::new(url.as_str(), feed_src), - span: (start..start + len).into(), - help: e.to_string(), - } - .into() - }) - } else { - Err(OpenringError::DateError) - } - })?; - - // Skip articles after args.before, if present - if let Some(before) = args.before { - if date.date_naive() > before { - continue; - } - } - - let summary = match item.summary() { - Some(s) => s.to_string(), - None => match item.content().map(|c| c.value()) { - Some(Some(v)) => v.to_string(), - _ => { - warn!(link=%item.links()[0].href(), ?source_link, "Skipping link from feed: no summary or content provided in feed."); - continue; - } - }, - }; - - let mut safe_summary = String::new(); - html_escape::decode_html_entities_to_string( - ammonia::clean(&summary), - &mut safe_summary, - ); - info!(summary = %summary); - // Uses the last link, since blogspot puts the article link last. - let link = Url::parse( - item.links() - .iter() - .find(|l| l.rel() == "alternate") - .unwrap() - .href(), - )?; - articles.push(Article { - link, - title: item.title().to_string(), - summary: safe_summary.trim().to_string(), - source_link: source_link.clone(), - source_title: source_title.clone(), - date, - }); + Some(s) => Url::parse(s)?, + }; + for entry in entries.iter() { + if let (Some(link), Some(title), Some(date)) = ( + entry + .links + .iter() + .find(|l| { + if let Some(rel) = &l.rel { + rel == "alternate" } else { - debug!(?item, "Skipping. Must have links."); + false } + }) + .map(|l| &l.href), + entry.title.as_ref().map(|t| &t.content), + entry.published, + ) { + // Skip articles after args.before, if present + if let Some(before) = args.before { + if date.date_naive() > before { + continue; } } + + let summary = match &entry.summary { + Some(s) => &s.content, + None => match &entry.content { + Some(c) => match &c.body { + Some(b) => b, + None => { + warn!( + ?link, + ?source_link, + "Skipping link from feed: no summary or content provided." + ); + continue; + } + }, + None => { + warn!( + ?link, + ?source_link, + "Skipping link from feed: no summary or content provided." + ); + continue; + } + }, + }; + + let mut safe_summary = String::new(); + html_escape::decode_html_entities_to_string( + ammonia::clean(summary), + &mut safe_summary, + ); + articles.push(Article { + link: Url::parse(link)?, + title: title.to_string(), + summary: safe_summary.trim().to_string(), + source_link: source_link.clone(), + source_title: source_title.clone(), + date, + }); + } else { + debug!(?entry, "Skipping. Must have link, title, and date"); } } }