diff --git a/composer.json b/composer.json index 3a57336..94acc67 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,6 @@ { "require": { - "johngrogg/ics-parser": "^2.1.17" + "johngrogg/ics-parser": "^2.1.17", + "twbs/bootstrap": "4.3.1" } } diff --git a/composer.lock b/composer.lock index d0cf446..ef3ddcb 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1852786d46444b665586f9455a5cd888", + "content-hash": "bdb9c2cf3bf1bc1e83193080c7d79b4b", "packages": [ { "name": "johngrogg/ics-parser", @@ -324,6 +324,61 @@ "standards" ], "time": "2019-11-18T17:27:11+00:00" + }, + { + "name": "twbs/bootstrap", + "version": "v4.3.1", + "source": { + "type": "git", + "url": "https://github.com/twbs/bootstrap.git", + "reference": "8fa0d3010112dca5dd6dd501173415856001ba8b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twbs/bootstrap/zipball/8fa0d3010112dca5dd6dd501173415856001ba8b", + "reference": "8fa0d3010112dca5dd6dd501173415856001ba8b", + "shasum": "" + }, + "replace": { + "twitter/bootstrap": "self.version" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jacob Thornton", + "email": "jacobthornton@gmail.com" + }, + { + "name": "Mark Otto", + "email": "markdotto@gmail.com" + } + ], + "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", + "homepage": "https://getbootstrap.com/", + "keywords": [ + "JS", + "css", + "framework", + "front-end", + "mobile-first", + "responsive", + "sass", + "web" + ], + "support": { + "issues": "https://github.com/twbs/bootstrap/issues", + "source": "https://github.com/twbs/bootstrap/tree/v4.3.1" + }, + "time": "2019-02-13T16:01:40+00:00" } ], "packages-dev": [], @@ -333,5 +388,6 @@ "prefer-stable": false, "prefer-lowest": false, "platform": [], - "platform-dev": [] + "platform-dev": [], + "plugin-api-version": "2.0.0" } diff --git a/index.php b/index.php index 0bca59d..f7b9598 100644 --- a/index.php +++ b/index.php @@ -2,72 +2,147 @@ require_once 'vendor/autoload.php'; use ICal\ICal; static $DATE_FORMAT = 'd.m.Y H:i'; -static $VISITORS_FILE = '/media/sg/dorf.jetzt_visitors'; -static $DORF_IN_LOCKDOWN = true; +static $VISITORS_FILE = 'C:\\Users\\Christopher Teutsch\\dorf_visitors.txt'; +static $DORF_IN_LOCKDOWN = false; static $DORF_VIRTUAL_EVENTS = true; static $ICAL_URL = 'https://chaosdorf.de/~derf/cccd_all.ics'; -$state_map = array( - 'closed' => (object) array( - 'state_string' => 'Das Dorf ist gerade geschlossen.', - 'svg' => 'lock', - 'color' => 'red', - ), - 'maybe_open' => (object) array( - 'state_string' => 'Das Dorf ist gerade vielleicht geöffnet:

Der Clubraum ist offen, aber es findet keine Veranstaltung statt.

- Der Status kann sich also kurzfristig ändern.', - 'svg' => 'done', - 'color' => 'brown', - ), - 'open' => (object) array( - 'state_string' => 'Das Dorf ist gerade geöffnet.

- Komm gerne vorbei.', - 'svg' => 'done', - 'color' => 'green', - ), - 'private' => (object) array( - 'state_string' => 'Das Dorf ist gerade privat:

Es sind Leute da, aber der Clubraum ist nicht geöffnet.

