Process schedule.json with Python instead of Go templates
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Luca 2022-08-29 05:08:36 +02:00
parent a5002ef8f2
commit d9852762fe
5 changed files with 110 additions and 74 deletions

View File

@ -5,6 +5,11 @@ type: docker
name: default name: default
steps: steps:
- name: fetch-schedule
image: python:3.10-alpine
commands:
- bin/fetch_schedule.py
- name: build - name: build
image: klakegg/hugo:ext-alpine-ci image: klakegg/hugo:ext-alpine-ci
when: when:

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
.hugo_build.lock .hugo_build.lock
data/schedule.json
public/ public/
resources/_gen/ resources/_gen/

85
bin/fetch_schedule.py Executable file
View File

@ -0,0 +1,85 @@
#!/usr/bin/env python3
from datetime import datetime, timedelta
from json import dumps, loads
from pathlib import Path
from urllib.request import urlopen
from zoneinfo import ZoneInfo
GRANULARITY = 30
SCHEDULE_URL = 'https://cfp.fairydust.reisen/iger-2022/schedule/export/schedule.json'
TIMEZONE = 'Europe/Berlin'
def parse_duration(s, num_parts):
duration = 0
for t in s.split(':', maxsplit=num_parts-1):
duration *= 60
duration += int(t)
return duration
def main():
with urlopen(SCHEDULE_URL) as f:
data = loads(f.read())
conference = data['schedule']['conference']
rooms = {}
for day in conference['days']:
for room in conference['rooms']:
name = room['name']
if name not in day['rooms']:
continue
if name not in rooms:
rooms[name] = []
rooms[name] += day['rooms'][name]
timezone = ZoneInfo(TIMEZONE)
start_date = None
end_date = None
for _, events in rooms.items():
for event in events:
date = datetime.fromisoformat(event['date']).astimezone(timezone)
if start_date is None or date < start_date:
start_date = date
event['start_date'] = date
date += timedelta(seconds=parse_duration(event['duration'], 2)*60)
if end_date is None or date > end_date:
end_date = date
event['end_date'] = date
timeline = []
timeslot = parse_duration(conference['timeslot_duration'], 2)
for offset in range(0, int((end_date-start_date).total_seconds()), GRANULARITY*60):
date = start_date + timedelta(seconds=offset)
timeline.append({'date': date.strftime('%Y-%m-%d'), 'start': offset//(timeslot*60)+1, 'time': date.strftime('%H:%M')})
out_data = {
'days': [day['date'] for day in conference['days']],
'end_date': end_date.isoformat(timespec='seconds'),
'rooms': {name: [{
'end': int((event['end_date']-start_date).total_seconds())//(timeslot*60)+1,
'end_time': event['end_date'].strftime('%H:%M'),
'speaker': ', '.join(person['public_name'] for person in event['persons']),
'start': int((event['start_date']-start_date).total_seconds())//(timeslot*60)+1,
'start_time': event['start_date'].strftime('%H:%M'),
'title': event['title'],
'url': event['url'],
} for event in events] for name, events in rooms.items()},
'span': GRANULARITY // timeslot,
'start_date': start_date.isoformat(timespec='seconds'),
'timeline': timeline,
'timezone': TIMEZONE,
'version': data['schedule']['version'],
}
with open(Path(__file__).resolve().parent.parent / 'data' / 'schedule.json', 'w') as f:
f.write(dumps(out_data))
if __name__ == '__main__':
main()

View File

@ -9,4 +9,4 @@ menu:
Wir werden in den nächsten Tagen nach und nach weitere Programmpunkte veröffentlichen. Wir werden in den nächsten Tagen nach und nach weitere Programmpunkte veröffentlichen.
Bitte beachtet, dass die zeitliche Planung sich aktuell noch jederzeit ändern kann. Bitte beachtet, dass die zeitliche Planung sich aktuell noch jederzeit ändern kann.
{{<schedule url="https://cfp.fairydust.reisen/iger-2022/schedule/export/schedule.json">}} {{<schedule>}}

View File

@ -1,102 +1,47 @@
{{ $data := getJSON (.Get "url") }} {{ with $.Site.Data.schedule }}
{{ with $data.schedule }}
{{ $timeslotDuration := 0 }}
{{ range split .conference.timeslot_duration ":" }}
{{ $timeslotDuration = add (mul $timeslotDuration 60) (int .) }}
{{ end }}
{{ $rooms := dict }}
{{ range $day := .conference.days }}
{{ range $room := $data.schedule.conference.rooms }}
{{ with index $day.rooms $room.name }}
{{ if index $rooms $room.name }}
{{ $rooms = merge $rooms (dict $room.name ((index $rooms $room.name) | append .)) }}
{{ else }}
{{ $rooms = merge $rooms (dict $room.name .) }}
{{ end }}
{{ end }}
{{ end }}
{{ end }}
{{ $events := slice }}
{{ range $rooms }}
{{ with . }}
{{ if $events }}
{{ $events = $events | append . }}
{{ else }}
{{ $events = . }}
{{ end }}
{{ end }}
{{ end }}
{{ $events = sort $events "date" }}
{{ $startDate := time (index $events 0).date }}
{{ $endDate := 0 }}
{{ with index $events (sub (len $events) 1) }}
{{ $lastDuration := 0 }}
{{ range split .duration ":" }}
{{ $lastDuration = add (mul $lastDuration 60) (int .) }}
{{ end }}
{{ $endDate = time (add (time .date).Unix (mul $lastDuration 60)) }}
{{ end }}
<p class="schedule-info"> <p class="schedule-info">
Version: <span class="schedule-version">{{ .version }}</span> Version: <span class="schedule-version">{{ .version }}</span>
<br>Zeitangaben in <span class="schedule-timezone">{{ $startDate.Format "MST" }}</span> <br>Zeitangaben in <span class="schedule-timezone">{{ .timezone }}</span>
</p> </p>
<div class="schedule-days"> <div class="schedule-days">
{{ range .conference.days }} {{ range .days }}
<a href="#{{ .date }}">{{ .date }}</a>&middot; <a href="#{{ . }}">{{ . }}</a>&middot;
{{ end }} {{ end }}
<a href="#">zurück nach oben</a> <a href="#">zurück nach oben</a>
</div> </div>
<div class="schedule"> <div class="schedule">
<div class="schedule-grid schedule-timeline" style="--span: {{ div 30 $timeslotDuration }}"> <div class="schedule-grid schedule-timeline" style="--span: {{ .span }}">
<h3 class="schedule-title"></h3> <h3 class="schedule-title"></h3>
{{ $lastDate := 0 }} {{ $lastDate := "" }}
{{ range seq 1 (div 30 $timeslotDuration) (div ($endDate.Sub $startDate).Minutes $timeslotDuration) }} {{ range .timeline }}
{{ $date := time (add $startDate.Unix (mul (sub . 1) (mul $timeslotDuration 60))) }} <div class="schedule-time" style="--start: {{ .start }}">
<div class="schedule-time" style="--start: {{ . }}"> {{ if ne .date $lastDate }}
{{ if or (not $lastDate) (ne ($date.Format "2006-01-02") ($lastDate.Format "2006-01-02")) }} <div class="schedule-date" id="{{ .date }}">{{ .date }}</div>
<div class="schedule-date" id="{{ $date.Format "2006-01-02" }}">{{ $date.Format "2006-01-02" }}</div>
{{ end }} {{ end }}
{{ $date.Format "15:04" }} {{ .time }}
</div> </div>
{{ $lastDate = $date }} {{ $lastDate = .date }}
{{ end }} {{ end }}
</div> </div>
{{ range sort $data.schedule.conference.rooms "name" }} {{ range $name, $events := .rooms }}
{{ $name := .name }}
{{ $room := index $rooms $name }}
{{ with $room }}
<div class="schedule-grid schedule-room"> <div class="schedule-grid schedule-room">
<h3 class="schedule-title">{{ $name }}</h3> <h3 class="schedule-title">{{ $name }}</h3>
{{ range . }} {{ range $events }}
{{ $start := add (div ((time .date).Sub $startDate).Minutes $timeslotDuration) 1 }} <a class="schedule-event" href="{{ .url }}" style="--start: {{ .start }};--end: {{ .end }}" target="_blank">
{{ $duration := 0 }}
{{ range split .duration ":" }}
{{ $duration = add (mul $duration 60) (int .) }}
{{ end }}
{{ $end := add $start (div $duration $timeslotDuration) }}
<a class="schedule-event" href="{{ .url }}" style="--start: {{ $start }};--end: {{ $end }}" target="_blank">
<div class="schedule-event-time"> <div class="schedule-event-time">
<span>{{ (time .date).Format "15:04" }}</span> <span>{{ .start_time }}</span>
<span>&ndash;</span> <span>&ndash;</span>
<span>{{ (time (int (add $startDate.Unix (mul (sub $end 1) (mul $timeslotDuration 60))))).Format "15:04" }}</span> <span>{{ .end_time }}</span>
</div> </div>
<div class="schedule-event-detail"> <div class="schedule-event-detail">
<h4 class="schedule-title" title="{{ .title }}">{{ .title }}</h4> <h4 class="schedule-title" title="{{ .title }}">{{ .title }}</h4>
{{ $speaker := delimit (apply .persons "index" "." "public_name") ", " }} <p class="schedule-speaker" title="{{ .speaker }}">{{ .speaker }}</p>
<p class="schedule-speaker" title="{{ $speaker }}">{{ $speaker }}</p>
</div> </div>
</a> </a>
{{ end }} {{ end }}
</div> </div>
{{ end }} {{ end }}
{{ end }}
</div> </div>
{{ end }} {{ end }}