from icalendar.cal import Calendar, Event import requests from flask import Flask from datetime import date, datetime, timedelta, time import zoneinfo from dataclasses import dataclass from danoan.toml_dataclass import TomlDataClassIO from os import environ import calendar @dataclass class CalendarConfig(TomlDataClassIO): file: str = "" url: str = "" @dataclass class Config(TomlDataClassIO): name: str timezone: str calendar: CalendarConfig def load_config(file_path): with open(file_path, "r") as fr: return Config.read(fr) app = Flask(__name__) config = load_config(environ.get("CONFIG_FILE", "config.toml")) user_name = config.name tz = zoneinfo.ZoneInfo(config.timezone) def fetch_calendar(calendar_url): return requests.get(calendar_url).content def read_calendar_file(calendar_file): with open(calendar_file, 'rb') as f: return f.read() def get_calendar(): calendar_config = config.calendar if calendar_config.file != "": return read_calendar_file(calendar_config.file) else: if calendar_config.url != "": return fetch_calendar(calendar_config.url) raise ValueError("Calendar URL not configured.") def fixup_date(dt): if type(dt) == date: return datetime.combine(dt, time.min, tzinfo=tz) elif dt.tzinfo is None: return dt.replace(tzinfo=tz) else: return dt.astimezone(tz) @app.route('/') def index(): start_date = datetime.combine(date.today(), time.min, tzinfo=tz) end_date = start_date + timedelta(days=30) output = Calendar() output.add('prodid', '-//Calendar Anonymiser//alin.ovh//') output.add('version', '2.0') # Parse with icalendar try: input = Calendar.from_ical(get_calendar()) for component in input.walk(): if component.name == "VEVENT": dtstart = fixup_date(component.get('dtstart').dt) dtend = fixup_date(component.get('dtend', component.get('dtstart')).dt) if dtstart >= start_date and dtend <= end_date: ev = Event() ev.add('summary', f'{user_name} Busy') ev.DTSTART = dtstart ev.DTEND = dtend output.add_component(ev) return output.to_ical(), { "Content-Type": "text/plain" } except Exception as e: return f"Error parsing with icalendar: {str(e)}", 500 if __name__ == '__main__': app.run(debug=True)