refined export script for events
This commit is contained in:
parent
82683cf1f8
commit
548e713876
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@ output/
|
|||||||
__pycache__/
|
__pycache__/
|
||||||
*.code-workspace
|
*.code-workspace
|
||||||
utils/.caldav_pass
|
utils/.caldav_pass
|
||||||
|
content/pages/termine.md
|
||||||
|
|||||||
@ -1,16 +1,59 @@
|
|||||||
import caldav
|
import caldav
|
||||||
from datetime import datetime
|
|
||||||
import vobject
|
import vobject
|
||||||
|
from datetime import datetime, date, time
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
server_url = "https://***REMOVED***
|
server_url = "https://***REMOVED***
|
||||||
cal_user = "tobias"
|
cal_user = "tobias"
|
||||||
cal_url = "https://***REMOVED***
|
cal_url = "https://***REMOVED***
|
||||||
cal_category = "Lesung/Veranstaltung"
|
cal_category = "Veranstaltung"
|
||||||
metadata_keys = ["summary", "dtstart", "dtend", "description", "location"]
|
|
||||||
result_file = "../content/pages/termine.md"
|
result_file = "../content/pages/termine.md"
|
||||||
|
now = datetime.now().astimezone()
|
||||||
|
|
||||||
# get passwort
|
cal_properties = [ # taken from ical specification
|
||||||
|
# descriptive
|
||||||
|
"attach", "categories", "class", "comment", "description", "geo", "location", "percent-complete", "priority", "resources", "status", "summary",
|
||||||
|
# date and time
|
||||||
|
"completed", "dtend", "due", "dtstart", "duration", "freebusy", "transp",
|
||||||
|
# timezone components
|
||||||
|
"tzid", "tzname", "tzoffsetfrom", "tzoffsetto", "tzurl",
|
||||||
|
# relationship
|
||||||
|
"attendee", "contact", "organizer", "recurrence-id", "related-to", "url", "uid",
|
||||||
|
# recurrence
|
||||||
|
"exdate", "exrule", "rdate", "rrule",
|
||||||
|
# alarm
|
||||||
|
# "action", "repeat", "trigger",
|
||||||
|
# change management
|
||||||
|
"created", "dtstamp", "last-modified", "sequence"
|
||||||
|
]
|
||||||
|
cal_prop_datetimes = ["dtend", "due", "dtstart", "duration", "dtstamp", "last-modified"]
|
||||||
|
|
||||||
|
|
||||||
|
"""Converts a datetime.datetime or datetime.date object into an aware datetime object."""
|
||||||
|
def fixDatetime(d, t=None, tz=None):
|
||||||
|
if not tz:
|
||||||
|
tz = now.tzinfo
|
||||||
|
|
||||||
|
# datetime object is made aware if necessary
|
||||||
|
if type(d) == datetime:
|
||||||
|
if d.tzinfo:
|
||||||
|
return d
|
||||||
|
else:
|
||||||
|
return datetime(d.date(), d.time(), tz)
|
||||||
|
|
||||||
|
# raise error if d is neither datetime nor date
|
||||||
|
elif type(d) != date:
|
||||||
|
raise TypeError("parameter must be a datetime.date or datetime.datetime object")
|
||||||
|
|
||||||
|
# d is a date object
|
||||||
|
if not t:
|
||||||
|
t = time(23, 59, 59, tzinfo=tz) # if no time parameter was passed, use 23:59:59
|
||||||
|
if not t.tzinfo:
|
||||||
|
t.replace(tzinfo=tz)
|
||||||
|
return datetime.combine(d, t)
|
||||||
|
|
||||||
|
|
||||||
|
# get password
|
||||||
with open(".caldav_pass", "r") as f:
|
with open(".caldav_pass", "r") as f:
|
||||||
cal_pass = f.read().strip()
|
cal_pass = f.read().strip()
|
||||||
|
|
||||||
@ -30,16 +73,41 @@ with caldav.DAVClient(url=server_url, username=cal_user, password=cal_pass) as d
|
|||||||
# 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"])]
|
||||||
|
|
||||||
# convert events into a structure that Pelican can use
|
# convert events into a structure suitable for Pelican
|
||||||
events = [{k: v[0].value for k, v in e.contents.items() if k in metadata_keys} for e in events]
|
e_tmp = []
|
||||||
|
for e in events:
|
||||||
|
d = {}
|
||||||
|
for k, v in e.contents.items():
|
||||||
|
# only keep specific calendar properties
|
||||||
|
if not k in cal_properties:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# v is usually a list with a single item
|
||||||
|
if len(v) == 1:
|
||||||
|
d[k] = v[0].value
|
||||||
|
# but sometimes there's more than one item (this only ever happens when k is "categories")
|
||||||
|
# and in this case, each list item's value is itself a one item list (which is stupid but that's how vobject handles categories)
|
||||||
|
else:
|
||||||
|
d[k] = [v[i].value[0] for i in range(len(v))]
|
||||||
|
e_tmp.append(d)
|
||||||
|
events = e_tmp
|
||||||
|
|
||||||
|
# fix dates and datetimes
|
||||||
|
for e in events:
|
||||||
|
for k in e.keys():
|
||||||
|
if k in cal_prop_datetimes:
|
||||||
|
e[k] = fixDatetime(e[k])
|
||||||
|
|
||||||
# keep only future events
|
# keep only future events
|
||||||
today = datetime.today().date()
|
events = [e for e in events if e["dtstart"] >= now]
|
||||||
events = [e for e in events if e["dtstart"].date() >= today]
|
|
||||||
|
# sort by start date
|
||||||
|
events.sort(key=lambda e: e["dtstart"])
|
||||||
|
|
||||||
# write data as YAML
|
# write data as YAML
|
||||||
with open(result_file, 'w') as f:
|
with open(result_file, 'w') as f:
|
||||||
f.write("---\n")
|
f.write("---\n")
|
||||||
yaml.dump({"termine": events}, f)
|
yaml.dump({"termine": events}, f)
|
||||||
f.write("---\n")
|
f.write("---\n")
|
||||||
|
f.write("written at " + datetime.today().isoformat(" "))
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user