From 759d05d47c2dfc4cb20113f725b15534360b90df Mon Sep 17 00:00:00 2001 From: Christopher Teutsch Date: Thu, 26 Jan 2023 13:52:00 +0100 Subject: [PATCH] start using objects --- app/State.php | 20 ++++++++ composer.json | 5 ++ index.php | 133 +++++++++++++++++++++++++++++--------------------- psalm.xml | 1 + 4 files changed, 103 insertions(+), 56 deletions(-) create mode 100644 app/State.php diff --git a/app/State.php b/app/State.php new file mode 100644 index 0000000..62b8aac --- /dev/null +++ b/app/State.php @@ -0,0 +1,20 @@ +description = $description; + $this->svg_name = $svg_name; + $this->color = $color; + } + +} diff --git a/composer.json b/composer.json index 637934d..08b1ed5 100644 --- a/composer.json +++ b/composer.json @@ -1,4 +1,9 @@ { + "autoload": { + "psr-4": { + "DorfJetzt\\": "app/" + } + }, "require": { "johngrogg/ics-parser": "^3", "symfony/http-client": "^6.2", diff --git a/index.php b/index.php index 05fec6d..ee7fc4d 100644 --- a/index.php +++ b/index.php @@ -9,12 +9,17 @@ use Symfony\Component\HttpClient\HttpClient; use Symfony\Component\HttpKernel\HttpCache\Store; use Twig\TwigFilter; use Twig\NodeVisitor\OptimizerNodeVisitor; +use DorfJetzt\State; +#region Configuration const VISITORS_FILE = '/opt/dorf.jetzt_visitors'; const ICAL_URL = 'https://chaosdorf.de/~derf/cccd_all.ics'; const HTTP_CACHE = '/tmp/dorf.jetzt/http_cache'; const TMPL_CACHE = '/tmp/dorf.jetzt/twig_cache'; const ROOM_STATE_URL = 'https://chaosdorf.de/raumstatus/status.png'; +const DEFAULT_TZ = 'Europe/Berlin'; +#endregion + const INVALID_UAS = [ "AhrefsBot", @@ -38,41 +43,44 @@ const HASH_TO_STATE = [ '0' => 'error', ]; -$STATE_MAP = [ - 'closed' => (object) [ - 'state_string' => 'Das Dorf ist gerade geschlossen.', - 'svg' => 'lock', - 'color' => 'red', - ], - 'maybe_open' => (object) [ - 'state_string' => 'Das Dorf ist gerade vielleicht geöffnet:

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

+function stateMap(string $state): State +{ + return match ($state) { + 'closed' => new State( + 'Das Dorf ist gerade geschlossen.', + 'lock', + 'red', + ), + 'maybe_open' => new State( + '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) [ - 'state_string' => 'Das Dorf ist gerade geöffnet.

+ 'done', + 'brown', + ), + 'open' => new State( + 'Das Dorf ist gerade geöffnet.

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

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

+ 'done', + 'green', + ), + 'private' => new State( + '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) [ - 'state_string' => 'Der Status vom Dorf ist gerade unbekannt', - 'svg' => 'warning', - 'color' => 'orange', - ], - 'error' => (object) [ - 'state_string' => 'Der Server konnte den Status vom Dorf nicht abrufen.', - 'svg' => 'error', - 'color' => 'blue', - ], -]; + 'lock', + 'fdd835', + ), + 'unknown' => new State( + 'Der Status vom Dorf ist gerade unbekannt', + 'warning', + 'orange', + ), + 'error' => new State( + 'Der Server konnte den Status vom Dorf nicht abrufen.', + 'error', + 'blue', + ), + }; +} function hasValidUa(): bool { @@ -85,22 +93,25 @@ function hasValidUa(): bool return false; } -function dateTimeFromEvent(ICal $ical, object $event): DateTimeImmutable { +function dateTimeFromEvent(ICal $ical, object $event): DateTimeImmutable +{ return DateTimeImmutable::createFromMutable($ical->iCalDateToDateTime($event->dtstart_array[3])); } /** - * @return array> + * @return array{summary: string, url: string, start: DateTimeImmutable, end: DateTimeImmutable}[] */ -function prepare_events(ICal $ical, array $events): array +function prepareEvents(ICal $ical, array $events): array { $returns = []; foreach ($events as $event) { $start = dateTimeFromEvent($ical, $event); $end = $start->add(new DateInterval($event->duration)); + $url = strval($event->url); + $summary = strval($event->summary); $returns[] = [ - 'summary' => $event->summary, - 'url' => $event->url, + 'summary' => $summary, + 'url' => $url, 'start' => $start, 'end' => $end, ]; @@ -108,26 +119,37 @@ function prepare_events(ICal $ical, array $events): array return $returns; } +function getState(\Symfony\Contracts\HttpClient\HttpClientInterface $http): State +{ + try { + $response = $http->request('GET', ROOM_STATE_URL); + $hash = md5($response->getContent()); + if (!array_key_exists($hash, HASH_TO_STATE)){ + error_log("Encountered unknown state hash $hash"); + } + return stateMap(HASH_TO_STATE[$hash]); + } catch (\Exception $e) { + return stateMap('error'); + } +} + + $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, [ +$state_obj = getState($client); + + + +$ical = new ICal(options: [ 'defaultSpan' => 2, - 'defaultTimeZone' => 'Europe/Berlin', + 'defaultTimeZone' => DEFAULT_TZ, 'defaultWeekStart' => 'MO', 'filterDaysBefore' => '1', ]); -$ical->initUrl(ICAL_URL, $acceptLanguage = 'de'); -$events = $ical->eventsFromInterval('2 week'); +$ical->initUrl(ICAL_URL, userAgent: 'dorf.jetzt', acceptLanguage: 'de'); +$events = $ical->eventsFromInterval('2 week') or []; if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { $locale = locale_accept_from_http($_SERVER['HTTP_ACCEPT_LANGUAGE']); setlocale(LC_TIME, $locale); @@ -138,7 +160,8 @@ if (is_string($visitors)) { } else { $visitors = 0; } -$state_obj = $STATE_MAP[$state]; + + $loader = new \Twig\Loader\FilesystemLoader('templates'); $twig = new \Twig\Environment($loader, [ @@ -162,15 +185,13 @@ function formatEndDt(?DateTimeImmutable $end, ?DateTimeImmutable $start, string } $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($ical, $events); +$twig->getExtension(\Twig\Extension\CoreExtension::class)->setTimezone(DEFAULT_TZ); echo ($twig->render("Main.twig", [ 'visitors' => $visitors, - 'state_svg' => $state_obj->svg, + 'state_svg' => $state_obj->svg_name, 'state_color' => $state_obj->color, - 'state_string' => $state_obj->state_string, - 'events' => $render_evts, + 'state_string' => $state_obj->description, + 'events' => prepareEvents($ical, $events), ])); /* Initialising values */ if (hasValidUa()) { diff --git a/psalm.xml b/psalm.xml index aa6b208..3c5e317 100644 --- a/psalm.xml +++ b/psalm.xml @@ -8,6 +8,7 @@ > +