- Komm gerne vorbei (aber frag lieber vorher, wie lange noch Leute da sind).', - 'svg' => 'lock', - 'color' => 'fdd835', - ), - 'unknown' => (object) array( - 'state_string' => 'Der Status vom Dorf ist gerade unbekannt', - 'svg' => 'warning', - 'color' => 'orange', - ), - 'error' => (object) array( - 'state_string' => 'Der Server konnte den Status vom Dorf nicht abrufen.', - 'svg' => 'error', - 'color' => 'blue', - ), -); -$hash_to_state = array( - 'bff0167ed8aba031c49122ef4046cf1b' => 'closed', - 'd8ec899c69283bc775952a767db9d5f5' => 'maybe_open', - '2c2672c641425e5b2acd6ee74f39ae60' => 'open', - '66aece8ae27ffd3a656d42005fa3efbd' => 'private', - '86c75c0ad413b06ff8291673162d0b64' => 'unknown', - '0' => 'error', -); +static $ICAL_STALE_SECONDS = 60 * 15; +static $ICAL_CACHE_FILE = 'C:\\Users\\Christopher Teutsch\\cccd_all.ics'; +//static $STATE_FILE = '/media/sg/dorf.jetzt_state'; +static $STATE_FILE = 'C:\\Users\\Christopher Teutsch\\dorf_state.txt'; +static $STATE_STALE_SECONDS = 60; if ($DORF_VIRTUAL_EVENTS || ! $DORF_IN_LOCKDOWN){ -$img = file_get_contents('https://chaosdorf.de/raumstatus/status.png'); -$hash = md5($img); -$state = $hash_to_state[$hash]; -$ical = new ICal(false, array( - 'defaultSpan' => 2, - 'defaultTimeZone' => 'Europe/Berlin', - 'defaultWeekStart' => 'MO', - 'filterDaysBefore' => '1', - )); -$ical->initUrl($ICAL_URL, $acceptLanguage = 'de'); -$events = $ical->eventsFromInterval('2 week'); -$first_event = $events[0]; -$events = array_slice($events, 1); -$locale = locale_accept_from_http($_SERVER['HTTP_ACCEPT_LANGUAGE']); -if ($locale !== null){ - setlocale(LC_TIME, $locale); + $ical = new ICal(false, array( + 'defaultSpan' => 2, + 'defaultTimeZone' => 'Europe/Berlin', + 'defaultWeekStart' => 'MO', + 'filterDaysBefore' => '1', + )); + if (is_file($ICAL_CACHE_FILE)){ + error_log('is file'); + $mtime = filemtime($ICAL_CACHE_FILE); + $time_diff = time() - $mtime; + error_log(sprintf('%d',$time_diff)); + if ($time_diff >= $ICAL_STALE_SECONDS){ + $data = file_get_contents($ICAL_URL); + file_put_contents($ICAL_CACHE_FILE); + $ical->initString($data); + } + else { + $ical->initFile() + } + // Else get state from network every time (inefficient!) + } else { + $state = get_state('https://chaosdorf.de/raumstatus/status.png'); + } + if () + $ical->initUrl($ICAL_URL, $acceptLanguage = 'de'); + $events = $ical->eventsFromInterval('2 week'); + $first_event = $events[0]; + $events = array_slice($events, 1); } +/** + * @param $url + * @return int + */ +function get_state($url): int +{ + $hash = hash('crc32b', file_get_contents($url)); + switch($hash){ + case '1ac9394d': + return State::STATE_UNKNOWN; + case 'bf48d8e5': + return State::STATE_OPEN; + case 'beab4306': + return State::STATE_MAYBE_OPEN; + case '4e7e398a': + return State::STATE_CLOSED; + case '5503654a': + return State::STATE_PRIVATE; + default: + error_log('Default state called in get_state(): hash '. $hash); + return State::STATE_ERROR; + } } +abstract class State{ // php doesn't have enums + const STATE_CLOSED = 0; + const STATE_OPEN = 1; + const STATE_MAYBE_OPEN = 2; + const STATE_PRIVATE = 3; + const STATE_UNKNOWN = 4; + const STATE_ERROR = -1; +} +class FormattingInfo{ + function __construct($state) + { + switch($state){ + case State::STATE_CLOSED: + $this->color = 'red'; + $this->svg = 'lock'; + $this->state_string = 'Das Dorf ist gerade geschlossen.'; + $this->img_alt = 'geschlossen'; + break; + case State::STATE_MAYBE_OPEN: + $this->color = 'brown'; + $this->svg = 'done'; + $this->state_string = 'Das Dorf ist gerade vielleicht geöffnet:

