aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVOC2015-11-13 19:48:45 +0100
committerVOC2015-11-13 19:48:45 +0100
commit92f4fa13749566f6c4378f2c9e80774e8320b825 (patch)
treef17c6da85da6edba9c7be10138687518ee534d50
parent32fd126b3fa937389efd1457e9d05daff9f3b347 (diff)
parent29af764323dc474c14e05985eeabd3a06ef19c86 (diff)
Merge branch 'mandators'
-rw-r--r--.gitignore3
-rw-r--r--assets/css/_allconferences.less25
-rw-r--r--assets/css/_closed.less1
-rw-r--r--assets/css/_structure.less1
-rw-r--r--assets/js/lustiges-script.js4
-rw-r--r--configs/conferences/31c3/config.php (renamed from config.php)6
-rwxr-xr-xconfigs/conferences/31c3/download.sh7
-rw-r--r--configs/conferences/31c3/main.less21
-rw-r--r--configs/conferences/cccamp15/config.php573
-rw-r--r--configs/conferences/cccamp15/main.less186
-rw-r--r--configs/conferences/chaosradio/config.php459
-rw-r--r--configs/conferences/chaosradio/main.less30
-rw-r--r--configs/conferences/datengarten/config.php489
-rw-r--r--configs/conferences/datengarten/main.less68
-rw-r--r--configs/conferences/gpn15/config.php421
-rw-r--r--configs/conferences/gpn15/main.less92
-rw-r--r--configs/conferences/gpn15/wolkenbar.pngbin0 -> 25703 bytes
-rw-r--r--configs/conferences/nixcon15/config.php425
-rwxr-xr-xconfigs/conferences/nixcon15/download.sh8
-rw-r--r--configs/conferences/nixcon15/main.less41
-rw-r--r--configs/conferences/ppw15b/config.php449
-rwxr-xr-xconfigs/conferences/ppw15b/download.sh7
-rwxr-xr-xconfigs/download.sh14
-rw-r--r--index.php132
-rw-r--r--lib/helper.php24
-rw-r--r--model/Conferences.php77
-rw-r--r--model/GenericConference.php67
-rw-r--r--model/Room.php2
-rw-r--r--template/about.phtml2
-rw-r--r--template/allclosed.phtml14
-rw-r--r--template/allconferences.phtml33
-rw-r--r--template/assemblies/header.phtml2
-rw-r--r--template/assemblies/upcoming.phtml21
-rw-r--r--template/closed.phtml22
-rw-r--r--template/embed.phtml2
-rw-r--r--template/page.phtml28
-rw-r--r--view/allclosed.php12
-rw-r--r--view/allconferences.php8
-rw-r--r--view/streams-json-v1.php164
39 files changed, 3788 insertions, 152 deletions
diff --git a/.gitignore b/.gitignore
index 59165ce..ef8a6bb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,6 @@ build
assets/css/main.css
assets/css/main.dep
assets/css/main.map
+*.swp
+*.save
+thumbs
diff --git a/assets/css/_allconferences.less b/assets/css/_allconferences.less
new file mode 100644
index 0000000..d8a14aa
--- /dev/null
+++ b/assets/css/_allconferences.less
@@ -0,0 +1,25 @@
+body.allconferences {
+ text-align: center;
+
+ .conference {
+ a {
+ font-size: @jumbo-font-size;
+ line-height: @jumbo-line-height;
+
+ @media (max-width: @screen-xs-min) {
+ font-size: @jumbo-font-size-xs;
+ }
+
+ display: block;
+ text-align: center;
+
+ &:hover {
+ text-decoration: none;
+ }
+ }
+
+ p {
+ margin-top: @line-height-computed;
+ }
+ }
+}
diff --git a/assets/css/_closed.less b/assets/css/_closed.less
index 8aeeb78..ff55b75 100644
--- a/assets/css/_closed.less
+++ b/assets/css/_closed.less
@@ -1,4 +1,5 @@
body.closed,
+body.allclosed,
body.not-started {
p {
margin-top: 50px;
diff --git a/assets/css/_structure.less b/assets/css/_structure.less
index 2082e38..d6e4257 100644
--- a/assets/css/_structure.less
+++ b/assets/css/_structure.less
@@ -88,3 +88,4 @@ body {
@import "_closed.less";
@import "_embed.less";
@import "_feedback.less";
+@import "_allconferences.less";
diff --git a/assets/js/lustiges-script.js b/assets/js/lustiges-script.js
index 15f0358..e53194a 100644
--- a/assets/js/lustiges-script.js
+++ b/assets/js/lustiges-script.js
@@ -350,7 +350,7 @@ $(function() {
$.each(talks, function(room, talk) {
- if(!talk.known)
+ if(!talk.room_known)
return;
if(talk.start < now)
@@ -558,7 +558,7 @@ $(function() {
// closed-countdown
$(function() {
var
- $el = $('.closed .countdown'),
+ $el = $('.countdown'),
dt = moment($el.data('dt'));
$el.attr('title', 'on '+dt.format('dddd, MMM Do YYYY'))
diff --git a/config.php b/configs/conferences/31c3/config.php
index 978d2d0..7a2df4b 100644
--- a/config.php
+++ b/configs/conferences/31c3/config.php
@@ -106,7 +106,7 @@ $GLOBALS['CONFIG']['CONFERENCE'] = array(
*
* Wird diese Zeile auskommentiert, wird der Link nicht angezeigt
*/
- 'RELIVE_JSON' => 'configs/vod.json',
+ 'RELIVE_JSON' => 'configs/conferences/31c3/vod.json',
);
/**
@@ -487,12 +487,12 @@ $GLOBALS['CONFIG']['SCHEDULE'] = array(
/**
* URL zum Fahrplan-XML
*
- * Diese URL muss immer verfügbar sein, sonst können kann die Programm-Ansicht
+ * Diese URL muss immer verfügbar sein, sonst könnte die Programm-Ansicht
* aufhören zu funktionieren. Üblicherweise wird diese daher Datei über
* das Script configs/download.sh heruntergeladen, welches von einem
* Cronjob regelmäßig getriggert wird.
*/
- 'URL' => 'configs/schedule.xml',
+ 'URL' => 'configs/conferences/31c3/schedule.xml',
/**
* Nur die angegebenen Räume aus dem Fahrplan beachten
diff --git a/configs/conferences/31c3/download.sh b/configs/conferences/31c3/download.sh
new file mode 100755
index 0000000..81d5ad7
--- /dev/null
+++ b/configs/conferences/31c3/download.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# fahrplan
+wget --no-check-certificate -q "http://events.ccc.de/congress/2014/Fahrplan/schedule.xml" -O /tmp/schedule.xml && mv /tmp/schedule.xml schedule.xml
+
+# vod json
+wget -q "http://cdn.c3voc.de/releases/relive/index.json" -O /tmp/vod.json && mv /tmp/vod.json vod.json
diff --git a/configs/conferences/31c3/main.less b/configs/conferences/31c3/main.less
new file mode 100644
index 0000000..a60d3b4
--- /dev/null
+++ b/configs/conferences/31c3/main.less
@@ -0,0 +1,21 @@
+@import "../../../assets/css/_structure.less";
+
+// conference specific styles here
+
+// often configured values (and their defaults):
+//
+// @brand-primary: #337ab7;
+// @text-color: @gray-dark;
+//
+// @link-color: @brand-primary;
+// @link-hover-color: darken(@link-color, 15%);
+//
+// @navbar-default-color: #777777;
+// @navbar-default-bg: #f8f8f8;
+//
+// @navbar-default-link-color: #777;
+// @navbar-default-link-hover-color: #333;
+
+body {
+ background-color: red;
+}
diff --git a/configs/conferences/cccamp15/config.php b/configs/conferences/cccamp15/config.php
new file mode 100644
index 0000000..82b935d
--- /dev/null
+++ b/configs/conferences/cccamp15/config.php
@@ -0,0 +1,573 @@
+<?php
+date_default_timezone_set('Europe/Berlin');
+
+/**
+ * Während der Entwicklung wird die BASEURL automatisch erraten
+ * In Produktionssituationen sollte manuell eine konfiguriert werden um Überraschungen zu vermeiden
+ *
+ * Protokollfreie URLs (welche, die mit // beginnen), werden automatisch mit dem korrekten Protokoll ergänzt.
+ * In diesem Fall wird auch ein SSL-Umschalt-Button im Header angezeigt
+ */
+if($_SERVER['HTTP_HOST'] != 'localhost')
+ $GLOBALS['CONFIG']['BASEURL'] = '//streaming.media.ccc.de/';
+
+$GLOBALS['CONFIG']['CONFERENCE'] = array(
+ /**
+ * Der Startzeitpunkt der Konferenz als Unix-Timestamp. Befinden wir uns davor, wird die Closed-Seite
+ * mit einem Text der Art "hat noch nicht angefangen" angezeigt.
+ *
+ * Wird dieser Zeitpunkt nicht angegeben, gilt die Konferenz immer als angefangen. (Siehe aber ENDS_AT
+ * und CLOSED weiter unten)
+ */
+ 'STARTS_AT' => strtotime("2014-12-27 06:00"),
+
+ /**
+ * Der Endzeitpunkt der Konferenz als Unix-Timestamp. Befinden wir uns danach, wird eine Danke-Und-Kommen-Sie-
+ * Gut-Nach-Hause-Seite sowie einem Ausblick auf die kommenden Events angezeigt.
+ *
+ * Wird dieser Zeitpunkt nicht angegeben, endet die Konferenz nie. (Siehe aber CLOSED weiter unten)
+ */
+ 'ENDS_AT' => strtotime("2014-12-30 21:00"),
+
+ /**
+ * Hiermit kann die Funktionalitaet von STARTS_AT/ENDS_AT überschrieben werden. Der Wert 'before'
+ * simuliert, dass die Konferenz noch nicht begonnen hat. Der Wert 'after' simuliert, dass die Konferenz
+ * bereits beendet ist. 'running' simuliert eine laufende Konferenz.
+ *
+ * Der Boolean true ist aus Abwärtskompatibilitätsgründen äquivalent zu 'after'. False ist äquivalent
+ * zu 'running'.
+ */
+ //'CLOSED' => false,
+
+ /**
+ * Titel der Konferenz (kann Leer- und Sonderzeichen enthalten)
+ * Dieser im Seiten-Header, im <title>-Tag, in der About-Seite und ggf. ab weiteren Stellen als
+ * Anzeigetext benutzt
+ */
+ 'TITLE' => 'Chaos Communication Camp 2015',
+
+ /**
+ * Veranstalter
+ * Wird für den <meta name="author">-Tag verdet. Wird diese Zeile auskommentiert, wird kein solcher
+ * <meta>-Tag generiert.
+ */
+ 'AUTHOR' => 'CCC',
+
+ /**
+ * Beschreibungstext
+ * Wird für den <meta name="description">-Tag verdet. Wird diese Zeile auskommentiert, wird kein solcher
+ * <meta>-Tag generiert.
+ */
+ 'DESCRIPTION' => 'Video Live-Streaming of the Chaos Communication Camp 2015',
+
+ /**
+ * Schlüsselwortliste, Kommasepariert
+ * Wird für den <meta name="keywords">-Tag verdet. Wird diese Zeile auskommentiert, wird kein solcher
+ * <meta>-Tag generiert.
+ */
+ 'KEYWORDS' => 'cccamp, CCC, Chaos Communication Camp, Camp, 2015, Hacking, Chaos Computer Club, Video, Media, Streaming, Hacker',
+
+ /**
+ * HTML-Code für den Footer (z.B. für spezielle Attribuierung mit <a>-Tags)
+ * Sollte üblicherweise nur Inline-Elemente enthalten
+ * Wird diese Zeile auskommentiert, wird die Standard-Attribuierung für (c3voc.de) verwendet
+ */
+ 'FOOTER_HTML' => '
+ by <a href="https://ccc.de">Chaos Computer Club e.V</a>,
+ <a href="http://www.ags.tu-bs.de/">ags</a>,
+ <a href="https://www.isystems.at">isystems.at</a> &amp;
+ <a href="https://c3voc.de">c3voc</a>
+ ',
+
+ /**
+ * HTML-Code für den Banner (nur auf der Startseite, direkt unter dem Header)
+ * wird üblicherweise für KeyVisuals oder Textmarke verwendet (vgl. Blaues
+ * Wischiwaschi auf http://media.ccc.de/)
+ *
+ * Dieser HTML-Block wird üblicherweise in der main.less speziell für die
+ * Konferenz umgestaltet.
+ *
+ * Wird diese Zeile auskommentiert, wird kein Banner ausgegeben.
+ */
+ //'BANNER_HTML' => '31C3 – a new dawn',
+
+ /**
+ * Link zu den Recordings
+ * Wird diese Zeile auskommentiert, wird der Link nicht angezeigt
+ */
+ 'RELEASES' => 'https://media.ccc.de/browse/conferences/camp2015/index.html',
+
+ /**
+ * Link zu einer (externen) ReLive-Übersichts-Seite
+ * Wird diese Zeile auskommentiert, wird der Link nicht angezeigt
+ */
+ //'RELIVE' => 'http://vod.c3voc.de/',
+
+ /**
+ * Alternativ kann ein ReLive-Json konfiguriert werden, um die interne
+ * ReLive-Ansicht zu aktivieren.
+ *
+ * Wird beides aktiviert, hat der externe Link Vorrang!
+ * Wird beides auskommentiert, wird der Link nicht angezeigt
+ */
+ 'RELIVE_JSON' => 'configs/vod.json',
+
+ /**
+ * APCU-Cache-Zeit in Sekunden
+ * Wird diese Zeile auskommentiert, werden die apc_*-Methoden nicht verwendet und
+ * das Relive-Json bei jedem Request von der Quelle geladen und geparst
+ */
+ //'RELIVE_JSON_CACHE' => 30*60,
+);
+
+$GLOBALS['CONFIG']['MULTICAST'] = array(
+
+ //'rtp://@239.255.0.1:5004' => 'Tent A – FullHD – h264/mp4',
+
+);
+
+/**
+ * Konfiguration der Stream-Übersicht auf der Startseite
+ */
+$GLOBALS['CONFIG']['OVERVIEW'] = array(
+ /**
+ * Abschnitte aud der Startseite und darunter aufgeführte Räume
+ * Es können beliebig neue Gruppen und Räume hinzugefügt werden
+ *
+ * Die Räume müssen in $GLOBALS['CONFIG']['ROOMS'] konfiguriert werden,
+ * sonst werden sie nicht angezeigt.
+ */
+ 'GROUPS' => array(
+ 'Lecture Tents' => array(
+ 'tent-1',
+ 'tent-2',
+ 'ber',
+ ),
+
+ 'Live DJ Sets' => array(
+ 'lounge',
+ ),
+ ),
+);
+
+
+
+/**
+ * Liste der Räume (= Audio & Video Produktionen, also auch DJ-Sets oä.)
+ */
+$GLOBALS['CONFIG']['ROOMS'] = array(
+ /**
+ * Array-Key ist der Raum-Slug, der z.B. auch zum erstellen der URLs,
+ * in $GLOBALS['CONFIG']['OVERVIEW'] oder im Feedback verwendet wird.
+ */
+ 'tent-1' => array(
+ /**
+ * Angezeige-Name
+ */
+ 'DISPLAY' => 'Tent 1 (South)',
+
+ /**
+ * ID des Video/Audio-Streams. Die Stream-ID ist davon abhängig, welches
+ * Event-Case in welchem Raum aufgebaut wird und wird üblicherweise von
+ * s1 bis s5 durchnummeriert.
+ */
+ 'STREAM' => 's1',
+
+ /**
+ * Stream-Vorschaubildchen auf der Übersichtsseite anzeigen
+ * Damit das funktioniert muss der entsprechende runit-Task auf dem
+ * CDN-Quell-Host (live.ber) laufen.
+ */
+ 'PREVIEW' => true,
+
+ /**
+ * Übersetzungstonspur aktivieren
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist werden nur
+ * die native-Streams verwendet, andernfalls wird native und translated
+ * angeboten und auch für beide Tonspuren eine Player-Seite angezeigt.
+ */
+ 'TRANSLATION' => true,
+
+ /**
+ * stereo-Tonspur statt native-Tonspur benutzen
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist werden
+ * die "native"-Mono-Streams verwendet, andernfalls wird statt "native"
+ * der Streamname "stereo" eingesetzt. Im normalen Konferenz-Setup
+ * müssen dann beide Kanäle der Kamera mit einem Signal bespielt werden.
+ */
+ 'STEREO' => false,
+
+ /**
+ * SD-Video-Stream (1024×576) verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein SD-Video
+ * angeboten. Wird auch HD_VIDEO auf false gesetzt oder auskommentiert ist, wird
+ * für diesen Raum überhaupt kein Video angeboten.
+ *
+ * In diesem Fall wird, sofern jeweils aktiviert, Slides, Audio und zuletzt Musik
+ * als Default-Stream angenommen.
+ */
+ 'SD_VIDEO' => true,
+
+ /**
+ * HD-Video-Stream (1920×1080) verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein HD-Video
+ * angeboten. Wird auch SD_VIDEO auf false gesetzt oder auskommentiert ist, wird
+ * für diesen Raum überhaupt kein Video angeboten.
+ *
+ * In diesem Fall wird, sofern jeweils aktiviert, Slides, Audio und zuletzt Musik
+ * als Default-Stream angenommen.
+ */
+ 'HD_VIDEO' => true,
+
+ /**
+ * Slide-Only-Stream (1024×576) verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein Slide-Only-
+ * Stream angeboten. Für diesen Raum wird dann keim Slides-Tab angeboten.
+ *
+ * In diesem Fall wird, sofern jeweils aktiviert, Audio und zuletzt Musik als
+ * Default-Stream angenommen.
+ */
+ 'SLIDES' => false,
+
+ /**
+ * Audio-Only-Stream verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein Audio-Only-
+ * Stream angeboten. Für diesen Raum wird dann keim Audio-Tab angeboten.
+ *
+ * In diesem Fall wird, sofern aktiviert, Musik als Default-Stream angenommen.
+ */
+ 'AUDIO' => true,
+
+ /**
+ * Musik-Stream verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein Musik-Stream
+ * angeboten. Für diesen Raum wird dann keim Musik-Tab angeboten.
+ *
+ * Ist kein einziger Stream angebote, wird statt der Stream-Seite ein 404-Fehler
+ * angezeigt.
+ */
+ 'MUSIC' => false,
+
+ /**
+ * Fahrplan-Ansicht auf der Raum-Seite aktivieren (boolean)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird der Raum nicht im Fahrplan gesucht und auch auf der Startseite
+ * findet keine Darstellung statt.
+ *
+ * Ebenso können alle Fahrplan-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['SCHEDULE']-Blocks deaktiviert werden
+ */
+ 'SCHEDULE' => true,
+
+ /**
+ * Name des Raums im Fahrplan
+ * Wenn diese Zeile auskommentiert ist wird der Raum-Slug verwendet
+ */
+ 'SCHEDULE_NAME' => 'Project 2501',
+
+ /**
+ * Feedback anzeigen (boolean)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * taucht der Raum auch im globalen Feedback-Formular nicht auf.
+ *
+ * Ebenso können alle Feedback-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['FEEDBACK']-Blocks deaktiviert werden
+ */
+ 'FEEDBACK' => true,
+
+ /**
+ * Subtitles-Player aktivieren (boolean)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird der Subtitles-Button und die damit verbundenen Funktionen deaktiviert.
+ *
+ * Ebenso können alle Subtitles-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['SUBTITLES']-Blocks deaktiviert werden
+ */
+ 'SUBTITLES' => false,
+
+ /**
+ * Embed-Form aktivieren (boolean)
+ *
+ * Ist dieses Feld auf true gesetzt, wird ein Embed-Tab unter dem Video
+ * angezeigt. Darüber kann der Player als iframe eingebunden werden.
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird kein Embed-Tab angeboten und die URL zum Einbetten existiert nicht.
+ *
+ * Ebenso können alle Embedding-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['EMBED']-Blocks deaktiviert werden
+ */
+ 'EMBED' => true,
+
+ /**
+ * IRC-Link aktivieren (boolean)
+ *
+ * Solange Twitter oder IRC aktiviert ist, wird ein "Chat"-Tab mit den
+ * jeweiligen Links angezeigt.
+ *
+ * Ist dieses Feld auf true gesetzt, wird ein irc://-Link angezeigt.
+ * WebIrc wird nach dem Congress nicht mehr unterstützt ;)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird kein IRC-Link angezeigt
+ *
+ * Ebenso können alle IRC-Links durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['IRC']-Blocks deaktiviert werden
+ */
+ 'IRC' => true,
+
+ /**
+ * Mit dem Angaben in diesem Block können die Vorgaben aus dem
+ * globalen $GLOBALS['CONFIG']['IRC'] Block überschrieben werden.
+ *
+ * Der globale $GLOBALS['CONFIG']['IRC']-Block muss trotzdem existieren,
+ * da sonst überhaupt kein IRC-Link erzeugt wird. (ggf. einfach `= true` setzen)
+ */
+ //'IRC_CONFIG' => array(
+ // 'DISPLAY' => '#31C3-hall-1 @ hackint',
+ // 'URL' => 'irc://irc.hackint.eu:6667/31C3-hall-1',
+ //),
+
+ /**
+ * Twitter-Link aktivieren (boolean)
+ *
+ * Ist dieses Feld auf true gesetzt, wird ein Link zu Twitter angezeigt.
+ *
+ * Solange Twitter oder IRC aktiviert ist, wird ein "Chat"-Tab mit den
+ * jeweiligen Links angezeigt.
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird kein Twitter-Link angezeigt
+ *
+ * Ebenso können alle Twitter-Links durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['TWITTER']-Blocks deaktiviert werden
+ **/
+ 'TWITTER' => true,
+
+ /**
+ * Mit dem Angaben in diesem Block können die Vorgaben aus dem
+ * globalen $GLOBALS['CONFIG']['TWITTER'] Block überschrieben werden.
+ *
+ * Der globale $GLOBALS['CONFIG']['TWITTER']-Block muss trotzdem existieren,
+ * da sonst überhaupt kein IRC-Link erzeugt wird. (ggf. einfach `= true` setzen)
+ */
+ //'TWITTER_CONFIG' => array(
+ // 'DISPLAY' => '#hall1 @ twitter',
+ // 'TEXT' => '#31C3 #hall1',
+ //),
+ ),
+
+ 'tent-2' => array(
+ 'DISPLAY' => 'Tent 2 (North)',
+ 'STREAM' => 's2',
+ 'PREVIEW' => true,
+
+ 'TRANSLATION' => true,
+ 'SD_VIDEO' => true,
+ 'HD_VIDEO' => true,
+ 'AUDIO' => true,
+ 'SLIDES' => false,
+ 'MUSIC' => false,
+
+ 'SCHEDULE' => true,
+ 'SCHEDULE_NAME' => 'Simulacron-3',
+ 'FEEDBACK' => true,
+ 'SUBTITLES' => false,
+ 'EMBED' => true,
+ 'IRC' => true,
+ 'TWITTER' => true,
+ ),
+
+ 'ber' => array(
+ 'DISPLAY' => 'BER Stage',
+ 'STREAM' => 's3',
+ 'PREVIEW' => true,
+
+ 'TRANSLATION' => false,
+ 'SD_VIDEO' => true,
+ 'HD_VIDEO' => true,
+ 'AUDIO' => true,
+ 'SLIDES' => false,
+ 'MUSIC' => false,
+
+ 'SCHEDULE' => false,
+ //'SCHEDULE_NAME' => 'Vortrag 2',
+
+ 'FEEDBACK' => true,
+ 'SUBTITLES' => false,
+ 'EMBED' => true,
+ 'IRC' => true,
+ 'TWITTER' => true,
+ ),
+
+ 'lounge' => array(
+ 'DISPLAY' => 'Lounge',
+ 'MUSIC' => true,
+ 'EMBED' => true,
+ ),
+);
+
+
+
+/**
+ * Konfigurationen zum Konferenz-Fahrplan
+ * Wird dieser Block auskommentiert, werden alle Fahrplan-Bezogenen Features deaktiviert
+ */
+$GLOBALS['CONFIG']['SCHEDULE'] = array(
+ /**
+ * URL zum Fahrplan-XML
+ *
+ * Diese URL muss immer verfügbar sein, sonst können kann die Programm-Ansicht
+ * aufhören zu funktionieren. Wenn die Quelle unverlässlich ist ;) sollte ein
+ * externer HTTP-Cache vorgeschaltet werden.
+ */
+ 'URL' => 'configs/schedule.xml',
+
+ /**
+ * Nur die angegebenen Räume aus dem Fahrplan beachten
+ *
+ * Wird diese Zeile auskommentiert, werden alle Räume angezeigt
+ */
+ //'ROOMFILTER' => array('Saal 1', 'Saal 2', 'Saal G', 'Saal 6'),
+
+ /**
+ * APCU-Cache-Zeit in Sekunden
+ * Wird diese Zeile auskommentiert, werden die apc_*-Methoden nicht verwendet und
+ * der Fahrplan bei jedem Request von der Quelle geladen und geparst
+ */
+ //'CACHE' => 30*60,
+
+ /**
+ * Skalierung der Programm-Vorschau in Sekunden pro Pixel
+ */
+ 'SCALE' => 7,
+
+ /**
+ * Simuliere das Verhalten als wäre die Konferenz bereits heute
+ *
+ * Diese folgende Beispiel-Zeile Simuliert, dass das
+ * Konferenz-Datum 2014-12-29 auf den heutigen Tag 2015-02-24 verschoben ist.
+ */
+ 'SIMULATE_OFFSET' => 0,
+);
+
+
+
+/**
+ * Konfiguration des Feedback-Formulars
+ *
+ * Wird dieser Block auskommentiert, wird das gesamte Feedback-System deaktiviert
+ */
+$GLOBALS['CONFIG']['FEEDBACK'] = array(
+ /**
+ * DSN zum abspeichern der eingegebenen Daten
+ * die Datenbank muss eine Tabelle enthaltem, die dem in `lib/schema.sql` angegebenen
+ * Schema entspricht.
+ *
+ * Achtung vor Dateirechten: Bei SQLite reicht es nicht, wenn wer Webseiten-Benutzer
+ * die .sqlite3-Datei schreiben darf, er muss auch im übergeordneten Order neue
+ * (Lock-)Dateien anlegen dürfen
+ */
+ 'DSN' => 'sqlite:/opt/streaming-feedback/feedback.sqlite3',
+
+ /**
+ * Login-Daten für die /feedback/read/-Seite, auf der eingegangenes
+ * Feedback gelesen werden kann.
+ *
+ * Durch auskommentieren der beiden Optionen wird diese Seite komplett deaktiviert,
+ * es kann dann nur noch durch manuelle Inspektion der .sqlite3-Datei auf das Feedback
+ * zugegriffen werden.
+ */
+ 'USERNAME' => 'katze',
+ 'PASSWORD' => trim(@file_get_contents('/opt/streaming-feedback/feedback-password')),
+);
+
+/**
+ * Globaler Schalter für die Embedding-Funktionalitäten
+ *
+ * Wird diese Zeile auskommentiert oder auf False gesetzt, werden alle
+ * Embedding-Funktionen deaktiviert.
+ */
+$GLOBALS['CONFIG']['EMBED'] = true;
+
+/**
+ * Konfiguration des L2S2-Systems
+ * https://github.com/c3subtitles/L2S2
+ *
+ * Wird dieser Block auskommentiert, wird das gesamte Subtitle-System deaktiviert
+ */
+$GLOBALS['CONFIG']['SUBTITLES'] = array(
+ /**
+ * URL des L2S2-Servers
+ */
+ 'URL' => 'http://subtitles.c3voc.de/',
+);
+
+/**
+ * Globale Konfiguration der IRC-Links.
+ *
+ * Wird dieser Block auskommentiert, werden keine IRC-Links mehr erzeugt. Sollen die
+ * IRC-Links für jeden Raum einzeln konfiguriert werden, muss dieser Block trotzdem
+ * existieren sein. ggf. einfach auf true setzen:
+ *
+ * $GLOBALS['CONFIG']['IRC'] = true
+ */
+$GLOBALS['CONFIG']['IRC'] = array(
+ /**
+ * Anzeigetext für die IRC-Links.
+ *
+ * %s wird durch den Raum-Slug ersetzt.
+ * Ist eine weitere Anpassung erfoderlich, kann ein IRC_CONFIG-Block in der
+ * Raum-Konfiguration zum Überschreiben dieser Angaben verwendet werden.
+ */
+ 'DISPLAY' => '#camp-everywhere @ hackint',
+
+ /**
+ * URL für die IRC-Links.
+ * Hierbei kann sowohl ein irc://-Link als auch ein Link zu einem
+ * WebIrc-Provider wie z.B. 'https://kiwiirc.com/client/irc.hackint.eu/#31C3-%s'
+ * verwendet werden.
+ *
+ * %s wird durch den urlencodeten Raum-Slug ersetzt.
+ * Eine Anpassung kann ebenfalls in der Raum-Konfiguration vorgenommen werden.
+ */
+ 'URL' => 'irc://irc.hackint.eu:6667/camp-everywhere',
+);
+
+/**
+ * Globale Konfiguration der Twitter-Links.
+ *
+ * Wird dieser Block auskommentiert, werden keine Twitter-Links mehr erzeugt. Sollen die
+ * Twitter-Links für jeden Raum einzeln konfiguriert werden, muss dieser Block trotzdem
+ * existieren sein. ggf. einfach auf true setzen:
+ *
+ * $GLOBALS['CONFIG']['TWITTER'] = true
+ */
+$GLOBALS['CONFIG']['TWITTER'] = array(
+ /**
+ * Anzeigetext für die Twitter-Links.
+ *
+ * %s wird durch den Raum-Slug ersetzt.
+ * Ist eine weitere Anpassung erfoderlich, kann ein TWITTER_CONFIG-Block in der
+ * Raum-Konfiguration zum Überschreiben dieser Angaben verwendet werden.
+ */
+ 'DISPLAY' => '#cccamp15 @ twitter',
+
+ /**
+ * Vorgabe-Tweet-Text für die Twitter-Links.
+ *
+ * %s wird durch den Raum-Slug ersetzt.
+ * Eine Anpassung kann ebenfalls in der Raum-Konfiguration vorgenommen werden.
+ */
+ 'TEXT' => '#cccamp15',
+);
diff --git a/configs/conferences/cccamp15/main.less b/configs/conferences/cccamp15/main.less
new file mode 100644
index 0000000..6b3ceeb
--- /dev/null
+++ b/configs/conferences/cccamp15/main.less
@@ -0,0 +1,186 @@
+@import "../../../assets/css/_structure.less";
+
+// conference specific styles here
+
+@grey_light: #d3d2d2;
+@grey_dark: #918f90;
+@grey_darker: #4f4c4d;
+
+@brown_light: #94694d;
+@brown_dark: #7a563f;
+
+@green_light: #6c9e30;
+@green_dark: #598227;
+
+@purple_light: #77438d;
+@purple_dark: #623672;
+
+@blueish_light: #707f9a;
+@blueish_dark: #5c687e;
+
+
+
+@tents_light: @blueish_light;
+@tents_dark: @blueish_dark;
+
+@radio_light: @purple_light;
+@radio_dark: @purple_dark;
+
+@recordings_light: @grey_dark;
+@recordings_dark: @grey_darker;
+
+@multicast_light: @brown_light;
+@multicast_dark: @brown_dark;
+
+
+// often configured values (and their defaults):
+//
+@brand-primary: @green_light;
+@text-color: @green_dark;
+
+@link-color: @green_light;
+@link-hover-color: @green_dark;
+
+@navbar-default-color: white;
+@navbar-default-bg: @brown_dark;
+
+@navbar-default-link-color: white;
+@navbar-default-link-hover-color: darken(white, 20%);
+
+@panel-default-border: @green_light;
+
+
+
+.overview {
+ .headline {
+ display: none;
+ }
+
+ p a {
+ text-decoration: underline;
+ }
+
+ .room-group-n0 {
+ &, a {
+ color: @tents_dark;
+ }
+
+ .panel {
+ border-color: @tents_dark;
+
+ .panel-heading,
+ .panel-heading a{
+ background-color: @tents_light;
+ border-color: @tents_dark;
+ color: white;
+ }
+ }
+ }
+
+ .room-group-n2 {
+ &, a {
+ color: @radio_dark;
+ }
+
+ .panel {
+ border-color: @radio_dark;
+
+ .panel-heading {
+ background-color: @radio_light;
+ border-color: @radio_dark;
+ color: white;
+ }
+ }
+ }
+
+ .recordings {
+ &, a {
+ color: @recordings_light;
+ }
+ a:hover {
+ color: @recordings_dark;
+ }
+
+ .panel {
+ border-color: @recordings_dark;
+ }
+ }
+
+
+
+
+ .room-group-multicast {
+ &, a {
+ color: @multicast_dark;
+ }
+
+ .panel {
+ border-color: @multicast_dark;
+
+ .panel-heading {
+ background-color: @multicast_light;
+ border-color: @multicast_dark;
+ color: white;
+ }
+ }
+
+ .room a {
+ font-size: @jumbo-font-size;
+ line-height: @jumbo-line-height;
+ color: @multicast_dark;
+
+ @media (max-width: @screen-xs-min) {
+ font-size: @jumbo-font-size-xs;
+ }
+
+ display: block;
+ text-align: center;
+
+ &:hover {
+ text-decoration: none;
+ }
+ }
+ }
+}
+
+body {
+ background: url(../img/bg.png) no-repeat top left;
+ background-attachment: fixed;
+ background-position: 0px 50px;
+}
+
+.tab-content {
+ background-color: white;
+}
+
+
+.navbar-brand {
+ text-indent: -9999em;
+ background: url(../img/logo.png) no-repeat;
+ background-size: auto 43px;
+ background-position: 0 5px;
+ width: 180px;
+}
+
+
+
+
+// colors of the schedule ("Fahrplan") widget below the video-player
+//
+// @schedule-now: @brand-danger;
+// @schedule-now-bg: fade(lighten(@brand-danger, 5%), 60%);
+// @schedule-border: lighten(@brand-primary, 50%);
+//
+// @schedule-room: darken(@brand-primary, 15%);
+// @schedule-author: #444;
+//
+// @schedule-selected-room: lighten(@brand-success, 10%);
+//
+// @schedule-daychange: darken(@brand-primary, 20%);
+// @schedule-daychange-bg: fade(white, 30%);
+//
+// @schedule-gap: darken(@brand-primary, 20%);
+// @schedule-gap-bg: fade(white, 30%);
+//
+// @schedule-pause: white;
+// @schedule-pause-bg: lighten(black, 85%);
diff --git a/configs/conferences/chaosradio/config.php b/configs/conferences/chaosradio/config.php
new file mode 100644
index 0000000..728f143
--- /dev/null
+++ b/configs/conferences/chaosradio/config.php
@@ -0,0 +1,459 @@
+<?php
+date_default_timezone_set('Europe/Berlin');
+
+/**
+ * Während der Entwicklung wird die BASEURL automatisch erraten
+ * In Produktionssituationen sollte manuell eine konfiguriert werden um Überraschungen zu vermeiden
+ *
+ * Protokollfreie URLs (welche, die mit // beginnen), werden automatisch mit dem korrekten Protokoll ergänzt.
+ * In diesem Fall wird auch ein SSL-Umschalt-Button im Header angezeigt
+ */
+if($_SERVER['HTTP_HOST'] != 'localhost')
+ $GLOBALS['CONFIG']['BASEURL'] = '//streaming.media.ccc.de/';
+
+
+$EPISODE = 217;
+$DATE = '29. September 2015';
+$TITLE = "Chaosradio $EPISODE - Ein Einblick in die Security-Industrie";
+
+
+$GLOBALS['CONFIG']['CONFERENCE'] = array(
+ /**
+ * Der Startzeitpunkt der Konferenz als Unix-Timestamp. Befinden wir uns davor, wird die Closed-Seite
+ * mit einem Text der Art "hat noch nicht angefangen" angezeigt.
+ *
+ * Wird dieser Zeitpunkt nicht angegeben, gilt die Konferenz immer als angefangen. (Siehe aber ENDS_AT
+ * und CLOSED weiter unten)
+ */
+ 'STARTS_AT' => strtotime("2015-10-29 21:30"),
+
+ /**
+ * Der Endzeitpunkt der Konferenz als Unix-Timestamp. Befinden wir uns danach, wird eine Danke-Und-Kommen-Sie-
+ * Gut-Nach-Hause-Seite sowie einem Ausblick auf die kommenden Events angezeigt.
+ *
+ * Wird dieser Zeitpunkt nicht angegeben, endet die Konferenz nie. (Siehe aber CLOSED weiter unten)
+ */
+ 'ENDS_AT' => strtotime("2015-10-29 23:59"),
+
+ /**
+ * Hiermit kann die Funktionalitaet von STARTS_AT/ENDS_AT überschrieben werden. Der Wert 'before'
+ * simuliert, dass die Konferenz noch nicht begonnen hat. Der Wert 'after' simuliert, dass die Konferenz
+ * bereits beendet ist. 'running' simuliert eine laufende Konferenz.
+ *
+ * Der Boolean true ist aus Abwärtskompatibilitätsgründen äquivalent zu 'after'. False ist äquivalent
+ * zu 'running'.
+ */
+ //'CLOSED' => false,
+
+ /**
+ * Titel der Konferenz (kann Leer- und Sonderzeichen enthalten)
+ * Dieser im Seiten-Header, im <title>-Tag, in der About-Seite und ggf. ab weiteren Stellen als
+ * Anzeigetext benutzt
+ */
+ 'TITLE' => 'Chaosradio',
+
+ /**
+ * Veranstalter
+ * Wird für den <meta name="author">-Tag verdet. Wird diese Zeile auskommentiert, wird kein solcher
+ * <meta>-Tag generiert.
+ */
+ 'AUTHOR' => 'CCCB',
+
+ /**
+ * Beschreibungstext
+ * Wird für den <meta name="description">-Tag verdet. Wird diese Zeile auskommentiert, wird kein solcher
+ * <meta>-Tag generiert.
+ */
+ 'DESCRIPTION' => 'Chaosradio (CR) ist eine zweistündige Talk-Sendung, die seit 1995 jeden letzten Donnerstag im Monat im Rahmen gesendet wird ',
+
+ /**
+ * Schlüsselwortliste, Kommasepariert
+ * Wird für den <meta name="keywords">-Tag verdet. Wird diese Zeile auskommentiert, wird kein solcher
+ * <meta>-Tag generiert.
+ */
+ 'KEYWORDS' => 'Chaosradio, Chaos Computer Club, Berlin, Video, Media, Streaming',
+
+ /**
+ * HTML-Code für den Footer (z.B. für spezielle Attribuierung mit <a>-Tags)
+ * Sollte üblicherweise nur Inline-Elemente enthalten
+ * Wird diese Zeile auskommentiert, wird die Standard-Attribuierung für (c3voc.de) verwendet
+ */
+ 'FOOTER_HTML' => '
+ by <a href="https://ccc.de">Chaos Computer Club e.V</a> &amp;
+ <a href="https://c3voc.de">c3voc</a>
+ ',
+
+ /**
+ * HTML-Code für den Banner (nur auf der Startseite, direkt unter dem Header)
+ * wird üblicherweise für KeyVisuals oder Textmarke verwendet (vgl. Blaues
+ * Wischiwaschi auf http://media.ccc.de/)
+ *
+ * Dieser HTML-Block wird üblicherweise in der main.less speziell für die
+ * Konferenz umgestaltet.
+ *
+ * Wird diese Zeile auskommentiert, wird kein Banner ausgegeben.
+ */
+ 'BANNER_HTML' => "
+ <h2>Chaosradio #$EPISODE – $DATE</h2>
+ <h3>$TITLE</h3>
+ ",
+
+ /**
+ * Link zu den Recordings
+ * Wird diese Zeile auskommentiert, wird der Link nicht angezeigt
+ */
+ 'RELEASES' => 'https://media.ccc.de/browse/broadcast/chaosradio/index.html',
+
+ /**
+ * Um die interne ReLive-Ansicht zu aktivieren, kann hier ein ReLive-JSON
+ * konfiguriert werden. Üblicherweise wird diese Datei über das Script
+ * configs/download.sh heruntergeladen, welches von einem Cronjob
+ * regelmäßig getriggert wird.
+ *
+ * Wird diese Zeile auskommentiert, wird der Link nicht angezeigt
+ */
+ //'RELIVE_JSON' => 'configs/vod.json',
+);
+
+/**
+ * Konfiguration der Stream-Übersicht auf der Startseite
+ */
+$GLOBALS['CONFIG']['OVERVIEW'] = array(
+ /**
+ * Abschnitte aud der Startseite und darunter aufgeführte Räume
+ * Es können beliebig neue Gruppen und Räume hinzugefügt werden
+ *
+ * Die Räume müssen in $GLOBALS['CONFIG']['ROOMS'] konfiguriert werden,
+ * sonst werden sie nicht angezeigt.
+ */
+ 'GROUPS' => array(
+ '' => array(
+ 'chaosradio',
+ ),
+ ),
+);
+
+
+
+/**
+ * Liste der Räume (= Audio & Video Produktionen, also auch DJ-Sets oä.)
+ */
+$GLOBALS['CONFIG']['ROOMS'] = array(
+ /**
+ * Array-Key ist der Raum-Slug, der z.B. auch zum erstellen der URLs,
+ * in $GLOBALS['CONFIG']['OVERVIEW'] oder im Feedback verwendet wird.
+ */
+ 'chaosradio' => array(
+ /**
+ * Angezeige-Name
+ */
+ 'DISPLAY' => "Chaosradio #$EPISODE",
+ /**
+ * ID des Video/Audio-Streams. Die Stream-ID ist davon abhängig, welches
+ * Event-Case in welchem Raum aufgebaut wird und wird üblicherweise von
+ * s1 bis s5 durchnummeriert.
+ */
+ 'STREAM' => 's5',
+
+ /**
+ * Stream-Vorschaubildchen auf der Übersichtsseite anzeigen
+ * Damit das funktioniert muss der entsprechende runit-Task auf dem
+ * CDN-Quell-Host (live.ber) laufen.
+ */
+ 'PREVIEW' => true,
+
+ /**
+ * Übersetzungstonspur aktivieren
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist werden nur
+ * die native-Streams verwendet, andernfalls wird native und translated
+ * angeboten und auch für beide Tonspuren eine Player-Seite angezeigt.
+ */
+ 'TRANSLATION' => false,
+
+ /**
+ * stereo-Tonspur statt native-Tonspur benutzen
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist werden
+ * die "native"-Mono-Streams verwendet, andernfalls wird statt "native"
+ * der Streamname "stereo" eingesetzt. Im normalen Konferenz-Setup
+ * müssen dann beide Kanäle der Kamera mit einem Signal bespielt werden.
+ */
+ 'STEREO' => false,
+
+ /**
+ * SD-Video-Stream (1024×576) verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein SD-Video
+ * angeboten. Wird auch HD_VIDEO auf false gesetzt oder auskommentiert ist, wird
+ * für diesen Raum überhaupt kein Video angeboten.
+ *
+ * In diesem Fall wird, sofern jeweils aktiviert, Slides, Audio und zuletzt Musik
+ * als Default-Stream angenommen.
+ */
+ 'SD_VIDEO' => true,
+
+ /**
+ * HD-Video-Stream (1920×1080) verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein HD-Video
+ * angeboten. Wird auch SD_VIDEO auf false gesetzt oder auskommentiert ist, wird
+ * für diesen Raum überhaupt kein Video angeboten.
+ *
+ * In diesem Fall wird, sofern jeweils aktiviert, Slides, Audio und zuletzt Musik
+ * als Default-Stream angenommen.
+ */
+ 'HD_VIDEO' => true,
+
+ /**
+ * Slide-Only-Stream (1024×576) verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein Slide-Only-
+ * Stream angeboten. Für diesen Raum wird dann keim Slides-Tab angeboten.
+ *
+ * In diesem Fall wird, sofern jeweils aktiviert, Audio und zuletzt Musik als
+ * Default-Stream angenommen.
+ */
+ 'SLIDES' => false,
+
+ /**
+ * Audio-Only-Stream verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein Audio-Only-
+ * Stream angeboten. Für diesen Raum wird dann keim Audio-Tab angeboten.
+ *
+ * In diesem Fall wird, sofern aktiviert, Musik als Default-Stream angenommen.
+ */
+ 'AUDIO' => true,
+
+ /**
+ * Musik-Stream verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein Musik-Stream
+ * angeboten. Für diesen Raum wird dann keim Musik-Tab angeboten.
+ *
+ * Ist kein einziger Stream angebote, wird statt der Stream-Seite ein 404-Fehler
+ * angezeigt.
+ */
+ 'MUSIC' => false,
+
+ /**
+ * Fahrplan-Ansicht auf der Raum-Seite aktivieren (boolean)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird der Raum nicht im Fahrplan gesucht und auch auf der Startseite
+ * findet keine Darstellung statt.
+ *
+ * Ebenso können alle Fahrplan-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['SCHEDULE']-Blocks deaktiviert werden
+ */
+ 'SCHEDULE' => false,
+
+ /**
+ * Name des Raums im Fahrplan
+ * Wenn diese Zeile auskommentiert ist wird der Raum-Slug verwendet
+ */
+ //'SCHEDULE_NAME' => 'Saal 1',
+
+ /**
+ * Feedback anzeigen (boolean)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * taucht der Raum auch im globalen Feedback-Formular nicht auf.
+ *
+ * Ebenso können alle Feedback-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['FEEDBACK']-Blocks deaktiviert werden
+ */
+ 'FEEDBACK' => false,
+
+ /**
+ * Subtitles-Player aktivieren (boolean)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird der Subtitles-Button und die damit verbundenen Funktionen deaktiviert.
+ *
+ * Ebenso können alle Subtitles-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['SUBTITLES']-Blocks deaktiviert werden
+ */
+ 'SUBTITLES' => false,
+
+ /**
+ * Embed-Form aktivieren (boolean)
+ *
+ * Ist dieses Feld auf true gesetzt, wird ein Embed-Tab unter dem Video
+ * angezeigt. Darüber kann der Player als iframe eingebunden werden.
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird kein Embed-Tab angeboten und die URL zum Einbetten existiert nicht.
+ *
+ * Ebenso können alle Embedding-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['EMBED']-Blocks deaktiviert werden
+ */
+ 'EMBED' => true,
+
+ /**
+ * IRC-Link aktivieren (boolean)
+ *
+ * Solange Twitter oder IRC aktiviert ist, wird ein "Chat"-Tab mit den
+ * jeweiligen Links angezeigt.
+ *
+ * Ist dieses Feld auf true gesetzt, wird ein irc://-Link angezeigt.
+ * WebIrc wird nach dem Congress nicht mehr unterstützt ;)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird kein IRC-Link angezeigt
+ *
+ * Ebenso können alle IRC-Links durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['IRC']-Blocks deaktiviert werden
+ */
+ 'IRC' => false,
+
+ /**
+ * Mit dem Angaben in diesem Block können die Vorgaben aus dem
+ * globalen $GLOBALS['CONFIG']['IRC'] Block überschrieben werden.
+ *
+ * Der globale $GLOBALS['CONFIG']['IRC']-Block muss trotzdem existieren,
+ * da sonst überhaupt kein IRC-Link erzeugt wird. (ggf. einfach `= true` setzen)
+ */
+ //'IRC_CONFIG' => array(
+ // 'DISPLAY' => '#31C3-hall-1 @ hackint',
+ // 'URL' => 'irc://irc.hackint.eu:6667/31C3-hall-1',
+ //),
+
+ /**
+ * Twitter-Link aktivieren (boolean)
+ *
+ * Ist dieses Feld auf true gesetzt, wird ein Link zu Twitter angezeigt.
+ *
+ * Solange Twitter oder IRC aktiviert ist, wird ein "Chat"-Tab mit den
+ * jeweiligen Links angezeigt.
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird kein Twitter-Link angezeigt
+ *
+ * Ebenso können alle Twitter-Links durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['TWITTER']-Blocks deaktiviert werden
+ **/
+ 'TWITTER' => true,
+
+ /**
+ * Mit dem Angaben in diesem Block können die Vorgaben aus dem
+ * globalen $GLOBALS['CONFIG']['TWITTER'] Block überschrieben werden.
+ *
+ * Der globale $GLOBALS['CONFIG']['TWITTER']-Block muss trotzdem existieren,
+ * da sonst überhaupt kein IRC-Link erzeugt wird. (ggf. einfach `= true` setzen)
+ */
+ //'TWITTER_CONFIG' => array(
+ // 'DISPLAY' => '#hall1 @ twitter',
+ // 'TEXT' => '#31C3 #hall1',
+ //),
+ ),
+);
+
+
+
+/**
+ * Konfigurationen zum Konferenz-Fahrplan
+ * Wird dieser Block auskommentiert, werden alle Fahrplan-Bezogenen Features deaktiviert
+ */
+$GLOBALS['CONFIG']['SCHEDULE'] = array(
+ /**
+ * URL zum Fahrplan-XML
+ *
+ * Diese URL muss immer verfügbar sein, sonst können kann die Programm-Ansicht
+ * aufhören zu funktionieren. Üblicherweise wird diese daher Datei über
+ * das Script configs/download.sh heruntergeladen, welches von einem
+ * Cronjob regelmäßig getriggert wird.
+ */
+ 'URL' => 'configs/schedule.xml',
+
+ /**
+ * Nur die angegebenen Räume aus dem Fahrplan beachten
+ *
+ * Wird diese Zeile auskommentiert, werden alle Räume angezeigt
+ */
+ //'ROOMFILTER' => array('Saal 1', 'Saal 2', 'Saal G', 'Saal 6'),
+
+ /**
+ * Skalierung der Programm-Vorschau in Sekunden pro Pixel
+ */
+ 'SCALE' => 7,
+
+ /**
+ * Simuliere das Verhalten als wäre die Konferenz bereits heute
+ *
+ * Diese folgende Beispiel-Zeile Simuliert, dass das
+ * Konferenz-Datum 2014-12-29 auf den heutigen Tag 2015-02-24 verschoben ist.
+ */
+ //'SIMULATE_OFFSET' => strtotime(/* Conference-Date */ '2014-12-28') - strtotime(/* Today */ '2015-03-01'),
+ 'SIMULATE_OFFSET' => 0,
+);
+
+
+
+/**
+ * Globaler Schalter für die Embedding-Funktionalitäten
+ *
+ * Wird diese Zeile auskommentiert oder auf False gesetzt, werden alle
+ * Embedding-Funktionen deaktiviert.
+ */
+$GLOBALS['CONFIG']['EMBED'] = true;
+
+/**
+ * Globale Konfiguration der IRC-Links.
+ *
+ * Wird dieser Block auskommentiert, werden keine IRC-Links mehr erzeugt. Sollen die
+ * IRC-Links für jeden Raum einzeln konfiguriert werden, muss dieser Block trotzdem
+ * existieren sein. ggf. einfach auf true setzen:
+ *
+ * $GLOBALS['CONFIG']['IRC'] = true
+ */
+$GLOBALS['CONFIG']['IRC'] = array(
+ /**
+ * Anzeigetext für die IRC-Links.
+ *
+ * %s wird durch den Raum-Slug ersetzt.
+ * Ist eine weitere Anpassung erfoderlich, kann ein IRC_CONFIG-Block in der
+ * Raum-Konfiguration zum Überschreiben dieser Angaben verwendet werden.
+ */
+ 'DISPLAY' => '#chaosradio @ freenode',
+
+ /**
+ * URL für die IRC-Links.
+ * Hierbei kann sowohl ein irc://-Link als auch ein Link zu einem
+ * WebIrc-Provider wie z.B. 'https://kiwiirc.com/client/irc.hackint.eu/#31C3-%s'
+ * verwendet werden.
+ *
+ * %s wird durch den urlencodeten Raum-Slug ersetzt.
+ * Eine Anpassung kann ebenfalls in der Raum-Konfiguration vorgenommen werden.
+ */
+ 'URL' => 'irc://irc.freenode.net/chaosradio',
+);
+
+/**
+ * Globale Konfiguration der Twitter-Links.
+ *
+ * Wird dieser Block auskommentiert, werden keine Twitter-Links mehr erzeugt. Sollen die
+ * Twitter-Links für jeden Raum einzeln konfiguriert werden, muss dieser Block trotzdem
+ * existieren sein. ggf. einfach auf true setzen:
+ *
+ * $GLOBALS['CONFIG']['TWITTER'] = true
+ */
+$GLOBALS['CONFIG']['TWITTER'] = array(
+ /**
+ * Anzeigetext für die Twitter-Links.
+ *
+ * %s wird durch den Raum-Slug ersetzt.
+ * Ist eine weitere Anpassung erfoderlich, kann ein TWITTER_CONFIG-Block in der
+ * Raum-Konfiguration zum Überschreiben dieser Angaben verwendet werden.
+ */
+ 'DISPLAY' => '#chaosradio @ twitter',
+
+ /**
+ * Vorgabe-Tweet-Text für die Twitter-Links.
+ *
+ * %s wird durch den Raum-Slug ersetzt.
+ * Eine Anpassung kann ebenfalls in der Raum-Konfiguration vorgenommen werden.
+ */
+ 'TEXT' => '#chaosradio',
+);
diff --git a/configs/conferences/chaosradio/main.less b/configs/conferences/chaosradio/main.less
new file mode 100644
index 0000000..b0c8f3a
--- /dev/null
+++ b/configs/conferences/chaosradio/main.less
@@ -0,0 +1,30 @@
+@import "../../../assets/css/_structure.less";
+
+@brand-primary: #3684dc;
+@highlight: #b6cd5d;
+@background: #251c16;
+@text-color: #ffffff;
+
+@link-color: #FFFF99;
+@panel-bg: #222222;
+@well-bg: @panel-bg;
+@panel-primary-border: #FFFFFF;
+@panel-default-heading-bg: #333333;
+@panel-default-text: #FFFFFF;
+
+@navbar-default-link-color: #FFFFFF;
+
+@nav-link-hover-bg: #000000;
+
+@navbar-default-bg: #333333;
+
+// conference specific styles here
+
+.banner {
+ text-align: center;
+ color: @brand-primary;
+}
+
+body {
+ background-color: black;
+}
diff --git a/configs/conferences/datengarten/config.php b/configs/conferences/datengarten/config.php
new file mode 100644
index 0000000..c120185
--- /dev/null
+++ b/configs/conferences/datengarten/config.php
@@ -0,0 +1,489 @@
+<?php
+date_default_timezone_set('Europe/Berlin');
+
+/**
+ * Während der Entwicklung wird die BASEURL automatisch erraten
+ * In Produktionssituationen sollte manuell eine konfiguriert werden um Überraschungen zu vermeiden
+ *
+ * Protokollfreie URLs (welche, die mit // beginnen), werden automatisch mit dem korrekten Protokoll ergänzt.
+ * In diesem Fall wird auch ein SSL-Umschalt-Button im Header angezeigt
+ */
+if($_SERVER['HTTP_HOST'] != 'localhost')
+ $GLOBALS['CONFIG']['BASEURL'] = '//streaming.media.ccc.de/';
+
+
+$EPISODE = 59;
+$DATE = '10. November 2015';
+$TITLE = 'lynxis - Coreboot';
+
+
+$GLOBALS['CONFIG']['CONFERENCE'] = array(
+ /**
+ * Der Startzeitpunkt der Konferenz als Unix-Timestamp. Befinden wir uns davor, wird die Closed-Seite
+ * mit einem Text der Art "hat noch nicht angefangen" angezeigt.
+ *
+ * Wird dieser Zeitpunkt nicht angegeben, gilt die Konferenz immer als angefangen. (Siehe aber ENDS_AT
+ * und CLOSED weiter unten)
+ */
+ 'STARTS_AT' => strtotime("2015-11-10 18:30"),
+
+ /**
+ * Der Endzeitpunkt der Konferenz als Unix-Timestamp. Befinden wir uns danach, wird eine Danke-Und-Kommen-Sie-
+ * Gut-Nach-Hause-Seite sowie einem Ausblick auf die kommenden Events angezeigt.
+ *
+ * Wird dieser Zeitpunkt nicht angegeben, endet die Konferenz nie. (Siehe aber CLOSED weiter unten)
+ */
+ 'ENDS_AT' => strtotime("2015-11-10 23:30"),
+
+ /**
+ * Hiermit kann die Funktionalitaet von STARTS_AT/ENDS_AT überschrieben werden. Der Wert 'before'
+ * simuliert, dass die Konferenz noch nicht begonnen hat. Der Wert 'after' simuliert, dass die Konferenz
+ * bereits beendet ist. 'running' simuliert eine laufende Konferenz.
+ *
+ * Der Boolean true ist aus Abwärtskompatibilitätsgründen äquivalent zu 'after'. False ist äquivalent
+ * zu 'running'.
+ */
+ 'CLOSED' => true,
+
+ /**
+ * Titel der Konferenz (kann Leer- und Sonderzeichen enthalten)
+ * Dieser im Seiten-Header, im <title>-Tag, in der About-Seite und ggf. ab weiteren Stellen als
+ * Anzeigetext benutzt
+ */
+ 'TITLE' => "Datengarten #$EPISODE",
+
+ /**
+ * Veranstalter
+ * Wird für den <meta name="author">-Tag verdet. Wird diese Zeile auskommentiert, wird kein solcher
+ * <meta>-Tag generiert.
+ */
+ 'AUTHOR' => 'CCCB',
+
+ /**
+ * Beschreibungstext
+ * Wird für den <meta name="description">-Tag verdet. Wird diese Zeile auskommentiert, wird kein solcher
+ * <meta>-Tag generiert.
+ */
+ 'DESCRIPTION' => 'Der Datengarten ist eine Vortrags- und Projektreihe im Rahmen des Club Discordia.',
+
+ /**
+ * Schlüsselwortliste, Kommasepariert
+ * Wird für den <meta name="keywords">-Tag verdet. Wird diese Zeile auskommentiert, wird kein solcher
+ * <meta>-Tag generiert.
+ */
+ 'KEYWORDS' => 'Datengarten, Chaos Computer Club, Berlin, Video, Media, Streaming, Club Discordia',
+
+ /**
+ * HTML-Code für den Footer (z.B. für spezielle Attribuierung mit <a>-Tags)
+ * Sollte üblicherweise nur Inline-Elemente enthalten
+ * Wird diese Zeile auskommentiert, wird die Standard-Attribuierung für (c3voc.de) verwendet
+ */
+ 'FOOTER_HTML' => '
+ by <a href="https://ccc.de">Chaos Computer Club e.V</a> &amp;
+ <a href="https://c3voc.de">c3voc</a>
+ ',
+
+ /**
+ * HTML-Code für den Banner (nur auf der Startseite, direkt unter dem Header)
+ * wird üblicherweise für KeyVisuals oder Textmarke verwendet (vgl. Blaues
+ * Wischiwaschi auf http://media.ccc.de/)
+ *
+ * Dieser HTML-Block wird üblicherweise in der main.less speziell für die
+ * Konferenz umgestaltet.
+ *
+ * Wird diese Zeile auskommentiert, wird kein Banner ausgegeben.
+ */
+ 'BANNER_HTML' => "
+ <h2>Datengarten #$EPISODE – $DATE</h2>
+ <h3>$TITLE</h3>
+ ",
+
+ /**
+ * Link zu den Recordings
+ * Wird diese Zeile auskommentiert, wird der Link nicht angezeigt
+ */
+ 'RELEASES' => 'https://media.ccc.de/browse/events/datengarten/index.html',
+
+ /**
+ * Um die interne ReLive-Ansicht zu aktivieren, kann hier ein ReLive-JSON
+ * konfiguriert werden. Üblicherweise wird diese Datei über das Script
+ * configs/download.sh heruntergeladen, welches von einem Cronjob
+ * regelmäßig getriggert wird.
+ *
+ * Wird diese Zeile auskommentiert, wird der Link nicht angezeigt
+ */
+ //'RELIVE_JSON' => 'configs/vod.json',
+);
+
+/**
+ * Konfiguration der Stream-Übersicht auf der Startseite
+ */
+$GLOBALS['CONFIG']['OVERVIEW'] = array(
+ /**
+ * Abschnitte aud der Startseite und darunter aufgeführte Räume
+ * Es können beliebig neue Gruppen und Räume hinzugefügt werden
+ *
+ * Die Räume müssen in $GLOBALS['CONFIG']['ROOMS'] konfiguriert werden,
+ * sonst werden sie nicht angezeigt.
+ */
+ 'GROUPS' => array(
+ '' => array(
+ 'datengarten',
+ ),
+ ),
+);
+
+
+
+/**
+ * Liste der Räume (= Audio & Video Produktionen, also auch DJ-Sets oä.)
+ */
+$GLOBALS['CONFIG']['ROOMS'] = array(
+ /**
+ * Array-Key ist der Raum-Slug, der z.B. auch zum erstellen der URLs,
+ * in $GLOBALS['CONFIG']['OVERVIEW'] oder im Feedback verwendet wird.
+ */
+ 'datengarten' => array(
+ /**
+ * Angezeige-Name
+ */
+ 'DISPLAY' => "Datengarten #$EPISODE",
+
+ /**
+ * ID des Video/Audio-Streams. Die Stream-ID ist davon abhängig, welches
+ * Event-Case in welchem Raum aufgebaut wird und wird üblicherweise von
+ * s1 bis s5 durchnummeriert.
+ */
+ 'STREAM' => 's5',
+
+ /**
+ * Stream-Vorschaubildchen auf der Übersichtsseite anzeigen
+ * Damit das funktioniert muss der entsprechende runit-Task auf dem
+ * CDN-Quell-Host (live.ber) laufen.
+ */
+ 'PREVIEW' => true,
+
+ /**
+ * Übersetzungstonspur aktivieren
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist werden nur
+ * die native-Streams verwendet, andernfalls wird native und translated
+ * angeboten und auch für beide Tonspuren eine Player-Seite angezeigt.
+ */
+ 'TRANSLATION' => false,
+
+ /**
+ * stereo-Tonspur statt native-Tonspur benutzen
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist werden
+ * die "native"-Mono-Streams verwendet, andernfalls wird statt "native"
+ * der Streamname "stereo" eingesetzt. Im normalen Konferenz-Setup
+ * müssen dann beide Kanäle der Kamera mit einem Signal bespielt werden.
+ */
+ 'STEREO' => false,
+
+ /**
+ * SD-Video-Stream (1024×576) verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein SD-Video
+ * angeboten. Wird auch HD_VIDEO auf false gesetzt oder auskommentiert ist, wird
+ * für diesen Raum überhaupt kein Video angeboten.
+ *
+ * In diesem Fall wird, sofern jeweils aktiviert, Slides, Audio und zuletzt Musik
+ * als Default-Stream angenommen.
+ */
+ 'SD_VIDEO' => true,
+
+ /**
+ * HD-Video-Stream (1920×1080) verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein HD-Video
+ * angeboten. Wird auch SD_VIDEO auf false gesetzt oder auskommentiert ist, wird
+ * für diesen Raum überhaupt kein Video angeboten.
+ *
+ * In diesem Fall wird, sofern jeweils aktiviert, Slides, Audio und zuletzt Musik
+ * als Default-Stream angenommen.
+ */
+ 'HD_VIDEO' => true,
+
+ /**
+ * Slide-Only-Stream (1024×576) verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein Slide-Only-
+ * Stream angeboten. Für diesen Raum wird dann keim Slides-Tab angeboten.
+ *
+ * In diesem Fall wird, sofern jeweils aktiviert, Audio und zuletzt Musik als
+ * Default-Stream angenommen.
+ */
+ 'SLIDES' => false,
+
+ /**
+ * Audio-Only-Stream verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein Audio-Only-
+ * Stream angeboten. Für diesen Raum wird dann keim Audio-Tab angeboten.
+ *
+ * In diesem Fall wird, sofern aktiviert, Musik als Default-Stream angenommen.
+ */
+ 'AUDIO' => true,
+
+ /**
+ * Musik-Stream verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein Musik-Stream
+ * angeboten. Für diesen Raum wird dann keim Musik-Tab angeboten.
+ *
+ * Ist kein einziger Stream angebote, wird statt der Stream-Seite ein 404-Fehler
+ * angezeigt.
+ */
+ 'MUSIC' => false,
+
+ /**
+ * Fahrplan-Ansicht auf der Raum-Seite aktivieren (boolean)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird der Raum nicht im Fahrplan gesucht und auch auf der Startseite
+ * findet keine Darstellung statt.
+ *
+ * Ebenso können alle Fahrplan-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['SCHEDULE']-Blocks deaktiviert werden
+ */
+ 'SCHEDULE' => false,
+
+ /**
+ * Name des Raums im Fahrplan
+ * Wenn diese Zeile auskommentiert ist wird der Raum-Slug verwendet
+ */
+ //'SCHEDULE_NAME' => 'Saal 1',
+
+ /**
+ * Feedback anzeigen (boolean)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * taucht der Raum auch im globalen Feedback-Formular nicht auf.
+ *
+ * Ebenso können alle Feedback-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['FEEDBACK']-Blocks deaktiviert werden
+ */
+ 'FEEDBACK' => false,
+
+ /**
+ * Subtitles-Player aktivieren (boolean)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird der Subtitles-Button und die damit verbundenen Funktionen deaktiviert.
+ *
+ * Ebenso können alle Subtitles-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['SUBTITLES']-Blocks deaktiviert werden
+ */
+ 'SUBTITLES' => false,
+
+ /**
+ * Embed-Form aktivieren (boolean)
+ *
+ * Ist dieses Feld auf true gesetzt, wird ein Embed-Tab unter dem Video
+ * angezeigt. Darüber kann der Player als iframe eingebunden werden.
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird kein Embed-Tab angeboten und die URL zum Einbetten existiert nicht.
+ *
+ * Ebenso können alle Embedding-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['EMBED']-Blocks deaktiviert werden
+ */
+ 'EMBED' => true,
+
+ /**
+ * IRC-Link aktivieren (boolean)
+ *
+ * Solange Twitter oder IRC aktiviert ist, wird ein "Chat"-Tab mit den
+ * jeweiligen Links angezeigt.
+ *
+ * Ist dieses Feld auf true gesetzt, wird ein irc://-Link angezeigt.
+ * WebIrc wird nach dem Congress nicht mehr unterstützt ;)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird kein IRC-Link angezeigt
+ *
+ * Ebenso können alle IRC-Links durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['IRC']-Blocks deaktiviert werden
+ */
+ 'IRC' => true,
+
+ /**
+ * Mit dem Angaben in diesem Block können die Vorgaben aus dem
+ * globalen $GLOBALS['CONFIG']['IRC'] Block überschrieben werden.
+ *
+ * Der globale $GLOBALS['CONFIG']['IRC']-Block muss trotzdem existieren,
+ * da sonst überhaupt kein IRC-Link erzeugt wird. (ggf. einfach `= true` setzen)
+ */
+ //'IRC_CONFIG' => array(
+ // 'DISPLAY' => '#31C3-hall-1 @ hackint',
+ // 'URL' => 'irc://irc.hackint.eu:6667/31C3-hall-1',
+ //),
+
+ /**
+ * Twitter-Link aktivieren (boolean)
+ *
+ * Ist dieses Feld auf true gesetzt, wird ein Link zu Twitter angezeigt.
+ *
+ * Solange Twitter oder IRC aktiviert ist, wird ein "Chat"-Tab mit den
+ * jeweiligen Links angezeigt.
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird kein Twitter-Link angezeigt
+ *
+ * Ebenso können alle Twitter-Links durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['TWITTER']-Blocks deaktiviert werden
+ **/
+ 'TWITTER' => true,
+
+ /**
+ * Mit dem Angaben in diesem Block können die Vorgaben aus dem
+ * globalen $GLOBALS['CONFIG']['TWITTER'] Block überschrieben werden.
+ *
+ * Der globale $GLOBALS['CONFIG']['TWITTER']-Block muss trotzdem existieren,
+ * da sonst überhaupt kein IRC-Link erzeugt wird. (ggf. einfach `= true` setzen)
+ */
+ //'TWITTER_CONFIG' => array(
+ // 'DISPLAY' => '#hall1 @ twitter',
+ // 'TEXT' => '#31C3 #hall1',
+ //),
+ ),
+);
+
+
+
+/**
+ * Konfigurationen zum Konferenz-Fahrplan
+ * Wird dieser Block auskommentiert, werden alle Fahrplan-Bezogenen Features deaktiviert
+ */
+//$GLOBALS['CONFIG']['SCHEDULE'] = array(
+ /**
+ * URL zum Fahrplan-XML
+ *
+ * Diese URL muss immer verfügbar sein, sonst können kann die Programm-Ansicht
+ * aufhören zu funktionieren. Üblicherweise wird diese daher Datei über
+ * das Script configs/download.sh heruntergeladen, welches von einem
+ * Cronjob regelmäßig getriggert wird.
+ */
+// 'URL' => 'configs/schedule.xml',
+
+ /**
+ * Nur die angegebenen Räume aus dem Fahrplan beachten
+ *
+ * Wird diese Zeile auskommentiert, werden alle Räume angezeigt
+ */
+ //'ROOMFILTER' => array('Saal 1', 'Saal 2', 'Saal G', 'Saal 6'),
+
+ /**
+ * Skalierung der Programm-Vorschau in Sekunden pro Pixel
+ */
+// 'SCALE' => 7,
+
+ /**
+ * Simuliere das Verhalten als wäre die Konferenz bereits heute
+ *
+ * Diese folgende Beispiel-Zeile Simuliert, dass das
+ * Konferenz-Datum 2014-12-29 auf den heutigen Tag 2015-02-24 verschoben ist.
+ */
+ //'SIMULATE_OFFSET' => strtotime(/* Conference-Date */ '2014-12-28') - strtotime(/* Today */ '2015-03-01'),
+// 'SIMULATE_OFFSET' => 0,
+//);
+
+
+
+/**
+ * Konfiguration des Feedback-Formulars
+ *
+ * Wird dieser Block auskommentiert, wird das gesamte Feedback-System deaktiviert
+ */
+//$GLOBALS['CONFIG']['FEEDBACK'] = array(
+ /**
+ * DSN zum abspeichern der eingegebenen Daten
+ * die Datenbank muss eine Tabelle enthaltem, die dem in `lib/schema.sql` angegebenen
+ * Schema entspricht.
+ *
+ * Achtung vor Dateirechten: Bei SQLite reicht es nicht, wenn wer Webseiten-Benutzer
+ * die .sqlite3-Datei schreiben darf, er muss auch im übergeordneten Order neue
+ * (Lock-)Dateien anlegen dürfen
+ */
+// 'DSN' => 'sqlite:/opt/31c3-streaming-feedback/feedback.sqlite3',
+
+ /**
+ * Login-Daten für die /feedback/read/-Seite, auf der eingegangenes
+ * Feedback gelesen werden kann.
+ *
+ * Durch auskommentieren der beiden Optionen wird diese Seite komplett deaktiviert,
+ * es kann dann nur noch durch manuelle Inspektion der .sqlite3-Datei auf das Feedback
+ * zugegriffen werden.
+ */
+// 'USERNAME' => 'katze',
+// 'PASSWORD' => trim(@file_get_contents('/opt/streaming-feedback/feedback-password')),
+//);
+
+/**
+ * Globaler Schalter für die Embedding-Funktionalitäten
+ *
+ * Wird diese Zeile auskommentiert oder auf False gesetzt, werden alle
+ * Embedding-Funktionen deaktiviert.
+ */
+$GLOBALS['CONFIG']['EMBED'] = true;
+
+/**
+ * Globale Konfiguration der IRC-Links.
+ *
+ * Wird dieser Block auskommentiert, werden keine IRC-Links mehr erzeugt. Sollen die
+ * IRC-Links für jeden Raum einzeln konfiguriert werden, muss dieser Block trotzdem
+ * existieren sein. ggf. einfach auf true setzen:
+ *
+ * $GLOBALS['CONFIG']['IRC'] = true
+ */
+$GLOBALS['CONFIG']['IRC'] = array(
+ /**
+ * Anzeigetext für die IRC-Links.
+ *
+ * %s wird durch den Raum-Slug ersetzt.
+ * Ist eine weitere Anpassung erfoderlich, kann ein IRC_CONFIG-Block in der
+ * Raum-Konfiguration zum Überschreiben dieser Angaben verwendet werden.
+ */
+ 'DISPLAY' => '#ccc @ ircnet',
+
+ /**
+ * URL für die IRC-Links.
+ * Hierbei kann sowohl ein irc://-Link als auch ein Link zu einem
+ * WebIrc-Provider wie z.B. 'https://kiwiirc.com/client/irc.hackint.eu/#31C3-%s'
+ * verwendet werden.
+ *
+ * %s wird durch den urlencodeten Raum-Slug ersetzt.
+ * Eine Anpassung kann ebenfalls in der Raum-Konfiguration vorgenommen werden.
+ */
+ 'URL' => 'irc://irc.de.ircnet.net/ccc',
+);
+
+/**
+ * Globale Konfiguration der Twitter-Links.
+ *
+ * Wird dieser Block auskommentiert, werden keine Twitter-Links mehr erzeugt. Sollen die
+ * Twitter-Links für jeden Raum einzeln konfiguriert werden, muss dieser Block trotzdem
+ * existieren sein. ggf. einfach auf true setzen:
+ *
+ * $GLOBALS['CONFIG']['TWITTER'] = true
+ */
+$GLOBALS['CONFIG']['TWITTER'] = array(
+ /**
+ * Anzeigetext für die Twitter-Links.
+ *
+ * %s wird durch den Raum-Slug ersetzt.
+ * Ist eine weitere Anpassung erfoderlich, kann ein TWITTER_CONFIG-Block in der
+ * Raum-Konfiguration zum Überschreiben dieser Angaben verwendet werden.
+ */
+ 'DISPLAY' => '#datengarten @ twitter',
+
+ /**
+ * Vorgabe-Tweet-Text für die Twitter-Links.
+ *
+ * %s wird durch den Raum-Slug ersetzt.
+ * Eine Anpassung kann ebenfalls in der Raum-Konfiguration vorgenommen werden.
+ */
+ 'TEXT' => '#datengarten',
+);
diff --git a/configs/conferences/datengarten/main.less b/configs/conferences/datengarten/main.less
new file mode 100644
index 0000000..e83c403
--- /dev/null
+++ b/configs/conferences/datengarten/main.less
@@ -0,0 +1,68 @@
+@import "../../../assets/css/_structure.less";
+
+@brand-primary: #3684dc;
+@highlight: #b6cd5d;
+@background: #251c16;
+@text-color: #ffffff;
+
+@link-color: #FFFF99;
+@panel-bg: #222222;
+@well-bg: @panel-bg;
+@panel-primary-border: #FFFFFF;
+@panel-default-heading-bg: #333333;
+@panel-default-text: #FFFFFF;
+
+@navbar-default-link-color: #FFFFFF;
+
+@nav-link-hover-bg: #000000;
+
+@navbar-default-bg: #333333;
+
+// conference specific styles here
+
+// often configured values (and their defaults):
+//
+// @brand-primary: #337ab7;
+// @text-color: @gray-dark;
+//
+// @link-color: @brand-primary;
+// @link-hover-color: darken(@link-color, 15%);
+//
+// @navbar-default-color: #777777;
+// @navbar-default-bg: #f8f8f8;
+//
+// @navbar-default-link-color: #777;
+// @navbar-default-link-hover-color: #333;
+
+
+
+
+
+// colors of the schedule ("Fahrplan") widget below the video-player
+//
+// @schedule-now: @brand-danger;
+// @schedule-now-bg: fade(lighten(@brand-danger, 5%), 60%);
+// @schedule-border: lighten(@brand-primary, 50%);
+//
+// @schedule-room: darken(@brand-primary, 15%);
+// @schedule-author: #444;
+//
+// @schedule-selected-room: lighten(@brand-success, 10%);
+//
+// @schedule-daychange: darken(@brand-primary, 20%);
+// @schedule-daychange-bg: fade(white, 30%);
+//
+// @schedule-gap: darken(@brand-primary, 20%);
+// @schedule-gap-bg: fade(white, 30%);
+//
+// @schedule-pause: white;
+// @schedule-pause-bg: lighten(black, 85%);
+
+.banner {
+ text-align: center;
+ color: @brand-primary;
+}
+
+body {
+ background-color: black;
+}
diff --git a/configs/conferences/gpn15/config.php b/configs/conferences/gpn15/config.php
new file mode 100644
index 0000000..84af8b6
--- /dev/null
+++ b/configs/conferences/gpn15/config.php
@@ -0,0 +1,421 @@
+<?php
+date_default_timezone_set('Europe/Berlin');
+
+/**
+ * Während der Entwicklung wird die BASEURL automatisch erraten
+ * In Produktionssituationen sollte manuell eine konfiguriert werden um Überraschungen zu vermeiden
+ */
+if($_SERVER['HTTP_HOST'] != 'localhost')
+ $GLOBALS['CONFIG']['BASEURL'] = 'http://streaming.media.ccc.de/';
+
+
+$GLOBALS['CONFIG']['CONFERENCE'] = array(
+ /**
+ * Am Ende der Konferenz wird durch das Umlegen dieses Schalters auf True eine Danke-Und-Kommen-Sie-
+ * Gut-Nach-Hause-Seite sowie einem Ausblick auf die kommenden Events angezeigt. Während einer
+ * Konferenz kann dieser Schalter auskommentiert oder auf false gesetzt werden.
+ */
+ 'CLOSED' => true,
+
+ /**
+ * Titel der Konferenz (kann Leer- und Sonderzeichen enthalten)
+ * Dieser im Seiten-Header, im <title>-Tag, in der About-Seite und ggf. ab weiteren Stellen als
+ * Anzeigetext benutzt
+ */
+ 'TITLE' => 'GPN15',
+
+ /**
+ * Veranstalter
+ * Wird für den <meta name="author">-Tag verdet. Wird diese Zeile auskommentiert, wird kein solcher
+ * <meta>-Tag generiert.
+ */
+ 'AUTHOR' => 'Entropia e.V.',
+
+ /**
+ * Beschreibungstext
+ * Wird für den <meta name="description">-Tag verdet. Wird diese Zeile auskommentiert, wird kein solcher
+ * <meta>-Tag generiert.
+ */
+ 'DESCRIPTION' => 'Gulaschprogrammiernacht 15',
+
+ /**
+ * Schlüsselwortliste, Kommasepariert
+ * Wird für den <meta name="keywords">-Tag verdet. Wird diese Zeile auskommentiert, wird kein solcher
+ * <meta>-Tag generiert.
+ */
+ 'KEYWORDS' => 'GPN15, Hacking, Chaos Computer Club, Video, Media, Streaming, Hacker, Entropia, Gulasch',
+
+ /**
+ * HTML-Code für den Footer (z.B. für spezielle Attribuierung mit <a>-Tags)
+ * Sollte üblicherweise nur Inline-Elemente enthalten
+ * Wird diese Zeile auskommentiert, wird die Standard-Attribuierung für (c3voc.de) verwendet
+ */
+ 'FOOTER_HTML' => '
+ by <a href="https://entropia.de">Entropia e.V</a> &amp;
+ <a href="https://c3voc.de">c3voc</a>
+ ',
+
+ /**
+ * HTML-Code für den Banner (nur auf der Startseite, direkt unter dem Header)
+ * wird üblicherweise für KeyVisuals oder Textmarke verwendet (vgl. Blaues
+ * Wischiwaschi auf http://media.ccc.de/)
+ *
+ * Dieser HTML-Block wird üblicherweise in der main.less speziell für die
+ * Konferenz umgestaltet.
+ *
+ * Wird diese Zeile auskommentiert, wird kein Banner ausgegeben.
+ */
+ //'BANNER_HTML' => '31C3 – a new dawn',
+
+ /**
+ * Link zu den Recordings
+ * Wird diese Zeile auskommentiert, wird der Link nicht angezeigt
+ */
+ 'RELEASES' => 'http://media.ccc.de/browse/conferences/gpn/gpn15/index.html',
+
+ /**
+ * Link zu einer (externen) ReLive-Übersichts-Seite
+ * Wird diese Zeile auskommentiert, wird der Link nicht angezeigt
+ */
+ //'RELIVE' => 'http://vod.c3voc.de/',
+
+ /**
+ * Alternativ kann ein ReLive-Json konfiguriert werden, um die interne
+ * ReLive-Ansicht zu aktivieren.
+ *
+ * Wird beides aktiviert, hat der externe Link Vorrang!
+ * Wird beides auskommentiert, wird der Link nicht angezeigt
+ */
+ 'RELIVE_JSON' => 'http://live.dus.c3voc.de/releases/relive/index.json',
+
+ /**
+ * APCU-Cache-Zeit in Sekunden
+ * Wird diese Zeile auskommentiert, werden die apc_*-Methoden nicht verwendet und
+ * das Relive-Json bei jedem Request von der Quelle geladen und geparst
+ */
+ //'RELIVE_JSON_CACHE' => 30*60,
+);
+
+/**
+ * Konfiguration der Stream-Übersicht auf der Startseite
+ */
+$GLOBALS['CONFIG']['OVERVIEW'] = array(
+ /**
+ * Abschnitte aud der Startseite und darunter aufgeführte Räume
+ * Es können beliebig neue Gruppen und Räume hinzugefügt werden
+ *
+ * Die Räume müssen in $GLOBALS['CONFIG']['ROOMS'] konfiguriert werden,
+ * sonst werden sie nicht angezeigt.
+ */
+ 'GROUPS' => array(
+ 'Lecture Rooms' => array(
+ 'vortragssaal',
+ 'medientheater',
+ 'blauer-salon',
+ ),
+ ),
+);
+
+
+
+/**
+ * Liste der Räume (= Audio & Video Produktionen, also auch DJ-Sets oä.)
+ */
+$GLOBALS['CONFIG']['ROOMS'] = array(
+ /**
+ * Array-Key ist der Raum-Slug, der z.B. auch zum erstellen der URLs,
+ * in $GLOBALS['CONFIG']['OVERVIEW'] oder im Feedback verwendet wird.
+ */
+ 'vortragssaal' => array(
+ /**
+ * Angezeige-Name
+ */
+ 'DISPLAY' => 'ZKM Vortragssaal',
+
+ /**
+ * ID des Video/Audio-Streams. Die Stream-ID ist davon abhängig, welches
+ * Event-Case in welchem Raum aufgebaut wird und wird üblicherweise von
+ * s1 bis s5 durchnummeriert.
+ */
+ 'STREAM' => 's2',
+
+ /**
+ * Stream-Vorschaubildchen auf der Übersichtsseite anzeigen
+ * Damit das funktioniert muss der entsprechende runit-Task auf dem
+ * CDN-Quell-Host (live.ber) laufen.
+ */
+ 'PREVIEW' => true,
+
+ /**
+ * Übersetzungstonspur aktivieren
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist werden nur
+ * die native-Streams verwendet, andernfalls wird native und translated
+ * angeboten und auch für beide Tonspuren eine Player-Seite angezeigt.
+ */
+ 'TRANSLATION' => false,
+
+ /**
+ * stereo-Tonspur statt native-Tonspur benutzen
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist werden
+ * die "native"-Mono-Streams verwendet, andernfalls wird statt "native"
+ * der Streamname "stereo" eingesetzt. Im normalen Konferenz-Setup
+ * müssen dann beide Kanäle der Kamera mit einem Signal bespielt werden.
+ */
+ 'STEREO' => false,
+
+ /**
+ * SD-Video-Stream (1024×576) verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein SD-Video
+ * angeboten. Wird auch HD_VIDEO auf false gesetzt oder auskommentiert ist, wird
+ * für diesen Raum überhaupt kein Video angeboten.
+ *
+ * In diesem Fall wird, sofern jeweils aktiviert, Slides, Audio und zuletzt Musik
+ * als Default-Stream angenommen.
+ */
+ 'SD_VIDEO' => true,
+
+ /**
+ * HD-Video-Stream (1920×1080) verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein HD-Video
+ * angeboten. Wird auch SD_VIDEO auf false gesetzt oder auskommentiert ist, wird
+ * für diesen Raum überhaupt kein Video angeboten.
+ *
+ * In diesem Fall wird, sofern jeweils aktiviert, Slides, Audio und zuletzt Musik
+ * als Default-Stream angenommen.
+ */
+ 'HD_VIDEO' => false,
+
+ /**
+ * Slide-Only-Stream (1024×576) verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein Slide-Only-
+ * Stream angeboten. Für diesen Raum wird dann keim Slides-Tab angeboten.
+ *
+ * In diesem Fall wird, sofern jeweils aktiviert, Audio und zuletzt Musik als
+ * Default-Stream angenommen.
+ */
+ 'SLIDES' => false,
+
+ /**
+ * Audio-Only-Stream verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein Audio-Only-
+ * Stream angeboten. Für diesen Raum wird dann keim Audio-Tab angeboten.
+ *
+ * In diesem Fall wird, sofern aktiviert, Musik als Default-Stream angenommen.
+ */
+ 'AUDIO' => true,
+
+ /**
+ * Musik-Stream verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein Musik-Stream
+ * angeboten. Für diesen Raum wird dann keim Musik-Tab angeboten.
+ *
+ * Ist kein einziger Stream angebote, wird statt der Stream-Seite ein 404-Fehler
+ * angezeigt.
+ */
+ 'MUSIC' => false,
+
+ /**
+ * Fahrplan-Ansicht auf der Raum-Seite aktivieren (boolean)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird der Raum nicht im Fahrplan gesucht und auch auf der Startseite
+ * findet keine Darstellung statt.
+ *
+ * Ebenso können alle Fahrplan-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['SCHEDULE']-Blocks deaktiviert werden
+ */
+ 'SCHEDULE' => true,
+
+ /**
+ * Name des Raums im Fahrplan
+ * Wenn diese Zeile auskommentiert ist wird der Raum-Slug verwendet
+ */
+ 'SCHEDULE_NAME' => 'ZKM-Vortragssaal',
+
+ /**
+ * Feedback anzeigen (boolean)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * taucht der Raum auch im globalen Feedback-Formular nicht auf.
+ *
+ * Ebenso können alle Feedback-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['FEEDBACK']-Blocks deaktiviert werden
+ */
+ 'FEEDBACK' => false,
+
+ /**
+ * Subtitles-Player aktivieren (boolean)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird der Subtitles-Button und die damit verbundenen Funktionen deaktiviert.
+ *
+ * Ebenso können alle Subtitles-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['SUBTITLES']-Blocks deaktiviert werden
+ */
+ 'SUBTITLES' => false,
+
+ /**
+ * Embed-Form aktivieren (boolean)
+ *
+ * Ist dieses Feld auf true gesetzt, wird ein Embed-Tab unter dem Video
+ * angezeigt. Darüber kann der Player als iframe eingebunden werden.
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird kein Embed-Tab angeboten und die URL zum Einbetten existiert nicht.
+ *
+ * Ebenso können alle Embedding-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['EMBED']-Blocks deaktiviert werden
+ */
+ 'EMBED' => false,
+
+ /**
+ * IRC-Link aktivieren (boolean)
+ *
+ * Solange Twitter oder IRC aktiviert ist, wird ein "Chat"-Tab mit den
+ * jeweiligen Links angezeigt.
+ *
+ * Ist dieses Feld auf true gesetzt, wird ein irc://-Link angezeigt.
+ * WebIrc wird nach dem Congress nicht mehr unterstützt ;)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird kein IRC-Link angezeigt
+ *
+ * Ebenso können alle IRC-Links durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['IRC']-Blocks deaktiviert werden
+ */
+ 'IRC' => false,
+
+ /**
+ * Mit dem Angaben in diesem Block können die Vorgaben aus dem
+ * globalen $GLOBALS['CONFIG']['IRC'] Block überschrieben werden.
+ *
+ * Der globale $GLOBALS['CONFIG']['IRC']-Block muss trotzdem existieren,
+ * da sonst überhaupt kein IRC-Link erzeugt wird. (ggf. einfach `= true` setzen)
+ */
+ 'IRC_CONFIG' => array(
+ 'DISPLAY' => '#31C3-hall-1 @ hackint',
+ 'URL' => 'irc://irc.hackint.eu:6667/31C3-hall-1',
+ ),
+
+ /**
+ * Twitter-Link aktivieren (boolean)
+ *
+ * Ist dieses Feld auf true gesetzt, wird ein Link zu Twitter angezeigt.
+ *
+ * Solange Twitter oder IRC aktiviert ist, wird ein "Chat"-Tab mit den
+ * jeweiligen Links angezeigt.
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird kein Twitter-Link angezeigt
+ *
+ * Ebenso können alle Twitter-Links durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['TWITTER']-Blocks deaktiviert werden
+ **/
+ 'TWITTER' => false,
+
+ /**
+ * Mit dem Angaben in diesem Block können die Vorgaben aus dem
+ * globalen $GLOBALS['CONFIG']['TWITTER'] Block überschrieben werden.
+ *
+ * Der globale $GLOBALS['CONFIG']['TWITTER']-Block muss trotzdem existieren,
+ * da sonst überhaupt kein IRC-Link erzeugt wird. (ggf. einfach `= true` setzen)
+ */
+ 'TWITTER_CONFIG' => array(
+ 'DISPLAY' => '#hall1 @ twitter',
+ 'TEXT' => '#31C3 #hall1',
+ ),
+ ),
+
+ 'medientheater' => array(
+ 'DISPLAY' => 'Medientheater',
+ 'STREAM' => 's3',
+ 'PREVIEW' => true,
+
+ 'TRANSLATION' => false,
+ 'SD_VIDEO' => true,
+ 'HD_VIDEO' => false,
+ 'AUDIO' => true,
+ 'SLIDES' => false,
+ 'MUSIC' => false,
+
+ 'SCHEDULE' => true,
+ 'SCHEDULE_NAME' => 'Medientheater',
+ 'FEEDBACK' => false,
+ 'SUBTITLES' => false,
+ 'EMBED' => false,
+ 'IRC' => false,
+ 'TWITTER' => false,
+ ),
+
+ 'blauer-salon' => array(
+ 'DISPLAY' => 'Blauer Salon',
+ 'STREAM' => 's4',
+ 'PREVIEW' => true,
+
+ 'TRANSLATION' => false,
+ 'SD_VIDEO' => true,
+ 'HD_VIDEO' => false,
+ 'AUDIO' => true,
+ 'SLIDES' => false,
+ 'MUSIC' => false,
+
+ 'SCHEDULE' => false,
+ 'FEEDBACK' => false,
+ 'SUBTITLES' => false,
+ 'EMBED' => false,
+ 'IRC' => false,
+ 'TWITTER' => false,
+ ),
+);
+
+
+
+/**
+ * Konfigurationen zum Konferenz-Fahrplan
+ * Wird dieser Block auskommentiert, werden alle Fahrplan-Bezogenen Features deaktiviert
+ */
+$GLOBALS['CONFIG']['SCHEDULE'] = array(
+ /**
+ * URL zum Fahrplan-XML
+ *
+ * Diese URL muss immer verfügbar sein, sonst können kann die Programm-Ansicht
+ * aufhören zu funktionieren. Wenn die Quelle unverlässlich ist ;) sollte ein
+ * externer HTTP-Cache vorgeschaltet werden.
+ */
+ 'URL' => 'http://bl0rg.net/~andi/gpn15-fahrplan/schedule.xml',
+
+ /**
+ * Nur die angegebenen Räume aus dem Fahrplan beachten
+ *
+ * Wird diese Zeile auskommentiert, werden alle Räume angezeigt
+ */
+ 'ROOMFILTER' => array('Medientheater', 'ZKM-Vortragssaal'),
+
+ /**
+ * APCU-Cache-Zeit in Sekunden
+ * Wird diese Zeile auskommentiert, werden die apc_*-Methoden nicht verwendet und
+ * der Fahrplan bei jedem Request von der Quelle geladen und geparst
+ */
+ //'CACHE' => 30*60,
+
+ /**
+ * Skalierung der Programm-Vorschau in Sekunden pro Pixel
+ */
+ 'SCALE' => 7,
+
+ /**
+ * Simuliere das Verhalten als wäre die Konferenz bereits heute
+ *
+ * Diese folgende Beispiel-Zeile Simuliert, dass das
+ * Konferenz-Datum 2014-12-29 auf den heutigen Tag 2015-02-24 verschoben ist.
+ */
+ //'SIMULATE_OFFSET' => strtotime(/* Conference-Date */ '2014-12-28') - strtotime(/* Today */ '2015-03-01'),
+ 'SIMULATE_OFFSET' => 0,
+);
diff --git a/configs/conferences/gpn15/main.less b/configs/conferences/gpn15/main.less
new file mode 100644
index 0000000..7706c49
--- /dev/null
+++ b/configs/conferences/gpn15/main.less
@@ -0,0 +1,92 @@
+@import "../../../assets/css/_structure.less";
+
+// conference specific styles here
+
+// often configured values (and their defaults):
+//
+// @brand-primary: #337ab7;
+// @text-color: @gray-dark;
+//
+// @link-color: @brand-primary;
+// @link-hover-color: darken(@link-color, 15%);
+//
+// @navbar-default-color: #777777;
+// @navbar-default-bg: #f8f8f8;
+//
+// @navbar-default-link-color: #777;
+// @navbar-default-link-hover-color: #333;
+
+html, body {
+ min-height: 100%;
+}
+
+body {
+ background-image: url("wolkenbar.png");
+ background-repeat: repeat-x;
+ background-position: bottom left;
+}
+
+.navbar-fixed-top {
+ background: @body-bg url("wolkenbar.png") repeat-x left -46px;
+ border-color: #000;
+}
+
+footer {
+ background-color: rgba(255,255,255,0.35);
+ a {
+ color: #777;
+ text-decoration: underline;
+ }
+}
+
+
+/*
+@gray-darker: #369; // #222
+@gray: #445; // #555
+@gray-light: #030333; // #999
+@gray-lighter: #0D0FAE; // #eee
+*/
+
+@body-bg: rgba(0, 122, 186, 1);
+@text-color: white;
+
+@panel-bg: lighten(@body-bg, 5%);
+
+@link-color: #ccc;
+@well-bg: @panel-bg;
+@panel-primary-border: #FFFFFF;
+@panel-default-heading-bg: darken(@body-bg, 2%);
+@panel-default-text: #FFFFFF;
+
+@navbar-default-link-color: #fff;
+@navbar-default-link-hover-color: #fff;
+@navbar-default-link-active-color: #fff;
+
+@nav-tabs-active-link-hover-color: #fff;
+@nav-link-hover-bg: lighten(@body-bg, 1%);
+
+// colors of the schedule ("Fahrplan") widget below the video-player
+//
+// @schedule-now: @brand-danger;
+// @schedule-now-bg: fade(lighten(@brand-danger, 5%), 60%);
+// @schedule-border: lighten(@brand-primary, 50%);
+//
+// @schedule-room: darken(@brand-primary, 15%);
+// @schedule-author: #444;
+//
+// @schedule-selected-room: lighten(@brand-success, 10%);
+@schedule-selected-room: #72b3d2;
+.schedule a {
+ color: #333;
+}
+
+//
+// @schedule-daychange: darken(@brand-primary, 20%);
+// @schedule-daychange-bg: fade(white, 30%);
+//
+// @schedule-gap: darken(@brand-primary, 20%);
+// @schedule-gap-bg: fade(white, 30%);
+//
+// @schedule-pause: white;
+@schedule-pause: #333;
+// @schedule-pause-bg: lighten(black, 85%);
diff --git a/configs/conferences/gpn15/wolkenbar.png b/configs/conferences/gpn15/wolkenbar.png
new file mode 100644
index 0000000..b1ffae2
--- /dev/null
+++ b/configs/conferences/gpn15/wolkenbar.png
Binary files differ
diff --git a/configs/conferences/nixcon15/config.php b/configs/conferences/nixcon15/config.php
new file mode 100644
index 0000000..212bb9c
--- /dev/null
+++ b/configs/conferences/nixcon15/config.php
@@ -0,0 +1,425 @@
+<?php
+date_default_timezone_set('Europe/Berlin');
+
+/**
+ * Während der Entwicklung wird die BASEURL automatisch erraten
+ * In Produktionssituationen sollte manuell eine konfiguriert werden um Überraschungen zu vermeiden
+ */
+if($_SERVER['HTTP_HOST'] != 'localhost')
+ $GLOBALS['CONFIG']['BASEURL'] = 'http://streaming.media.ccc.de/';
+
+
+$GLOBALS['CONFIG']['CONFERENCE'] = array(
+ /**
+ * Der Startzeitpunkt der Konferenz als Unix-Timestamp. Befinden wir uns davor, wird die Closed-Seite
+ * mit einem Text der Art "hat noch nicht angefangen" angezeigt.
+ *
+ * Wird dieser Zeitpunkt nicht angegeben, gilt die Konferenz immer als angefangen. (Siehe aber ENDS_AT
+ * und CLOSED weiter unten)
+ */
+ 'STARTS_AT' => strtotime("2015-11-14 08:00"),
+
+ /**
+ * Der Endzeitpunkt der Konferenz als Unix-Timestamp. Befinden wir uns danach, wird eine Danke-Und-Kommen-Sie-
+ * Gut-Nach-Hause-Seite sowie einem Ausblick auf die kommenden Events angezeigt.
+ *
+ * Wird dieser Zeitpunkt nicht angegeben, endet die Konferenz nie. (Siehe aber CLOSED weiter unten)
+ */
+ 'ENDS_AT' => strtotime("2015-11-15 19:30"),
+
+ /**
+ * Hiermit kann die Funktionalitaet von STARTS_AT/ENDS_AT überschrieben werden. Der Wert 'before'
+ * simuliert, dass die Konferenz noch nicht begonnen hat. Der Wert 'after' simuliert, dass die Konferenz
+ * bereits beendet ist. 'running' simuliert eine laufende Konferenz.
+ *
+ * Der Boolean true ist aus Abwärtskompatibilitätsgründen äquivalent zu 'after'. False ist äquivalent
+ * zu 'running'.
+ */
+ //'CLOSED' => false,
+
+ /**
+ * Titel der Konferenz (kann Leer- und Sonderzeichen enthalten)
+ * Dieser im Seiten-Header, im <title>-Tag, in der About-Seite und ggf. ab weiteren Stellen als
+ * Anzeigetext benutzt
+ */
+ 'TITLE' => 'NixCon 2015',
+
+ /**
+ * Veranstalter
+ * Wird für den <meta name="author">-Tag verdet. Wird diese Zeile auskommentiert, wird kein solcher
+ * <meta>-Tag generiert.
+ */
+ 'AUTHOR' => '@NixConBerlin',
+
+ /**
+ * Beschreibungstext
+ * Wird für den <meta name="description">-Tag verdet. Wird diese Zeile auskommentiert, wird kein solcher
+ * <meta>-Tag generiert.
+ */
+ 'DESCRIPTION' => 'The NixOS Conference.',
+
+ /**
+ * Schlüsselwortliste, Kommasepariert
+ * Wird für den <meta name="keywords">-Tag verdet. Wird diese Zeile auskommentiert, wird kein solcher
+ * <meta>-Tag generiert.
+ */
+ 'KEYWORDS' => 'NixOS, NixCon, Berlin, Video, Media, Streaming',
+
+ /**
+ * HTML-Code für den Footer (z.B. für spezielle Attribuierung mit <a>-Tags)
+ * Sollte üblicherweise nur Inline-Elemente enthalten
+ * Wird diese Zeile auskommentiert, wird die Standard-Attribuierung für (c3voc.de) verwendet
+ */
+ 'FOOTER_HTML' => '
+ by <a href="http://nixos.org">NixOS</a> & <a href="https://c3voc.de">c3voc</a>
+ ',
+
+ /**
+ * HTML-Code für den Banner (nur auf der Startseite, direkt unter dem Header)
+ * wird üblicherweise für KeyVisuals oder Textmarke verwendet (vgl. Blaues
+ * Wischiwaschi auf http://media.ccc.de/)
+ *
+ * Dieser HTML-Block wird üblicherweise in der main.less speziell für die
+ * Konferenz umgestaltet.
+ *
+ * Wird diese Zeile auskommentiert, wird kein Banner ausgegeben.
+ */
+ //'BANNER_HTML' => '
+ // <div class="container">
+ // <h2>Berlin 13.-15. November 2015 #ppw15a</h2>
+ // </div>
+ //',
+
+ /**
+ * Link zu den Recordings
+ * Wird diese Zeile auskommentiert, wird der Link nicht angezeigt
+ */
+ //'RELEASES' => 'https://media.ccc.de/browse/events/datengarten/index.html',
+
+ /**
+ * Link zu einer (externen) ReLive-Übersichts-Seite
+ * Wird diese Zeile auskommentiert, wird der Link nicht angezeigt
+ */
+ //'RELIVE' => 'http://vod.c3voc.de/',
+
+ /**
+ * Alternativ kann ein ReLive-Json konfiguriert werden, um die interne
+ * ReLive-Ansicht zu aktivieren.
+ *
+ * Wird beides aktiviert, hat der externe Link Vorrang!
+ * Wird beides auskommentiert, wird der Link nicht angezeigt
+ */
+ 'RELIVE_JSON' => 'configs/conferences/nixcon2015/relive.json',
+
+ /**
+ * APCU-Cache-Zeit in Sekunden
+ * Wird diese Zeile auskommentiert, werden die apc_*-Methoden nicht verwendet und
+ * das Relive-Json bei jedem Request von der Quelle geladen und geparst
+ */
+ //'RELIVE_JSON_CACHE' => 30*60,
+);
+
+/**
+ * Konfiguration der Stream-Übersicht auf der Startseite
+ */
+$GLOBALS['CONFIG']['OVERVIEW'] = array(
+ /**
+ * Abschnitte aud der Startseite und darunter aufgeführte Räume
+ * Es können beliebig neue Gruppen und Räume hinzugefügt werden
+ *
+ * Die Räume müssen in $GLOBALS['CONFIG']['ROOMS'] konfiguriert werden,
+ * sonst werden sie nicht angezeigt.
+ */
+ 'GROUPS' => array(
+ '' => array(
+ 'room',
+ ),
+ ),
+);
+
+
+
+/**
+ * Liste der Räume (= Audio & Video Produktionen, also auch DJ-Sets oä.)
+ */
+$GLOBALS['CONFIG']['ROOMS'] = array(
+ /**
+ * Array-Key ist der Raum-Slug, der z.B. auch zum erstellen der URLs,
+ * in $GLOBALS['CONFIG']['OVERVIEW'] oder im Feedback verwendet wird.
+ */
+ 'room' => array(
+ /**
+ * Angezeige-Name
+ */
+ 'DISPLAY' => 'Main room',
+
+ /**
+ * ID des Video/Audio-Streams. Die Stream-ID ist davon abhängig, welches
+ * Event-Case in welchem Raum aufgebaut wird und wird üblicherweise von
+ * s1 bis s5 durchnummeriert.
+ */
+ 'STREAM' => 's2',
+
+ /**
+ * Stream-Vorschaubildchen auf der Übersichtsseite anzeigen
+ * Damit das funktioniert muss der entsprechende runit-Task auf dem
+ * CDN-Quell-Host (live.ber) laufen.
+ */
+ 'PREVIEW' => true,
+
+ /**
+ * Übersetzungstonspur aktivieren
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist werden nur
+ * die native-Streams verwendet, andernfalls wird native und translated
+ * angeboten und auch für beide Tonspuren eine Player-Seite angezeigt.
+ */
+ 'TRANSLATION' => false,
+
+ /**
+ * stereo-Tonspur statt native-Tonspur benutzen
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist werden
+ * die "native"-Mono-Streams verwendet, andernfalls wird statt "native"
+ * der Streamname "stereo" eingesetzt. Im normalen Konferenz-Setup
+ * müssen dann beide Kanäle der Kamera mit einem Signal bespielt werden.
+ */
+ 'STEREO' => false,
+
+ /**
+ * SD-Video-Stream (1024×576) verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein SD-Video
+ * angeboten. Wird auch HD_VIDEO auf false gesetzt oder auskommentiert ist, wird
+ * für diesen Raum überhaupt kein Video angeboten.
+ *
+ * In diesem Fall wird, sofern jeweils aktiviert, Slides, Audio und zuletzt Musik
+ * als Default-Stream angenommen.
+ */
+ 'SD_VIDEO' => true,
+
+ /**
+ * HD-Video-Stream (1920×1080) verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein HD-Video
+ * angeboten. Wird auch SD_VIDEO auf false gesetzt oder auskommentiert ist, wird
+ * für diesen Raum überhaupt kein Video angeboten.
+ *
+ * In diesem Fall wird, sofern jeweils aktiviert, Slides, Audio und zuletzt Musik
+ * als Default-Stream angenommen.
+ */
+ 'HD_VIDEO' => false,
+
+ /**
+ * Slide-Only-Stream (1024×576) verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein Slide-Only-
+ * Stream angeboten. Für diesen Raum wird dann keim Slides-Tab angeboten.
+ *
+ * In diesem Fall wird, sofern jeweils aktiviert, Audio und zuletzt Musik als
+ * Default-Stream angenommen.
+ */
+ 'SLIDES' => false,
+
+ /**
+ * Audio-Only-Stream verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein Audio-Only-
+ * Stream angeboten. Für diesen Raum wird dann keim Audio-Tab angeboten.
+ *
+ * In diesem Fall wird, sofern aktiviert, Musik als Default-Stream angenommen.
+ */
+ 'AUDIO' => true,
+
+ /**
+ * Musik-Stream verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein Musik-Stream
+ * angeboten. Für diesen Raum wird dann keim Musik-Tab angeboten.
+ *
+ * Ist kein einziger Stream angebote, wird statt der Stream-Seite ein 404-Fehler
+ * angezeigt.
+ */
+ 'MUSIC' => false,
+
+ /**
+ * Fahrplan-Ansicht auf der Raum-Seite aktivieren (boolean)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird der Raum nicht im Fahrplan gesucht und auch auf der Startseite
+ * findet keine Darstellung statt.
+ *
+ * Ebenso können alle Fahrplan-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['SCHEDULE']-Blocks deaktiviert werden
+ */
+ 'SCHEDULE' => true,
+
+ /**
+ * Name des Raums im Fahrplan
+ * Wenn diese Zeile auskommentiert ist wird der Raum-Slug verwendet
+ */
+ 'SCHEDULE_NAME' => 'NixCon',
+
+ /**
+ * Feedback anzeigen (boolean)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * taucht der Raum auch im globalen Feedback-Formular nicht auf.
+ *
+ * Ebenso können alle Feedback-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['FEEDBACK']-Blocks deaktiviert werden
+ */
+ 'FEEDBACK' => true,
+
+ /**
+ * Subtitles-Player aktivieren (boolean)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird der Subtitles-Button und die damit verbundenen Funktionen deaktiviert.
+ *
+ * Ebenso können alle Subtitles-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['SUBTITLES']-Blocks deaktiviert werden
+ */
+ 'SUBTITLES' => false,
+
+ /**
+ * Embed-Form aktivieren (boolean)
+ *
+ * Ist dieses Feld auf true gesetzt, wird ein Embed-Tab unter dem Video
+ * angezeigt. Darüber kann der Player als iframe eingebunden werden.
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird kein Embed-Tab angeboten und die URL zum Einbetten existiert nicht.
+ *
+ * Ebenso können alle Embedding-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['EMBED']-Blocks deaktiviert werden
+ */
+ 'EMBED' => true,
+
+ /**
+ * IRC-Link aktivieren (boolean)
+ *
+ * Solange Twitter oder IRC aktiviert ist, wird ein "Chat"-Tab mit den
+ * jeweiligen Links angezeigt.
+ *
+ * Ist dieses Feld auf true gesetzt, wird ein irc://-Link angezeigt.
+ * WebIrc wird nach dem Congress nicht mehr unterstützt ;)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird kein IRC-Link angezeigt
+ *
+ * Ebenso können alle IRC-Links durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['IRC']-Blocks deaktiviert werden
+ */
+ 'IRC' => false,
+
+ /**
+ * Mit dem Angaben in diesem Block können die Vorgaben aus dem
+ * globalen $GLOBALS['CONFIG']['IRC'] Block überschrieben werden.
+ *
+ * Der globale $GLOBALS['CONFIG']['IRC']-Block muss trotzdem existieren,
+ * da sonst überhaupt kein IRC-Link erzeugt wird. (ggf. einfach `= true` setzen)
+ */
+ //'IRC_CONFIG' => array(
+ // 'DISPLAY' => '#31C3-hall-1 @ hackint',
+ // 'URL' => 'irc://irc.hackint.eu:6667/31C3-hall-1',
+ //),
+
+ /**
+ * Twitter-Link aktivieren (boolean)
+ *
+ * Ist dieses Feld auf true gesetzt, wird ein Link zu Twitter angezeigt.
+ *
+ * Solange Twitter oder IRC aktiviert ist, wird ein "Chat"-Tab mit den
+ * jeweiligen Links angezeigt.
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird kein Twitter-Link angezeigt
+ *
+ * Ebenso können alle Twitter-Links durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['TWITTER']-Blocks deaktiviert werden
+ **/
+ 'TWITTER' => true,
+
+ /**
+ * Mit dem Angaben in diesem Block können die Vorgaben aus dem
+ * globalen $GLOBALS['CONFIG']['TWITTER'] Block überschrieben werden.
+ *
+ * Der globale $GLOBALS['CONFIG']['TWITTER']-Block muss trotzdem existieren,
+ * da sonst überhaupt kein IRC-Link erzeugt wird. (ggf. einfach `= true` setzen)
+ */
+ //'TWITTER_CONFIG' => array(
+ // 'DISPLAY' => '#ppw15b @ twitter',
+ // 'TEXT' => '#ppw15b',
+ //),
+ ),
+);
+
+/**
+ * Globaler Schalter für die Embedding-Funktionalitäten
+ *
+ * Wird diese Zeile auskommentiert oder auf False gesetzt, werden alle
+ * Embedding-Funktionen deaktiviert.
+ */
+$GLOBALS['CONFIG']['EMBED'] = true;
+
+/**
+ * Globale Konfiguration der Twitter-Links.
+ *
+ * Wird dieser Block auskommentiert, werden keine Twitter-Links mehr erzeugt. Sollen die
+ * Twitter-Links für jeden Raum einzeln konfiguriert werden, muss dieser Block trotzdem
+ * existieren sein. ggf. einfach auf true setzen:
+ *
+ * $GLOBALS['CONFIG']['TWITTER'] = true
+ */
+$GLOBALS['CONFIG']['TWITTER'] = array(
+ /**
+ * Anzeigetext für die Twitter-Links.
+ *
+ * %s wird durch den Raum-Slug ersetzt.
+ * Ist eine weitere Anpassung erfoderlich, kann ein TWITTER_CONFIG-Block in der
+ * Raum-Konfiguration zum Überschreiben dieser Angaben verwendet werden.
+ */
+ 'DISPLAY' => '#nixconf @ twitter',
+
+ /**
+ * Vorgabe-Tweet-Text für die Twitter-Links.
+ *
+ * %s wird durch den Raum-Slug ersetzt.
+ * Eine Anpassung kann ebenfalls in der Raum-Konfiguration vorgenommen werden.
+ */
+ 'TEXT' => '#nixconf #nixos',
+);
+
+/**
+ * Konfigurationen zum Konferenz-Fahrplan
+ * Wird dieser Block auskommentiert, werden alle Fahrplan-Bezogenen Features deaktiviert
+ */
+$GLOBALS['CONFIG']['SCHEDULE'] = array(
+ /**
+ * URL zum Fahrplan-XML
+ *
+ * Diese URL muss immer verfügbar sein, sonst können kann die Programm-Ansicht
+ * aufhören zu funktionieren. Wenn die Quelle unverlässlich ist ;) sollte ein
+ * externer HTTP-Cache vorgeschaltet werden.
+ */
+ 'URL' => 'configs/conferences/nixcon15/schedule.xml',
+ /**
+ * APCU-Cache-Zeit in Sekunden
+ * Wird diese Zeile auskommentiert, werden die apc_*-Methoden nicht verwendet und
+ * der Fahrplan bei jedem Request von der Quelle geladen und geparst
+ */
+ //'CACHE' => 30*60,
+ /**
+ * Skalierung der Programm-Vorschau in Sekunden pro Pixel
+ */
+ 'SCALE' => 7,
+ /**
+ * Simuliere das Verhalten als wäre die Konferenz bereits heute
+ *
+ * Diese folgende Beispiel-Zeile Simuliert, dass das
+ * Konferenz-Datum 2014-12-29 auf den heutigen Tag 2015-02-24 verschoben ist.
+ */
+ //'SIMULATE_OFFSET' => strtotime(/* Conference-Date */ '2015-03-11') - strtotime(/* Today */ '2015-03-03'),
+ 'SIMULATE_OFFSET' => 0,
+);
diff --git a/configs/conferences/nixcon15/download.sh b/configs/conferences/nixcon15/download.sh
new file mode 100755
index 0000000..a81b80c
--- /dev/null
+++ b/configs/conferences/nixcon15/download.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+# fahrplan
+wget --no-check-certificate -q "http://n621.de/fud/nixcon.xml" -O /tmp/nixcon2015-schedule.xml && mv /tmp/nixcon2015-schedule.xml schedule.xml
+
+# relive
+wget --no-check-certificate -q "http://live.ber.c3voc.de/releases/relive/nixcon2015/index.json" -O /tmp/nixcon2015-relive.json && mv /tmp/nixcon2015-relive.json relive.json
+
diff --git a/configs/conferences/nixcon15/main.less b/configs/conferences/nixcon15/main.less
new file mode 100644
index 0000000..8fd6be2
--- /dev/null
+++ b/configs/conferences/nixcon15/main.less
@@ -0,0 +1,41 @@
+@import "../../../assets/css/_structure.less";
+
+// conference specific styles here
+
+// often configured values (and their defaults):
+//
+// @brand-primary: #2D3038;
+// @text-color: @gray-dark;
+//
+// @link-color: @brand-primary;
+// @link-hover-color: darken(@link-color, 15%);
+//
+@navbar-default-color: #FFF;
+@navbar-default-bg: #282A30;
+//
+@navbar-default-link-color: #FFF;
+@navbar-default-link-hover-color: #777;
+
+
+
+
+
+// colors of the schedule ("Fahrplan") widget below the video-player
+//
+// @schedule-now: @brand-danger;
+// @schedule-now-bg: fade(lighten(@brand-danger, 5%), 60%);
+// @schedule-border: lighten(@brand-primary, 50%);
+//
+// @schedule-room: darken(@brand-primary, 15%);
+// @schedule-author: #444;
+//
+// @schedule-selected-room: lighten(@brand-success, 10%);
+//
+// @schedule-daychange: darken(@brand-primary, 20%);
+// @schedule-daychange-bg: fade(white, 30%);
+//
+// @schedule-gap: darken(@brand-primary, 20%);
+// @schedule-gap-bg: fade(white, 30%);
+//
+// @schedule-pause: white;
+// @schedule-pause-bg: lighten(black, 85%);
diff --git a/configs/conferences/ppw15b/config.php b/configs/conferences/ppw15b/config.php
new file mode 100644
index 0000000..fb5fc0c
--- /dev/null
+++ b/configs/conferences/ppw15b/config.php
@@ -0,0 +1,449 @@
+<?php
+date_default_timezone_set('Europe/Berlin');
+
+/**
+ * Während der Entwicklung wird die BASEURL automatisch erraten
+ * In Produktionssituationen sollte manuell eine konfiguriert werden um Überraschungen zu vermeiden
+ */
+if($_SERVER['HTTP_HOST'] != 'localhost')
+ $GLOBALS['CONFIG']['BASEURL'] = '//streaming.media.ccc.de/';
+
+
+$GLOBALS['CONFIG']['CONFERENCE'] = array(
+ /**
+ * Der Startzeitpunkt der Konferenz als Unix-Timestamp. Befinden wir uns davor, wird die Closed-Seite
+ * mit einem Text der Art "hat noch nicht angefangen" angezeigt.
+ *
+ * Wird dieser Zeitpunkt nicht angegeben, gilt die Konferenz immer als angefangen. (Siehe aber ENDS_AT
+ * und CLOSED weiter unten)
+ */
+ 'STARTS_AT' => strtotime("2015-11-13 15:30"),
+
+ /**
+ * Der Endzeitpunkt der Konferenz als Unix-Timestamp. Befinden wir uns danach, wird eine Danke-Und-Kommen-Sie-
+ * Gut-Nach-Hause-Seite sowie einem Ausblick auf die kommenden Events angezeigt.
+ *
+ * Wird dieser Zeitpunkt nicht angegeben, endet die Konferenz nie. (Siehe aber CLOSED weiter unten)
+ */
+ 'ENDS_AT' => strtotime("2015-11-15 20:00"),
+
+ /**
+ * Hiermit kann die Funktionalitaet von STARTS_AT/ENDS_AT überschrieben werden. Der Wert 'before'
+ * simuliert, dass die Konferenz noch nicht begonnen hat. Der Wert 'after' simuliert, dass die Konferenz
+ * bereits beendet ist. 'running' simuliert eine laufende Konferenz.
+ *
+ * Der Boolean true ist aus Abwärtskompatibilitätsgründen äquivalent zu 'after'. False ist äquivalent
+ * zu 'running'.
+ */
+ //'CLOSED' => false,
+
+ /**
+ * Titel der Konferenz (kann Leer- und Sonderzeichen enthalten)
+ * Dieser im Seiten-Header, im <title>-Tag, in der About-Seite und ggf. ab weiteren Stellen als
+ * Anzeigetext benutzt
+ */
+ 'TITLE' => '6. Podlove Podcaster Workshop',
+
+ /**
+ * Veranstalter
+ * Wird für den <meta name="author">-Tag verdet. Wird diese Zeile auskommentiert, wird kein solcher
+ * <meta>-Tag generiert.
+ */
+ 'AUTHOR' => 'Metaebene',
+
+ /**
+ * Beschreibungstext
+ * Wird für den <meta name="description">-Tag verdet. Wird diese Zeile auskommentiert, wird kein solcher
+ * <meta>-Tag generiert.
+ */
+ 'DESCRIPTION' => 'Podlove Podcaster Workshop',
+
+ /**
+ * Schlüsselwortliste, Kommasepariert
+ * Wird für den <meta name="keywords">-Tag verdet. Wird diese Zeile auskommentiert, wird kein solcher
+ * <meta>-Tag generiert.
+ */
+ 'KEYWORDS' => 'Podlove, Podcaster, Workshop, Berlin, Video, Media, Streaming',
+
+ /**
+ * HTML-Code für den Footer (z.B. für spezielle Attribuierung mit <a>-Tags)
+ * Sollte üblicherweise nur Inline-Elemente enthalten
+ * Wird diese Zeile auskommentiert, wird die Standard-Attribuierung für (c3voc.de) verwendet
+ */
+ 'FOOTER_HTML' => '
+ by <a href="http://metaebene.me">metaebene</a> &amp;
+ <a href="https://c3voc.de">c3voc</a>
+ ',
+
+ /**
+ * HTML-Code für den Banner (nur auf der Startseite, direkt unter dem Header)
+ * wird üblicherweise für KeyVisuals oder Textmarke verwendet (vgl. Blaues
+ * Wischiwaschi auf http://media.ccc.de/)
+ *
+ * Dieser HTML-Block wird üblicherweise in der main.less speziell für die
+ * Konferenz umgestaltet.
+ *
+ * Wird diese Zeile auskommentiert, wird kein Banner ausgegeben.
+ */
+ 'BANNER_HTML' => '
+ <div class="container">
+ <h2>Berlin 13.-15. November 2015 #ppw15b</h2>
+ </div>
+ ',
+
+ /**
+ * Link zu den Recordings
+ * Wird diese Zeile auskommentiert, wird der Link nicht angezeigt
+ */
+ //'RELEASES' => 'https://media.ccc.de/browse/events/datengarten/index.html',
+
+ /**
+ * Link zu einer (externen) ReLive-Übersichts-Seite
+ * Wird diese Zeile auskommentiert, wird der Link nicht angezeigt
+ */
+ //'RELIVE' => 'http://vod.c3voc.de/',
+
+ /**
+ * Alternativ kann ein ReLive-Json konfiguriert werden, um die interne
+ * ReLive-Ansicht zu aktivieren.
+ *
+ * Wird beides aktiviert, hat der externe Link Vorrang!
+ * Wird beides auskommentiert, wird der Link nicht angezeigt
+ */
+ 'RELIVE_JSON' => 'configs/conferences/ppw15b/relive.json',
+
+ /**
+ * APCU-Cache-Zeit in Sekunden
+ * Wird diese Zeile auskommentiert, werden die apc_*-Methoden nicht verwendet und
+ * das Relive-Json bei jedem Request von der Quelle geladen und geparst
+ */
+ //'RELIVE_JSON_CACHE' => 30*60,
+);
+
+/**
+ * Konfiguration der Stream-Übersicht auf der Startseite
+ */
+$GLOBALS['CONFIG']['OVERVIEW'] = array(
+ /**
+ * Abschnitte aud der Startseite und darunter aufgeführte Räume
+ * Es können beliebig neue Gruppen und Räume hinzugefügt werden
+ *
+ * Die Räume müssen in $GLOBALS['CONFIG']['ROOMS'] konfiguriert werden,
+ * sonst werden sie nicht angezeigt.
+ */
+ 'GROUPS' => array(
+ '' => array(
+ 'mosaik',
+ 'alphabet',
+ ),
+ ),
+);
+
+
+
+/**
+ * Liste der Räume (= Audio & Video Produktionen, also auch DJ-Sets oä.)
+ */
+$GLOBALS['CONFIG']['ROOMS'] = array(
+ /**
+ * Array-Key ist der Raum-Slug, der z.B. auch zum erstellen der URLs,
+ * in $GLOBALS['CONFIG']['OVERVIEW'] oder im Feedback verwendet wird.
+ */
+ 'mosaik' => array(
+ /**
+ * Angezeige-Name
+ */
+ 'DISPLAY' => 'Mosaik',
+
+ /**
+ * ID des Video/Audio-Streams. Die Stream-ID ist davon abhängig, welches
+ * Event-Case in welchem Raum aufgebaut wird und wird üblicherweise von
+ * s1 bis s5 durchnummeriert.
+ */
+ 'STREAM' => 's1',
+
+ /**
+ * Stream-Vorschaubildchen auf der Übersichtsseite anzeigen
+ * Damit das funktioniert muss der entsprechende runit-Task auf dem
+ * CDN-Quell-Host (live.ber) laufen.
+ */
+ 'PREVIEW' => true,
+
+ /**
+ * Übersetzungstonspur aktivieren
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist werden nur
+ * die native-Streams verwendet, andernfalls wird native und translated
+ * angeboten und auch für beide Tonspuren eine Player-Seite angezeigt.
+ */
+ 'TRANSLATION' => false,
+
+ /**
+ * stereo-Tonspur statt native-Tonspur benutzen
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist werden
+ * die "native"-Mono-Streams verwendet, andernfalls wird statt "native"
+ * der Streamname "stereo" eingesetzt. Im normalen Konferenz-Setup
+ * müssen dann beide Kanäle der Kamera mit einem Signal bespielt werden.
+ */
+ 'STEREO' => false,
+
+ /**
+ * SD-Video-Stream (1024×576) verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein SD-Video
+ * angeboten. Wird auch HD_VIDEO auf false gesetzt oder auskommentiert ist, wird
+ * für diesen Raum überhaupt kein Video angeboten.
+ *
+ * In diesem Fall wird, sofern jeweils aktiviert, Slides, Audio und zuletzt Musik
+ * als Default-Stream angenommen.
+ */
+ 'SD_VIDEO' => true,
+
+ /**
+ * HD-Video-Stream (1920×1080) verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein HD-Video
+ * angeboten. Wird auch SD_VIDEO auf false gesetzt oder auskommentiert ist, wird
+ * für diesen Raum überhaupt kein Video angeboten.
+ *
+ * In diesem Fall wird, sofern jeweils aktiviert, Slides, Audio und zuletzt Musik
+ * als Default-Stream angenommen.
+ */
+ 'HD_VIDEO' => false,
+
+ /**
+ * Slide-Only-Stream (1024×576) verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein Slide-Only-
+ * Stream angeboten. Für diesen Raum wird dann keim Slides-Tab angeboten.
+ *
+ * In diesem Fall wird, sofern jeweils aktiviert, Audio und zuletzt Musik als
+ * Default-Stream angenommen.
+ */
+ 'SLIDES' => false,
+
+ /**
+ * Audio-Only-Stream verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein Audio-Only-
+ * Stream angeboten. Für diesen Raum wird dann keim Audio-Tab angeboten.
+ *
+ * In diesem Fall wird, sofern aktiviert, Musik als Default-Stream angenommen.
+ */
+ 'AUDIO' => true,
+
+ /**
+ * Musik-Stream verfügbar
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist ẃird kein Musik-Stream
+ * angeboten. Für diesen Raum wird dann keim Musik-Tab angeboten.
+ *
+ * Ist kein einziger Stream angebote, wird statt der Stream-Seite ein 404-Fehler
+ * angezeigt.
+ */
+ 'MUSIC' => false,
+
+ /**
+ * Fahrplan-Ansicht auf der Raum-Seite aktivieren (boolean)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird der Raum nicht im Fahrplan gesucht und auch auf der Startseite
+ * findet keine Darstellung statt.
+ *
+ * Ebenso können alle Fahrplan-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['SCHEDULE']-Blocks deaktiviert werden
+ */
+ 'SCHEDULE' => true,
+
+ /**
+ * Name des Raums im Fahrplan
+ * Wenn diese Zeile auskommentiert ist wird der Raum-Slug verwendet
+ */
+ 'SCHEDULE_NAME' => 'MOSAIK',
+
+ /**
+ * Feedback anzeigen (boolean)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * taucht der Raum auch im globalen Feedback-Formular nicht auf.
+ *
+ * Ebenso können alle Feedback-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['FEEDBACK']-Blocks deaktiviert werden
+ */
+ 'FEEDBACK' => true,
+
+ /**
+ * Subtitles-Player aktivieren (boolean)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird der Subtitles-Button und die damit verbundenen Funktionen deaktiviert.
+ *
+ * Ebenso können alle Subtitles-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['SUBTITLES']-Blocks deaktiviert werden
+ */
+ 'SUBTITLES' => false,
+
+ /**
+ * Embed-Form aktivieren (boolean)
+ *
+ * Ist dieses Feld auf true gesetzt, wird ein Embed-Tab unter dem Video
+ * angezeigt. Darüber kann der Player als iframe eingebunden werden.
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird kein Embed-Tab angeboten und die URL zum Einbetten existiert nicht.
+ *
+ * Ebenso können alle Embedding-Funktionialitäten durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['EMBED']-Blocks deaktiviert werden
+ */
+ 'EMBED' => true,
+
+ /**
+ * IRC-Link aktivieren (boolean)
+ *
+ * Solange Twitter oder IRC aktiviert ist, wird ein "Chat"-Tab mit den
+ * jeweiligen Links angezeigt.
+ *
+ * Ist dieses Feld auf true gesetzt, wird ein irc://-Link angezeigt.
+ * WebIrc wird nach dem Congress nicht mehr unterstützt ;)
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird kein IRC-Link angezeigt
+ *
+ * Ebenso können alle IRC-Links durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['IRC']-Blocks deaktiviert werden
+ */
+ 'IRC' => false,
+
+ /**
+ * Mit dem Angaben in diesem Block können die Vorgaben aus dem
+ * globalen $GLOBALS['CONFIG']['IRC'] Block überschrieben werden.
+ *
+ * Der globale $GLOBALS['CONFIG']['IRC']-Block muss trotzdem existieren,
+ * da sonst überhaupt kein IRC-Link erzeugt wird. (ggf. einfach `= true` setzen)
+ */
+ //'IRC_CONFIG' => array(
+ // 'DISPLAY' => '#31C3-hall-1 @ hackint',
+ // 'URL' => 'irc://irc.hackint.eu:6667/31C3-hall-1',
+ //),
+
+ /**
+ * Twitter-Link aktivieren (boolean)
+ *
+ * Ist dieses Feld auf true gesetzt, wird ein Link zu Twitter angezeigt.
+ *
+ * Solange Twitter oder IRC aktiviert ist, wird ein "Chat"-Tab mit den
+ * jeweiligen Links angezeigt.
+ *
+ * Wenn diese Zeile auskommentiert oder auf false gesetzt ist,
+ * wird kein Twitter-Link angezeigt
+ *
+ * Ebenso können alle Twitter-Links durch auskommentieren
+ * des globalen $GLOBALS['CONFIG']['TWITTER']-Blocks deaktiviert werden
+ **/
+ 'TWITTER' => true,
+
+ /**
+ * Mit dem Angaben in diesem Block können die Vorgaben aus dem
+ * globalen $GLOBALS['CONFIG']['TWITTER'] Block überschrieben werden.
+ *
+ * Der globale $GLOBALS['CONFIG']['TWITTER']-Block muss trotzdem existieren,
+ * da sonst überhaupt kein IRC-Link erzeugt wird. (ggf. einfach `= true` setzen)
+ */
+ //'TWITTER_CONFIG' => array(
+ // 'DISPLAY' => '#ppw15b @ twitter',
+ // 'TEXT' => '#ppw15b',
+ //),
+ ),
+ 'alphabet' => array(
+ 'DISPLAY' => 'Alphabet',
+
+ 'STREAM' => 's4',
+ 'PREVIEW' => true,
+
+ 'TRANSLATION' => false,
+ 'STEREO' => false,
+ 'SD_VIDEO' => true,
+ 'HD_VIDEO' => false,
+ 'AUDIO' => true,
+
+ 'SCHEDULE' => true,
+ 'SCHEDULE_NAME' => 'ALPHABET',
+
+ 'FEEDBACK' => true,
+ 'EMBED' => true,
+ 'TWITTER' => true,
+ ),
+);
+
+/**
+ * Globaler Schalter für die Embedding-Funktionalitäten
+ *
+ * Wird diese Zeile auskommentiert oder auf False gesetzt, werden alle
+ * Embedding-Funktionen deaktiviert.
+ */
+$GLOBALS['CONFIG']['EMBED'] = true;
+
+/**
+ * Globale Konfiguration der Twitter-Links.
+ *
+ * Wird dieser Block auskommentiert, werden keine Twitter-Links mehr erzeugt. Sollen die
+ * Twitter-Links für jeden Raum einzeln konfiguriert werden, muss dieser Block trotzdem
+ * existieren sein. ggf. einfach auf true setzen:
+ *
+ * $GLOBALS['CONFIG']['TWITTER'] = true
+ */
+$GLOBALS['CONFIG']['TWITTER'] = array(
+ /**
+ * Anzeigetext für die Twitter-Links.
+ *
+ * %s wird durch den Raum-Slug ersetzt.
+ * Ist eine weitere Anpassung erfoderlich, kann ein TWITTER_CONFIG-Block in der
+ * Raum-Konfiguration zum Überschreiben dieser Angaben verwendet werden.
+ */
+ 'DISPLAY' => '#ppw15b @ twitter',
+
+ /**
+ * Vorgabe-Tweet-Text für die Twitter-Links.
+ *
+ * %s wird durch den Raum-Slug ersetzt.
+ * Eine Anpassung kann ebenfalls in der Raum-Konfiguration vorgenommen werden.
+ */
+ 'TEXT' => '#ppw15b',
+);
+
+/**
+ * Konfigurationen zum Konferenz-Fahrplan
+ * Wird dieser Block auskommentiert, werden alle Fahrplan-Bezogenen Features deaktiviert
+ */
+$GLOBALS['CONFIG']['SCHEDULE'] = array(
+ /**
+ * URL zum Fahrplan-XML
+ *
+ * Diese URL muss immer verfügbar sein, sonst können kann die Programm-Ansicht
+ * aufhören zu funktionieren. Wenn die Quelle unverlässlich ist ;) sollte ein
+ * externer HTTP-Cache vorgeschaltet werden.
+ */
+ 'URL' => 'configs/conferences/ppw15b/schedule.xml',
+
+ /**
+ * Nur die angegebenen Räume aus dem Fahrplan beachten
+ *
+ * Wird diese Zeile auskommentiert, werden alle Räume angezeigt
+ */
+ 'ROOMFILTER' => array('MOSAIK', 'ALPHABET'),
+
+ /**
+ * Skalierung der Programm-Vorschau in Sekunden pro Pixel
+ */
+ 'SCALE' => 7,
+
+ /**
+ * Simuliere das Verhalten als wäre die Konferenz bereits heute
+ *
+ * Diese folgende Beispiel-Zeile Simuliert, dass das
+ * Konferenz-Datum 2014-12-29 auf den heutigen Tag 2015-02-24 verschoben ist.
+ */
+ //'SIMULATE_OFFSET' => strtotime(/* Conference-Date */ '2015-03-11') - strtotime(/* Today */ '2015-03-03'),
+ 'SIMULATE_OFFSET' => 0,
+);
diff --git a/configs/conferences/ppw15b/download.sh b/configs/conferences/ppw15b/download.sh
new file mode 100755
index 0000000..181655d
--- /dev/null
+++ b/configs/conferences/ppw15b/download.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# fahrplan
+wget --no-check-certificate -q "https://frab.sendegate.de/en/ppw15b/public/schedule.xml" -O /tmp/ppw15b-schedule.xml && mv /tmp/ppw15b-schedule.xml schedule.xml
+
+# relive
+wget --no-check-certificate -q "http://live.ber.c3voc.de/releases/relive/ppw15b/index.json" -O /tmp/ppw15b-relive.json && mv /tmp/ppw15b-relive.json relive.json
diff --git a/configs/download.sh b/configs/download.sh
index 8808ff0..c2a2b3e 100755
--- a/configs/download.sh
+++ b/configs/download.sh
@@ -1,10 +1,14 @@
#!/bin/sh
-# fahrplan
-wget --no-check-certificate -q "http://events.ccc.de/congress/2014/Fahrplan/schedule.xml" -O /tmp/schedule.xml && mv /tmp/schedule.xml schedule.xml
-
-# vod json
-wget -q "http://cdn.c3voc.de/releases/relive/index.json" -O /tmp/vod.json && mv /tmp/vod.json vod.json
+# conferences
+wd=`pwd`
+for d in conferences/*; do
+ if [ -x $d/download.sh ]; then
+ cd $d
+ ./download.sh
+ cd $wd
+ fi
+done
# eventkalender upcoming
wget -q --no-check-certificate "https://c3voc.de/eventkalender/events.json?filter=upcoming&streaming=yes" -O /tmp/upcoming.json && mv /tmp/upcoming.json upcoming.json
diff --git a/index.php b/index.php
index ccdd77b..f9e416f 100644
--- a/index.php
+++ b/index.php
@@ -4,14 +4,15 @@ if(!ini_get('short_open_tag'))
die('`short_open_tag = On` is required');
require_once('lib/helper.php');
-require_once('config.php');
require_once('lib/PhpTemplate.php');
require_once('lib/Exceptions.php');
require_once('lib/less.php/Less.php');
require_once('model/ModelBase.php');
+require_once('model/Conferences.php');
require_once('model/Conference.php');
+require_once('model/GenericConference.php');
require_once('model/Feedback.php');
require_once('model/Schedule.php');
require_once('model/Overview.php');
@@ -22,9 +23,90 @@ require_once('model/Stream.php');
require_once('model/Relive.php');
require_once('model/Upcoming.php');
-$route = @$_GET['route'];
-$route = rtrim($route, '/');
+ob_start();
+try {
+ $route = @$_GET['route'];
+ $route = rtrim($route, '/');
+
+ // GLOBAL ROUTES
+ if($route == 'gen/main.css')
+ {
+ // global css (for conferences overview)
+ handle_lesscss_request('assets/css/main.less', '../assets/css/');
+ exit;
+ }
+
+ else if($route == 'streams/v1.json')
+ {
+ require('view/streams-json-v1.php');
+ exit;
+ }
+
+
+ // generic template
+ $tpl = new PhpTemplate('template/page.phtml');
+ $tpl->set(array(
+ 'baseurl' => forceslash(baseurl()),
+ 'route' => $route,
+ 'canonicalurl' => forceslash(baseurl()).forceslash($route),
+ 'assemblies' => './template/assemblies/',
+ 'assets' => 'assets/',
+
+ 'conference' => new GenericConference(),
+ ));
+
+ @list($mandator, $route) = explode('/', $route, 2);
+ if(!$mandator)
+ {
+ // root requested
+
+ if(Conferences::getActiveConferencesCount() == 0)
+ {
+ // no clients
+ // error
+
+ require('view/allclosed.php');
+ exit;
+ }
+ else if(Conferences::getActiveConferencesCount() == 1)
+ {
+ // one client
+ // redirect
+
+ $clients = Conferences::getActiveConferences();
+ header('Location: '.forceslash( baseurl() . $clients[0]['link'] ));
+ exit;
+ }
+ else
+ {
+ // multiple clients
+ // show overview
+
+ require('view/allconferences.php');
+ exit;
+ }
+ }
+ else if(!Conferences::exists($mandator))
+ {
+ // old url OR wrong client OR
+ // -> error
+ require('view/404.php');
+ exit;
+ }
+
+ Conferences::load($mandator);
+}
+catch(Exception $e)
+{
+ ob_clean();
+ require('view/500.php');
+}
+
+
+
+// PER-CONFERENCE CODE
+$GLOBALS['MANDATOR'] = $mandator;
$conference = new Conference();
$tpl = new PhpTemplate('template/page.phtml');
@@ -33,6 +115,7 @@ $tpl->set(array(
'route' => $route,
'canonicalurl' => forceslash(baseurl()).forceslash($route),
'assemblies' => './template/assemblies/',
+ 'assets' => '../assets/',
'conference' => $conference,
'feedback' => new Feedback(),
@@ -42,15 +125,15 @@ $tpl->set(array(
if(startswith('//', @$GLOBALS['CONFIG']['BASEURL']))
{
$tpl->set(array(
- 'httpsurl' => forceslash('https:'.$GLOBALS['CONFIG']['BASEURL']).forceslash($route),
- 'httpurl' => forceslash('http:'. $GLOBALS['CONFIG']['BASEURL']).forceslash($route),
+ 'httpsurl' => forceslash(forceslash('https:'.$GLOBALS['CONFIG']['BASEURL']).@$GLOBALS['MANDATOR']).forceslash($route),
+ 'httpurl' => forceslash(forceslash('http:'. $GLOBALS['CONFIG']['BASEURL']).@$GLOBALS['MANDATOR']).forceslash($route),
));
}
ob_start();
try {
-
+ // ALWAYS AVAILABLE ROUTES
if($route == 'feedback/read')
{
require('view/feedback-read.php');
@@ -61,36 +144,27 @@ try {
require('view/schedule-json.php');
}
- else if($route == 'streams/v1.json')
- {
- require('view/streams-json-v1.php');
- }
-
else if($route == 'gen/main.css')
{
- $dir = forceslash(sys_get_temp_dir());
-
- $css_file = Less_Cache::Get([
- 'assets/css/main.less' => '../assets/css/',
- ], [
- 'sourceMap' => true,
- 'compress' => true,
- 'relativeUrls' => true,
-
- 'cache_dir' => $dir,
- ]);
-
- $css = file_get_contents($dir.$css_file);
- header('Content-Type: text/css');
- header('Content-Length: '.strlen($css));
- print($css);
+ if(Conferences::hasCustomStyles($mandator))
+ {
+ handle_lesscss_request(
+ Conferences::getCustomStyles($mandator),
+ '../../'.Conferences::getCustomStylesDir($mandator)
+ );
+ }
+ else {
+ handle_lesscss_request('assets/css/main.less', '../../assets/css/');
+ }
}
+ // HAS-NOT-BEGUN VIEW
else if(!$conference->hasBegun())
{
require('view/not-started.php');
}
+ // ROUTES AVAILABLE AFTER BUT NOT BEFORE THE CONFERENCE
else if(preg_match('@^relive/([0-9]+)$@', $route, $m))
{
$_GET = array(
@@ -104,11 +178,14 @@ try {
require('view/relive.php');
}
+
+ // HAS-ENDED VIEW
else if($conference->hasEnded())
{
require('view/closed.php');
}
+ // ROUTES AVAILABLE ONLY DURING THE CONFERENCE
else if($route == '')
{
require('view/overview.php');
@@ -180,6 +257,7 @@ try {
require('view/embed.php');
}
+ // UNKNOWN ROUTE
else
{
throw new NotFoundException();
diff --git a/lib/helper.php b/lib/helper.php
index c6fd9a9..0d4d868 100644
--- a/lib/helper.php
+++ b/lib/helper.php
@@ -18,14 +18,14 @@ function baseurl()
if(startswith('//', $base))
$base = proto().':'.$base;
- return $base;
+ return forceslash(forceslash($base).@$GLOBALS['MANDATOR']);
}
$base = ssl() ? 'https://' : 'http://';
$base .= $_SERVER['HTTP_HOST'];
$base .= forceslash(dirname($_SERVER['SCRIPT_NAME']));
- return $base;
+ return forceslash(forceslash($base).@$GLOBALS['MANDATOR']);
}
function forceslash($url)
@@ -41,3 +41,23 @@ function startswith($needle, $haystack)
{
return substr($haystack, 0, strlen($needle)) == $needle;
}
+
+function handle_lesscss_request($lessfile, $relative_path)
+{
+ $dir = forceslash(sys_get_temp_dir());
+
+ $css_file = Less_Cache::Get([
+ $lessfile => $relative_path,
+ ], [
+ 'sourceMap' => true,
+ 'compress' => true,
+ 'relativeUrls' => true,
+
+ 'cache_dir' => $dir,
+ ]);
+
+ $css = file_get_contents($dir.$css_file);
+ header('Content-Type: text/css');
+ header('Content-Length: '.strlen($css));
+ print($css);
+}
diff --git a/model/Conferences.php b/model/Conferences.php
new file mode 100644
index 0000000..9396a48
--- /dev/null
+++ b/model/Conferences.php
@@ -0,0 +1,77 @@
+<?php
+
+class Conferences extends ModelBase
+{
+ const MANDATOR_DIR = 'configs/conferences/';
+
+ public static function getConferences() {
+ $conferences = [];
+ foreach(scandir(forceslash(Conferences::MANDATOR_DIR)) as $el)
+ {
+ if($el[0] == '.')
+ continue;
+
+ $conferences[$el] = Conferences::getConferenceInformation($el);
+ }
+
+ return $conferences;
+ }
+ public static function getConferencesCount() {
+ return count(Conferences::getConferences());
+ }
+
+ public static function getActiveConferences() {
+ return array_values(array_filter(
+ Conferences::getConferences(),
+ function($info) {
+ return $info['active'];
+ }
+ ));
+ }
+
+ public static function getActiveConferencesCount() {
+ return count(Conferences::getActiveConferences());
+ }
+
+ public static function exists($mandator) {
+ return array_key_exists($mandator, Conferences::getConferences());
+ }
+
+ public static function getConferenceInformation($mandator) {
+ if(isset($GLOBALS['CONFIG']))
+ $saved_config = $GLOBALS['CONFIG'];
+
+ Conferences::load($mandator);
+ $conf = new Conference();
+ $info = [
+ 'slug' => $mandator,
+ 'link' => forceslash($mandator),
+ 'active' => !$conf->isClosed(),
+ 'title' => $conf->getTitle(),
+ 'description' => $conf->getDescription(),
+
+ 'CONFIG' => $GLOBALS['CONFIG'],
+ ];
+ unset($GLOBALS['CONFIG']);
+
+ if(isset($saved_config))
+ $GLOBALS['CONFIG'] = $saved_config;
+
+ return $info;
+ }
+
+ public static function hasCustomStyles($mandator) {
+ return file_exists(Conferences::getCustomStyles($mandator));
+ }
+ public static function getCustomStyles($mandator) {
+ return forceslash(Conferences::getCustomStylesDir($mandator)).'main.less';
+ }
+ public static function getCustomStylesDir($mandator) {
+ return forceslash(Conferences::MANDATOR_DIR).forceslash($mandator);
+ }
+
+ public static function load($mandator) {
+ include(forceslash(Conferences::MANDATOR_DIR).forceslash($mandator).'config.php');
+ return isset($GLOBALS['CONFIG']);
+ }
+}
diff --git a/model/GenericConference.php b/model/GenericConference.php
new file mode 100644
index 0000000..949766f
--- /dev/null
+++ b/model/GenericConference.php
@@ -0,0 +1,67 @@
+<?php
+
+class GenericConference extends Conference
+{
+ public function getTitle() {
+ return 'C3Voc Streaming';
+ }
+
+ public function hasBegun() {
+ return true;
+ }
+
+ public function hasEnded() {
+ return true;
+ }
+
+ public function hasAuthor() {
+ return true;
+ }
+ public function getAuthor() {
+ return 'C3Voc';
+ }
+
+ public function hasDescription() {
+ return true;
+ }
+ public function getDescription() {
+ return 'Video Live-Streaming of the CCC';
+ }
+
+ public function hasKeywords() {
+ return true;
+ }
+ public function getKeywords() {
+ return 'Video, Media, Streaming, VOC, C3Voc, CCC';
+ }
+
+
+
+ public function hasReleases() {
+ return true;
+ }
+ public function getReleasesUrl() {
+ return '//media.ccc.de/';
+ }
+
+ public function hasRelive() {
+ return false;
+ }
+ public function getReliveUrl() {
+ return null;
+ }
+
+ public function hasBannerHtml() {
+ return false;
+ }
+ public function getBannerHtml() {
+ return null;
+ }
+
+ public function hasFooterHtml() {
+ return false;
+ }
+ public function getFooterHtml() {
+ return null;
+ }
+}
diff --git a/model/Room.php b/model/Room.php
index 6e37043..124d057 100644
--- a/model/Room.php
+++ b/model/Room.php
@@ -43,7 +43,7 @@ class Room extends ModelBase
}
public function getThumb() {
- return 'thumbs/'.$this->getStream().'.png';
+ return '../thumbs/'.$this->getStream().'.png';
}
public function getLink() {
diff --git a/template/about.phtml b/template/about.phtml
index 68aa2fb..eee4896 100644
--- a/template/about.phtml
+++ b/template/about.phtml
@@ -6,7 +6,7 @@
<p>
If you like what we're doing, you can flattr us:<br /><br />
<a href="https://flattr.com/thing/3755795/">
- <img src="assets/img/flattrbutton.png" alt="Flattr this" />
+ <img src="<?=h($assets)?>/img/flattrbutton.png" alt="Flattr this" />
</a>
</p>
diff --git a/template/allclosed.phtml b/template/allclosed.phtml
new file mode 100644
index 0000000..31947a7
--- /dev/null
+++ b/template/allclosed.phtml
@@ -0,0 +1,14 @@
+<div class="container about">
+ <? if($next): ?>
+ <h2>See you soon at <?=h($next['name'])?></h2>
+ <span class="countdown" data-dt="<?=h($next['start_date'])?>"></span>
+ <? endif ?>
+
+ <p>
+ You can watch most of our Recordings at <a href="<?=h($conference->getReleasesUrl())?>"><?=h($conference->getReleasesUrl())?></a>.
+ </p>
+
+ <br><br><br>
+
+ <? include("$assemblies/upcoming.phtml") ?>
+</div>
diff --git a/template/allconferences.phtml b/template/allconferences.phtml
new file mode 100644
index 0000000..2d47b82
--- /dev/null
+++ b/template/allconferences.phtml
@@ -0,0 +1,33 @@
+<div class="container">
+ <h1><?=h($title)?></h1>
+ <p>We are currently active on multiple Conferences. Please choose which one you want access.</p>
+
+ <br><br>
+
+ <div class="row clearfix">
+ <? $count = count($conferences) ?>
+ <? foreach($conferences as $idx => $info): ?>
+ <?
+ // when we have more then 3 conferences, all but the last 3 will be displayed with 1/3 width
+ if($count - $idx <= ($count % 3))
+ $w = 12/($count%3);
+ else
+ $w = 12/3;
+ ?>
+
+ <div class="
+ clearfix
+ conference
+ col-xs-12
+ col-md-<?=h($w)?>
+ ">
+ <div class="panel panel-default">
+ <div class="panel-body">
+ <a href="<?=h($info['link'])?>"><?=h($info['title'])?></a>
+ <p><?=h($info['description'])?></p>
+ </div>
+ </div>
+ </div>
+ <? endforeach ?>
+ </div>
+</div>
diff --git a/template/assemblies/header.phtml b/template/assemblies/header.phtml
index f57054c..a213dd3 100644
--- a/template/assemblies/header.phtml
+++ b/template/assemblies/header.phtml
@@ -15,7 +15,7 @@
</a>
<? endif ?>
- <? if(!$conference->hasEnded() && $feedback->isEnabled()): ?>
+ <? if(!$conference->hasEnded() && isset($feedback) && $feedback->isEnabled()): ?>
<a class="form-control btn btn-default" href="<?=h($feedback->getUrl())?>">
<span class="fa fa-bullhorn"></span>
</a>
diff --git a/template/assemblies/upcoming.phtml b/template/assemblies/upcoming.phtml
new file mode 100644
index 0000000..7d9ffac
--- /dev/null
+++ b/template/assemblies/upcoming.phtml
@@ -0,0 +1,21 @@
+<? foreach($events as $event): ?>
+ <div class="col-xs-10 col-xs-offset-1 col-md-6 col-md-offset-3">
+
+ <div class="panel panel-default">
+ <div class="panel-heading">
+ <? if($event['description']): ?>
+ <a href="<?=h($event['description'])?>">
+ <?=h($event['name'])?>
+ </a>
+ <? else: ?>
+ <?=h($event['name'])?>
+ <? endif ?>
+ </div>
+ <div class="panel-body">
+ <?=h($event['location'])?><br />
+ <?=h($event['start_date'])?> – <?=h($event['end_date'])?>
+ </div>
+ </div>
+
+ </div>
+<? endforeach ?>
diff --git a/template/closed.phtml b/template/closed.phtml
index 6ca7416..0b56e74 100644
--- a/template/closed.phtml
+++ b/template/closed.phtml
@@ -29,25 +29,5 @@
<br><br><br>
- <? foreach($events as $event): ?>
- <div class="col-xs-10 col-xs-offset-1 col-md-6 col-md-offset-3">
-
- <div class="panel panel-default">
- <div class="panel-heading">
- <? if($event['description']): ?>
- <a href="<?=h($event['description'])?>">
- <?=h($event['name'])?>
- </a>
- <? else: ?>
- <?=h($event['name'])?>
- <? endif ?>
- </div>
- <div class="panel-body">
- <?=h($event['location'])?><br />
- <?=h($event['start_date'])?> – <?=h($event['end_date'])?>
- </div>
- </div>
-
- </div>
- <? endforeach ?>
+ <? include("$assemblies/upcoming.phtml") ?>
</div>
diff --git a/template/embed.phtml b/template/embed.phtml
index dd8629a..f99ece1 100644
--- a/template/embed.phtml
+++ b/template/embed.phtml
@@ -1 +1 @@
-<? require('assemblies/player/'.$stream->getPlayerType().'.phtml') ?>
+<? require("$assemblies/player/".$stream->getPlayerType().'.phtml') ?>
diff --git a/template/page.phtml b/template/page.phtml
index bd73065..ac639a2 100644
--- a/template/page.phtml
+++ b/template/page.phtml
@@ -29,20 +29,20 @@
<base href="<?=h($baseurl)?>" />
<link href="<?=h($canonicalurl)?>" rel="canonical" />
- <link href="assets/img/apple-touch-icon.png" rel="apple-touch-icon" />
- <link href="assets/img/favicon.png" rel="icon" type="image/png" />
+ <link href="<?=h($assets)?>img/apple-touch-icon.png" rel="apple-touch-icon" />
+ <link href="<?=h($assets)?>img/favicon.png" rel="icon" type="image/png" />
- <link type="text/css" rel="stylesheet" href="assets/mejs/mediaelementplayer.min.css" />
+ <link type="text/css" rel="stylesheet" href="<?=h($assets)?>mejs/mediaelementplayer.min.css" />
<link type="text/css" rel="stylesheet" href="gen/main.css" />
- <script type="text/javascript" src="assets/js/lib/jquery.min.js"></script>
- <script type="text/javascript" src="assets/js/lib/jquery.scrollTo.min.js"></script>
- <script type="text/javascript" src="assets/js/lib/bootstrap.min.js"></script>
- <script type="text/javascript" src="assets/js/lib/bootstrap-datepicker.min.js"></script>
- <script type="text/javascript" src="assets/js/lib/moment.min.js"></script>
+ <script type="text/javascript" src="<?=h($assets)?>js/lib/jquery.min.js"></script>
+ <script type="text/javascript" src="<?=h($assets)?>js/lib/jquery.scrollTo.min.js"></script>
+ <script type="text/javascript" src="<?=h($assets)?>js/lib/bootstrap.min.js"></script>
+ <script type="text/javascript" src="<?=h($assets)?>js/lib/bootstrap-datepicker.min.js"></script>
+ <script type="text/javascript" src="<?=h($assets)?>js/lib/moment.min.js"></script>
- <script type="text/javascript" src="assets/mejs/mediaelement-and-player.min.js"></script>
- <script type="text/javascript" src="assets/js/lustiges-script.js"></script>
+ <script type="text/javascript" src="<?=h($assets)?>mejs/mediaelement-and-player.min.js"></script>
+ <script type="text/javascript" src="<?=h($assets)?>js/lustiges-script.js"></script>
</head>
<body class="<?=h(is_numeric($page[0]) ? 'e'.$page : $page)?>">
<? if(!@$naked): ?>
@@ -55,8 +55,10 @@
<? include("$assemblies/footer.phtml") ?>
<? endif ?>
- <span class="js-settings"
- data-scheduleoffset="<?=h($schedule->getSimulationOffset())?>"
- ></span>
+ <? if(isset($schedule)): ?>
+ <span class="js-settings"
+ data-scheduleoffset="<?=h($schedule->getSimulationOffset())?>"
+ ></span>
+ <? endif ?>
</body>
</html>
diff --git a/view/allclosed.php b/view/allclosed.php
new file mode 100644
index 0000000..869cbc1
--- /dev/null
+++ b/view/allclosed.php
@@ -0,0 +1,12 @@
+<?php
+
+$upcoming = new Upcoming();
+$events = $upcoming->getNextEvents();
+
+echo $tpl->render(array(
+ 'page' => 'allclosed',
+ 'title' => 'See you soon … somewhere else!',
+
+ 'next' => @$events[0],
+ 'events' => $events,
+));
diff --git a/view/allconferences.php b/view/allconferences.php
new file mode 100644
index 0000000..8cce073
--- /dev/null
+++ b/view/allconferences.php
@@ -0,0 +1,8 @@
+<?php
+
+echo $tpl->render(array(
+ 'page' => 'allconferences',
+ 'title' => 'Multiple Conferences',
+
+ 'conferences' => Conferences::getActiveConferences(),
+));
diff --git a/view/streams-json-v1.php b/view/streams-json-v1.php
index c705bd7..af0909b 100644
--- a/view/streams-json-v1.php
+++ b/view/streams-json-v1.php
@@ -2,97 +2,111 @@
header('Content-Type: application/json');
-if($conference->isClosed())
-{
- echo '[]';
- return;
-}
-
-$overview = new Overview();
+$conferences = Conferences::getActiveConferences();
$struct = array();
-foreach($overview->getGroups() as $group => $rooms)
+if(isset($GLOBALS['CONFIG']))
+ $saved_config = $GLOBALS['CONFIG'];
+
+foreach ($conferences as $conference)
{
- $roomstruct = array();
- foreach($rooms as $room)
+ /*
+ ok. das ist so hacky. EIGENTLICH müsste man aus ModelBase
+ das $GLOBALS tilgen und von der api ne v2 releasen, welche
+ conferences als eigenes Objekt betrachtet
+ */
+ $GLOBALS['CONFIG'] = $conference['CONFIG'];
+ $GLOBALS['MANDATOR'] = $conference['slug'];
+
+ $overview = new Overview();
+
+ foreach($overview->getGroups() as $group => $rooms)
{
- $streams = array();
- foreach($room->getStreams() as $stream)
+ $roomstruct = array();
+ foreach($rooms as $room)
{
- $key = $stream->getSelection().'-'.$stream->getLanguage();
-
- $urls = array();
- switch($stream->getPlayerType())
+ $streams = array();
+ foreach($room->getStreams() as $stream)
{
- case 'video':
- foreach ($stream->getVideoProtos() as $proto => $display)
- {
- $urls[$proto] = array(
- 'display' => $display,
- 'tech' => $stream->getVideoTech($proto),
- 'url' => $stream->getVideoUrl($proto),
- );
- }
- break;
+ $key = $stream->getSelection().'-'.$stream->getLanguage();
+
+ $urls = array();
+ switch($stream->getPlayerType())
+ {
+ case 'video':
+ foreach ($stream->getVideoProtos() as $proto => $display)
+ {
+ $urls[$proto] = array(
+ 'display' => $display,
+ 'tech' => $stream->getVideoTech($proto),
+ 'url' => $stream->getVideoUrl($proto),
+ );
+ }
+ break;
+
+ case 'slides':
+ foreach ($stream->getSlidesProtos() as $proto => $display)
+ {
+ $urls[$proto] = array(
+ 'display' => $display,
+ 'tech' => $stream->getSlidesTech($proto),
+ 'url' => $stream->getSlidesUrl($proto),
+ );
+ }
+ break;
- case 'slides':
- foreach ($stream->getSlidesProtos() as $proto => $display)
- {
- $urls[$proto] = array(
- 'display' => $display,
- 'tech' => $stream->getSlidesTech($proto),
- 'url' => $stream->getSlidesUrl($proto),
- );
- }
- break;
+ case 'audio':
+ foreach ($stream->getAudioProtos() as $proto => $display)
+ {
+ $urls[$proto] = array(
+ 'display' => $display,
+ 'tech' => $stream->getAudioTech($proto),
+ 'url' => $stream->getAudioUrl($proto),
+ );
+ }
+ break;
- case 'audio':
- foreach ($stream->getAudioProtos() as $proto => $display)
- {
- $urls[$proto] = array(
- 'display' => $display,
- 'tech' => $stream->getAudioTech($proto),
- 'url' => $stream->getAudioUrl($proto),
- );
- }
- break;
+ case 'music':
+ foreach ($stream->getMusicProtos() as $proto => $display)
+ {
+ $urls[$proto] = array(
+ 'display' => $display,
+ 'tech' => $stream->getMusicTech($proto),
+ 'url' => $stream->getMusicUrl($proto),
+ );
+ }
+ break;
+ }
- case 'music':
- foreach ($stream->getMusicProtos() as $proto => $display)
- {
- $urls[$proto] = array(
- 'display' => $display,
- 'tech' => $stream->getMusicTech($proto),
- 'url' => $stream->getMusicUrl($proto),
- );
- }
- break;
+ $streams[] = array(
+ 'slug' => $key,
+ 'display' => $stream->getDisplay(),
+ 'type' => $stream->getPlayerType(),
+ 'isTranslated' => $stream->isTranslated(),
+ 'videoSize' => $stream->getVideoSize(),
+ 'urls' => $urls,
+ );
}
- $streams[] = array(
- 'slug' => $key,
- 'display' => $stream->getDisplay(),
- 'type' => $stream->getPlayerType(),
- 'isTranslated' => $stream->isTranslated(),
- 'videoSize' => $stream->getVideoSize(),
- 'urls' => $urls,
+ $roomstruct[] = array(
+ 'slug' => $room->getSlug(),
+ 'schedulename' => $room->getScheduleName(),
+ 'thumb' => forceslash(baseurl()).$room->getThumb(),
+ 'link' => forceslash(baseurl()).$room->getLink(),
+ 'display' => $room->getDisplay(),
+ 'streams' => $streams,
);
}
- $roomstruct[] = array(
- 'slug' => $room->getSlug(),
- 'schedulename' => $room->getScheduleName(),
- 'thumb' => forceslash(baseurl()).$room->getThumb(),
- 'link' => forceslash(baseurl()).$room->getLink(),
- 'display' => $room->getDisplay(),
- 'streams' => $streams,
+ $struct[] = array(
+ 'conference' => $conference['title'],
+ 'group' => $group,
+ 'rooms' => $roomstruct,
);
}
-
- $struct[] = array(
- 'group' => $group,
- 'rooms' => $roomstruct,
- );
}
+if(isset($saved_config))
+ $GLOBALS['CONFIG'] = $saved_config;
+
echo json_encode($struct, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);