add RSS debug tool

This commit is contained in:
_ 2025-09-11 01:06:11 +00:00
parent 6daa02e8ad
commit aeaa6eb3a6
5 changed files with 206 additions and 21 deletions

123
Cargo.lock generated
View file

@ -97,6 +97,19 @@ version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" 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]] [[package]]
name = "atomic-waker" name = "atomic-waker"
version = "1.1.2" version = "1.1.2"
@ -259,6 +272,81 @@ version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 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]] [[package]]
name = "displaydoc" name = "displaydoc"
version = "0.2.5" version = "0.2.5"
@ -673,6 +761,12 @@ dependencies = [
"zerovec", "zerovec",
] ]
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]] [[package]]
name = "idna" name = "idna"
version = "1.0.3" version = "1.0.3"
@ -872,6 +966,12 @@ dependencies = [
"tempfile", "tempfile",
] ]
[[package]]
name = "never"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c96aba5aa877601bb3f6dd6a63a969e1f82e60646e81e71b14496995e9853c91"
[[package]] [[package]]
name = "nom" name = "nom"
version = "8.0.0" version = "8.0.0"
@ -1052,6 +1152,16 @@ dependencies = [
"version_check", "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]] [[package]]
name = "quote" name = "quote"
version = "1.0.40" version = "1.0.40"
@ -1178,6 +1288,18 @@ dependencies = [
"thiserror", "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]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.26" version = "0.1.26"
@ -1877,6 +1999,7 @@ dependencies = [
"maud", "maud",
"reqwest", "reqwest",
"rrule", "rrule",
"rss",
"serde", "serde",
"serde_json", "serde_json",
"tokio", "tokio",

View file

@ -14,6 +14,7 @@ icalendar = { version = "0.17.1", features = ["chrono-tz", "parser", "serde"] }
maud = "0.27.0" maud = "0.27.0"
reqwest = "0.12.22" reqwest = "0.12.22"
rrule = "0.14.0" rrule = "0.14.0"
rss = "2.0.12"
serde = { version = "1.0.219", features = ["derive"] } serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1.0.142" serde_json = "1.0.142"
tokio = { version = "1.47.1", features = ["rt-multi-thread", "time"] } tokio = { version = "1.47.1", features = ["rt-multi-thread", "time"] }

View file

@ -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 - [ ] Rewrite README considering best practices
- [ ] Add dynamic OpenGraph meta tags - [ ] Add dynamic OpenGraph meta tags

View file

@ -77,25 +77,6 @@ struct CliAuto {
config: Utf8PathBuf, 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 { struct Parameters {
/// Events before this time will be ignored if they cause an error /// Events before this time will be ignored if they cause an error
ignore_before: DateTime<chrono_tz::Tz>, ignore_before: DateTime<chrono_tz::Tz>,
@ -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<()> { fn main_debug_output(cli: CliDebugOutput) -> Result<()> {
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
tracing::info!("Started tracing"); tracing::info!("Started tracing");
@ -500,11 +487,75 @@ fn main_debug_output(cli: CliDebugOutput) -> Result<()> {
Ok(()) Ok(())
} }
#[derive(clap::Parser)]
struct CliDebugRss {
paths: Vec<Utf8PathBuf>,
}
/// Wraps rss::Item in our own type suitable for merging
struct RssItem {
channel_title: String,
date: chrono::DateTime<chrono::FixedOffset>,
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<()> { fn main() -> Result<()> {
let cli = Cli::try_parse()?; let cli = Cli::try_parse()?;
match cli.command { match cli.command {
Commands::Auto(x) => main_auto(x), Commands::Auto(x) => main_auto(x),
Commands::DebugOutput(x) => main_debug_output(x), Commands::DebugOutput(x) => main_debug_output(x),
Commands::DebugRss(x) => main_debug_rss(x),
} }
} }

View file

@ -14,7 +14,7 @@ struct SillyDownloadable {
#[derive(Clone, Deserialize)] #[derive(Clone, Deserialize)]
pub(crate) struct Config { pub(crate) struct Config {
#[serde(flatten)] #[serde(flatten)]
pub(crate) dl: SillyDownloadable, dl: SillyDownloadable,
#[serde(flatten)] #[serde(flatten)]
pub(crate) ui: CalendarUi, pub(crate) ui: CalendarUi,