Der Clubraum ist offen, aber es findet keine Veranstaltung statt.

+ Der Status kann sich also kurzfristig ändern.'; + $this->img_alt = 'vielleicht geöffnet'; + break; + case State::STATE_OPEN: + $this->color = 'green'; + $this->svg = 'done'; + $this->state_string = 'Das Dorf ist gerade geöffnet.

+ Komm gerne vorbei.'; + $this->img_alt = 'geöffnet'; + break; + case State::STATE_PRIVATE: + $this->color = 'fdd835'; + $this->svg = 'lock'; + $this->state_string = 'Das Dorf ist gerade privat:

Es sind Leute da, aber der Clubraum ist nicht geöffnet.

+ Komm gerne vorbei (aber frag lieber vorher, wie lange noch Leute da sind).'; + $this->img_alt = 'privat'; + break; + case State::STATE_UNKNOWN: + $this->color = 'orange'; + $this->svg = 'warning'; + $this->state_string = 'Der Status vom Dorf ist gerade unbekannt'; + $this->img_alt = 'unbekannt'; + case State::STATE_ERROR: + $this->color = 'blue'; + $this->svg = 'error'; + $this->state_string = 'Der Server konnte den Status vom Dorf nicht ermitteln. Sorry.'; + $this->img_alt = 'konnte nicht abgerufen werden'; + break; + } + } + public $svg; + public $img_alt; + public $state_string; + public $color; +} +if (! $DORF_IN_LOCKDOWN){ + // Try to acquire state locally, but *only* if STATE_FILE exists + if (is_file($STATE_FILE)){ + error_log('is file'); + $mtime = filemtime($STATE_FILE); + $time_diff = time() - $mtime; + error_log(sprintf('%d',$time_diff)); + if ($time_diff >= $STATE_STALE_SECONDS){ + $state = get_state('https://chaosdorf.de/raumstatus/status.png'); + $result = file_put_contents($STATE_FILE, sprintf('%d',$state)); + } + else { + $state = sscanf(file_get_contents($STATE_FILE),'%d')[0]; + } + // Else get state from network every time (inefficient!) + } else { + $state = get_state('https://chaosdorf.de/raumstatus/status.png'); + } + $fmt = new FormattingInfo($state); + +} + function format_event($event): string{ global $DATE_FORMAT, $ical; $startdate_loop = $ical->iCalDateToDateTime($event->dtstart_array[3]); @@ -87,8 +162,7 @@ $v = file_get_contents($VISITORS_FILE); Was geht im Dorf.jetzt? - - + @@ -99,20 +173,20 @@ $v = file_get_contents($VISITORS_FILE);

-
Das Chaosdorf ist geschlossen
+

Das Chaosdorf ist geschlossen

Das Chaosdorf ist aufgrund eines Beschlusses des Vereins geschlossen.

Das gilt bis auf Weiteres.

Natürlich hört das Chaosdorfleben nicht auf, kommt uns gerne im VirtualSpace besuchen.

- +
-
Türstatus
- -

state_string ?>

+

Türstatus

+ <?= $fmt->img_alt ?> +

state_string ?>

@@ -122,15 +196,15 @@ $v = file_get_contents($VISITORS_FILE);
-
Events
+

Events

-
Nächste Veranstaltung
+

Nächste Veranstaltung

-

summary, ENT_QUOTES, 'UTF-8') ?>
- - Details zur Veranstaltung +

summary, ENT_QUOTES, 'UTF-8') ?>

+
+

-
Danach:
+

Danach:

@@ -144,7 +218,7 @@ $v = file_get_contents($VISITORS_FILE);
Event-Kalender -
Aktuell keine Veranstaltungen.
+

Aktuell keine Veranstaltungen.

Es stehen aktuell keine Veranstaltungen an.