diff --git a/.codex-temp/php-server-error.log b/.codex-temp/php-server-error.log index 0d7d47c..dd33359 100644 --- a/.codex-temp/php-server-error.log +++ b/.codex-temp/php-server-error.log @@ -510,3 +510,5 @@ [Sat Apr 4 14:01:01 2026] 127.0.0.1:63369 [200]: GET /favicon.ico [Sat Apr 4 14:01:01 2026] 127.0.0.1:63369 Closing [Sat Apr 4 14:01:01 2026] 127.0.0.1:61071 Accepted +[Sat Apr 4 14:02:40 2026] 127.0.0.1:61071 Closed without sending a request; it was probably just an unused speculative preconnection +[Sat Apr 4 14:02:40 2026] 127.0.0.1:61071 Closing diff --git a/.codex-temp/render_narrative.php b/.codex-temp/render_narrative.php new file mode 100644 index 0000000..a0682ea --- /dev/null +++ b/.codex-temp/render_narrative.php @@ -0,0 +1,13 @@ +Monat Im Ueberblick<\/h3>.*?

(.*?)<\/p>/s', $html, $m)) { + echo html_entity_decode(strip_tags($m[1]), ENT_QUOTES | ENT_HTML5, 'UTF-8'), PHP_EOL; +} else { + echo 'NARRATIVE_NOT_FOUND', PHP_EOL; +} diff --git a/.codex-temp/render_narrative2.php b/.codex-temp/render_narrative2.php new file mode 100644 index 0000000..882c31d --- /dev/null +++ b/.codex-temp/render_narrative2.php @@ -0,0 +1,13 @@ +(.*?)<\/p>/s', $html, $m)) { + echo html_entity_decode(strip_tags($m[1]), ENT_QUOTES | ENT_HTML5, 'UTF-8'), PHP_EOL; +} else { + echo 'NARRATIVE_NOT_FOUND', PHP_EOL; +} diff --git a/public/monatsvorhersage_old.php b/public/monatsvorhersage_old.php index 724d973..ab14485 100644 --- a/public/monatsvorhersage_old.php +++ b/public/monatsvorhersage_old.php @@ -589,6 +589,105 @@ if (!function_exists('buildObservationTipCalendarIcs')) { } } +if (!function_exists('monthForecastBuildNarrativeText')) { + function monthForecastBuildNarrativeText(array $monthEventList, int $monthNumber, string $monthName, int $year): string + { + $filteredEvents = array_values(array_filter( + $monthEventList, + static fn (array $item): bool => (string) ($item['type'] ?? '') !== 'favorite_satellite_pass' + )); + + $skyIntroByMonth = [ + 1 => 'Der Sternenhimmel im Januar wird noch von den klassischen Wintersternbildern beherrscht. Orion, Stier, Fuhrmann, Zwillinge und der Grosse Hund praegen den Abendhimmel, waehrend im Osten bereits erste Fruehlingsboten hoeher steigen.', + 2 => 'Der Februar zeigt den Winterhimmel in seiner vielleicht schoensten Form. Orion, Stier, Zwillinge, Fuhrmann und Grosser Hund stehen abends eindrucksvoll ueber dem Horizont, spaeter in der Nacht ruesten sich bereits Loewe und andere Fruehlingssternbilder fuer ihren Auftritt.', + 3 => 'Der Sternenhimmel im Maerz bildet den Uebergang von den Winter- zu den Fruehlingssternbildern. Abends stehen Orion, Zwillinge, Fuhrmann und Stier noch markant am Himmel, waehrend gegen Mitternacht Loewe, Jungfrau und Bootes immer mehr Aufmerksamkeit auf sich ziehen.', + 4 => 'Im April dominiert der Fruehlingshimmel den Abend. Loewe, Jungfrau und Bootes stehen guenstig, waehrend die Wintersternbilder nun rasch in den Westen abwandern und am spaeteren Abend bereits Platz fuer den kommenden Sommerhimmel machen.', + 5 => 'Der Mai zeigt den Fruehlingshimmel in voller Pracht. Loewe, Jungfrau, Bootes und die ausgedehnte Wasserschlange praegen die Nacht, waehrend sich im Osten schon die ersten Sternbilder des Sommers bemerkbar machen.', + 6 => 'Im Juni werden die Naechte kurz, doch gerade in der spaeteren Dunkelheit treten bereits die Sommersternbilder hervor. Schwan, Leier und Adler gewinnen an Hoehe, waehrend der Fruehlingshimmel langsam nach Westen rueckt.', + 7 => 'Der Juli gehoert dem Sommerhimmel. Das Sommerdreieck aus Wega, Deneb und Atair dominiert den Blick nach oben, daneben laden Schuetze, Skorpion und die reichen Sternfelder der Milchstrasse zu ausgedehnten Beobachtungen ein.', + 8 => 'Im August zeigt sich der Sommerhimmel von seiner eindrucksvollsten Seite. Das Sommerdreieck steht hoch, die Milchstrasse zieht sich markant ueber den Himmel, und in der zweiten Nachthaelfte machen sich bereits erste Herbststernbilder bemerkbar.', + 9 => 'Der September vermittelt zwischen Sommer- und Herbsthimmel. Das Sommerdreieck bleibt ein Blickfang, doch Pegasus, Andromeda und die herbstlichen Sternbilder steigen nun immer besser am Abendhimmel auf.', + 10 => 'Im Oktober uebernimmt der Herbsthimmel die Hauptrolle. Pegasus, Andromeda, Perseus und Dreieck stehen guenstig, waehrend sich gegen Morgen schon die ersten Vorboten des Winterhimmels zeigen.', + 11 => 'Der November bringt lange dunkle Naechte und einen Himmel zwischen Herbst und Winter. Pegasus und Andromeda stehen noch gut, waehrend Stier, Fuhrmann und Orion im Laufe der Nacht immer eindrucksvoller werden.', + 12 => 'Im Dezember kehrt der Winterhimmel eindrucksvoll zurueck. Orion, Stier, Zwillinge, Fuhrmann und der Grosse Hund dominieren den Abend und machen den Monat zu einer besonders attraktiven Zeit fuer Sternbeobachtungen.', + ]; + + $paragraphs = []; + $paragraphs[] = $skyIntroByMonth[$monthNumber] ?? ($monthName . ' ' . $year . ' bietet einen abwechslungsreichen Himmel zwischen den jahreszeitlichen Sternbildern.'); + + $findEvents = static function (array $events, callable $filter, int $limit = 3): array { + $matches = []; + foreach ($events as $event) { + if ($filter($event)) { + $matches[] = $event; + if (count($matches) >= $limit) { + break; + } + } + } + return $matches; + }; + + $describeEvents = static function (array $events): string { + $parts = []; + foreach ($events as $event) { + $label = trim((string) ($event['event'] ?? '')); + $date = trim((string) ($event['date'] ?? '')); + if ($label === '' || $date === '') { + continue; + } + $parts[] = $label . ' am ' . $date; + } + return implode(', ', $parts); + }; + + $moonEvents = $findEvents( + $filteredEvents, + static fn (array $event): bool => in_array((string) ($event['type'] ?? ''), ['moon_phase', 'golden_handle', 'moon_planet_approach', 'moon_deep_sky_approach', 'moon_occultation', 'moon_apsis'], true), + 4 + ); + if ($moonEvents !== []) { + $paragraphs[] = 'Auch der Mond liefert im Laufe des Monats einige markante Beobachtungsmomente. Besonders auffaellig sind ' . $describeEvents($moonEvents) . '.'; + } + + $planetEvents = $findEvents( + $filteredEvents, + static fn (array $event): bool => in_array((string) ($event['type'] ?? ''), ['inner_planet_elongation', 'venus_peak_magnitude', 'outer_planet_event', 'outer_planet_station', 'planet_conjunction', 'planet_constellation_change', 'planet_parade', 'mercury_good_visibility'], true), + 5 + ); + if ($planetEvents !== []) { + $paragraphs[] = 'Bei den Planeten lohnt sich vor allem der Blick auf ' . $describeEvents($planetEvents) . '. Diese Termine geben dem Monat seinen charakteristischen planetaren Akzent.'; + } + + $eclipseEvents = $findEvents( + $filteredEvents, + static fn (array $event): bool => in_array((string) ($event['type'] ?? ''), ['eclipse', 'lunar_eclipse', 'solar_eclipse'], true), + 3 + ); + if ($eclipseEvents !== []) { + $paragraphs[] = 'Besondere Aufmerksamkeit verdienen ausserdem die Finsternistermine. In diesem Monat stechen ' . $describeEvents($eclipseEvents) . ' hervor.'; + } + + $meteorEvents = $findEvents( + $filteredEvents, + static fn (array $event): bool => (string) ($event['type'] ?? '') === 'meteor_shower_peak', + 2 + ); + if ($meteorEvents !== []) { + $paragraphs[] = 'Freunde von Meteoren sollten zudem die Aktivitaet der Meteorstroeme im Blick behalten. Erwähnenswert sind besonders ' . $describeEvents($meteorEvents) . '.'; + } + + if (count($paragraphs) === 1 && $filteredEvents !== []) { + $highlights = array_slice($filteredEvents, 0, 4); + $paragraphs[] = 'Zu den auffaelligen Terminen des Monats gehoeren ' . $describeEvents($highlights) . '.'; + } + + $paragraphs[] = 'Die chronologische Ereignisliste darunter dient als kompakte Terminuebersicht; automatische ISS- und Favoriten-Satellitenueberfluege bleiben in diesem Beschreibungstext bewusst unberuecksichtigt.'; + + return implode("\n\n", $paragraphs); + } +} + try { $dbConfig = require __DIR__ . '/../config/database.php'; $dsn = sprintf( @@ -1816,6 +1915,8 @@ usort( static fn (array $a, array $b): int => strcmp((string) ($a['local_iso'] ?? ''), (string) ($b['local_iso'] ?? '')) ); +$monthNarrativeText = monthForecastBuildNarrativeText($monthEventList, $selectedMonth, $months[$selectedMonth], $selectedYear); + $observationTipInsertSql = buildObservationTipInsertSql($monthEventList, new DateTimeZone($chartTimezone)); $observationTipCalendarIcs = buildObservationTipCalendarIcs($monthEventList, new DateTimeZone($chartTimezone)); @@ -1887,6 +1988,18 @@ $observationTipCalendarFilenameJson = json_encode(sprintf('astrotools-monatserei +

+
+
+

Monat Im Ueberblick

+

+
+
+ +
+
@@ -2007,6 +2120,7 @@ $observationTipCalendarFilenameJson = json_encode(sprintf('astrotools-monatserei } .monatsvorhersage-form, +.monatsnarrativ-card, .monatskarte-card { border: 1px solid rgba(201, 168, 76, 0.14); border-radius: calc(var(--radius) + 4px); @@ -2137,6 +2251,11 @@ $observationTipCalendarFilenameJson = json_encode(sprintf('astrotools-monatserei justify-content: flex-end; } +.monatsnarrativ-text { + font-size: 1.02rem; + white-space: pre-line; +} + .monatskarte-stage { padding: 0 20px 20px; }