diff --git a/Cargo.lock b/Cargo.lock index 6d0ee0f..aefefa1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,15 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + [[package]] name = "android_system_properties" version = "0.1.5" @@ -43,19 +52,6 @@ dependencies = [ "syn 2.0.114", ] -[[package]] -name = "atom_syndication" -version = "0.12.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f68d23e2cb4fd958c705b91a6b4c80ceeaf27a9e11651272a8389d5ce1a4a3" -dependencies = [ - "chrono", - "derive_builder", - "diligent-date-parser", - "never", - "quick-xml", -] - [[package]] name = "atomic-waker" version = "1.1.2" @@ -144,6 +140,7 @@ dependencies = [ "iana-time-zone", "js-sys", "num-traits", + "serde", "wasm-bindgen", "windows-link", ] @@ -159,16 +156,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -218,41 +205,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "darling" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.114", -] - -[[package]] -name = "darling_macro" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" -dependencies = [ - "darling_core", - "quote", - "syn 2.0.114", -] - [[package]] name = "data-encoding" version = "2.9.0" @@ -269,37 +221,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "derive_builder" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" -dependencies = [ - "derive_builder_macro", -] - -[[package]] -name = "derive_builder_core" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "derive_builder_macro" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" -dependencies = [ - "derive_builder_core", - "syn 2.0.114", -] - [[package]] name = "digest" version = "0.10.7" @@ -310,15 +231,6 @@ dependencies = [ "crypto-common", ] -[[package]] -name = "diligent-date-parser" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8ede7d79366f419921e2e2f67889c12125726692a313bffb474bd5f37a581e9" -dependencies = [ - "chrono", -] - [[package]] name = "displaydoc" version = "0.2.5" @@ -362,10 +274,21 @@ dependencies = [ ] [[package]] -name = "fastrand" -version = "2.3.0" +name = "feed-rs" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "e4c0591d23efd0d595099af69a31863ac1823046b1b021e3b06ba3aae7e00991" +dependencies = [ + "chrono", + "mediatype", + "quick-xml", + "regex", + "serde", + "serde_json", + "siphasher", + "url", + "uuid", +] [[package]] name = "find-msvc-tools" @@ -383,27 +306,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.2.2" @@ -556,25 +458,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "h2" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" -dependencies = [ - "atomic-waker", - "bytes", - "fnv", - "futures-core", - "futures-sink", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "hashbrown" version = "0.16.1" @@ -654,7 +537,6 @@ dependencies = [ "bytes", "futures-channel", "futures-core", - "h2", "http", "http-body", "httparse", @@ -683,22 +565,6 @@ dependencies = [ "webpki-roots 1.0.5", ] -[[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes", - "http-body-util", - "hyper", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", -] - [[package]] name = "hyper-util" version = "0.1.19" @@ -718,11 +584,9 @@ dependencies = [ "percent-encoding", "pin-project-lite", "socket2", - "system-configuration", "tokio", "tower-service", "tracing", - "windows-registry", ] [[package]] @@ -830,12 +694,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "idna" version = "1.1.0" @@ -920,12 +778,6 @@ version = "0.2.180" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" -[[package]] -name = "linux-raw-sys" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" - [[package]] name = "litemap" version = "0.8.1" @@ -985,6 +837,15 @@ dependencies = [ "xml5ever", ] +[[package]] +name = "mediatype" +version = "0.19.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33746aadcb41349ec291e7f2f0a3aa6834d1d7c58066fb4b01f68efc4c4b7631" +dependencies = [ + "serde", +] + [[package]] name = "memchr" version = "2.7.6" @@ -998,9 +859,9 @@ dependencies = [ "anyhow", "chrono", "dotenvy", + "feed-rs", "htmd", "reqwest", - "rss", "serde", "serde_json", "serenity", @@ -1046,29 +907,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "native-tls" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "never" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c96aba5aa877601bb3f6dd6a63a969e1f82e60646e81e71b14496995e9853c91" - [[package]] name = "new_debug_unreachable" version = "1.0.6" @@ -1096,50 +934,6 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" -[[package]] -name = "openssl" -version = "0.10.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" -dependencies = [ - "bitflags 2.10.0", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "openssl-probe" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" - -[[package]] -name = "openssl-sys" -version = "0.9.111" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "parking_lot" version = "0.11.2" @@ -1244,12 +1038,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - [[package]] name = "potential_utf" version = "0.1.4" @@ -1446,6 +1234,35 @@ dependencies = [ "bitflags 2.10.0", ] +[[package]] +name = "regex" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + [[package]] name = "reqwest" version = "0.12.28" @@ -1454,22 +1271,17 @@ checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ "base64", "bytes", - "encoding_rs", "futures-core", "futures-util", - "h2", "http", "http-body", "http-body-util", "hyper", "hyper-rustls", - "hyper-tls", "hyper-util", "js-sys", "log", - "mime", "mime_guess", - "native-tls", "percent-encoding", "pin-project-lite", "quinn", @@ -1480,7 +1292,6 @@ dependencies = [ "serde_urlencoded", "sync_wrapper", "tokio", - "tokio-native-tls", "tokio-rustls 0.26.4", "tokio-util", "tower", @@ -1508,37 +1319,12 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rss" -version = "2.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2107738f003660f0a91f56fd3e3bd3ab5d918b2ddaf1e1ec2136fb1c46f71bf" -dependencies = [ - "atom_syndication", - "derive_builder", - "never", - "quick-xml", -] - [[package]] name = "rustc-hash" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" -[[package]] -name = "rustix" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" -dependencies = [ - "bitflags 2.10.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.61.2", -] - [[package]] name = "rustls" version = "0.22.4" @@ -1611,15 +1397,6 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" -[[package]] -name = "schannel" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" -dependencies = [ - "windows-sys 0.61.2", -] - [[package]] name = "scopeguard" version = "1.2.0" @@ -1636,29 +1413,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "security-framework" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" -dependencies = [ - "bitflags 2.10.0", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "serde" version = "1.0.228" @@ -1879,12 +1633,6 @@ dependencies = [ "quote", ] -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - [[package]] name = "subtle" version = "2.6.1" @@ -1933,40 +1681,6 @@ dependencies = [ "syn 2.0.114", ] -[[package]] -name = "system-configuration" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" -dependencies = [ - "bitflags 2.10.0", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "tempfile" -version = "3.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" -dependencies = [ - "fastrand", - "getrandom 0.3.4", - "once_cell", - "rustix", - "windows-sys 0.61.2", -] - [[package]] name = "tendril" version = "0.4.3" @@ -2102,16 +1816,6 @@ dependencies = [ "syn 2.0.114", ] -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.25.0" @@ -2362,18 +2066,23 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +[[package]] +name = "uuid" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" +dependencies = [ + "getrandom 0.3.4", + "js-sys", + "wasm-bindgen", +] + [[package]] name = "uwl" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4bf03e0ca70d626ecc4ba6b0763b934b6f2976e8c744088bb3c1d646fbb1ad0" -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "version_check" version = "0.9.5" @@ -2576,17 +2285,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" -[[package]] -name = "windows-registry" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" -dependencies = [ - "windows-link", - "windows-result", - "windows-strings", -] - [[package]] name = "windows-result" version = "0.4.1" diff --git a/Cargo.toml b/Cargo.toml index 1b651c8..5dcf268 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" [dependencies] serenity = { version = "0.12", default-features = false, features = ["client", "gateway", "rustls_backend", "model", "standard_framework"] } tokio = { version = "1", features = ["full"] } -rss = "2.0" +feed-rs = "2" reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/src/main.rs b/src/main.rs index c65049c..00b1149 100644 --- a/src/main.rs +++ b/src/main.rs @@ -85,30 +85,29 @@ async fn check_feed( ) -> Result<()> { let feed = rss::fetch_feed(&config.rss).await?; - // items usually come in descending order (newest first) + // entries usually come in descending order (newest first) // we should probably reverse them to process oldest first to maintain order in Discord - let mut items = feed.items().to_vec(); + let mut items = feed.entries; items.reverse(); for item in items { let item_id = rss::get_field_value(&item, config, "link") - .or_else(|| item.guid().map(|g| g.value().to_string())) - .unwrap_or_default(); + .unwrap_or_else(|| item.id.clone()); if item_id.is_empty() { continue; } if !storage.is_processed(name, &item_id)? { // Category check if let Some(filters) = &config.category_filter { - let item_categories: Vec<_> = item.categories().iter().map(|c| c.name()).collect(); - if item_categories.iter().any(|c| filters.contains(&c.to_string())) { + let item_categories: Vec<_> = item.categories.iter().map(|c| c.term.clone()).collect(); + if item_categories.iter().any(|c| filters.contains(c)) { println!("[{}] Filtered by category: {:?}", name, item_categories); storage.mark_processed(name, &item_id)?; continue; } } - println!("[{}] New item: {:?}", name, item.title()); + println!("[{}] New item: {:?}", name, item.title.as_ref().map(|t| &t.content)); let content = rss::build_content(config, &item); let channel_id = config.channel.parse::()?; @@ -121,18 +120,13 @@ async fn check_feed( let post = serenity::builder::CreateForumPost::new( title, serenity::builder::CreateMessage::new().content(content) - ).add_applied_tag(serenity::model::id::ForumTagId::new(tag_id)); + ).add_applied_tag(serenity::all::ForumTagId::new(tag_id)); if let Err(e) = channel.create_forum_post(&http, post).await { eprintln!("[{}] Failed to create forum post: {}", name, e); continue; } - // After creating thread, post the message if needed, - // but CreateThread in Serenity for Forum usually takes message too? - // Actually, for Forum channels, the first message is part of the thread creation. - // Let's refine this if needed based on Serenity 0.12 API. - storage.mark_processed(name, &item_id)?; } } diff --git a/src/rss.rs b/src/rss.rs index 4e8acc0..5f72b87 100644 --- a/src/rss.rs +++ b/src/rss.rs @@ -1,16 +1,16 @@ use crate::config::RssConfig; use anyhow::Result; use htmd::HtmlToMarkdown; -use rss::Channel; +use feed_rs::model::{Feed, Entry}; -pub async fn fetch_feed(url: &str) -> Result { +pub async fn fetch_feed(url: &str) -> Result { let content = reqwest::get(url).await?.bytes().await?; - let channel = Channel::read_from(&content[..])?; - Ok(channel) + let feed = feed_rs::parser::parse(&content[..])?; + Ok(feed) } pub fn get_field_value( - item: &rss::Item, + item: &Entry, config: &RssConfig, field: &str, ) -> Option { @@ -25,54 +25,33 @@ pub fn get_field_value( _ => None, }; - if let Some(p) = path { - // Simple JSON path-like resolution for extensions if needed - // For now, check standard fields first, then extensions - resolve_path(item, p) + if let Some(_p) = path { + // Path-based resolution is harder with feed-rs because it's already abstracted. + // We'll map some known paths to feed-rs fields. + match _p.as_str() { + "title" => item.title.as_ref().map(|t| t.content.clone()), + "link" => item.links.first().map(|l| l.href.clone()), + "description" | "summary" => item.summary.as_ref().map(|s| s.content.clone()), + "content" => item.content.as_ref().and_then(|c| c.body.clone()), + "published" | "pubDate" => item.published.map(|d| d.to_rfc3339()), + "dc:creator" | "author.name" => item.authors.first().map(|a| a.name.clone()), + "author.uri" => item.authors.first().and_then(|a| a.uri.clone()), + _ => None, + } } else { match field { - "title" => item.title().map(|s| s.to_string()), - "link" => item.link().map(|s| s.to_string()), - "content" => item.content().or(item.description()).map(|s| s.to_string()), - "author" => item.author().map(|s| s.to_string()), - "pubDate" => item.pub_date().map(|s| s.to_string()), + "title" => item.title.as_ref().map(|t| t.content.clone()), + "link" => item.links.first().map(|l| l.href.clone()), + "content" => item.content.as_ref().and_then(|c| c.body.clone()) + .or_else(|| item.summary.as_ref().map(|s| s.content.clone())), + "author" => item.authors.first().map(|a| a.name.clone()), + "pubDate" => item.published.map(|d| d.to_rfc3339()), _ => None, } } } -fn resolve_path(item: &rss::Item, path: &str) -> Option { - // This is a simplified version. The TS version used a more complex object traversal. - // rss-rs doesn't expose a raw JSON-like structure easily for all extensions. - // We'll handle common cases or use extensions() if needed. - - match path { - "title" => item.title().map(|s| s.to_string()), - "link" => item.link().map(|s| s.to_string()), - "description" => item.description().map(|s| s.to_string()), - "content" => item.content().map(|s| s.to_string()), - "pubDate" => item.pub_date().map(|s| s.to_string()), - "dc:creator" => item.dublin_core_ext() - .and_then(|dc| dc.creators().first()) - .map(|s| s.to_string()), - _ => { - // Check extensions - for (ns, ext) in item.extensions() { - if path.starts_with(ns) { - let local_name = &path[ns.len()+1..]; - if let Some(v) = ext.get(local_name) { - if let Some(first) = v.first() { - return first.value().map(|s| s.to_string()); - } - } - } - } - None - } - } -} - -pub fn build_content(config: &RssConfig, item: &rss::Item) -> String { +pub fn build_content(config: &RssConfig, item: &Entry) -> String { let mut parts = Vec::new(); let ht = HtmlToMarkdown::new(); @@ -81,7 +60,7 @@ pub fn build_content(config: &RssConfig, item: &rss::Item) -> String { let content = get_field_value(item, config, "content"); let author = get_field_value(item, config, "author"); let author_link = get_field_value(item, config, "authorLink"); - let pub_date = get_field_value(item, config, "pubDate"); + let pub_date = item.published; if let Some(l) = link.as_ref() { parts.push(format!("# {} | [{}](<{}>)", config.emoji, title, l)); @@ -103,11 +82,7 @@ pub fn build_content(config: &RssConfig, item: &rss::Item) -> String { } if let Some(pd) = pub_date { - if let Ok(dt) = chrono::DateTime::parse_from_rfc2822(&pd) { - parts.push(format!("\n-# 🕐 ", dt.timestamp())); - } else if let Ok(dt) = chrono::DateTime::parse_from_rfc3339(&pd) { - parts.push(format!("\n-# 🕐 ", dt.timestamp())); - } + parts.push(format!("\n-# 🕐 ", pd.timestamp())); } let joined = parts.join("\n");