diff --git a/.gitignore b/.gitignore
index b5f2439..d8c050d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,3 +12,4 @@ schedule.de.xml
snapshot-*.png
env
.DS_Store
+*/thumbs
diff --git a/froscon2021/__init__.py b/froscon2021/__init__.py
new file mode 100644
index 0000000..0f031e2
--- /dev/null
+++ b/froscon2021/__init__.py
@@ -0,0 +1,167 @@
+#!/usr/bin/python3
+
+import subprocess
+import os.path
+from renderlib import *
+from easing import *
+import svg.path
+
+# URL to Schedule-XML
+scheduleUrl = 'https://programm.froscon.de/2021/schedule.xml'
+
+# For (really) too long titles
+titlemap = {
+ #
+}
+
+
+def introFrames(args):
+ xml = etree.parse('froscon2021/artwork/intro.svg').getroot()
+ pathstr = xml.find(".//*[@id='animatePath']").get('d')
+ frog = xml.find(".//*[@id='animatePath']").get('d')
+ path = svg.path.parse_path(pathstr)
+
+ init = path.point(0)
+
+ frames = 3*fps
+ for i in range(0, frames):
+ p = path.point(i / frames) - init
+ yield (
+ ('animatePath', 'style', 'opacity', 0),
+ ('frog', 'attr', 'transform', 'translate(%.4f, %.4f)' % (p.real, p.imag+120)),
+ ('title', 'style', 'opacity', 0),
+ ('names', 'style', 'opacity', 0),
+ )
+
+ frames = int(0.5*fps)
+ for i in range(0, frames):
+ yield (
+ ('animatePath', 'style', 'opacity', 0),
+ ('frog', 'attr', 'transform', 'translate(%.4f, %.4f)' % (p.real, p.imag+120)),
+ ('title', 'style', 'opacity', easeLinear(i, 0, 1, frames)),
+ ('names', 'style', 'opacity', easeLinear(i, 0, 1, frames)),
+ )
+
+ frames = int(3.0*fps)
+ for i in range(0, frames):
+ yield (
+ ('animatePath', 'style', 'opacity', 0),
+ ('frog', 'attr', 'transform', 'translate(%.4f, %.4f)' % (p.real, p.imag+120)),
+ )
+
+def outroFrames(args):
+ xml = etree.parse('froscon2019/artwork/outro.svg').getroot()
+ pathstr = xml.find(".//*[@id='animatePath']").get('d')
+ frog = xml.find(".//*[@id='animatePath']").get('d')
+ path = svg.path.parse_path(pathstr)
+
+ init = path.point(0)
+
+ frames = int(4*fps)
+ for i in range(0, frames):
+ p = path.point(i / frames) - init
+ yield (
+ )
+
+def pauseFrames(args):
+ frames = 2*fps
+ for i in range(0, frames):
+ yield (
+ ('text1', 'style', 'opacity', 1),
+ ('text2', 'style', 'opacity', 0),
+ )
+
+ frames = 1*fps
+ for i in range(0, frames):
+ yield (
+ ('text1', 'style', 'opacity', easeLinear(i, 1, -1, frames)),
+ ('text2', 'style', 'opacity', 0),
+ )
+
+ frames = 1*fps
+ for i in range(0, frames):
+ yield (
+ ('text1', 'style', 'opacity', 0),
+ ('text2', 'style', 'opacity', easeLinear(i, 0, 1, frames)),
+ )
+
+ frames = 2*fps
+ for i in range(0, frames):
+ yield (
+ ('text1', 'style', 'opacity', 0),
+ ('text2', 'style', 'opacity', 1),
+ )
+
+ frames = 1*fps
+ for i in range(0, frames):
+ yield (
+ ('text1', 'style', 'opacity', 0),
+ ('text2', 'style', 'opacity', easeLinear(i, 1, -1, frames)),
+ )
+
+ frames = 1*fps
+ for i in range(0, frames):
+ yield (
+ ('text1', 'style', 'opacity', easeLinear(i, 0, 1, frames)),
+ ('text2', 'style', 'opacity', 0),
+ )
+
+def debug():
+ render('intro.svg',
+ '../intro.ts',
+ introFrames,
+ {
+ '$id': 2404,
+ '$title': 'Linux Container im High Performance Computing',
+ '$subtitle': 'Vom Wal zur Singularität und weiter',
+ '$personnames': 'Holger Gantikow'
+ }
+ )
+
+# render('outro.svg',
+# '../outro.ts',
+# outroFrames
+# )
+
+# render('pause.svg',
+# '../pause.ts',
+# pauseFrames
+# )
+
+
+def tasks(queue, args, idlist, skiplist):
+ # iterate over all events extracted from the schedule xml-export
+ for event in events(scheduleUrl):
+ if event['room'] not in ('HS 1/2', 'HS3', 'HS4', 'HS5', 'HS6', 'HS7', 'HS8', 'C116', 'Workshop'):
+ print("skipping room %s (%s)" % (event['room'], event['title']))
+ continue
+
+ if (event['id'] in idlist or not idlist) and not 'intro' in skiplist:
+ # generate a task description and put them into the queue
+ queue.put(Rendertask(
+ infile = 'intro.svg',
+ outfile = str(event['id'])+".ts",
+ sequence = introFrames,
+ parameters = {
+ '$id': event['id'],
+ '$title': event['title'],
+# '$subtitle': event['subtitle'],
+ '$personnames': event['personnames']
+ }
+ ))
+
+ if not 'outro' in skiplist:
+ # place a task for the outro into the queue
+ queue.put(Rendertask(
+ infile = 'outro.svg',
+ outfile = 'outro.ts',
+ sequence = outroFrames
+ ))
+
+ if not 'pause' in skiplist:
+ # place the pause-sequence into the queue
+ queue.put(Rendertask(
+ infile = 'pause.svg',
+ outfile = 'pause.ts',
+ sequence = pauseFrames
+ ))
diff --git a/froscon2021/artwork/background.svg b/froscon2021/artwork/background.svg
new file mode 100644
index 0000000..1a38199
--- /dev/null
+++ b/froscon2021/artwork/background.svg
@@ -0,0 +1,166 @@
+
+
+
+
diff --git a/froscon2021/artwork/intro.svg b/froscon2021/artwork/intro.svg
new file mode 100644
index 0000000..51c637a
--- /dev/null
+++ b/froscon2021/artwork/intro.svg
@@ -0,0 +1,891 @@
+
+
diff --git a/froscon2021/artwork/logo-bw.svg b/froscon2021/artwork/logo-bw.svg
new file mode 100644
index 0000000..f30babb
--- /dev/null
+++ b/froscon2021/artwork/logo-bw.svg
@@ -0,0 +1,208 @@
+
+
+
+
diff --git a/froscon2021/artwork/logo.svg b/froscon2021/artwork/logo.svg
new file mode 100644
index 0000000..a57e99c
--- /dev/null
+++ b/froscon2021/artwork/logo.svg
@@ -0,0 +1,222 @@
+
+
+
+
diff --git a/froscon2021/artwork/outro.svg b/froscon2021/artwork/outro.svg
new file mode 100644
index 0000000..d794053
--- /dev/null
+++ b/froscon2021/artwork/outro.svg
@@ -0,0 +1,551 @@
+
+
diff --git a/froscon2021/artwork/overlay.svg b/froscon2021/artwork/overlay.svg
new file mode 100644
index 0000000..60dc691
--- /dev/null
+++ b/froscon2021/artwork/overlay.svg
@@ -0,0 +1,183 @@
+
+
+
+
diff --git a/froscon2021/artwork/pause.svg b/froscon2021/artwork/pause.svg
new file mode 100644
index 0000000..de1efc2
--- /dev/null
+++ b/froscon2021/artwork/pause.svg
@@ -0,0 +1,478 @@
+
+
+
+
diff --git a/froscon2022/__init__.py b/froscon2022/__init__.py
index 4df93e5..1c457ff 100644
--- a/froscon2022/__init__.py
+++ b/froscon2022/__init__.py
@@ -7,7 +7,7 @@ from easing import *
import svg.path
# URL to Schedule-XML
-scheduleUrl = 'https://programm.froscon.de/2022/schedule.xml'
+scheduleUrl = 'https://bats.science/froscon2022/schedule.xml'
# For (really) too long titles
titlemap = {
diff --git a/froscon2022/artwork/intro.svg b/froscon2022/artwork/intro.svg
index a309733..19e733f 100644
--- a/froscon2022/artwork/intro.svg
+++ b/froscon2022/artwork/intro.svg
@@ -4,7 +4,7 @@
height="1080"
id="svg2"
version="1.1"
- inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
+ inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
sodipodi:docname="intro.svg"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
@@ -157,16 +157,16 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="0.55767043"
- inkscape:cx="846.37803"
- inkscape:cy="856.24049"
+ inkscape:zoom="0.51594277"
+ inkscape:cx="948.74864"
+ inkscape:cy="488.42626"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
- inkscape:window-width="3836"
- inkscape:window-height="1042"
- inkscape:window-x="2560"
- inkscape:window-y="1091"
+ inkscape:window-width="1916"
+ inkscape:window-height="1026"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
inkscape:window-maximized="1"
showguides="true"
inkscape:guide-bbox="true"
@@ -228,25 +228,25 @@
id="rect3809-1"
style="fill:#1f1fa3;fill-opacity:1;stroke-width:3.6841" />$title$personnames
diff --git a/froscon2023/__init__.py b/froscon2023/__init__.py
new file mode 100644
index 0000000..183fc52
--- /dev/null
+++ b/froscon2023/__init__.py
@@ -0,0 +1,160 @@
+#!/usr/bin/python3
+
+import subprocess
+import os.path
+from renderlib import *
+from easing import *
+import svg.path
+
+# URL to Schedule-XML
+scheduleUrl = 'https://bats.science/froscon2023/schedule.xml'
+
+# For (really) too long titles
+titlemap = {
+ #
+}
+
+
+def introFrames(args):
+ xml = etree.parse('froscon2023/artwork/intro.svg').getroot()
+ pathstr = xml.find(".//*[@id='animatePath']").get('d')
+ frog = xml.find(".//*[@id='animatePath']").get('d')
+ path = svg.path.parse_path(pathstr)
+
+ init = path.point(0)
+
+ frames = 3*fps
+ for i in range(0, frames):
+ p = path.point(i / frames) - init
+ yield (
+ ('animatePath', 'style', 'opacity', 0),
+ ('frog', 'attr', 'transform', 'translate(%.4f, %.4f)' % (p.real, p.imag+120)),
+ ('title', 'style', 'opacity', 0),
+ ('names', 'style', 'opacity', 0),
+ )
+
+# frames = int(0.5*fps)
+# for i in range(0, frames):
+# yield (
+# ('animatePath', 'style', 'opacity', 0),
+# ('frog', 'attr', 'transform', 'translate(%.4f, %.4f)' % (p.real, p.imag+120)),
+# ('title', 'style', 'opacity', easeLinear(i, 0, 1, frames)),
+# ('names', 'style', 'opacity', easeLinear(i, 0, 1, frames)),
+# )
+
+ frames = int(3.0*fps)
+ for i in range(0, frames):
+ yield (
+ ('animatePath', 'style', 'opacity', 0),
+ ('frog', 'attr', 'transform', 'translate(%.4f, %.4f)' % (p.real, p.imag+120)),
+ )
+
+def outroFrames(args):
+ xml = etree.parse('froscon2023/artwork/outro.svg').getroot()
+
+ frames = int(4*fps)
+ for i in range(0, frames):
+ yield ()
+
+def pauseFrames(args):
+ frames = 2*fps
+ for i in range(0, frames):
+ yield (
+ ('text1', 'style', 'opacity', 1),
+ ('text2', 'style', 'opacity', 0),
+ )
+
+ frames = 1*fps
+ for i in range(0, frames):
+ yield (
+ ('text1', 'style', 'opacity', easeLinear(i, 1, -1, frames)),
+ ('text2', 'style', 'opacity', 0),
+ )
+
+ frames = 1*fps
+ for i in range(0, frames):
+ yield (
+ ('text1', 'style', 'opacity', 0),
+ ('text2', 'style', 'opacity', easeLinear(i, 0, 1, frames)),
+ )
+
+ frames = 2*fps
+ for i in range(0, frames):
+ yield (
+ ('text1', 'style', 'opacity', 0),
+ ('text2', 'style', 'opacity', 1),
+ )
+
+ frames = 1*fps
+ for i in range(0, frames):
+ yield (
+ ('text1', 'style', 'opacity', 0),
+ ('text2', 'style', 'opacity', easeLinear(i, 1, -1, frames)),
+ )
+
+ frames = 1*fps
+ for i in range(0, frames):
+ yield (
+ ('text1', 'style', 'opacity', easeLinear(i, 0, 1, frames)),
+ ('text2', 'style', 'opacity', 0),
+ )
+
+def debug():
+ render('intro.svg',
+ '../intro.ts',
+ introFrames,
+ {
+ '$id': 2404,
+ '$title': 'Linux Container im High Performance Computing',
+ '$subtitle': 'Vom Wal zur Singularität und weiter',
+ '$personnames': 'Holger Gantikow'
+ }
+ )
+
+# render('outro.svg',
+# '../outro.ts',
+# outroFrames
+# )
+
+# render('pause.svg',
+# '../pause.ts',
+# pauseFrames
+# )
+
+
+def tasks(queue, args, idlist, skiplist):
+ # iterate over all events extracted from the schedule xml-export
+ for event in events(scheduleUrl):
+ if event['room'] not in ('HS1', 'HS3', 'HS4', 'HS6', 'HS7', 'HS8'):
+ print("skipping room %s (%s)" % (event['room'], event['title']))
+ continue
+
+ if (event['id'] in idlist or not idlist) and not 'intro' in skiplist:
+ # generate a task description and put them into the queue
+ queue.put(Rendertask(
+ infile = 'intro.svg',
+ outfile = str(event['id'])+".ts",
+ sequence = introFrames,
+ parameters = {
+ '$id': event['id'],
+ '$title': event['title'],
+# '$subtitle': event['subtitle'],
+ '$personnames': event['personnames']
+ }
+ ))
+
+ if not 'outro' in skiplist:
+ # place a task for the outro into the queue
+ queue.put(Rendertask(
+ infile = 'outro.svg',
+ outfile = 'outro.ts',
+ sequence = outroFrames
+ ))
+
+ if not 'pause' in skiplist:
+ # place the pause-sequence into the queue
+ queue.put(Rendertask(
+ infile = 'pause.svg',
+ outfile = 'pause.ts',
+ sequence = pauseFrames
+ ))
diff --git a/froscon2023/artwork/background.svg b/froscon2023/artwork/background.svg
new file mode 100644
index 0000000..0f15119
--- /dev/null
+++ b/froscon2023/artwork/background.svg
@@ -0,0 +1,263 @@
+
+
+
+
diff --git a/froscon2023/artwork/intro.svg b/froscon2023/artwork/intro.svg
new file mode 100644
index 0000000..a0a1167
--- /dev/null
+++ b/froscon2023/artwork/intro.svg
@@ -0,0 +1,443 @@
+
+
diff --git a/froscon2023/artwork/outro.svg b/froscon2023/artwork/outro.svg
new file mode 100644
index 0000000..96358e9
--- /dev/null
+++ b/froscon2023/artwork/outro.svg
@@ -0,0 +1,584 @@
+
+
diff --git a/froscon2023/artwork/pause.svg b/froscon2023/artwork/pause.svg
new file mode 100644
index 0000000..2daff41
--- /dev/null
+++ b/froscon2023/artwork/pause.svg
@@ -0,0 +1,562 @@
+
+
+
+
diff --git a/froscon2023/genthumbs.sh b/froscon2023/genthumbs.sh
new file mode 100755
index 0000000..7db64d2
--- /dev/null
+++ b/froscon2023/genthumbs.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+rm -rf thumbs
+mkdir thumbs
+
+for intro in *.ts; do
+ echo $intro
+ ffmpeg -hide_banner -loglevel quiet -ss 4 -i "${intro}" -frames:v 1 "thumbs/${intro}.png"
+done
diff --git a/renderlib.py b/renderlib.py
index 57c9366..c4047dc 100644
--- a/renderlib.py
+++ b/renderlib.py
@@ -101,7 +101,7 @@ def renderFrame(infile, task, outfile):
else:
# invoke inkscape to convert the generated svg-file into a png inside the .frames-directory
- cmd = 'inkscape --export-background=white --export-background-opacity=0 --export-width={1} --export-height={2} --export-filename="{3}" "{4}" --pipe 2>&1 >/dev/null'.format(task.workdir, width, height, os.path.abspath(outfile), os.path.abspath(infile))
+ cmd = 'dbus-run-session inkscape --export-background=white --export-background-opacity=0 --export-width={1} --export-height={2} --export-png="{3}" "{4}" 2>&1 >/dev/null'.format(task.workdir, width, height, os.path.abspath(outfile), os.path.abspath(infile))
errorReturn = subprocess.check_output(cmd, shell=True, universal_newlines=True, stderr=subprocess.STDOUT, cwd=task.workdir)
if errorReturn != '':
print("inkscape exited with error\n" + errorReturn)