mycal.py (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | 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(): today = date.today() start_of_week = today - timedelta(days=today.weekday()) start_date = datetime.combine(start_of_week, 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) |