Add calendar generator
This commit is contained in:
		
							parent
							
								
									d55a0ee07f
								
							
						
					
					
						commit
						fbc6fe31dd
					
				
					 5 changed files with 101 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -8,6 +8,7 @@ Running a dev setup
 | 
			
		|||
* run hugo webserver: `hugo serve`
 | 
			
		||||
* Point your browser to `http://localhost:1313/s/`
 | 
			
		||||
* 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
 | 
			
		||||
long as `hugo serve` is running.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										4
									
								
								build.sh
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								build.sh
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,4 +1,6 @@
 | 
			
		|||
#!/usr/bin/env sh
 | 
			
		||||
 | 
			
		||||
tools/merge_cals.py
 | 
			
		||||
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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
baseURL: "https://staging.berlin.ccc.de/s"
 | 
			
		||||
languageCode: "de-de"
 | 
			
		||||
title: "Chaos Computer Club Berlin e.V."
 | 
			
		||||
title: "Chaos Computer Club Berlin"
 | 
			
		||||
theme: "beautifulhugo"
 | 
			
		||||
RelativeURLs: true
 | 
			
		||||
CanonifyURLs: true
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
									
								
							
							
						
						
									
										88
									
								
								tools/gen_upcoming.py
									
										
									
									
									
										Executable 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()
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue