pcs-website-test/lektor/lektordata/scripts/calendar-fetcher.py
2025-01-09 16:23:01 +01:00

125 lines
No EOL
3.7 KiB
Python

from datetime import datetime, date, timedelta, timezone
import recurring_ical_events
import requests
from copy import deepcopy
from icalendar import Calendar, Event
import locale
import sys
#This is duplicated code from calendar-fetcher-main.py
def split_multiday_events(events):
"""
Split multi-day events into separate daily events.
Args:
events: Iterator of iCal events
Returns:
List of events where multi-day events are split into daily events
"""
split_events = []
for event in events:
# Get start and end dates
start = event.get('dtstart').dt
end = event.get('dtend').dt if event.get('dtend') else start
# Convert datetime to date if needed
if isinstance(start, datetime):
start = start.date()
if isinstance(end, datetime):
end = end.date()
# If it's a single day event or not a date/datetime, add as is
if not isinstance(start, date) or not isinstance(end, date) or start == end:
split_events.append(event)
continue
# For multi-day events, create separate events for each day
current_date = start
while current_date < end:
# Create a copy of the original event
daily_event = Event()
for key in event:
daily_event[key] = deepcopy(event[key])
# Update the date for this instance
daily_event['dtstart'].dt = current_date
if 'dtend' in daily_event:
daily_event['dtend'].dt = current_date + timedelta(days=1)
split_events.append(daily_event)
current_date += timedelta(days=1)
return split_events
def fetch_upcoming_events(ics_url):
# Set German locale
locale.setlocale(locale.LC_TIME, 'de_DE.UTF-8')
response = requests.get(ics_url)
calendar = Calendar.from_ical(response.content)
now=datetime.now(timezone.utc) # + timedelta(days=1)
raw_events = split_multiday_events(recurring_ical_events.of(calendar).after(now))
now_date = now.date()
now_datetime = now
events = []
for raw_event in raw_events:
start = raw_event.get('dtstart').dt
if isinstance(start, datetime):
my_now = now_datetime
else:
my_now = now_date
if start >= my_now:
events.append(raw_event)
for event in events:
start = event.get('dtstart').dt
out_summary = event.get('summary')
location = event.get('location', 'No location specified')
out_startdate = start.strftime("%a. %-d. %B %Y")
# Format output based on whether it's an all-day event
if isinstance(start, date) and not isinstance(start, datetime):
out_starttime = "&nbsp;"
else:
out_starttime = start.strftime('%-H:%M')
if location != 'No location specified':
out_location = location
else:
out_location = "&nbsp;"
print(f"* <div>{out_summary}</div>&nbsp;")
print(f" * <div>{out_startdate}</div>&nbsp;")
print(f" * <div>{out_starttime}</div>&nbsp;")
print(f" * <div>{out_location}</div>&nbsp;")
if __name__ == "__main__":
ics_url = sys.argv[1]
# ics_url = "https://backoffice.pc-stammertal.ch/remote.php/dav/public-calendars/RqLX5wj25aY6cpnP?export"
print("_model: page")
print("---")
print("title: Termine")
print("---")
print("body:")
print("")
fetch_upcoming_events(ics_url)
print("")
print("---")
print("_template: page.html")
print("")
print("")