initial version
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/target
|
1605
Cargo.lock
generated
Normal file
1605
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
10
Cargo.toml
Normal file
10
Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "html_to_ics"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
regex = "1.10"
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
uuid = { version = "1.6", features = ["v4"] }
|
||||
reqwest = { version = "0.11", features = ["blocking"] }
|
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
curl -s -H 'Cookie: riscms_muellkalender=11443990_985180' \
|
||||
'https://www.luftenberg.at/system/web/kalender.aspx?sprache=1&menuonr=226723085&typids=227710683,227710684'
|
||||
|
101
src/main.rs
Normal file
101
src/main.rs
Normal file
@@ -0,0 +1,101 @@
|
||||
use regex::Regex;
|
||||
use chrono::{NaiveDate, Utc};
|
||||
use uuid::Uuid;
|
||||
use std::process;
|
||||
|
||||
fn parse_german_date(date_str: &str) -> Option<NaiveDate> {
|
||||
NaiveDate::parse_from_str(date_str, "%d.%m.%Y").ok()
|
||||
}
|
||||
|
||||
fn create_ics_event(date: NaiveDate, title: &str, event_type: &str) -> String {
|
||||
let uid = Uuid::new_v4();
|
||||
let date_str = date.format("%Y%m%d");
|
||||
let timestamp = Utc::now().format("%Y%m%dT%H%M%SZ");
|
||||
|
||||
format!(
|
||||
"BEGIN:VEVENT\n\
|
||||
DTSTART;VALUE=DATE:{date_str}\n\
|
||||
DTEND;VALUE=DATE:{date_str}\n\
|
||||
DTSTAMP:{timestamp}\n\
|
||||
UID:{uid}\n\
|
||||
CREATED:{timestamp}\n\
|
||||
DESCRIPTION:{event_type}\n\
|
||||
LAST-MODIFIED:{timestamp}\n\
|
||||
LOCATION:Luftenberg an der Donau\n\
|
||||
SEQUENCE:0\n\
|
||||
STATUS:CONFIRMED\n\
|
||||
SUMMARY:{title}\n\
|
||||
TRANSP:TRANSPARENT\n\
|
||||
END:VEVENT"
|
||||
)
|
||||
}
|
||||
|
||||
fn fetch_waste_dates() -> Result<String, Box<dyn std::error::Error>> {
|
||||
let client = reqwest::blocking::Client::new();
|
||||
|
||||
let response = client
|
||||
.get("https://www.luftenberg.at/system/web/kalender.aspx?sprache=1&menuonr=226723085&typids=227710683,227710684")
|
||||
.header("Cookie", "riscms_muellkalender=11443990_985180")
|
||||
.send()?;
|
||||
|
||||
Ok(response.text()?)
|
||||
}
|
||||
|
||||
fn html_to_ics(html_content: &str) -> Result<String, &'static str> {
|
||||
let pattern = Regex::new(
|
||||
r#"td_kal.*?(\d{2}\.\d{2}\.\d{4}).*?<a[^>]*>([^<]+)</a>.*?<span>([^<]+)</span>"#
|
||||
).unwrap();
|
||||
|
||||
let mut ics_content = String::from(
|
||||
"BEGIN:VCALENDAR\n\
|
||||
VERSION:2.0\n\
|
||||
PRODID:-//Luftenberg//Waste Collection Calendar//EN\n\
|
||||
CALSCALE:GREGORIAN\n\
|
||||
METHOD:PUBLISH\n\
|
||||
X-WR-CALNAME:Abfalltermine Luftenberg\n\
|
||||
X-WR-CALDESC:Waste collection dates for Luftenberg an der Donau\n\
|
||||
X-WR-TIMEZONE:Europe/Vienna\n"
|
||||
);
|
||||
|
||||
let mut event_count = 0;
|
||||
|
||||
for cap in pattern.captures_iter(html_content) {
|
||||
let date_str = &cap[1];
|
||||
let title = &cap[2];
|
||||
let event_type = &cap[3];
|
||||
|
||||
if let Some(date) = parse_german_date(date_str) {
|
||||
let event = create_ics_event(date, title, event_type);
|
||||
ics_content.push_str(&event);
|
||||
ics_content.push('\n');
|
||||
event_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if event_count == 0 {
|
||||
return Err("No waste collection events found");
|
||||
}
|
||||
|
||||
ics_content.push_str("END:VCALENDAR");
|
||||
Ok(ics_content)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let html_content = match fetch_waste_dates() {
|
||||
Ok(content) => content,
|
||||
Err(e) => {
|
||||
eprintln!("Error fetching waste dates: {}", e);
|
||||
process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
let ics_output = match html_to_ics(&html_content) {
|
||||
Ok(content) => content,
|
||||
Err(e) => {
|
||||
eprintln!("Error: {}", e);
|
||||
process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
println!("{}", ics_output);
|
||||
}
|
Reference in New Issue
Block a user