server: add Updated invitation parsing support
This commit is contained in:
@@ -149,7 +149,7 @@ pub fn extract_calendar_metadata_from_mail(
|
||||
|
||||
// Fallback extraction: if iCal did not provide metadata, extract from subject/body before generating fallback HTML
|
||||
if body_html.is_none() {
|
||||
// Try to extract summary from subject (e.g., "New event: <summary> @ ...")
|
||||
// Try to extract summary from subject (e.g., "New event: <summary> @ ..." or "Updated invitation: <summary> @ ...")
|
||||
if summary.is_none() {
|
||||
if let Some(subject) = m.headers.get_first_value("Subject") {
|
||||
if let Some(caps) = regex::Regex::new(r"New event: ([^@]+) @")
|
||||
@@ -162,14 +162,19 @@ pub fn extract_calendar_metadata_from_mail(
|
||||
.and_then(|re| re.captures(&subject))
|
||||
{
|
||||
summary = Some(caps[1].trim().to_string());
|
||||
} else if let Some(caps) = regex::Regex::new(r"Updated invitation: ([^@]+) @")
|
||||
.ok()
|
||||
.and_then(|re| re.captures(&subject))
|
||||
{
|
||||
summary = Some(caps[1].trim().to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
// Try to extract start/end dates from subject
|
||||
if start_date.is_none() || end_date.is_none() {
|
||||
if let Some(subject) = m.headers.get_first_value("Subject") {
|
||||
// Pattern: New event: Dentist appt @ Tue Sep 23, 2025 3pm - 4pm (PDT) (tconvertino@gmail.com)
|
||||
if let Some(caps) = regex::Regex::new(r"New event: [^@]+@ ([A-Za-z]{3}) ([A-Za-z]{3}) (\d{1,2}), (\d{4}) (\d{1,2})(?::(\d{2}))? ?([ap]m) ?- ?(\d{1,2})(?::(\d{2}))? ?([ap]m)").ok().and_then(|re| re.captures(&subject)) {
|
||||
// Pattern: @ Tue Sep 23, 2025 3pm - 4pm (works for New event, Invitation, Updated invitation, etc.)
|
||||
if let Some(caps) = regex::Regex::new(r"@ ([A-Za-z]{3}) ([A-Za-z]{3}) (\d{1,2}), (\d{4}) (\d{1,2})(?::(\d{2}))? ?([ap]m) ?- ?(\d{1,2})(?::(\d{2}))? ?([ap]m)").ok().and_then(|re| re.captures(&subject)) {
|
||||
let month = &caps[2];
|
||||
let day = &caps[3];
|
||||
let year = &caps[4];
|
||||
@@ -2606,6 +2611,29 @@ mod tests {
|
||||
assert!(html.contains(r#"data-event-day="2026-01-18""#), "Jan 18 should be highlighted");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn google_calendar_email_5_updated_invitation() {
|
||||
use mailparse::parse_mail;
|
||||
let raw_email = include_str!("../../server/testdata/google-calendar-example-5.eml");
|
||||
let parsed = parse_mail(raw_email.as_bytes()).expect("parse_mail");
|
||||
let mut part_addr = vec![];
|
||||
let body = extract_body(&parsed, &mut part_addr).expect("extract_body");
|
||||
let meta = extract_calendar_metadata_from_mail(&parsed, &body);
|
||||
// Assert detection as Google Calendar
|
||||
assert!(meta.is_google_calendar_event);
|
||||
// Assert metadata extraction for updated invitation
|
||||
assert_eq!(meta.summary, Some("painting class".to_string()));
|
||||
assert_eq!(meta.organizer, Some("tconvertino@gmail.com".to_string()));
|
||||
// Dates: Thursday Feb 12, 2026 7pm - 9pm (same day event with time)
|
||||
assert_eq!(meta.start_date, Some("20260212".to_string()));
|
||||
assert_eq!(meta.end_date, Some("20260212".to_string()));
|
||||
// Assert ical summary is rendered and shows Feb 12 highlighted
|
||||
let html = meta.body_html.expect("body_html");
|
||||
println!("Rendered HTML: {}", html);
|
||||
assert!(html.contains("ical-flex"), "Calendar widget should be rendered");
|
||||
assert!(html.contains(r#"data-event-day="2026-02-12""#), "Feb 12 should be highlighted");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recurring_event_rrule_metadata_and_highlight() {
|
||||
use super::render_ical_summary;
|
||||
|
||||
Reference in New Issue
Block a user