lots of work around extracting, parsing and presenting events

This commit is contained in:
eclipse 2025-02-17 21:05:18 +01:00
parent 1063657e96
commit e00b177221
4 changed files with 56 additions and 66 deletions

View File

@ -8,11 +8,8 @@ SITESUBTITLE = "Schriftsteller"
SITEURL = "" SITEURL = ""
TIMEZONE = 'Europe/Berlin' TIMEZONE = 'Europe/Berlin'
DATE_FORMATS = {
'de': '%a, %d. %b %y',
'en': '%Y-%m-%d(%a)',
}
DEFAULT_LANG = 'de' DEFAULT_LANG = 'de'
#DEFAULT_DATE_FORMAT = '%d.%m.%Y' (doesn't seem to work)
THEME = "theme/" THEME = "theme/"
@ -84,6 +81,7 @@ SOCIAL = (
# Technical Settings # # Technical Settings #
############################################################################### ###############################################################################
PLUGINS = ["pelican.plugins.yaml_metadata"]
JINJA_ENVIRONMENT = { "extensions": ["jinja2.ext.debug", "jinja2.ext.do"] } JINJA_ENVIRONMENT = { "extensions": ["jinja2.ext.debug", "jinja2.ext.do"] }

View File

@ -227,9 +227,15 @@ a {
} }
/* grid settings for event list */ /* grid settings for event list */
.event-grid { .events {}
display: grid;
grid-template-columns: minmax(auto, 250px) minmax(60%, auto); .event-info {
vertical-align: top;
max-width: 240px;
}
.event-detail {
vertical-align: top;
} }
/* flex settings for layout of cards */ /* flex settings for layout of cards */

View File

