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 @@
>
+