ical_offset/main.py

79 lines
2.4 KiB
Python

"""
Take existing calendar and update it slightly
"""
from datetime import date, datetime, time, timedelta
import requests
from flask import Flask, Response, request
from icalendar import Calendar, Event
from werkzeug.middleware.proxy_fix import ProxyFix
app = Flask(__name__)
app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1) # type: ignore[assignment]
@app.route("/", methods=["get"])
def process() -> Response:
"""
Fetch ICS url and convert from Events to Todos
Returns:
Response: ical response
"""
# Fetch existing calendar
orig = requests.get(request.args["url"], timeout=30)
days = int(request.args.get("days", "0"))
hours = int(request.args.get("hours", "0"))
mins = int(request.args.get("mins", "0"))
if orig.status_code != 200:
return Response(orig.text, headers=orig.headers, status=orig.status_code)
orig_cal = Calendar.from_ical(orig.text)
cal = Calendar()
cal.add("version", "2.0")
cal.add(
"prodid",
"-//Scott Wallace//event2task//EN",
)
for component in orig_cal.subcomponents:
if isinstance(component, Event):
entry = Event()
entry.add("description", component["description"])
entry.add("dtstamp", component["dtstamp"])
if days or hours or mins:
start = component.decoded("dtstart")
end = component.decoded("dtend")
if isinstance(start, date):
entry.add(
"dtstart",
datetime.combine(start, time(0))
+ timedelta(days=days, hours=hours, minutes=mins),
)
if isinstance(end, date):
entry.add(
"dtend",
datetime.combine(end, time(0))
+ timedelta(days=days, hours=hours, minutes=mins),
)
if not entry.get("dtstart"):
entry.add("dtstart", component["dtstart"])
if not entry.get("dtend"):
entry.add("dtend", component["dtend"])
entry.add("summary", component["summary"])
entry.add("uid", component["uid"])
cal.add_component(entry)
return Response(
cal.to_ical().decode().replace("\\r\\n", "\n").strip(),
headers={"content-type": "text/calendar; charset=UTF-8"},
)