""" Take existing calendar and update it slightly """ from datetime import date, datetime, time, timedelta import requests from flask import Flask, Response, request, make_response from icalendar import Calendar, Event from werkzeug.middleware.proxy_fix import ProxyFix import logging 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: logging.warning("%s returned a %d", orig.request.url, orig.status_code) return make_response(orig.text, 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"}, )