feat: allow to generate confence class from json

# Conflicts:
#	model/Conferences.php
This commit is contained in:
Andreas Hubel 2022-05-13 14:31:48 +02:00
parent f77b532447
commit 78de064699
6 changed files with 302 additions and 48 deletions

View file

@ -164,38 +164,3 @@ function download($what, $url, $cache)
}
return true;
}
function do_download($url, $cache)
{
$handle = curl_init($url);
curl_setopt_array($handle, [
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 10,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false, /* accept all certificates, even self-signed */
CURLOPT_SSL_VERIFYHOST => 2, /* verify hostname is in cert */
CURLOPT_CONNECTTIMEOUT => 3, /* connect-timeout in seconds */
CURLOPT_TIMEOUT => 5, /* transfer timeout im seconds */
CURLOPT_REDIR_PROTOCOLS => CURLPROTO_HTTP | CURLPROTO_HTTPS,
CURLOPT_USERAGENT => '@c3voc Streaming-Website Downloader-Cronjob, Contact voc AT c3voc DOT de in case of problems. Might the Winkekatze be with you',
]);
$return = curl_exec($handle);
$info = curl_getinfo($handle);
curl_close($handle);
if($info['http_code'] != 200)
return 'http-code = '.$info['http_code'];
$tempfile = tempnam(dirname($cache), 'dl-');
if(!$tempfile)
return 'could not create tempfile in '.dirname($cache);
if(false === file_put_contents($tempfile, $return))
return 'could write data into tempfile '.$tempfile;
chmod($tempfile, 0644);
rename($tempfile, $cache);
return true;
}

View file

@ -15,8 +15,10 @@ require_once('lib/Exceptions.php');
require_once('lib/less.php/Less.php');
require_once('model/ModelBase.php');
require_once('model/ModelJson.php');
require_once('model/Conferences.php');
require_once('model/Conference.php');
require_once('model/ConferenceJson.php');
require_once('model/GenericConference.php');
require_once('model/Feedback.php');
require_once('model/Schedule.php');

View file

@ -172,3 +172,66 @@ function slugify($text)
return $text;
}
function do_download($url, $cache, $return_response = false)
{
$handle = curl_init($url);
curl_setopt_array($handle, [
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 10,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false, /* accept all certificates, even self-signed */
CURLOPT_SSL_VERIFYHOST => 2, /* verify hostname is in cert */
CURLOPT_CONNECTTIMEOUT => 3, /* connect-timeout in seconds */
CURLOPT_TIMEOUT => 5, /* transfer timeout im seconds */
CURLOPT_REDIR_PROTOCOLS => CURLPROTO_HTTP | CURLPROTO_HTTPS,
CURLOPT_USERAGENT => '@c3voc Streaming-Website Downloader-Cronjob, Contact voc AT c3voc DOT de in case of problems. Might the Winkekatze be with you',
]);
$return = curl_exec($handle);
$info = curl_getinfo($handle);
curl_close($handle);
// TODO: should we add proper exceptions?
if($info['http_code'] != 200)
return 'http-code = '.$info['http_code'];
$tempfile = tempnam(dirname($cache), 'dl-');
if(!$tempfile)
return 'could not create tempfile in '.dirname($cache);
if(false === file_put_contents($tempfile, $return))
return 'could write data into tempfile '.$tempfile;
chmod($tempfile, 0644);
rename($tempfile, $cache);
return $return_response ? $return : true;
}
// specifies the number of seconds after which data will be refreshed
static $cache_lifetime = 300; // 5min
$check_time = time() - $cache_lifetime;
function query_data($operation, $query, $variables = [], $assoc = false, $cache = null) {
global $check_time;
$cache = $cache ?: joinpath([$GLOBALS['BASEDIR'], 'cache', $operation, http_build_query($variables) . '.json']);
if (file_exists($cache) && filemtime($cache) > $check_time) {
$res = file_get_contents($cache);
} else {
$url = 'https://data.c3voc.de/graphql?variables=' .json_encode($variables) . '&query=' . urlencode(preg_replace('/\s\s+/', ' ', $query));
$res = do_download($url, $cache, true);
}
$r = json_decode($res, $assoc);
if (is_null($r)) {
throw new NotFoundException();
}
// TODO: add error handling?
// TODO: should we return the cached value, when we did not get an answer?
return $assoc ? @$r['data'] : @$r->data;
}

133
model/ConferenceJson.php Normal file
View file

