+ Streaming |
+
+
+
+
+
+
+ RTMP | HLS
+
+
+
+
+
+
+
+
+
diff --git a/functions.php b/functions.php
index c3c2a7c..4cc3b5a 100644
--- a/functions.php
+++ b/functions.php
@@ -335,4 +335,11 @@ if (function_exists("pll_register_string")) {
pll_register_string('hall3','G1');
pll_register_string('hall4','Пловдив');
pll_register_string('hall5','Бургас');
+ pll_register_string('bulgaria_hall','BULGARIA_HALL');
+ pll_register_string('chamber_hall','CHAMBER_HALL');
+ pll_register_string('music_hall','MUSIC_HALL');
+ pll_register_string('low_quality','LOW_QUALITY');
+ pll_register_string('normal_quality','NORMAL_QUALITY');
+ pll_register_string('high_quality','HIGH_QUALITY');
+ pll_register_string('all_streams','ALL_STREAMS');
}
diff --git a/img/banner-bg-2015.png b/img/banner-bg-2015.png
index 093979f..296cf6b 100644
Binary files a/img/banner-bg-2015.png and b/img/banner-bg-2015.png differ
diff --git a/img/banner-en-2015.png b/img/banner-en-2015.png
index d7179b7..0bf36e9 100644
Binary files a/img/banner-en-2015.png and b/img/banner-en-2015.png differ
diff --git a/page-schedule.php b/page-schedule.php
new file mode 100644
index 0000000..77f5cda
--- /dev/null
+++ b/page-schedule.php
@@ -0,0 +1,58 @@
+ 'footer-schedule', 'container_class' => 'content subnav cf' ) );
+
+require("schedule-config.php");
+
+$content = require __DIR__ . DIRECTORY_SEPARATOR . 'schedule' . DIRECTORY_SEPARATOR . 'parse.php';
+//var_dump($data);
+?>
+
+
+
+
+
diff --git a/page-speakers.php b/page-speakers.php
index c84fa41..d4deb25 100644
--- a/page-speakers.php
+++ b/page-speakers.php
@@ -1,90 +1,34 @@
'footer-schedule', 'container_class' => 'content subnav cf' ) );
-get_header();
-
-if ( preg_match('/^(schedule|programa|speakers|halls)/', $pagename) ) {
- wp_nav_menu( array( 'theme_location' => 'footer-schedule', 'container_class' => 'content subnav cf' ) );
-}
+require("schedule-config.php");
+$content = require __DIR__ . DIRECTORY_SEPARATOR . 'schedule' . DIRECTORY_SEPARATOR . 'parse.php';
+//var_dump($data);
?>
-
-
-
+
+
-
- 'speakers', 'nopaging' => 'true', 'order' => 'ASC' );
- $speakers = new WP_Query( $speakers_args );
-
- if ( $speakers->have_posts() ) :
- while ( $speakers->have_posts() ) : $speakers->the_post();
- ?>
-
-
-
-
-
- 'speakers', 'nopaging' => 'true', 'order' => 'ASC' );
- $speakers = new WP_Query( $speakers_args );
-
- if ( $speakers->have_posts() ) :
- while ( $speakers->have_posts() ) : $speakers->the_post();
- ?>
-
-
-
-
-
-
- ';
- if (!empty($custom['github'])) echo '
';
- if (!empty($custom['public_email'])) echo '
';
-?>
-
-
-
-
-
-
+
+ foreach ($content['gspk'] as $line) {
+ echo $line, PHP_EOL;
+ }
+
+?>
+
+
+
+
+
+
diff --git a/schedule-config.php b/schedule-config.php
new file mode 100644
index 0000000..0034ff9
--- /dev/null
+++ b/schedule-config.php
@@ -0,0 +1,58 @@
+ array('lectures' => array(1, 2, 3), 'workshops' => array(4, 5), 'all' => array(1, 2, 3, 4, 5) ),
+ '2015' => array('lectures' => array(6, 7, 8), 'workshops' => array(9), 'all' => array(6, 7, 8, 9) )
+);
+
+/* clarion conference ids */
+$confids = array('2014' => 1, '2015' => 2);
+
+
+/* get stuff from WP and parse */
+$siteurl = get_option('siteurl');
+$year = preg_replace('%.*/([0-9]*)$%', '\1', $siteurl);
+
+$CF['confid'] = $confids[$year];
+
+/* TODO make this read the ids from the proper place, as this breaks other years*/
+if ( preg_match('/^workshop/', $pagename) ) {
+ $CF['allowedhallids'] = $hall_defs[$year]['workshops'];
+} else if (preg_match('/^(speakers|lektori)/', $pagename) ) {
+ $CF['allowedhallids'] = $hall_defs[$year]['all'];
+} else {
+ $CF['allowedhallids'] = $hall_defs[$year]['lectures'];
+}
+
+/*
+ * There is no better way to get where the speakers are
+ */
+
+if ('en' === $CF['lang']) {
+ $CF['s_slug'] = 'speakers';
+} else {
+ $CF['s_slug'] = 'lektori';
+}
+
+$args = array(
+ 'name' => $CF['s_slug'],
+ 'post_type' => 'page',
+ 'numberposts' => 1
+);
+
+$speakers_url = '';
+
+$my_posts = get_posts($args);
+if( $my_posts ) {
+ $CF['speakers_url'] = get_permalink( $my_posts[0]->ID );
+}
+
+
+?>
diff --git a/schedule/.gitignore b/schedule/.gitignore
new file mode 100644
index 0000000..f3917d2
--- /dev/null
+++ b/schedule/.gitignore
@@ -0,0 +1,2 @@
+cache
+cache.json
diff --git a/schedule/class.SmartCurl.php b/schedule/class.SmartCurl.php
new file mode 100644
index 0000000..b963a31
--- /dev/null
+++ b/schedule/class.SmartCurl.php
@@ -0,0 +1,137 @@
+cache_dir = __DIR__ . DIRECTORY_SEPARATOR . $cache_dir;
+ }
+
+ if (!file_exists($this->cache_dir)) {
+ mkdir($this->cache_dir);
+ }
+
+ $this->cache_index = $this->cache_dir . '.json';
+
+ $cache = file_exists($this->cache_index) ? file_get_contents($this->cache_index) : false;
+
+ if ($cache !== false) {
+ $cache = json_decode($cache, true);
+ }
+
+ if ($cache !== false) {
+ static::importEtags($cache);
+ }
+
+ if (!is_null($url_root)) {
+ $this->url_root = $url_root;
+ }
+
+ $ch = curl_init();
+
+ if ($ch === false) {
+ throw new Exception('curl init failed');
+ }
+
+ $this->ch = $ch;
+
+ if (curl_setopt_array($ch, [
+ CURLOPT_FAILONERROR => true,
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_HEADER => true,
+ //CURLINFO_HEADER_OUT => true,
+ ]) === false) {
+ throw new Exception('curl setopt failed');
+ }
+ }
+
+ public function __destruct() {
+ curl_close($this->ch);
+ file_put_contents($this->cache_index, json_encode(static::exportEtags()));
+ }
+
+ public static function importEtags(array $etags) {
+ static::$etags = array_merge(static::$etags, $etags);
+ }
+
+ public static function exportEtags() {
+ return static::$etags;
+ }
+
+ public function getUrl($filename) {
+ if (is_null($this->url_root)) {
+ $url = $filename;
+ }
+ else {
+ $url = $this->url_root . $filename;
+ }
+
+ if (curl_setopt($this->ch, CURLOPT_URL, $url) === false) {
+ throw new Exception('set url failed');
+ }
+
+ $cache_file = $this->cache_dir . DIRECTORY_SEPARATOR . $filename;
+
+ $etag = array_key_exists($url, static::$etags) && file_exists($cache_file) ? static::$etags[$url] : null;
+
+ if (curl_setopt($this->ch, CURLOPT_HTTPHEADER, [
+ 'If-None-Match:' . (is_null($etag) ? '' : ' ' . $etag),
+ ]) === false) {
+ throw new Exception('set etag failed');
+ }
+
+ $response = curl_exec($this->ch);
+
+ if ($response === false) {
+ return false;
+ }
+
+ //var_dump(curl_getinfo($this->ch, CURLINFO_HEADER_OUT));
+ //var_dump($response);
+
+ $header_size = curl_getinfo($this->ch, CURLINFO_HEADER_SIZE);
+ $header = substr($response, 0, $header_size);
+ $headers = array_filter(explode("\r\n", $header));
+
+ foreach ($headers as $header_line) {
+ if (stripos($header_line, 'etag:') === 0) {
+ static::$etags[$url] = trim(substr($header_line, strlen('etag:')));
+ }
+ }
+
+ $http_code = curl_getinfo($this->ch, CURLINFO_HTTP_CODE);
+
+ if ($http_code === 304 && !is_null($this->url_root)) {
+ // use cache
+
+ if (file_exists($cache_file)) {
+ return file_get_contents($cache_file);
+ }
+ else {
+ return false;
+ }
+ }
+
+ if (strlen($response) === $header_size) {
+ return false;
+ }
+
+ $body = substr($response, $header_size);
+
+ if ($http_code === 200) {
+ $dirname = dirname($filename);
+
+ if ($dirname !== '.') {
+ mkdir($this->cache_dir . DIRECTORY_SEPARATOR . $dirname, 0777, true);
+ }
+
+ file_put_contents($cache_file, $body);
+ }
+
+ return $body;
+ }
+}
diff --git a/schedule/index.php b/schedule/index.php
new file mode 100644
index 0000000..32fc571
--- /dev/null
+++ b/schedule/index.php
@@ -0,0 +1,49 @@
+
+
+Test schedule
+
+
+
+
+
+
+
+
+ 'events.json',
+ 'speakers' => 'speakers.json',
+ 'tracks' => 'tracks.json',
+ 'event_types' => 'event_types.json',
+ 'halls' => 'halls.json',
+ 'slots' => 'slots.json',
+];
+
+
+$data = [];
+
+foreach ($filenames as $name => $filename) {
+ $curl = new SmartCurl($base_url, 'cache' . DIRECTORY_SEPARATOR .$CF['confid']);
+ $json = $curl->getUrl($filename);
+
+ if ($json === false) {
+ echo 'get failed: ', $filename, ' ', $base_url, PHP_EOL;
+ exit;
+ }
+
+ $decoded = json_decode($json, true);
+
+ if ($decoded === false) {
+ echo 'decode failed: ', $filename, PHP_EOL;
+ exit;
+ }
+
+ $add = true;
+ switch ($name) {
+ case 'halls':
+ $ret = array();
+ foreach($decoded as $id => $hall) {
+ if (in_array($id, $CF['allowedhallids'])) $ret[$id] = $hall['name'];
+ }
+ $decoded = $ret;
+ break;
+ case 'slots':
+ $decoded = array_map(function($el) {
+ foreach (['starts_at', 'ends_at'] as $key) {
+ $el[$key] = strtotime($el[$key]);
+ }
+
+ return $el;
+ }, $decoded);
+ break;
+ }
+
+ $data[$name] = $decoded;
+}
+
+function compareKeys($a, $b, $key) {
+ $valA = &$a[$key];
+ $valB = &$b[$key];
+
+ return ($valA < $valB) ? -1 : (($valA > $valB) ? 1 : 0);
+}
+
+uasort($data['slots'], function($a, $b) {
+ return compareKeys($a, $b, 'starts_at') ?: compareKeys($a, $b, 'hall_id');
+});
+
+//array_pop($data['halls']);
+
+return $data;
diff --git a/schedule/parse.php b/schedule/parse.php
new file mode 100644
index 0000000..6ab9345
--- /dev/null
+++ b/schedule/parse.php
@@ -0,0 +1,169 @@
+ array('name' => 'English', 'locale' => 'en_US.UTF8'), 'bg' => array ('name' => 'Български', 'locale' => 'bg_BG.UTF8'));
+
+$cut_len = 70;
+$cfp_url = 'http://cfp.openfest.org';
+$time = 0;
+$date = 0;
+$lines = [];
+$fulltalks = [];
+$prev_event_id = 0;
+$colspan = 1;
+$hall_ids = array_keys($data['halls']);
+$first_hall_id = min($hall_ids);
+$last_hall_id = max($hall_ids);
+
+/* We need to set these so we actually parse properly the dates. WP fucks up both. */
+date_default_timezone_set('Europe/Sofia');
+setlocale(LC_TIME, $languages[$CF['lang']]['locale']);
+
+foreach ($data['slots'] as $slot_id => $slot) {
+ if (! in_array($slot['hall_id'], $CF['allowedhallids'])) continue;
+ $slotTime = $slot['starts_at'];
+ $slotDate = date('d', $slotTime);
+
+ if ($slotDate !== $date) {
+ /* this seems to be the easiest way to localize the date */
+ $localdate = strftime('%d %B - %A' ,$slotTime);
+ $lines[] = '';
+ $lines[] = '' . $localdate . ' | ';
+ $lines[] = ' | ';
+ $lines[] = '
';
+
+ $date = $slotDate;
+ }
+
+ if ($slotTime !== $time) {
+ if ($time !== 0) {
+ $lines[] = '';
+ }
+
+ $lines[] = '';
+ $lines[] = '' . date('H:i', $slot['starts_at']) . ' - ' . date('H:i', $slot['ends_at']) . ' | ';
+
+ $time = $slotTime;
+ }
+
+ $eid = &$slot['event_id'];
+ $event = &$data['events'][$eid];
+
+ if (is_null($eid)) {
+ $lines[] = 'TBA | ';
+ }
+ else {
+ $title = mb_substr($event['title'], 0, $cut_len) . (mb_strlen($event['title']) > $cut_len ? '...' : '');
+ $speakers = '';
+
+ if (count($event['participant_user_ids']) > 0) {
+ $speakers = json_encode($event['participant_user_ids']) . '
';
+
+ $spk = array();
+ $speaker_name = array();
+ foreach ($event['participant_user_ids'] as $uid) {
+ /* The check for uid==4 is for us not to show the "Opefest Team" as a presenter for lunches, etc. */
+ if ($uid == 4 || empty ($data['speakers'][$uid])) {
+ continue;
+ } else {
+ /* TODO: fix the URL */
+ $name = $data['speakers'][$uid]['first_name'] . ' ' . $data['speakers'][$uid]['last_name'];
+ $spk[$uid] = '' . $name . '';
+ }
+ }
+ $speakers = implode (', ', $spk);
+ }
+
+
+ /* Hack, we don't want language for the misc track. This is the same for all years. */
+ if ('misc' !== $data['tracks'][$event['track_id']]['name']['en']) {
+ $csslang = "schedule-".$event['language'];
+ } else {
+ $csslang = "";
+ }
+ $cssclass = &$data['tracks'][$event['track_id']]['css_class'];
+ $style = ' class="' . $cssclass . ' ' . $csslang . '"';
+ $content = '' . htmlspecialchars($title) . '
' . $speakers;
+
+
+ /* these are done by $eid, as otherwise we get some talks more than once (for example the lunch) */
+ $fulltalks[$eid] = '';
+ $fulltalks[$eid] .= '';
+ /* We don't want '()' when we don't have a speaker name */
+ $fulltalk_spkr = strlen($speakers)>1 ? ' (' . $speakers . ')' : '';
+ $fulltalks[$eid] .= '' . $event['title'] . ' ' . $fulltalk_spkr . '';
+ $fulltalks[$eid] .= '
' . $event['abstract'] . '
';
+ $fulltalks[$eid] .= '';
+
+ if ($slot['event_id'] === $prev_event_id) {
+ array_pop($lines);
+ $lines[] = '' . $content . ' | ';
+ }
+ else {
+ $lines[] = '' . $content . ' | ';
+ $colspan = 1;
+ }
+ }
+
+ $prev_event_id = $slot['event_id'];
+}
+
+$lines[] = '
';
+/* create the legend */
+
+$legend = [];
+
+foreach($data['tracks'] as $track) {
+ $legend[] = '' . $track['name'][$CF['lang']] . ' |
';
+}
+foreach ($languages as $l => $n) {
+ $legend[] = '' . $n['name'] . ' |
';
+}
+
+$gspk = [];
+$fspk = [];
+$types = [];
+$types['twitter']['url']='https://twitter.com/';
+$types['twitter']['class']='fa fa-twitter';
+$types['github']['url']='https://github.com/';
+$types['github']['class']='fa fa-github';
+$types['email']['url']='mailto:';
+$types['email']['class']='fa fa-envelope';
+
+$gspk[] = '';
+
+foreach ($data['speakers'] as $speaker) {
+ $name = $speaker['first_name'] . ' ' . $speaker['last_name'];
+
+ $gspk[] = '
';
+
+ $fspk[] = '
';
+ $fspk[] = '
';
+ $fspk[] = '
' . $name . '
';
+ $fspk[] = '
';
+ foreach ($types as $type => $parm) {
+ if (!empty($speaker[$type])) {
+ $fspk[] = '
';
+ }
+ }
+ $fspk[] = '
';
+ $fspk[] = '
' . $speaker['biography'] . '
';
+ $fspk[] = '
';
+}
+
+$gspk[] = '
';
+
+return array_merge($data, compact('lines', 'fulltalks', 'gspk', 'fspk', 'legend'));