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 | import os from icalendar.cal import Calendar, Event import requests from flask import Flask from datetime import date, datetime, timedelta, time import zoneinfo app = Flask(__name__) user_name = (os.environ.get("NAME") or os.environ.get("USER") or "unknown").title() tz = zoneinfo.ZoneInfo(os.environ.get("TZ") or "Europe/Berlin") 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(): file = os.environ.get('CALENDAR_FILE') if file is not None: return read_calendar_file(file) else: calendar_url = os.environ.get("CALENDAR_URL") if calendar_url is None: raise ValueError("CALENDAR_URL not set.") return fetch_calendar(calendar_url) 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) |