all repos — mycal @ 56e04818a38a01991561ee774d7e67009bbaf2ab

private calendar anonymiser

export free/busy components instead of events

Alan Pearce
commit

56e04818a38a01991561ee774d7e67009bbaf2ab

parent

3dca02155b5db16e82f5de990fa1324cc908f71d

1 file changed, 21 insertions(+), 4 deletions(-)

changed files
M mycal.pymycal.py
@@ -1,12 +1,13 @@
from icalendar.cal import Calendar, FreeBusy +import icalendar + import requests from flask import Flask -from datetime import date, datetime, timedelta, time +from datetime import date, datetime, timedelta, time, timezone import zoneinfo from dataclasses import dataclass from danoan.toml_dataclass import TomlDataClassIO from os import environ -import calendar @dataclass class CalendarConfig(TomlDataClassIO):
@@ -51,6 +52,13 @@ return dt.replace(tzinfo=tz)
else: return dt.astimezone(tz) +def to_utc(dt): + return dt.astimezone(tz=timezone.utc) + +def looks_tentative(component): + summary = str(component.get('summary')) + return component.get('status') == 'TENTATIVE' or 'TBD' in summary or summary.endswith("?") + @app.route(f'/{str.lower(config.name)}.ics') def index(): today = date.today()
@@ -69,12 +77,21 @@ 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) + dtstamp = fixup_date(component.get('dtstamp').dt) if dtstart >= start_date and dtend <= end_date: - busy = FreeBusy() + busy = FreeBusy(uid=component.get('uid')) + vp = icalendar.prop.vPeriod([ to_utc(d) for d in [dtstart, dtend] ]) + + if looks_tentative(component): + vp.FBTYPE = icalendar.enums.FBTYPE.BUSY_TENTATIVE + else: + vp.FBTYPE = icalendar.enums.FBTYPE.BUSY_UNAVAILABLE + + busy.add('freebusy', vp) busy.add('summary', f'{config.name} Busy') - busy.uid = component.get('uid') busy.add('dtstart', dtstart) busy.add('dtend', dtend) + busy.add('dtstamp', dtstamp) output.add_component(busy) return output.to_ical(), { "Content-Type": "text/plain" } except Exception as e: