switched format of events config file from INI to YAML in order to allow multiple servers/calendars

This commit is contained in:
eclipse 2025-09-19 11:29:36 +02:00
parent 91ec700723
commit 5993a159fb
4 changed files with 50 additions and 21 deletions

1
.gitignore vendored
View File

@ -8,6 +8,7 @@ config.ini
config.dev.ini config.dev.ini
config.prod.ini config.prod.ini
events.ini events.ini
events.yaml
deploy.ini deploy.ini
.venv/ .venv/
.vscode/ .vscode/

View File

@ -24,10 +24,11 @@ Außerdem nutze ich folgende Pelican-Plugins:
### Termine ### 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` * `caldav`
* `vobject` * `vobject`
* `pyyaml` (bereits mit Pelican mitinstalliert)
### Bildverarbeitung ### Bildverarbeitung

9
events.example.yaml Normal file
View File

@ -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/

View File

@ -10,28 +10,39 @@ import os, os.path
from urllib.parse import urlparse 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 # check current working directory
if os.path.isfile(os.getcwd() + '/events.ini'): if os.path.isfile(os.getcwd() + '/' + CONFIG_FILE):
project_root = os.getcwd() project_root = os.getcwd()
# check this script's location dir # 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__)) project_root = os.path.dirname(os.path.realpath(__file__))
# check parent dir of this script's dir # 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__)) + '/..' project_root = os.path.dirname(os.path.realpath(__file__)) + '/..'
# OK no luck # OK no luck
else: else:
print("Cannot find file 'events.ini'; aborting.") print(f"Cannot find file config file {CONFIG_FILE} anywhere; aborting.")
exit(1) exit(1)
# read ini file # read yaml config file
cp = configparser.ConfigParser() with open(project_root + "/" + CONFIG_FILE, 'r') as file:
cp.read(project_root + '/events.ini') config = yaml.safe_load(file)
server_url = cp["CalDAV"]["server_url"]
cal_url = cp["CalDAV"]["cal_url"] servers = []
cal_user = cp["CalDAV"]["cal_user"] for server in config["CalDAV"]["servers"]:
cal_pass = cp["CalDAV"]["cal_pass"] 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. # Category to filter events for. Only events that belong to this category will be processed.
cal_category = "Veranstaltung" cal_category = "Veranstaltung"
@ -158,15 +169,22 @@ def refresh_events():
# create vobject calendar # create vobject calendar
vcal = vobject.newFromBehavior("vcalendar") vcal = vobject.newFromBehavior("vcalendar")
# establish connection to caldav server # loop over all servers from the
with caldav.DAVClient(url=server_url, username=cal_user, password=cal_pass) as dav_client: for server in servers:
# establish connection to calendar
dav_cal = dav_client.calendar(url=cal_url)
# put all events from caldav calendar into vobject calendar # establish connection to caldav server
for e in dav_cal.events(): with caldav.DAVClient(url=server["url"], username=server["user"], password=server["pass"]) as dav_client:
for ev in e.vobject_instance.contents["vevent"]:
vcal.add(ev) # 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 # 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"])] 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"])]