Add calendar generator

This commit is contained in:
Daniel Molkentin 2018-07-14 22:53:59 +02:00
parent d55a0ee07f
commit fbc6fe31dd
5 changed files with 101 additions and 2 deletions

View file

@ -8,6 +8,7 @@ Running a dev setup
* run hugo webserver: `hugo serve` * run hugo webserver: `hugo serve`
* Point your browser to `http://localhost:1313/s/` * Point your browser to `http://localhost:1313/s/`
* To ready your site for upload, run "./build.sh", which also generates all.ics * To ready your site for upload, run "./build.sh", which also generates all.ics
and adds the calendar table to index.html
Every change you make on the project will be reflected in your browser as Every change you make on the project will be reflected in your browser as
long as `hugo serve` is running. long as `hugo serve` is running.

View file

@ -1,4 +1,6 @@
#!/usr/bin/env sh #!/usr/bin/env sh
tools/merge_cals.py
hugo hugo
tools/merge_cals.py
upcoming="$(tools/gen_upcoming.py static/all.ics 7 7|tr '\n' ' ')"
sed -i "s#CALENDAR#$upcoming#g" public/index.html

View file

@ -1,6 +1,6 @@
baseURL: "https://staging.berlin.ccc.de/s" baseURL: "https://staging.berlin.ccc.de/s"
languageCode: "de-de" languageCode: "de-de"
title: "Chaos Computer Club Berlin e.V." title: "Chaos Computer Club Berlin"
theme: "beautifulhugo" theme: "beautifulhugo"
RelativeURLs: true RelativeURLs: true
CanonifyURLs: true CanonifyURLs: true

View file

@ -0,0 +1,8 @@
---
description: "Startseite CCCB mit Kurzkalender"
---
### Nächste Veranstaltungen:
CALENDAR
Keinen Termin mehr verpeilen? Einfach den [Veranstaltungskalender abonnieren](all.ics)!

88
tools/gen_upcoming.py Executable file
View file

@ -0,0 +1,88 @@
#!/usr/bin/env python3
import sys
from datetime import datetime, timedelta
from dateutil.parser import parse
from dateutil.rrule import rruleset, rrulestr
import icalendar
import locale
import logging
from pprint import pprint
def vevent_to_event(event, rrstart=None):
if rrstart == None:
begin = parse(event['DTSTART'].to_ical())
else:
begin = rrstart
return { "name": event['SUMMARY'].to_ical(), "url": event['URL'].to_ical(), "begin": begin }
def parse_single_event(event, start, end):
logging.info("Processing single event %s" % event['SUMMARY'].to_ical().decode('utf-8'))
dtstart = parse(event['DTSTART'].to_ical())
if dtstart >= start and dtstart < end:
return vevent_to_event(event)
else:
return None
def parse_recurring_event(event, start, end):
logging.info("Processing recurring event %s" % event['SUMMARY'].to_ical().decode('utf-8'))
dtstart = parse(event['DTSTART'].to_ical())
rs = rruleset()
rs.rrule(rrulestr(event['RRULE'].to_ical().decode('utf-8'), dtstart=dtstart))
if 'EXDATE' in event.keys():
exdates = event['EXDATE']
for exdate in exdates:
rs.exdate(parse(exdate.to_ical()))
dates = list(rs)
events = []
for date in dates:
if date >= start and date < end:
events.append(vevent_to_event(event, date))
return events
def find_events(icsfilestr, start, end, num):
with open(icsfilestr, 'r') as icsfile:
cal=icalendar.Calendar.from_ical(icsfile.read())
events=[]
for event in cal.subcomponents:
if event.name == 'VEVENT':
if 'RRULE' in event.keys():
events = events + parse_recurring_event(event, start, end)
else:
ev = parse_single_event(event, start, end)
if ev != None:
events.append(ev)
events = sorted(events, key=lambda k: k['begin'])
events = events[0:num]
return events
def format_events(events):
print('<table class="table table-condensed">')
for event in events:
dateStr = event['begin'].strftime("%A, %d.%m um %H:%M Uhr")
#print("<li><a href=\"%s\">%s: %s</a></li>" % (event['url'].decode('utf-8'), dateStr, event['name'].decode('utf-8')))
print("<tr><td>%s</td><td><a href=\"%s\">%s</a></td></tr>"
% (dateStr, event['url'].decode('utf-8'), event['name'].decode('utf-8')))
print('</table>')
def main():
if len(sys.argv) < 3:
print("Usage: %s calendar max_days max_items" % sys.argv[0])
sys.exit(-1)
locale.setlocale(locale.LC_TIME, "de_DE.UTF-8")
calendar=sys.argv[1]
max_days=int(sys.argv[2])
max_items=int(sys.argv[3])
events=find_events(calendar, datetime.now(), datetime.now() + timedelta(days=max_days), max_items)
format_events(events)
if __name__ == "__main__":
main()