diff --git a/composer.lock b/composer.lock index 3600f1f..9d83a82 100644 --- a/composer.lock +++ b/composer.lock @@ -2827,89 +2827,6 @@ ], "time": "2022-11-03T14:55:06+00:00" }, - { - "name": "symfony/polyfill-php80", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-11-03T14:55:06+00:00" - }, { "name": "symfony/string", "version": "v6.2.2", @@ -2998,16 +2915,16 @@ }, { "name": "vimeo/psalm", - "version": "5.4.0", + "version": "5.5.0", "source": { "type": "git", "url": "https://github.com/vimeo/psalm.git", - "reference": "62db5d4f6a7ae0a20f7cc5a4952d730272fc0863" + "reference": "b63061a27f2683ec0f3509012bb22daab3b65b61" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vimeo/psalm/zipball/62db5d4f6a7ae0a20f7cc5a4952d730272fc0863", - "reference": "62db5d4f6a7ae0a20f7cc5a4952d730272fc0863", + "url": "https://api.github.com/repos/vimeo/psalm/zipball/b63061a27f2683ec0f3509012bb22daab3b65b61", + "reference": "b63061a27f2683ec0f3509012bb22daab3b65b61", "shasum": "" }, "require": { @@ -3030,11 +2947,10 @@ "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", "nikic/php-parser": "^4.13", "php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0", - "sebastian/diff": "^4.0", + "sebastian/diff": "^4.0 || ^5.0", "spatie/array-to-xml": "^2.17.0", "symfony/console": "^4.1.6 || ^5.0 || ^6.0", - "symfony/filesystem": "^5.4 || ^6.0", - "symfony/polyfill-php80": "^1.25" + "symfony/filesystem": "^5.4 || ^6.0" }, "provide": { "psalm/psalm": "self.version" @@ -3097,9 +3013,9 @@ ], "support": { "issues": "https://github.com/vimeo/psalm/issues", - "source": "https://github.com/vimeo/psalm/tree/5.4.0" + "source": "https://github.com/vimeo/psalm/tree/5.5.0" }, - "time": "2022-12-19T21:31:12+00:00" + "time": "2023-01-23T01:50:35+00:00" }, { "name": "webmozart/assert", diff --git a/index.php b/index.php index 592eb5c..05fec6d 100644 --- a/index.php +++ b/index.php @@ -1,4 +1,6 @@ 'error', ]; -function hasValidUa(): bool -{ - if (isset($_SERVER['HTTP_USER_AGENT'])) { - if (in_array(true, array_map(fn ($ua) => str_contains($_SERVER['HTTP_USER_AGENT'], $ua), INVALID_UAS))) { - return false; - } - return true; - } - return false; -} - -/** - * @param object $event - */ -function format_event($event): string -{ - global $DATE_FORMAT, $ical; - $startdate_loop = $ical->iCalDateToDateTime($event->dtstart_array[3]); - $startdate_str = $startdate_loop->format($DATE_FORMAT); - $interval_loop = new DateInterval($event->duration); - if ($interval_loop->d != 0 || $interval_loop->h >= 24) { - $enddate_str = $startdate_loop->add($interval_loop)->format($DATE_FORMAT); - } else { - $enddate_str = $startdate_loop->add($interval_loop)->format('H:i'); - } - return $startdate_str . ' – ' . $enddate_str; -} -/** - * @return array> - */ -function prepare_events(array $events): array{ - global $ical; - $returns = []; - foreach ($events as $event){ - $start = DateTimeImmutable::createFromMutable($ical->iCalDateToDateTime($event->dtstart_array[3])); - $end = $start->add(new DateInterval($event->duration)); - $returns[] = [ - 'summary' => $event->summary, - 'url' => $event->url, - 'start' => $start, - 'end' => $end, - ]; - } - return $returns; -} - -$store = new Store('/tmp/dorf.jetzt/http_cache'); -$client = HttpClient::create(); -$client = new CachingHttpClient($client, $store, ['default_ttl' => 60, 'allow_revalidate' => true]); - -static $DATE_FORMAT = 'd.m.Y H:i'; -static $VISITORS_FILE = '/opt/dorf.jetzt_visitors'; -static $DORF_IN_LOCKDOWN = false; -static $DORF_VIRTUAL_EVENTS = true; -static $ICAL_URL = 'https://chaosdorf.de/~derf/cccd_all.ics'; -$state_map = [ +$STATE_MAP = [ 'closed' => (object) [ 'state_string' => 'Das Dorf ist gerade geschlossen.', 'svg' => 'lock', @@ -119,55 +73,88 @@ $state_map = [ 'color' => 'blue', ], ]; -$hash_to_state = [ - 'bff0167ed8aba031c49122ef4046cf1b' => 'closed', - 'd8ec899c69283bc775952a767db9d5f5' => 'maybe_open', - '2c2672c641425e5b2acd6ee74f39ae60' => 'open', - '66aece8ae27ffd3a656d42005fa3efbd' => 'private', - '86c75c0ad413b06ff8291673162d0b64' => 'unknown', - '0' => 'error', -]; -$state = 'error'; -if ($DORF_VIRTUAL_EVENTS || !$DORF_IN_LOCKDOWN) { - try { - $response = $client->request('GET', 'https://chaosdorf.de/raumstatus/status.png'); - $hash = md5($response->getContent()); - } catch (\Exception $e) { - $hash = 0; - } - $state = $hash_to_state[$hash]; - $ical = new ICal(false, [ - '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); - if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { - $locale = locale_accept_from_http($_SERVER['HTTP_ACCEPT_LANGUAGE']); - setlocale(LC_TIME, $locale); + +function hasValidUa(): bool +{ + if (isset($_SERVER['HTTP_USER_AGENT'])) { + if (in_array(true, array_map(fn ($ua) => str_contains($_SERVER['HTTP_USER_AGENT'], $ua), INVALID_UAS))) { + return false; + } + return true; } + return false; } -$visitors = file_get_contents($VISITORS_FILE); + +function dateTimeFromEvent(ICal $ical, object $event): DateTimeImmutable { + return DateTimeImmutable::createFromMutable($ical->iCalDateToDateTime($event->dtstart_array[3])); +} + +/** + * @return array> + */ +function prepare_events(ICal $ical, array $events): array +{ + $returns = []; + foreach ($events as $event) { + $start = dateTimeFromEvent($ical, $event); + $end = $start->add(new DateInterval($event->duration)); + $returns[] = [ + 'summary' => $event->summary, + 'url' => $event->url, + 'start' => $start, + 'end' => $end, + ]; + } + return $returns; +} + +$store = new Store(HTTP_CACHE); +$client = HttpClient::create(); +$client = new CachingHttpClient($client, $store, ['default_ttl' => 60, 'allow_revalidate' => true]); + +$state = 'error'; +try { + $response = $client->request('GET', ROOM_STATE_URL); + $hash = md5($response->getContent()); +} catch (\Exception $e) { + $hash = 0; +} +$state = HASH_TO_STATE[$hash]; +$ical = new ICal(false, [ + 'defaultSpan' => 2, + 'defaultTimeZone' => 'Europe/Berlin', + 'defaultWeekStart' => 'MO', + 'filterDaysBefore' => '1', +]); +$ical->initUrl(ICAL_URL, $acceptLanguage = 'de'); +$events = $ical->eventsFromInterval('2 week'); +if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { + $locale = locale_accept_from_http($_SERVER['HTTP_ACCEPT_LANGUAGE']); + setlocale(LC_TIME, $locale); +} +$visitors = file_get_contents(VISITORS_FILE); if (is_string($visitors)) { $visitors = intval($visitors); } else { $visitors = 0; } -$state_obj = $state_map[$state]; +$state_obj = $STATE_MAP[$state]; $loader = new \Twig\Loader\FilesystemLoader('templates'); $twig = new \Twig\Environment($loader, [ - //'cache' => '/tmp/dorf.jetzt/twig_cache' + 'cache' => TMPL_CACHE, + 'auto_reload' => true, + // The 'raw' optimizer sometimes eats the only 'raw' that is used + 'optimizations' => OptimizerNodeVisitor::OPTIMIZE_ALL ^ OptimizerNodeVisitor::OPTIMIZE_RAW_FILTER, ]); -function formatEndDt(DateTime|DateTimeImmutable $end, DateTime|DateTimeImmutable $start, string $tz = 'Europe/Berlin'): string{ - $daySame = $end->setTimeZone(new DateTimeZone($tz))->format('d.m.Y') == $start->setTimeZone(new DateTimeZone($tz))->format('d.m.Y'); - $endIsMidnight = $end->setTimeZone(new DateTimeZone($tz))->format('H:i') == '00:00' && $start->setTimeZone(new DateTimeZone($tz))->format('H:i') != '00:00'; - if ($daySame || $endIsMidnight){ +function formatEndDt(?DateTimeImmutable $end, ?DateTimeImmutable $start, string $timezone = 'Europe/Berlin'): string +{ + if ($end == null || $start == null) return "ERROR"; + $tz = new DateTimeZone($timezone); + $daySame = $end->setTimeZone($tz)->format('d.m.Y') == $start->setTimeZone($tz)->format('d.m.Y'); + $endIsMidnight = $end->setTimeZone($tz)->format('H:i') == '00:00' && $start->setTimeZone($tz)->format('H:i') != '00:00'; + if ($daySame || $endIsMidnight) { return $end->format('H:i'); } else { return $end->format('d.m.Y H:i'); @@ -177,8 +164,8 @@ function formatEndDt(DateTime|DateTimeImmutable $end, DateTime|DateTimeImmutable $twig->addFilter(new TwigFilter('end_datetime', 'formatEndDt')); //$twig->addExtension(new \Twig\Extra\Intl\IntlExtension()); $twig->getExtension(\Twig\Extension\CoreExtension::class)->setTimezone('Europe/Berlin'); -$render_evts = prepare_events($events); -echo($twig->render("Main.twig", [ +$render_evts = prepare_events($ical, $events); +echo ($twig->render("Main.twig", [ 'visitors' => $visitors, 'state_svg' => $state_obj->svg, 'state_color' => $state_obj->color, @@ -188,5 +175,5 @@ echo($twig->render("Main.twig", [ /* Initialising values */ if (hasValidUa()) { $visitors++; - file_put_contents($VISITORS_FILE, strval($visitors)); + file_put_contents(VISITORS_FILE, strval($visitors)); } diff --git a/templates/Main.twig b/templates/Main.twig index 61ccbc6..5b7b768 100644 --- a/templates/Main.twig +++ b/templates/Main.twig @@ -17,7 +17,7 @@
Türstatus
-

{{ state_string|raw }}

+

{{ state_string | raw }}

@@ -37,7 +37,7 @@ {% for event in events %} - {% if loop.index > 0 %} + {% if loop.index0 > 0 %}
{{ event.start|date('d.m.Y H:i', 'Europe/Berlin') }} – {{ event.end|end_datetime(event.start, 'Europe/Berlin') }} {{ event.summary|e }}