@ -1,25 +1,34 @@
{% extends "page.html" %} {% extends "page.html" %}
{# note that this template's filename is ''termine.noformat.html'' and not ''termine.html''. This is because vscodium's auto-format breaks the ''replace'' filters in the summary line, which is bad. The double file extension enables an exlude rule for all "noformat.html" files from within vscodium's settings.json file. #}
{% block content_body %}
{% if page.termine is defined %} {% if page.termine is defined %}
<article> {% set date_format = "%d.%m." %}
<header class="event-grid" style="grid-row-template: auto);"> {% set time_format = "%H:%M" %}
<div>Termin</div> {% block content_body %}
<div>Veranstaltung</div> <table class="events">
</header> <thead>
<div class="event-grid" style="grid-row-template: repeat({{page.termine | length}}, auto);"> <tr>
<th class="event-info">Wann & Wo</th>
<th class="event-detail">Was & Wieso</th>
</tr>
</thead>
<tbody>
{% for t in page.termine %} {% for t in page.termine %}
<div>{{ t.startdate }}{% if t.enddate is defined %}{{t.enddate }}{% elif t.starttime is defined %}, {{ t.starttime }}{% endif %}</div> <tr>
<div> <td class="event-info"><strong>{{ t.startdate | strftime(date_format) }}{% if t.enddate is defined %}{{t.enddate | strftime(date_format) }}{% elif t.starttime is defined %} {{ t.starttime | strftime(time_format) }}{% endif %}</strong><br>{{ t.location }}</td>
<details> <td class="event-detail">
<summary>{{ t.summary }}</summary> <p>{{ t.summary }} {% if "Moderation" in t.categories %}(Moderation){%endif%}</p>
{% if t.description is defined %}<p>{{ t.description | replace("\n\n", "</p><p>") | replace("\n", "<br>") | replace("</p><br><p>", "</p><p>")}}</p>{% endif %} {% if t.description is defined %}<p>{{ t.description | replace("\n\n", "</p><p>") | replace("\n", "<br>") | replace("</p><br><p>", "</p><p>")}}</p>{% endif %}
{% if t.location is defined %}<p>Ort: {{ t.location }}</p>{% endif %} {% if t.attach is defined %}<p><a href="{{ t.attach }}" target="_blank" title="siehe auch …">Mehr Infos</a></p>{% endif %}
</details> </td>
</div> </tr>
{% endfor %} {% endfor %}
</div> </body>
{% if page.date is defined %}<footer>Letzte Aktualisierung: {{ page.date }}</footer>{% endif %} </table>
</article>
{% endif %}
{% endblock content_body %} {% endblock content_body %}
{% if page.written_at is defined %}
{% block content_footer %}
<p style="text-align: center";>Letzte Aktualisierung: {{ page.written_at | strftime("%d.%m.%Y, %H:%M Uhr") }}</p>
{% endblock content_footer %}
{% endif %}
{% endif %}

View File

@ -4,11 +4,6 @@ from datetime import datetime, date, time, timedelta
import yaml import yaml
import os import os
import locale
import threading
from contextlib import contextmanager
"""CalDAV server url""" """CalDAV server url"""
server_url = "https://***REMOVED*** server_url = "https://***REMOVED***
"""CalDAV calendar url""" """CalDAV calendar url"""
@ -84,7 +79,7 @@ def extractEventData(events):
if len(v) == 1: if len(v) == 1:
d[k] = v[0].value d[k] = v[0].value
# but sometimes the list has more than one item; this only ever happens for the property "categories" # but sometimes the list has more than one item; this only ever happens for the property "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) # 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: else:
d[k] = [v[i].value[0] for i in range(len(v))] d[k] = [v[i].value[0] for i in range(len(v))]
e_tmp.append(d) e_tmp.append(d)
@ -129,47 +124,29 @@ events = [e for e in events if e["dtstart"] >= now]
# sort by start date # sort by start date
events.sort(key=lambda e: e["dtstart"]) events.sort(key=lambda e: e["dtstart"])
# add start date to metadata, also start time and/or end date
for e in events:
# start date
e["startdate"] = e["dtstart"].astimezone()
# start time (if not the default time)
if e["dtstart"].timetz() != time(23, 59, 59, tzinfo=now.tzinfo):
e["starttime"] = e["dtstart"].astimezone()
# end date (if different from start date)
if e["dtstart"].date() < e["dtend"].date():
e["enddate"] = e["dtend"].astimezone()
# read default metadata if present # read default metadata if present
default_metadata = None default_metadata = None
if os.path.isfile(result_file + ".metadata"): if os.path.isfile(result_file + ".metadata"):
with open(result_file + ".metadata", "r") as f: with open(result_file + ".metadata", "r") as f:
default_metadata = yaml.safe_load(f) default_metadata = yaml.safe_load(f)
# set up a context manager in order to threadsafely format dates and times with the German locale
# source: https://stackoverflow.com/a/24070673
LOCALE_LOCK = threading.Lock()
@contextmanager
def setlocale(name):
with LOCALE_LOCK:
saved = locale.setlocale(locale.LC_TIME)
try:
yield locale.setlocale(locale.LC_TIME, name)
finally:
locale.setlocale(locale.LC_TIME, saved)
# temporary set locale to de_DE (category "time" only) and format start date as well as start time or end date
with setlocale('de_DE.UTF-8'):
for e in events:
# start date
e["startdate"] = e["dtstart"].strftime("%a, %d.%m.")
# start time (if not the default time)
if e["dtstart"].timetz() != time(23, 59, 59, tzinfo=now.tzinfo):
e["starttime"] = e["dtstart"].strftime("%H:%M Uhr")
# end date (if different from start date)
if e["dtstart"].date() < e["dtend"].date():
e["enddate"] = e["dtend"].date().strftime("%a, %d.%m.")
# add current date to default metadata while we're at it
if default_metadata:
default_metadata["date"] = now.strftime("%Y-%m-%d %H:%M")
# 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")
if default_metadata: if default_metadata:
yaml.dump(default_metadata, f) yaml.dump(default_metadata, f)
yaml.dump({"termine": events}, f) yaml.dump({"termine": events}, f)
# write current datetime to file
yaml.dump({"written_at": now}, f)
f.write("---\n") f.write("---\n")
f.write("written at " + datetime.today().isoformat(" "))