@ -0,0 +1,133 @@
<?php
class ConferenceJson extends Conference
{
private $start;
private $end;
private $rooms;
public function __construct($json, $mandator)
{
$c = $json->conference;
$this->start = DateTime::createFromFormat('c', @$c->start ?: @$c->startDate);
$this->end = DateTime::createFromFormat('c', @$c->end ?: @$c->endDate);
$groups = [];
// if ( $c->streamingConfig->overviewPage->sections )
foreach(@$c->streamingConfig->overviewPage->sections as $s) {
$groups[@$s->title] = array_map(
function($r) { return $r->slug; },
@$s->items ?: @$s->rooms ?: []
);
}
$this->rooms = [];
$rooms = @$c->rooms->nodes ?: $c->rooms;
foreach($rooms as $r) {
$this->rooms[$r->slug] = array_merge(
get_object_vars($r),
@get_object_vars($r->streamingConfig) ?: [],
@get_object_vars($r->streamingConfig->chat) ?: []
);
}
parent::__construct([
'conference' => array_merge([
'title' => $c->title,
'author' => $c->organizer,
'description' => $c->description,
'keywords' => @implode(', ', $c->keywords),
], @get_object_vars($c->streamingConfig) ?: []),
'rooms' => $this->rooms,
'overview' => [
'groups' => $groups
]
], $mandator ?: $c->acronym);
}
public function has($keychain)
{
return ModelJson::_has($this->config, $keychain);
}
public function get($keychain, $default = null)
{
return ModelJson::_get($this->config, $keychain, $default);
}
/*
public function getTitle() {
return $this->data->conference->title;
}
public function hasAuthor() {
return !empty($this->data->conference->organizer);
}
public function getAuthor() {
return $this->data->conference->organizer ?: '';
}
*/
public function startsAt() {
return $this->start;
}
public function endsAt() {
return $this->end;
}
public function hasEnded() {
// on the preview-domain no conference ever ends
if($this->isPreviewEnabled())
return false;
if($this->has('CONFERENCE.CLOSED')) {
$closed = $this->get('CONFERENCE.CLOSED');
if($closed == "after" || $closed === true)
return true;
else if($closed == "running" || $closed == "before" ||
$closed === false)
return false;
}
if($this->end) {
$now = new DateTime('now');
return $now >= $this->end;
} else {
return false;
}
}
public function getRooms()
{
$rooms = array();
foreach($this->rooms as $slug => $room)
$rooms[] = $this->getRoom($slug);
return $rooms;
}
public function getRoomIfExists($room)
{
if($this->hasRoom($room))
return $this->getRoom($room);
return null;
}
public function hasRoom($slug)
{
return array_key_exists($slug, $this->rooms);
}
public function getRoom($slug) {
return new Room($this, $slug);
}
public function hasFeedback() {
return $this->has('FEEDBACK');
}
}

View file

@ -65,7 +65,7 @@ class Conferences
}
public static function getLastConference() {
return Conferences::getFinishedConferencesSorted()[0];
return @Conferences::getFinishedConferencesSorted()[0];
}
public static function exists($mandator) {
@ -100,26 +100,67 @@ class Conferences
}
public static function loadConferenceConfig($mandator) {
// try to find config.json for this conference/mandator in local configs
$configfile = forceslash(Conferences::MANDATOR_DIR).forceslash($mandator).'config.json';
if (file_exists($configfile)) {
$data = file_get_contents($configfile);
$config = json_decode($data);
if(is_null($config)) {
throw new ConfigException("Loading $configfile did not return an object. Maybe it's not a real JSON file?" . json_last_error_msg());
}
return new ConferenceJson($config, $mandator);
}
// try to find config.php for this conference/mandator in local configs
$configfile = forceslash(Conferences::MANDATOR_DIR).forceslash($mandator).'config.php';
try {
if (file_exists($configfile)) {
$config = include($configfile);
}
catch(Exception $e) {
throw new NotFoundException();
if(!is_array($config)) {
throw new ConfigException("Loading $configfile did not return an array. Maybe it's missing a return-statement?");
}
$config = Conferences::migrateTranslationConfiguration($config);
return new Conference($config, $mandator);
}
if(!is_array($config)) {
throw new ConfigException("Loading $configfile did not return an array. Maybe it's missing a return-statement?");
}
// otherwise try to find conference in c3data postgres
$query = 'query StreamingConfig($acronym: String!) {
conference(acronym: $acronym) {
title
acronym
description
keywords
organizer
startDate
endDate
streamingConfig
rooms(orderBy: [RANK_ASC, NAME_ASC], filter: {streamId: {isNull: false}}) {
nodes {
guid
name
slug
streamId
streamingConfig
}
}
}
}';
$data = query_data('conferenceConfig', $query, ['acronym' => $mandator]);
$config = Conferences::migrateTranslationConfiguration($config);
return $config;
return new ConferenceJson($data, $mandator);
}
public static function getConference($mandator) {
return new Conference(Conferences::loadConferenceConfig($mandator), $mandator);
return Conferences::loadConferenceConfig($mandator);
}
public static function hasCustomStyles($mandator) {

50
model/ModelJson.php Normal file
View file

@ -0,0 +1,50 @@
<?php
class ModelJson
{
protected $config;
public function __construct($config)
{
$this->config = $config;
}
public function has($keychain)
{
return ModelJson::_has($this->config, $keychain);
}
public static function _has($array, $keychain)
{
if(!is_array($keychain))
$keychain = explode('.', $keychain);
$key = strtolower($keychain[0]);
if(!isset($array[$key]))
return false;
if(count($keychain) == 1)
return true;
return ModelJson::_has($array[$key], array_slice($keychain, 1));
}
public function get($keychain, $default = null)
{
return ModelJson::_get($this->config, $keychain, $default);
}
public static function _get($array, $keychain, $default)
{
if(!is_array($keychain))
$keychain = explode('.', $keychain);
$key = strtolower($keychain[0]);
if(!isset($array[$key]))
return $default;
if(count($keychain) == 1)
return $array[$key];
return ModelJson::_get($array[$key], array_slice($keychain, 1), $default);
}
}