From d9852762fe2c32f53bdaf192ab31a539cb42d4e3 Mon Sep 17 00:00:00 2001 From: Luca Date: Mon, 29 Aug 2022 05:08:36 +0200 Subject: [PATCH] Process schedule.json with Python instead of Go templates --- .drone.yml | 5 ++ .gitignore | 1 + bin/fetch_schedule.py | 85 +++++++++++++++++++++++++++++ content/pages/schedule.md | 2 +- layouts/shortcodes/schedule.html | 91 +++++++------------------------- 5 files changed, 110 insertions(+), 74 deletions(-) create mode 100755 bin/fetch_schedule.py diff --git a/.drone.yml b/.drone.yml index 463b6b0..c33672b 100644 --- a/.drone.yml +++ b/.drone.yml @@ -5,6 +5,11 @@ type: docker name: default steps: + - name: fetch-schedule + image: python:3.10-alpine + commands: + - bin/fetch_schedule.py + - name: build image: klakegg/hugo:ext-alpine-ci when: diff --git a/.gitignore b/.gitignore index 2fb78d7..87dac11 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .hugo_build.lock +data/schedule.json public/ resources/_gen/ diff --git a/bin/fetch_schedule.py b/bin/fetch_schedule.py new file mode 100755 index 0000000..c6098fb --- /dev/null +++ b/bin/fetch_schedule.py @@ -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() diff --git a/content/pages/schedule.md b/content/pages/schedule.md index 16703d5..e4fca69 100644 --- a/content/pages/schedule.md +++ b/content/pages/schedule.md @@ -9,4 +9,4 @@ menu: 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. -{{}} +{{}} diff --git a/layouts/shortcodes/schedule.html b/layouts/shortcodes/schedule.html index 53f913e..0ed30ea 100644 --- a/layouts/shortcodes/schedule.html +++ b/layouts/shortcodes/schedule.html @@ -1,102 +1,47 @@ -{{ $data := getJSON (.Get "url") }} -{{ 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 }} - +{{ with $.Site.Data.schedule }}

Version: {{ .version }} -
Zeitangaben in {{ $startDate.Format "MST" }} +
Zeitangaben in {{ .timezone }}

-{{ range .conference.days }} - {{ .date }}· +{{ range .days }} + {{ . }}· {{ end }} zurück nach oben
-
+

-{{ $lastDate := 0 }} -{{ range seq 1 (div 30 $timeslotDuration) (div ($endDate.Sub $startDate).Minutes $timeslotDuration) }} -{{ $date := time (add $startDate.Unix (mul (sub . 1) (mul $timeslotDuration 60))) }} -
-{{ if or (not $lastDate) (ne ($date.Format "2006-01-02") ($lastDate.Format "2006-01-02")) }} -
{{ $date.Format "2006-01-02" }}
+{{ $lastDate := "" }} +{{ range .timeline }} +
+{{ if ne .date $lastDate }} +
{{ .date }}
{{ end }} - {{ $date.Format "15:04" }} + {{ .time }}
-{{ $lastDate = $date }} +{{ $lastDate = .date }} {{ end }}
-{{ range sort $data.schedule.conference.rooms "name" }} -{{ $name := .name }} -{{ $room := index $rooms $name }} -{{ with $room }} +{{ range $name, $events := .rooms }}

{{ $name }}

-{{ range . }} -{{ $start := add (div ((time .date).Sub $startDate).Minutes $timeslotDuration) 1 }} -{{ $duration := 0 }} -{{ range split .duration ":" }} -{{ $duration = add (mul $duration 60) (int .) }} -{{ end }} -{{ $end := add $start (div $duration $timeslotDuration) }} - +{{ range $events }} +
- {{ (time .date).Format "15:04" }} + {{ .start_time }} - {{ (time (int (add $startDate.Unix (mul (sub $end 1) (mul $timeslotDuration 60))))).Format "15:04" }} + {{ .end_time }}

{{ .title }}

-{{ $speaker := delimit (apply .persons "index" "." "public_name") ", " }} -

{{ $speaker }}

+

{{ .speaker }}

{{ end }}
{{ end }} -{{ end }}
- {{ end }}