more chatgpt

This commit is contained in:
lda committed 2025-05-16 04:12:33 +07:00
1 parent c55867a6ee
commit 4deb4cee6d
3 files changed
+85 -41

No files matched your search

Generated
+1
View File
@@ -350,6 +350,7 @@ version = "0.1.0"
dependencies = [
"actix-cors",
"actix-web",
"chrono",
"icalendar",
"regex",
"reqwest",
+1
View File
@@ -7,6 +7,7 @@ publish = ["gitea"]
[dependencies]
actix-cors = "0.7"
actix-web = "4"
chrono = "0.4.41"
icalendar = "0.16.13"
regex = "1.11.1"
reqwest = {version = "0.12", features = ["blocking"]}
+83 -41
View File
@@ -1,51 +1,94 @@
use actix_cors::Cors;
use actix_web::{App, HttpResponse, HttpServer, Responder, get, http::header};
use icalendar::{
Calendar, CalendarComponent, Component,
parser::{read_calendar, read_calendar_simple},
};
use actix_web::{App, HttpResponse, HttpServer, Responder, get, http::header, web};
use chrono::{NaiveDate, TimeDelta};
use icalendar::{Calendar, CalendarComponent, Component};
use regex::Regex;
use reqwest::Client;
const ICS_URL: &str = "https://calendar.google.com/calendar/ical/i7p4ol56gi8sqe0dq7uc3m0o4c%40group.calendar.google.com/public/basic.ics";
const REGEX_PATTERN: &str = r"(CLASS 1|G1)";
#[get("/filtered-ics")]
async fn filtered_ics() -> impl Responder {
match fetch_and_filter_calendar(ICS_URL, REGEX_PATTERN).await {
Ok(ics_content) => HttpResponse::Ok()
.content_type("text/calendar")
.body(ics_content),
Err(err_msg) => HttpResponse::InternalServerError().body(err_msg),
}
}
async fn fetch_and_filter_calendar(url: &str, pattern: &str) -> Result<String, String> {
let body = fetch_ics_content(url).await?;
let calendar = parse_calendar(&body)?;
let filtered_calendar = filter_events(calendar, pattern)?;
Ok(serialize_calendar(filtered_calendar))
}
async fn fetch_ics_content(url: &str) -> Result<String, &str> {
async fn filtered_ics(now: web::Data<NaiveDate>) -> impl Responder {
let now: NaiveDate = **now;
let client = Client::new();
let response = client
.get(url)
.send()
.await
.map_err(|_| "Failed to fetch ICS file")?;
response
.text()
.await
.map_err(|_| "Failed to read response body")
let ics_url = ICS_URL;
// Fetch the .ics content
let response = match client.get(ics_url).send().await {
Ok(resp) => resp,
Err(e) => return HttpResponse::BadGateway().body(format!("Failed to fetch ICS file: {e}")),
};
let body = match response.text().await {
Ok(text) => text,
Err(e) => {
return HttpResponse::InternalServerError()
.body(format!("Failed to read response body: {e}"));
}
};
// Parse the .ics content
let calendar = match body.parse::<Calendar>() {
Ok(cal) => cal,
Err(e) => {
return HttpResponse::InternalServerError()
.body(format!("Failed to parse ICS file: {e}"));
}
};
let start_date = now - TimeDelta::days(365);
let end_date = now + TimeDelta::days(365);
// Filter events by summary and date range
let filtered_events = filter_events_by_date_and_regex(calendar, start_date, end_date);
// Create a new calendar with filtered events
let filtered_calendar = Calendar {
components: filtered_events,
..Default::default()
};
// Serialize the filtered calendar
let ics_output = filtered_calendar.to_string();
HttpResponse::Ok()
.content_type("text/calendar")
.body(ics_output)
}
fn parse_calendar(content: &str) -> Result<Calendar, &str> {
read_calendar(content)
.map(Calendar::from)
.map_err(|_| "Failed to parse ICS file")
fn filter_events_by_date_and_regex(
calendar: Calendar,
// pattern: &str,
start_date: NaiveDate,
end_date: NaiveDate,
) -> Vec<CalendarComponent> {
// let summary_filter = Regex::new(pattern).unwrap();
calendar
.components
.into_iter()
.filter_map(|component| {
let CalendarComponent::Event(event) = component else {
return Some(component);
};
let start = event.get_start()?.date_naive();
if start < start_date || start > end_date {
return None;
}
let summary = event.get_summary()?;
if summary.contains("CLASS 2") || (2..=6).any(|c| summary.contains(&format!("G{c}"))) {
// not perfect...
None
} else {
Some(CalendarComponent::Event(event))
}
})
.collect()
}
#[allow(dead_code)]
fn filter_events(calendar: Calendar, pattern: &str) -> Result<Calendar, String> {
let summary_filter = Regex::new(pattern).map_err(|_| "Invalid regex pattern")?;
let filtered_components: Vec<CalendarComponent> = calendar
@@ -69,10 +112,6 @@ fn filter_events(calendar: Calendar, pattern: &str) -> Result<Calendar, String>
})
}
fn serialize_calendar(calendar: Calendar) -> String {
calendar.to_string()
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
@@ -81,7 +120,10 @@ async fn main() -> std::io::Result<()> {
.allowed_methods(vec!["GET"])
.allowed_headers(vec![header::CONTENT_TYPE])
.max_age(3600);
App::new().wrap(cors).service(filtered_ics)
App::new()
.wrap(cors)
.app_data(web::Data::new(chrono::Local::now().date_naive())) // how to freeze date
.service(filtered_ics)
})
.bind(("127.0.0.1", 8080))?
.run()