From aeaa6eb3a656520b3bbc2574a0d289090064a462 Mon Sep 17 00:00:00 2001 From: _ <_@_> Date: Thu, 11 Sep 2025 01:06:11 +0000 Subject: [PATCH] add RSS debug tool --- Cargo.lock | 123 ++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + README.md | 12 +++- src/main.rs | 89 ++++++++++++++++++++++------- src/wac_common_ninja.rs | 2 +- 5 files changed, 206 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b5e5799..19fd449 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -97,6 +97,19 @@ version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +[[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" @@ -259,6 +272,81 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[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", +] + +[[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", +] + +[[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", +] + +[[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", +] + +[[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" @@ -673,6 +761,12 @@ 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.0.3" @@ -872,6 +966,12 @@ dependencies = [ "tempfile", ] +[[package]] +name = "never" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c96aba5aa877601bb3f6dd6a63a969e1f82e60646e81e71b14496995e9853c91" + [[package]] name = "nom" version = "8.0.0" @@ -1052,6 +1152,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "quick-xml" +version = "0.37.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" +dependencies = [ + "encoding_rs", + "memchr", +] + [[package]] name = "quote" version = "1.0.40" @@ -1178,6 +1288,18 @@ dependencies = [ "thiserror", ] +[[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-demangle" version = "0.1.26" @@ -1877,6 +1999,7 @@ dependencies = [ "maud", "reqwest", "rrule", + "rss", "serde", "serde_json", "tokio", diff --git a/Cargo.toml b/Cargo.toml index b986352..9b506eb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ icalendar = { version = "0.17.1", features = ["chrono-tz", "parser", "serde"] } maud = "0.27.0" reqwest = "0.12.22" rrule = "0.14.0" +rss = "2.0.12" serde = { version = "1.0.219", features = ["derive"] } serde_json = "1.0.142" tokio = { version = "1.47.1", features = ["rt-multi-thread", "time"] } diff --git a/README.md b/README.md index e91a064..3fa62d4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,14 @@ -todo +# Running + +```bash +# Run autonomous forever +./wide-angle-calendar auto --config config.toml + +# Run RSS debug tool +cargo run -- debug-rss untracked/*.rss +``` + +# TODO - [ ] Rewrite README considering best practices - [ ] Add dynamic OpenGraph meta tags diff --git a/src/main.rs b/src/main.rs index b1633b3..c766a78 100644 --- a/src/main.rs +++ b/src/main.rs @@ -77,25 +77,6 @@ struct CliAuto { config: Utf8PathBuf, } -#[derive(clap::Parser)] -struct CliDebugOutput { - #[arg(long)] - config: Utf8PathBuf, -} - -#[derive(clap::Subcommand)] -enum Commands { - Auto(CliAuto), - DebugOutput(CliDebugOutput), -} - -#[derive(clap::Parser)] -#[command(version, about, long_about = None)] -struct Cli { - #[command(subcommand)] - command: Commands, -} - struct Parameters { /// Events before this time will be ignored if they cause an error ignore_before: DateTime, @@ -484,6 +465,12 @@ fn main_auto(cli: CliAuto) -> Result<()> { } } +#[derive(clap::Parser)] +struct CliDebugOutput { + #[arg(long)] + config: Utf8PathBuf, +} + fn main_debug_output(cli: CliDebugOutput) -> Result<()> { tracing_subscriber::fmt::init(); tracing::info!("Started tracing"); @@ -500,11 +487,75 @@ fn main_debug_output(cli: CliDebugOutput) -> Result<()> { Ok(()) } +#[derive(clap::Parser)] +struct CliDebugRss { + paths: Vec, +} + +/// Wraps rss::Item in our own type suitable for merging +struct RssItem { + channel_title: String, + date: chrono::DateTime, + inner: rss::Item, +} + +fn main_debug_rss(cli: CliDebugRss) -> Result<()> { + let mut items = Vec::new(); + + for path in &cli.paths { + let s = std::fs::read(path)?; + let channel = rss::Channel::read_from(std::io::BufReader::new(std::io::Cursor::new(s)))?; + + let channel_title = channel.title.clone(); + for item in channel.into_items() { + let date = chrono::DateTime::parse_from_rfc2822( + item.pub_date() + .as_ref() + .context("Every RSS Item should have a pub_date")?, + )?; + + let item = RssItem { + channel_title: channel_title.clone(), + date, + inner: item, + }; + + items.push(item); + } + } + + items.sort_by_key(|item| item.date); + + for item in &items { + println!("{}", item.channel_title); + println!("{:?}", item.inner.title); + println!("{}", item.date.to_rfc3339()); + println!(); + } + + Ok(()) +} + +#[derive(clap::Subcommand)] +enum Commands { + Auto(CliAuto), + DebugOutput(CliDebugOutput), + DebugRss(CliDebugRss), +} + +#[derive(clap::Parser)] +#[command(version, about, long_about = None)] +struct Cli { + #[command(subcommand)] + command: Commands, +} + fn main() -> Result<()> { let cli = Cli::try_parse()?; match cli.command { Commands::Auto(x) => main_auto(x), Commands::DebugOutput(x) => main_debug_output(x), + Commands::DebugRss(x) => main_debug_rss(x), } } diff --git a/src/wac_common_ninja.rs b/src/wac_common_ninja.rs index 52fb1b1..f6a668d 100644 --- a/src/wac_common_ninja.rs +++ b/src/wac_common_ninja.rs @@ -14,7 +14,7 @@ struct SillyDownloadable { #[derive(Clone, Deserialize)] pub(crate) struct Config { #[serde(flatten)] - pub(crate) dl: SillyDownloadable, + dl: SillyDownloadable, #[serde(flatten)] pub(crate) ui: CalendarUi,