From 5993a159fb766eafeb0fd7e968e3cf9a6e596e53 Mon Sep 17 00:00:00 2001 From: eclipse Date: Fri, 19 Sep 2025 11:29:36 +0200 Subject: [PATCH] switched format of events config file from INI to YAML in order to allow multiple servers/calendars --- .gitignore | 1 + README.md | 3 ++- events.example.yaml | 9 +++++++ utils/refresh_events.py | 58 +++++++++++++++++++++++++++-------------- 4 files changed, 50 insertions(+), 21 deletions(-) create mode 100644 events.example.yaml diff --git a/.gitignore b/.gitignore index 207b5c4..a193936 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ config.ini config.dev.ini config.prod.ini events.ini +events.yaml deploy.ini .venv/ .vscode/ \ No newline at end of file diff --git a/README.md b/README.md index 15db910..de4d6e4 100644 --- a/README.md +++ b/README.md @@ -24,10 +24,11 @@ Außerdem nutze ich folgende Pelican-Plugins: ### Termine -Das Script `utils/refresh-events.py` benötigt folgende Python-Packages (beide via `pip` installierbar): +Das Script `utils/refresh-events.py` benötigt folgende Python-Packages (alle via `pip` installierbar): * `caldav` * `vobject` +* `pyyaml` (bereits mit Pelican mitinstalliert) ### Bildverarbeitung diff --git a/events.example.yaml b/events.example.yaml new file mode 100644 index 0000000..f276ed3 --- /dev/null +++ b/events.example.yaml @@ -0,0 +1,9 @@ +# Credentials for extracting event data from CalDAV calendar instances vir utils/refresh_events.py +CalDAV: + servers: + - url: https://example.org/caldav/dav.php + user: spam + pass: eggs + calendar_paths: # you must omit the server part from the URI + - /calendars/spam/awesomecalendar/ + - /calendars/spam/veryawesomecalendar/ diff --git a/utils/refresh_events.py b/utils/refresh_events.py index ec86329..980bc56 100755 --- a/utils/refresh_events.py +++ b/utils/refresh_events.py @@ -10,28 +10,39 @@ import os, os.path from urllib.parse import urlparse -# find out where events.ini lives; that's the project root dir +# name of the config file +#CONFIG_FILE = "events.ini" +CONFIG_FILE = "events.yaml" + +# find out where the config file lives; that's the project root dir # check current working directory -if os.path.isfile(os.getcwd() + '/events.ini'): +if os.path.isfile(os.getcwd() + '/' + CONFIG_FILE): project_root = os.getcwd() # check this script's location dir -elif os.path.isfile(os.path.dirname(os.path.realpath(__file__)) + '/events.ini'): +elif os.path.isfile(os.path.dirname(os.path.realpath(__file__)) + '/' + CONFIG_FILE): project_root = os.path.dirname(os.path.realpath(__file__)) # check parent dir of this script's dir -elif os.path.isfile(os.path.dirname(os.path.realpath(__file__)) + '/../events.ini'): +elif os.path.isfile(os.path.dirname(os.path.realpath(__file__)) + '/../' + CONFIG_FILE): project_root = os.path.dirname(os.path.realpath(__file__)) + '/..' # OK no luck else: - print("Cannot find file 'events.ini'; aborting.") + print(f"Cannot find file config file {CONFIG_FILE} anywhere; aborting.") exit(1) -# read ini file -cp = configparser.ConfigParser() -cp.read(project_root + '/events.ini') -server_url = cp["CalDAV"]["server_url"] -cal_url = cp["CalDAV"]["cal_url"] -cal_user = cp["CalDAV"]["cal_user"] -cal_pass = cp["CalDAV"]["cal_pass"] +# read yaml config file +with open(project_root + "/" + CONFIG_FILE, 'r') as file: + config = yaml.safe_load(file) + +servers = [] +for server in config["CalDAV"]["servers"]: + servers.append({ + "url": server["url"], + "user": server["user"], + "pass": server["pass"], + "calendar_paths": server["calendar_paths"] + }) + +#print(f"servers are {servers}") #DEBUG # Category to filter events for. Only events that belong to this category will be processed. cal_category = "Veranstaltung" @@ -158,15 +169,22 @@ def refresh_events(): # create vobject calendar vcal = vobject.newFromBehavior("vcalendar") - # establish connection to caldav server - with caldav.DAVClient(url=server_url, username=cal_user, password=cal_pass) as dav_client: - # establish connection to calendar - dav_cal = dav_client.calendar(url=cal_url) + # loop over all servers from the + for server in servers: - # put all events from caldav calendar into vobject calendar - for e in dav_cal.events(): - for ev in e.vobject_instance.contents["vevent"]: - vcal.add(ev) + # establish connection to caldav server + with caldav.DAVClient(url=server["url"], username=server["user"], password=server["pass"]) as dav_client: + + # loop over calendars from this server + for cal_path in server["calendar_paths"]: + + # establish connection to calendar + dav_cal = dav_client.calendar(url=server["url"]+cal_path) + + # put all events from caldav calendar into vobject calendar + for e in dav_cal.events(): + for ev in e.vobject_instance.contents["vevent"]: + vcal.add(ev) # we only want events belonging to a specific category events = [e for e in vcal.getChildren() if "categories" in e.contents.keys() and cal_category in map(lambda x: x.value[0], e.contents["categories"])]