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)
|