Merge pull request #3 from initLab/master

sync with upstream
This commit is contained in:
Vencislav Atanasov 2015-11-17 23:49:32 +02:00
commit e9783ec7e6
13 changed files with 1206 additions and 378 deletions

View File

@ -276,6 +276,10 @@ nav .menu > li:hover {
text-indent: -9999px; text-indent: -9999px;
} }
nav > .content {
max-width: 1080px;
}
nav ul a { nav ul a {
color: #000; color: #000;
text-decoration: none; text-decoration: none;
@ -459,9 +463,8 @@ nav .selected {
/* News */ /* News */
h4 { h4 {
margin: 1em 0 0 0; margin: 1em 0 0.4em 0;
padding: 0; padding: 0;
height: 70px;
} }
p.info + p { p.info + p {
@ -600,6 +603,10 @@ footer .content li a {
display: inline-block; display: inline-block;
padding: 0 2.2em 1em 0; padding: 0 2.2em 1em 0;
} }
.sponsors-frontpage p a {
display: inline;
padding: 0;
}
/* Plugins */ /* Plugins */
.gmp_map_opts { .gmp_map_opts {
@ -727,13 +734,15 @@ a.button:hover { opacity: 0.8; }
padding: 0.6em 0.4em; padding: 0.6em 0.4em;
text-align: center; text-align: center;
vertical-align: middle; vertical-align: middle;
box-shadow: 0px 1px 2px #999;
} }
.schedule-legend td { .schedule-legend td {
padding: 0.4em; padding: 0.4em;
} }
.schedule a { .schedule a {
border-bottom: dotted 1px #000; border-bottom: dotted 1px #999;
color: #000; color: #000;
font-weight: bold;
} }
.schedule a:hover { .schedule a:hover {
border-bottom: none; border-bottom: none;
@ -747,15 +756,102 @@ a.button:hover { opacity: 0.8; }
.schedule-empty { .schedule-empty {
background: #FFF; background: #FFF;
} }
.schedule-social {
background: #EDD7A7; /* Color definitions */
/* Open-biz track 2015 */
.schedule-open-biz {
background: #75d3b3;
color: #000;
} }
.schedule-open-biz a {
color: #000;
}
.schedule-10 {
background: #75d3b3;
color: #000;
}
.schedule-10 a {
color: #000;
}
/* OpenArt track 2015*/
.schedule-open-art {
background: #F0A388;
}
.schedule-11 {
background: #F0A388;
}
/* Technical track 2015 */
.schedule-technical { .schedule-technical {
background: #A4D183; background: #e9d765;
color: #000;
} }
.schedule-technical a {
color: #000;
}
.schedule-12 {
background: #e9d765;
color: #000;
}
.schedule-12 a {
color: #000;
}
/* Civic hacking track 2015 */
.schedule-civic {
background: #DAEBBB;
color: #000;
}
.schedule-civic a {
color: #000;
}
.schedule-13 {
background: #DAEBBB;
color: #000;
}
.schedule-13 a {
color: #000;
}
/* Social track 2015 */
.schedule-social {
background: #a6b4de;
}
.schedule-14 {
background: #;
}
/* Advanced technical track 2015 */
.schedule-advanced-technical {
background: #DF9959;
color: #000;
}
.schedule-advanced-technical a {
color: #000;
}
.schedule-15 {
background: #DF9959;
color: #000;
}
.schedule-15 a {
color: #000;
}
/* Misc track 2015 */
.schedule-misc {
background: #fff;
}
.schedule-16 {
background: #fff;
}
/* Workshop 2015 */
.schedule-workshop { .schedule-workshop {
background: #E2E0E9; background: #E2E0E9;
} }
.schedule-en::after { .schedule-en::after {
content: " "; content: " ";
background: url('../img/en_US.png'); background: url('../img/en_US.png');
@ -772,21 +868,6 @@ a.button:hover { opacity: 0.8; }
display: block; display: block;
margin: 0.3em auto 0.3em auto; margin: 0.3em auto 0.3em auto;
} }
.schedule-civic {
background: #E8AAAB;
}
.schedule-advanced-technical {
background: #91C4DF;
}
.schedule-open-biz {
background: #DECDCB;
}
.schedule-misc {
background: #B0E9EC;
}
.schedule-open-art {
background: #ED9134;
}
.schedule-avatar { .schedule-avatar {
float: left; float: left;
padding: 0.3em; padding: 0.3em;

View File

@ -1,4 +1,257 @@
<?php get_header(); ?> <?php get_header(); ?>
<style>
.ofhr-text-center {
text-align: center;
}
</style>
<?php
// set this to 0 if there is something not working with the stream player code
// (people will still have the Streaming page with all the links to the streams)
if (1) {
?>
<script>
var g_streams_info = [
{
"hall": <?php echo json_encode(pll__('BULGARIA_HALL')); ?>,
"default": true,
"qualities": [
{
"label": <?php echo json_encode(pll__('LOW_QUALITY'));?>,
"iframe_url": "http://stream.openfest.org/bulgaria-low.html",
"rtmp_url": "rtmp://stream.openfest.org/st/bulgaria-low",
"hls_url": "http://stream.openfest.org/hls/bulgaria-low.m3u8",
},
{
"label": <?php echo json_encode(pll__('NORMAL_QUALITY'));?>,
"default": true,
"iframe_url": "http://stream.openfest.org/bulgaria.html",
"rtmp_url": "rtmp://stream.openfest.org/st/bulgaria",
"hls_url": "http://stream.openfest.org/hls/bulgaria.m3u8",
},
{
"label": <?php echo json_encode(pll__('HIGH_QUALITY'));?>,
"iframe_url": "http://stream.openfest.org/bulgaria-hd.html",
"rtmp_url": "rtmp://stream.openfest.org/st/bulgaria-hd",
"hls_url": "http://stream.openfest.org/hls/bulgaria-hd.m3u8",
},
]
},
{
"hall": <?php echo json_encode(pll__('CHAMBER_HALL'));?>,
"qualities": [
{
"label": <?php echo json_encode(pll__('LOW_QUALITY'));?>,
"iframe_url": "http://stream.openfest.org/chamber-low.html",
"rtmp_url": "rtmp://stream.openfest.org/st/chamber-low",
"hls_url": "http://stream.openfest.org/hls/chamber-low.m3u8",
},
{
"label": <?php echo json_encode(pll__('NORMAL_QUALITY'));?>,
"default": true,
"iframe_url": "http://stream.openfest.org/chamber.html",
"rtmp_url": "rtmp://stream.openfest.org/st/chamber",
"hls_url": "http://stream.openfest.org/hls/chamber.m3u8",
},
]
},
{
"hall": <?php echo json_encode(pll__('MUSIC_HALL'));?>,
"qualities": [
{
"label": <?php echo json_encode(pll__('LOW_QUALITY'));?>,
"iframe_url": "http://stream.openfest.org/music-low.html",
"rtmp_url": "rtmp://stream.openfest.org/st/music-low",
"hls_url": "http://stream.openfest.org/hls/music-low.m3u8",
},
{
"label": <?php echo json_encode(pll__('NORMAL_QUALITY'));?>,
"default": true,
"iframe_url": "http://stream.openfest.org/music.html",
"rtmp_url": "rtmp://stream.openfest.org/st/music",
"hls_url": "http://stream.openfest.org/hls/music.m3u8",
}
]
}
];
</script>
<section class="content">
<h3>Streaming | <small><a href="streaming"><?php echo htmlentities(pll__('ALL_STREAMS'));?></a></small></h3>
<h3 id="of-stream-halls-container" class="ofhr-text-center">
</h3>
<p id="of-stream-iframe-container">
<iframe id="of-stream-iframe" style="border: none; height: 395px; width: 100%; overflow: none;" allowfullscreen>
<p>Браузърът Ви не поддържа iframes</p>
</iframe>
</p>
<p class="ofhr-text-center">
<a id="of-stream-rtmp-link" href="#">RTMP</a> | <a id="of-stream-hls-link" href="#">HLS</a>
</p>
<p id="of-stream-qualities-container" class="ofhr-text-center">
</p>
<div class="separator"></div>
<script>
function of_hall_link_on_click(event) {
event.preventDefault();
var hall_node = event.target;
var stream_id = hall_node.getAttribute("data-stream-id");
of_update_player(stream_id);
}
function of_quality_link_on_click(event) {
event.preventDefault();
var quality_node = event.target;
var stream_id = quality_node.getAttribute("data-stream-id");
var quality_id = quality_node.getAttribute("data-quality-id");
of_update_player(stream_id, quality_id);
}
function of_update_player(desired_stream_id, desired_quality_id) {
var default_stream_id = -1;
// if there is a provided stream id use it (otherwise use the one
// with default property set to true)
if (desired_stream_id !== undefined) {
default_stream_id = desired_stream_id;
}
// clear halls list
var halls_container = document.getElementById("of-stream-halls-container");
while (halls_container.lastChild) {
halls_container.removeChild(halls_container.lastChild);
}
// build halls list
var stream_id = 0;
for (stream_id = 0; stream_id < g_streams_info.length; stream_id++) {
var stream = g_streams_info[stream_id];
// if we have to find the default stream, find it and set it as default
if (stream["default"] && (default_stream_id == -1)) {
default_stream_id = stream_id;
}
// append the hall name to the halls list container
var small = document.createElement("small");
var text = document.createTextNode(stream["hall"]);
// if this is not the default stream id, make links and attach listeners
// so that you can switch between halls
if (stream_id != default_stream_id) {
var anchor = document.createElement("a");
anchor.setAttribute("href", "#");
anchor.setAttribute("data-stream-id", stream_id);
anchor.appendChild(text);
if (anchor.addEventListener) {
// For all major browsers, except IE 8 and earlier
anchor.addEventListener("click", of_hall_link_on_click);
} else if (x.attachEvent) {
// For IE 8 and earlier versions
anchor.attachEvent("onclick", of_hall_link_on_click);
}
small.appendChild(anchor);
} else {
small.appendChild(text);
}
halls_container.appendChild(small);
// insert separator if not the last element
if (stream_id != (g_streams_info.length - 1)) {
var separator = document.createTextNode(" | ");
halls_container.appendChild(separator);
}
}
var stream = g_streams_info[default_stream_id];
var qualities = stream["qualities"];
var default_quality_id = -1;
// if there is a provided quality id use it (otherwise use the one
// with default property set to true)
if (desired_quality_id !== undefined) {
default_quality_id = desired_quality_id;
}
// clear the qualities list
var qualities_container = document.getElementById("of-stream-qualities-container");
while (qualities_container.lastChild) {
qualities_container.removeChild(qualities_container.lastChild);
}
// build the qualities list
var quality_id = 0;
for (quality_id = 0; quality_id < qualities.length; quality_id++) {
var quality = qualities[quality_id];
// if we have to find the default quality, find it and set it as default
if (quality["default"] && (default_quality_id == -1)) {
default_quality_id = quality_id;
}
var text = document.createTextNode(quality["label"]);
// if this is not the default quality, make links and attach listeners
// so that you can switch between qualities
if (quality_id != default_quality_id) {
var anchor = document.createElement("a");
anchor.setAttribute("href", "#");
anchor.setAttribute("data-stream-id", default_stream_id);
anchor.setAttribute("data-quality-id", quality_id);
anchor.appendChild(text);
if (anchor.addEventListener) {
// For all major browsers, except IE 8 and earlier
anchor.addEventListener("click", of_quality_link_on_click);
} else if (x.attachEvent) {
// For IE 8 and earlier versions
anchor.attachEvent("onclick", of_quality_link_on_click);
}
qualities_container.appendChild(anchor);
} else {
qualities_container.appendChild(text);
}
// append separator if this is not the last element
if (quality_id != qualities.length - 1) {
var separator = document.createTextNode(" | ");
qualities_container.appendChild(separator);
}
}
var default_quality = qualities[default_quality_id];
// update the RTMP link
var rtmp = document.getElementById("of-stream-rtmp-link");
rtmp.setAttribute("href", default_quality["rtmp_url"]);
// update the HLS link
var hls = document.getElementById("of-stream-hls-link");
hls.setAttribute("href", default_quality["hls_url"]);
// update the iframe
var iframe = document.getElementById("of-stream-iframe");
iframe.setAttribute("src", default_quality["iframe_url"]);
}
// updates the player with the default one in g_streams_info
of_update_player();
</script>
</section>
<?php } ?>
<section class="content"> <section class="content">
<?php echo do_shortcode( '[sh-latest-posts cat="news" label="'.pll__('Новини').'"]' ); ?> <?php echo do_shortcode( '[sh-latest-posts cat="news" label="'.pll__('Новини').'"]' ); ?>
<div class="separator"></div> <div class="separator"></div>

View File

@ -335,4 +335,11 @@ if (function_exists("pll_register_string")) {
pll_register_string('hall3','G1'); pll_register_string('hall3','G1');
pll_register_string('hall4','Пловдив'); pll_register_string('hall4','Пловдив');
pll_register_string('hall5','Бургас'); 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');
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 108 KiB

58
page-schedule.php Normal file
View File

@ -0,0 +1,58 @@
<?php
/* Template Name: Schedule */
get_header();
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);
?>
<section class="content grid">
<div class="col-left">
<h1><?php pll_e('Програма') ?></h1>
<table cellpadding="0" cellspacing="0" style="text-align: center;" class="schedule">
<thead>
<tr>
<td>&nbsp;</td>
<?php
foreach ($content['halls'] as $hall_name) {
?>
<td><?php echo htmlspecialchars($hall_name[$CF['lang']]); ?></td>
<?php
}
?>
</tr>
</thead>
<tbody>
<?php
foreach ($content['lines'] as $line) {
echo str_replace('SPKURL', $CF['speakers_url'], $line), PHP_EOL;
}
?>
</tbody>
</table>
<div class="separator"></div>
<table cellpadding="0" cellspacing="0" class="schedule schedule-legend">
<tbody>
<?php
foreach ($content['legend'] as $line) {
echo $line, PHP_EOL;
}
?>
</tbody>
</table>
<?php
foreach ($content['fulltalks'] as $line) {
echo str_replace('SPKURL', $CF['speakers_url'], $line), PHP_EOL;
}
?>
</div>
<?php get_sidebar(); ?>
</section>
<?php echo do_shortcode( '[transport]' ); ?>
<?php get_footer(); ?>

View File

@ -1,90 +1,34 @@
<?php <?php
/* /* Template Name: Speakers */
* Template Name: Speakers
*/
get_header(); get_header();
wp_nav_menu( array( 'theme_location' => 'footer-schedule', 'container_class' => 'content subnav cf' ) );
if ( preg_match('/^(schedule|programa|speakers|halls)/', $pagename) ) { require("schedule-config.php");
wp_nav_menu( array( 'theme_location' => 'footer-schedule', 'container_class' => 'content subnav cf' ) );
}
$content = require __DIR__ . DIRECTORY_SEPARATOR . 'schedule' . DIRECTORY_SEPARATOR . 'parse.php';
//var_dump($data);
?> ?>
<div class="separator"></div>
<section class="content grid"> <section class="content grid">
<div class="col-left"> <div class="col-left">
<h1 class="big"><?php e_('Лектори'); ?></h1> <h1><?php pll_e('Лектори') ?></h1>
<div class="grid members">
<?php
$speakers_args = array( 'post_type' => 'speakers', 'nopaging' => 'true', 'order' => 'ASC' );
$speakers = new WP_Query( $speakers_args );
if ( $speakers->have_posts() ) :
while ( $speakers->have_posts() ) : $speakers->the_post();
?>
<div class="member col4">
<a href="#<?php the_title(); ?>">
<?php
if ( has_post_thumbnail() ) {
the_post_thumbnail(array(100, 100));
} else {
?>
<img src="/img/speaker.jpg">
<?php
}
?><br>
<?php the_title(); ?>
</a>
</div>
<?php
endwhile;
wp_reset_postdata();
endif;
?>
</div>
<div class="separator"></div>
<?php
$speakers_args = array( 'post_type' => 'speakers', 'nopaging' => 'true', 'order' => 'ASC' );
$speakers = new WP_Query( $speakers_args );
if ( $speakers->have_posts() ) :
while ( $speakers->have_posts() ) : $speakers->the_post();
?>
<div class="speaker" id="<?php the_title() ?>">
<?php
if ( has_post_thumbnail() ) {
the_post_thumbnail(array(100, 100));
} else {
?>
<img src="/img/speaker.jpg">
<?php
}
?>
<h3><?php the_title(); ?></h3>
<div class="icons">
<?php
$custom = get_post_custom();
if (!empty($custom['twitter'])) echo '<a href="https://twitter.com/'.$custom['twitter'][0].'"><i class="fa fa-twitter"></i></a>';
if (!empty($custom['github'])) echo '<a href="https://github.com/'.$custom['github'][0].'"><i class="fa fa-github"></i></a>';
if (!empty($custom['public_email'])) echo '<a href="mailto:'.$custom['public_email'][0].'"><i class="fa fa-envelope"></i></a>';
?>
</div>
<?php
the_content();
?>
</div>
<?php <?php
endwhile;
wp_reset_postdata(); foreach ($content['gspk'] as $line) {
endif; echo $line, PHP_EOL;
?> }
?>
<div class="separator"></div>
<?php
foreach ($content['fspk'] as $line) {
echo $line, PHP_EOL;
}
?>
</div> </div>
<?php get_sidebar(); ?> <?php get_sidebar(); ?>
</section> </section>
<?php echo do_shortcode( '[transport]' ); ?>
<?php get_footer(); ?> <?php get_footer(); ?>

58
schedule-config.php Normal file
View File

@ -0,0 +1,58 @@
<?php
/* basic config for all conferences
* needs to be included from a WP page, otherwise won't work properly
* some of this stuff would need to be moved to be taken from Clarion in the future
*/
$CF = array();
$CF['lang'] = pll_current_language('slug');
$hall_defs = array( '2014' => 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 );
}
?>

2
schedule/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
cache
cache.json

View File

@ -0,0 +1,137 @@
<?php
class SmartCurl {
protected static $etags = [];
protected $ch = null;
protected $cache_dir = __DIR__ . DIRECTORY_SEPARATOR . 'cache';
protected $cache_index;
protected $url_root = null;
public function __construct($url_root = null, $cache_dir = null) {
if (!is_null($cache_dir)) {
$this->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;
}
}

49
schedule/index.php Normal file
View File

@ -0,0 +1,49 @@
<html>
<head>
<title>Test schedule</title>
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="http://www.openfest.org/2014/wp-content/themes/initfest/style.css" />
</head>
<pre>
<?php
//header('Content-Type: text/plain; charset=utf-8');
error_reporting(~0);
ini_set('display_errors', 1);
$content = require __DIR__ . DIRECTORY_SEPARATOR . 'parse.php';
?>
</pre>
<table border="1" style="text-align: center;">
<thead>
<tr>
<td>&nbsp;</td>
<?php
foreach ($content['halls'] as $hall_name) {
?>
<td><?php echo htmlspecialchars($hall_name); ?></td>
<?php
}
?>
</tr>
</thead>
<tbody>
<?php
foreach ($content['lines'] as $line) {
echo $line, PHP_EOL;
}
?>
</tbody>
</table>
<div class="separator"></div>
<?php
foreach ($content['fulltalks'] as $line) {
echo $line, PHP_EOL;
}
foreach ($content['gspk'] as $line) {
echo $line, PHP_EOL;
}
foreach ($content['fspk'] as $line) {
echo $line, PHP_EOL;
}

70
schedule/load.php Normal file
View File

@ -0,0 +1,70 @@
<?php
require __DIR__ . DIRECTORY_SEPARATOR . 'class.SmartCurl.php';
$base_url = 'https://cfp.openfest.org/api/conferences/'. $CF['confid'] .'/';
$filenames = [
'events' => '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;

169
schedule/parse.php Normal file
View File

@ -0,0 +1,169 @@
<?php
// 'halfnarp_friendly'
// 'events'
// 'speakers'
// 'tracks' [en/bg]
// 'event_types' [en/bg]
// 'halls'
// 'slots'
$data = require __DIR__ . DIRECTORY_SEPARATOR . 'load.php';
/* no idea why do I have to write this, doesn't seem to exist in the system */
$languages = array('en' => 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[] = '<tr>';
$lines[] = '<td>' . $localdate . '</td>';
$lines[] = '<td colspan="3">&nbsp;</td>';
$lines[] = '</tr>';
$date = $slotDate;
}
if ($slotTime !== $time) {
if ($time !== 0) {
$lines[] = '</tr>';
}
$lines[] = '<tr>';
$lines[] = '<td>' . date('H:i', $slot['starts_at']) . ' - ' . date('H:i', $slot['ends_at']) . '</td>';
$time = $slotTime;
}
$eid = &$slot['event_id'];
$event = &$data['events'][$eid];
if (is_null($eid)) {
$lines[] = '<td>TBA</td>';
}
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']) . '<br>';
$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] = '<a class="vt-p" href="SPKURL#'. $name . '">' . $name . '</a>';
}
}
$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 = '<a href=#lecture-' . $eid . '>' . htmlspecialchars($title) . '</a> <br>' . $speakers;
/* these are done by $eid, as otherwise we get some talks more than once (for example the lunch) */
$fulltalks[$eid] = '';
$fulltalks[$eid] .= '<section id="lecture-' . $eid . '">';
/* We don't want '()' when we don't have a speaker name */
$fulltalk_spkr = strlen($speakers)>1 ? ' (' . $speakers . ')' : '';
$fulltalks[$eid] .= '<p><strong>' . $event['title'] . ' ' . $fulltalk_spkr . '</strong>';
$fulltalks[$eid] .= '<p>' . $event['abstract'] . '</p>';
$fulltalks[$eid] .= '<div class="separator"></div></section>';
if ($slot['event_id'] === $prev_event_id) {
array_pop($lines);
$lines[] = '<td' . $style . ' colspan="' . ++$colspan . '">' . $content . '</td>';
}
else {
$lines[] = '<td' . $style . '>' . $content . '</td>';
$colspan = 1;
}
}
$prev_event_id = $slot['event_id'];
}
$lines[] = '</tr>';
/* create the legend */
$legend = [];
foreach($data['tracks'] as $track) {
$legend[] = '<tr><td class="' . $track['css_class'] . '">' . $track['name'][$CF['lang']] . '</td></tr>';
}
foreach ($languages as $l => $n) {
$legend[] = '<tr><td class="schedule-' . $l . '">' . $n['name'] . '</td></tr>';
}
$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[] = '<div class="grid members">';
foreach ($data['speakers'] as $speaker) {
$name = $speaker['first_name'] . ' ' . $speaker['last_name'];
$gspk[] = '<div class="member col4">';
$gspk[] = '<a href="#' . $name . '">';
$gspk[] = '<img width="100" height="100" src="' . $cfp_url . $speaker['picture']['schedule']['url'].'" class="attachment-100x100 wp-post-image" alt="' . $name .'" />';
$gspk[] = '</a> </div>';
$fspk[] = '<div class="speaker" id="' . $name . '">';
$fspk[] = '<img width="100" height="100" src="' . $cfp_url . $speaker['picture']['schedule']['url'].'" class="attachment-100x100 wp-post-image" alt="' . $name .'" />';
$fspk[] = '<h3>' . $name . '</h3>';
$fspk[] = '<div class="icons">';
foreach ($types as $type => $parm) {
if (!empty($speaker[$type])) {
$fspk[] = '<a href="'. $parm['url'] . $speaker[$type] . '"><i class="' . $parm['class'] . '"></i></a>';
}
}
$fspk[] = '</div>';
$fspk[] = '<p>' . $speaker['biography'] . '</p>';
$fspk[] = '</div><div class="separator"></div>';
}
$gspk[] = '</div>';
return array_merge($data, compact('lines', 'fulltalks', 'gspk', 'fspk', 'legend'));