#!/usr/bin/env python from datetime import datetime from flask import Flask from caldav import DAVClient, Calendar, Principal, Todo import re import configparser def parseConfig() -> tuple[str, str, str, str]: def passwordFromFile() -> str: calDavPasswordFile = config.get("calDAV", "passwordFile") with open(calDavPasswordFile, "r") as file: return file.readline().strip() config = configparser.ConfigParser() # config.read("/etc/calDAVtoCSV/config.ini") config.read("/etc/calDAVtoCSV/config.ini") calDavAddress = config.get("calDAV", "address") calDavUsername = config.get("calDAV", "username") caldavpwd = config.get("calDAV", "password", fallback=None) caldavpwd = caldavpwd if caldavpwd is not None else passwordFromFile() calDavCalendarName = config.get("calDAV", "calendarName") return calDavAddress, calDavUsername, caldavpwd, calDavCalendarName def fetch_10_next_todos_as_csv() -> str: def auth(add: str, user: str, pwd: str) -> Principal: # TODO: on the final version, fetch it locally client = DAVClient(url=add, username=user, password=pwd) principal = client.principal() return principal def get_calendar(principal: Principal, name: str) -> Calendar: calendar = principal.calendar(name=name) return calendar def filter_todos(todos: list[Todo]) -> list[Todo]: today = datetime.today().date() return [ todo for todo in todos if ( match := re.search( r"\d{4}-\d{2}-\d{2}", todo.icalendar_component["due"] ) ) and datetime.strptime(match.group(), "%Y-%m-%d").date() > today ] def todos_to_csv(todos: list[Todo]) -> str: result = "".join( f"{todo.icalendar_component['uid']},{todo.icalendar_component['summary']}\n" for todo in todos ) return result add, user, pwd, name = parseConfig() principal = auth(add, user, pwd) calendar = get_calendar(principal, name) sorted_todos = calendar.todos(sort_keys=("due")) cut_todos = sorted_todos[:10] filtered_todos = filter_todos(cut_todos) csv = todos_to_csv(filtered_todos) return csv app = Flask(__name__) @app.route("/") def send_events(): return fetch_10_next_todos_as_csv() # not suitable for production apparently, just for testing if __name__ == "__main__": app.run(host="0.0.0.0", port=8000)