From a4e4c89e154316ebd9d4a60352eddc8544ef2f4c Mon Sep 17 00:00:00 2001
From: _ <_@_>
Date: Tue, 12 Aug 2025 22:11:34 +0000
Subject: [PATCH] cosmetic updates
---
README.md | 27 ++++++-----------------
src/main.rs | 62 +++++++++++++++++++++++++++++++++++++++++++----------
2 files changed, 58 insertions(+), 31 deletions(-)
diff --git a/README.md b/README.md
index bc5bb48..e91a064 100644
--- a/README.md
+++ b/README.md
@@ -1,21 +1,8 @@
-Merges multiple ics files into one stream
+todo
-Try `cargo run -- ics-debug --tz America/New_York sample-data/nascar.ics sample-data/formula-1.ics`
-
-Expected output is the next month or so of NASCAR and Formula 1 racing:
-
-```
-2025-08-03 00:00:00 EDT - NASCAR Cup - Iowa Corn 350
-2025-08-03 00:00:00 EDT - F1 - Lenovo Hungarian Grand Prix
-2025-08-10 00:00:00 EDT - NASCAR Cup - Go Bowling At The Glen (Watkins Glen)
-2025-08-16 00:00:00 EDT - NASCAR Cup - Cook Out 400 (Richmond)
-2025-08-23 00:00:00 EDT - NASCAR Cup - Coke Zero Sugar 400 (Daytona)
-2025-08-31 00:00:00 EDT - NASCAR Cup -Playoff- Southern 500 (Darlington)
-2025-08-31 00:00:00 EDT - F1 - Heineken Dutch Grand Prix
-2025-09-07 00:00:00 EDT - NASCAR Cup -Playoff- Enjoy Illinois 300 (Gateway)
-2025-09-07 00:00:00 EDT - F1 - Gran Premio d'Italia
-2025-09-13 00:00:00 EDT - NASCAR Cup -Playoff- Bass Pro Shops Night Race (Bristol)
-2025-09-21 00:00:00 EDT - F1 - Qatar Airways Azerbaijan Grand Prix
-```
-
-If the sample data is old, try the iCal links from , e.g. `curl https://calendar.google.com/calendar/ical/fa9bjl6tu13dd10b066stoo5do%40group.calendar.google.com/public/basic.ics > sample-data/formula-1.ics`
+- [ ] Rewrite README considering best practices
+- [ ] Add dynamic OpenGraph meta tags
+- [ ] HTML templating for faster styling
+- [ ] Maybe put descriptions behind `details` tag
+- [ ] Publish ICS to subscribe to?
+- [ ] systemd unit or something
diff --git a/src/main.rs b/src/main.rs
index ab092e7..44ff1a4 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -15,7 +15,7 @@ struct ConfigIcal {
google_id: Option,
/// A canonical webpage we can direct users to
- html_url: url::Url,
+ html_url: Option,
/// Very short name for putting on each event
short_name: String,
@@ -26,10 +26,16 @@ struct ConfigIcal {
#[derive(Deserialize)]
struct ConfigOutput {
+ /// Used as the OpenGraph description in meta tags
+ description: String,
+
/// Timezone to use for output (e.g. "Antarctica/South_Pole")
///
///
timezone: chrono_tz::Tz,
+
+ /// Used as the page title and OpenGraph title in meta tags
+ title: String,
}
#[derive(Deserialize)]
@@ -359,7 +365,11 @@ fn process_data(data: &Data, now: DateTime) -> Result) -> Result<()> {
+fn output_html(
+ config: &ConfigOutput,
+ instances: &[EventWithUrl],
+ now: DateTime,
+) -> Result<()> {
let today = now.date_naive();
let mut last_month_printed: Option = None;
let mut last_date_printed = None;
@@ -437,10 +447,16 @@ fn output_html(instances: &[EventWithUrl], now: DateTime) -> Resu
li class="past" { (time) " - " (summary) }
});
} else {
+ let calendar_link = if let Some(html_url) = &ei.calendar.html_url {
+ maud::html! { a href=(html_url) { (ei.calendar.short_name) } }
+ } else {
+ maud::html! { (ei.calendar.short_name)}
+ };
+
day_list.push(maud::html! {
li { p { (time) " - " (summary) }
ul {
- li { a href=(ei.calendar.html_url) { (ei.calendar.short_name) } }
+ li { (calendar_link) " calendar" }
@if let Some(location) = location {
li { "Location: " (location) }
}
@@ -476,12 +492,33 @@ fn output_html(instances: &[EventWithUrl], now: DateTime) -> Resu
}
"#;
+
+ let description = &config.description;
+ let title = &config.title;
+
let s = maud::html! {
- (maud::PreEscaped(css))
- h1 { "Wide-Angle Calendar" }
- p { "Written at: " (now.to_rfc3339()) }
- @for entry in html_list {
- (entry)
+ html lang="en" {
+ head {
+ meta http-equiv="Content-Type" content="text/html; charset=utf-8" {}
+ meta name="viewport" content="width=device-width, initial-scale=1" {}
+ (maud::PreEscaped(css))
+
+ meta property="og:locale" content="en" {}
+ meta property="og:type" content="website" {}
+
+ meta property="description" content=(description) {}
+ meta property="og:description" content=(description) {}
+
+ title { (title) }
+ met property="og:title" content=(title) {}
+ }
+ body {
+ h1 { (title) }
+ p { "Written at: " (now.to_rfc3339()) }
+ @for entry in html_list {
+ (entry)
+ }
+ }
}
}
.into_string();
@@ -525,10 +562,13 @@ async fn do_everything(cli: &CliAuto) -> Result<()> {
let tz = &config.output.timezone;
let now = Utc::now().with_timezone(tz);
let instances = process_data(&data, now)?;
- output_html(&instances, now)?;
+ output_html(&config.output, &instances, now)?;
Ok(())
}
+/// Seconds to sleep between auto cycles
+const SLEEP_SECS: u64 = 9000;
+
fn main_auto(cli: CliAuto) -> Result<()> {
tracing_subscriber::fmt::init();
loop {
@@ -539,7 +579,7 @@ fn main_auto(cli: CliAuto) -> Result<()> {
})?;
rt.shutdown_timeout(Duration::from_secs(10));
tracing::info!("The service is eeping");
- std::thread::sleep(Duration::from_secs(5823));
+ std::thread::sleep(Duration::from_secs(SLEEP_SECS));
}
}
@@ -552,7 +592,7 @@ fn main_ics_debug(cli: CliIcsDebug) -> Result<()> {
let tz = &config.output.timezone;
let now = Utc::now().with_timezone(tz);
let instances = process_data(&data, now)?;
- output_html(&instances, now)?;
+ output_html(&config.output, &instances, now)?;
Ok(())
}