diff --git a/.codex-temp/php-server.err.log b/.codex-temp/php-server.err.log index ef6c2ae..8cb2a71 100644 --- a/.codex-temp/php-server.err.log +++ b/.codex-temp/php-server.err.log @@ -485,3 +485,144 @@ Stack trace: [Fri Apr 3 13:56:21 2026] 127.0.0.1:63611 Accepted [Fri Apr 3 13:56:30 2026] 127.0.0.1:63611 [200]: GET /monatsvorhersage_old.php?year=2026&month=4 [Fri Apr 3 13:56:30 2026] 127.0.0.1:63611 Closing +[Fri Apr 3 14:05:53 2026] 127.0.0.1:50654 Accepted +[Fri Apr 3 14:06:03 2026] 127.0.0.1:50654 [200]: GET /monatsvorhersage_old.php?year=2026&month=8 +[Fri Apr 3 14:06:03 2026] 127.0.0.1:50654 Closing +[Fri Apr 3 14:06:41 2026] 127.0.0.1:49941 Accepted +[Fri Apr 3 14:06:56 2026] 127.0.0.1:49941 [200]: GET /monatsvorhersage_old.php?year=2026&month=2 +[Fri Apr 3 14:06:56 2026] 127.0.0.1:49941 Closing +[Fri Apr 3 14:06:56 2026] 127.0.0.1:62553 Accepted +[Fri Apr 3 14:06:56 2026] 127.0.0.1:63990 Accepted +[Fri Apr 3 14:06:56 2026] 127.0.0.1:62553 [200]: GET /css/style.css +[Fri Apr 3 14:06:57 2026] 127.0.0.1:63990 [200]: GET /.well-known/appspecific/com.chrome.devtools.json +[Fri Apr 3 14:06:57 2026] 127.0.0.1:63990 Closing +[Fri Apr 3 14:06:57 2026] 127.0.0.1:62972 Accepted +[Fri Apr 3 14:06:57 2026] 127.0.0.1:62972 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 14:06:57 2026] 127.0.0.1:62553 Closing +[Fri Apr 3 14:06:57 2026] 127.0.0.1:62972 Closing +[Fri Apr 3 14:06:57 2026] 127.0.0.1:52058 Accepted +[Fri Apr 3 14:06:57 2026] 127.0.0.1:55168 Accepted +[Fri Apr 3 14:06:57 2026] 127.0.0.1:52058 [200]: GET /images/star16x16.png +[Fri Apr 3 14:06:57 2026] 127.0.0.1:55168 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 14:06:57 2026] 127.0.0.1:52058 Closing +[Fri Apr 3 14:06:57 2026] 127.0.0.1:55168 Closing +[Fri Apr 3 14:06:57 2026] 127.0.0.1:55317 Accepted +[Fri Apr 3 14:06:59 2026] 127.0.0.1:55317 [200]: GET /favicon.ico +[Fri Apr 3 14:06:59 2026] 127.0.0.1:55317 Closing +[Fri Apr 3 14:08:03 2026] 127.0.0.1:57315 Accepted +[Fri Apr 3 14:08:18 2026] 127.0.0.1:57315 [200]: GET /monatsvorhersage_old.php?year=2026&month=2 +[Fri Apr 3 14:08:18 2026] 127.0.0.1:57315 Closing +[Fri Apr 3 14:08:18 2026] 127.0.0.1:64377 Accepted +[Fri Apr 3 14:08:18 2026] 127.0.0.1:50770 Accepted +[Fri Apr 3 14:08:19 2026] 127.0.0.1:64377 [200]: GET /.well-known/appspecific/com.chrome.devtools.json +[Fri Apr 3 14:08:19 2026] 127.0.0.1:64377 Closing +[Fri Apr 3 14:08:19 2026] 127.0.0.1:51194 Accepted +[Fri Apr 3 14:08:19 2026] 127.0.0.1:50770 [200]: GET /css/style.css +[Fri Apr 3 14:08:19 2026] 127.0.0.1:51194 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 14:08:19 2026] 127.0.0.1:50770 Closing +[Fri Apr 3 14:08:19 2026] 127.0.0.1:51194 Closing +[Fri Apr 3 14:08:19 2026] 127.0.0.1:64032 Accepted +[Fri Apr 3 14:08:19 2026] 127.0.0.1:49570 Accepted +[Fri Apr 3 14:08:19 2026] 127.0.0.1:64032 [200]: GET /images/star16x16.png +[Fri Apr 3 14:08:19 2026] 127.0.0.1:49570 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 14:08:19 2026] 127.0.0.1:64032 Closing +[Fri Apr 3 14:08:19 2026] 127.0.0.1:49570 Closing +[Fri Apr 3 14:08:19 2026] 127.0.0.1:59174 Accepted +[Fri Apr 3 14:08:20 2026] 127.0.0.1:59174 [200]: GET /favicon.ico +[Fri Apr 3 14:08:20 2026] 127.0.0.1:59174 Closing +[Fri Apr 3 14:08:27 2026] 127.0.0.1:49907 Accepted +[Fri Apr 3 14:08:41 2026] 127.0.0.1:49907 [200]: GET /monatsvorhersage_old.php?year=2026&month=3 +[Fri Apr 3 14:08:41 2026] 127.0.0.1:49907 Closing +[Fri Apr 3 14:08:41 2026] 127.0.0.1:63117 Accepted +[Fri Apr 3 14:08:41 2026] 127.0.0.1:52613 Accepted +[Fri Apr 3 14:08:42 2026] 127.0.0.1:63117 [200]: GET /.well-known/appspecific/com.chrome.devtools.json +[Fri Apr 3 14:08:42 2026] 127.0.0.1:63117 Closing +[Fri Apr 3 14:08:42 2026] 127.0.0.1:55863 Accepted +[Fri Apr 3 14:08:42 2026] 127.0.0.1:52613 [200]: GET /css/style.css +[Fri Apr 3 14:08:42 2026] 127.0.0.1:55863 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 14:08:42 2026] 127.0.0.1:52613 Closing +[Fri Apr 3 14:08:42 2026] 127.0.0.1:55863 Closing +[Fri Apr 3 14:08:42 2026] 127.0.0.1:59052 Accepted +[Fri Apr 3 14:08:42 2026] 127.0.0.1:55989 Accepted +[Fri Apr 3 14:08:42 2026] 127.0.0.1:59052 [200]: GET /images/star16x16.png +[Fri Apr 3 14:08:42 2026] 127.0.0.1:55989 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 14:08:42 2026] 127.0.0.1:59052 Closing +[Fri Apr 3 14:08:42 2026] 127.0.0.1:55989 Closing +[Fri Apr 3 14:08:43 2026] 127.0.0.1:57151 Accepted +[Fri Apr 3 14:08:44 2026] 127.0.0.1:57151 [200]: GET /favicon.ico +[Fri Apr 3 14:08:44 2026] 127.0.0.1:57151 Closing +[Fri Apr 3 14:09:32 2026] 127.0.0.1:54316 Accepted +[Fri Apr 3 14:09:42 2026] 127.0.0.1:54316 [200]: GET /monatsvorhersage_old.php?year=2026&month=8 +[Fri Apr 3 14:09:42 2026] 127.0.0.1:54316 Closing +[Fri Apr 3 14:09:42 2026] 127.0.0.1:54318 Accepted +[Fri Apr 3 14:09:42 2026] 127.0.0.1:50161 Accepted +[Fri Apr 3 14:09:51 2026] 127.0.0.1:54318 [200]: GET /monatsvorhersage_old.php?year=2026&month=8 +[Fri Apr 3 14:09:51 2026] 127.0.0.1:54318 Closing +[Fri Apr 3 14:10:00 2026] 127.0.0.1:50161 [200]: GET /monatsvorhersage_old.php?year=2026&month=8 +[Fri Apr 3 14:10:00 2026] 127.0.0.1:50161 Closing +[Fri Apr 3 14:10:00 2026] 127.0.0.1:61489 Accepted +[Fri Apr 3 14:10:00 2026] 127.0.0.1:54701 Accepted +[Fri Apr 3 14:10:00 2026] 127.0.0.1:61489 [200]: GET /css/style.css +[Fri Apr 3 14:10:00 2026] 127.0.0.1:51314 Accepted +[Fri Apr 3 14:10:02 2026] 127.0.0.1:54701 [200]: GET /.well-known/appspecific/com.chrome.devtools.json +[Fri Apr 3 14:10:02 2026] 127.0.0.1:54701 Closing +[Fri Apr 3 14:10:02 2026] 127.0.0.1:51314 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 14:10:02 2026] 127.0.0.1:61489 Closing +[Fri Apr 3 14:10:02 2026] 127.0.0.1:51314 Closing +[Fri Apr 3 14:10:02 2026] 127.0.0.1:63337 Accepted +[Fri Apr 3 14:10:02 2026] 127.0.0.1:63619 Accepted +[Fri Apr 3 14:10:02 2026] 127.0.0.1:63337 [200]: GET /images/star16x16.png +[Fri Apr 3 14:10:02 2026] 127.0.0.1:63619 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 14:10:02 2026] 127.0.0.1:63337 Closing +[Fri Apr 3 14:10:02 2026] 127.0.0.1:63619 Closing +[Fri Apr 3 14:10:02 2026] 127.0.0.1:49976 Accepted +[Fri Apr 3 14:10:03 2026] 127.0.0.1:49976 [200]: GET /favicon.ico +[Fri Apr 3 14:10:03 2026] 127.0.0.1:49976 Closing +[Fri Apr 3 14:10:31 2026] 127.0.0.1:49480 Accepted +[Fri Apr 3 14:10:41 2026] 127.0.0.1:49480 [200]: GET /monatsvorhersage_old.php?year=2026&month=8 +[Fri Apr 3 14:10:41 2026] 127.0.0.1:49480 Closing +[Fri Apr 3 14:10:41 2026] 127.0.0.1:49482 Accepted +[Fri Apr 3 14:10:51 2026] 127.0.0.1:49482 [200]: GET /monatsvorhersage_old.php?year=2026&month=8 +[Fri Apr 3 14:10:51 2026] 127.0.0.1:49482 Closing +[Fri Apr 3 14:11:02 2026] 127.0.0.1:59645 Accepted +[Fri Apr 3 14:11:11 2026] 127.0.0.1:59645 [200]: GET /monatsvorhersage_old.php?year=2026&month=8 +[Fri Apr 3 14:11:11 2026] 127.0.0.1:59645 Closing +[Fri Apr 3 14:11:11 2026] 127.0.0.1:60717 Accepted +[Fri Apr 3 14:11:11 2026] 127.0.0.1:59210 Accepted +[Fri Apr 3 14:11:12 2026] 127.0.0.1:60717 [200]: GET /.well-known/appspecific/com.chrome.devtools.json +[Fri Apr 3 14:11:12 2026] 127.0.0.1:60717 Closing +[Fri Apr 3 14:11:12 2026] 127.0.0.1:61585 Accepted +[Fri Apr 3 14:11:12 2026] 127.0.0.1:59210 [200]: GET /css/style.css +[Fri Apr 3 14:11:12 2026] 127.0.0.1:61585 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 14:11:12 2026] 127.0.0.1:59210 Closing +[Fri Apr 3 14:11:12 2026] 127.0.0.1:61585 Closing +[Fri Apr 3 14:11:12 2026] 127.0.0.1:53714 Accepted +[Fri Apr 3 14:11:12 2026] 127.0.0.1:63463 Accepted +[Fri Apr 3 14:11:12 2026] 127.0.0.1:53714 [200]: GET /images/star16x16.png +[Fri Apr 3 14:11:12 2026] 127.0.0.1:63463 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 14:11:12 2026] 127.0.0.1:53714 Closing +[Fri Apr 3 14:11:12 2026] 127.0.0.1:63463 Closing +[Fri Apr 3 14:11:12 2026] 127.0.0.1:56763 Accepted +[Fri Apr 3 14:11:13 2026] 127.0.0.1:56763 [200]: GET /favicon.ico +[Fri Apr 3 14:11:13 2026] 127.0.0.1:56763 Closing +[Fri Apr 3 14:43:43 2026] 127.0.0.1:60823 Accepted +[Fri Apr 3 14:43:52 2026] 127.0.0.1:60823 [200]: GET /monatsvorhersage_old.php?year=2026&month=8 +[Fri Apr 3 14:43:52 2026] 127.0.0.1:60823 Closing +[Fri Apr 3 14:43:52 2026] 127.0.0.1:61798 Accepted +[Fri Apr 3 14:43:52 2026] 127.0.0.1:51856 Accepted +[Fri Apr 3 14:43:53 2026] 127.0.0.1:61798 [200]: GET /.well-known/appspecific/com.chrome.devtools.json +[Fri Apr 3 14:43:53 2026] 127.0.0.1:61798 Closing +[Fri Apr 3 14:43:53 2026] 127.0.0.1:50589 Accepted +[Fri Apr 3 14:43:53 2026] 127.0.0.1:51856 [200]: GET /css/style.css +[Fri Apr 3 14:43:53 2026] 127.0.0.1:50589 [200]: GET /js/astronomy.browser.min.js +[Fri Apr 3 14:43:53 2026] 127.0.0.1:51856 Closing +[Fri Apr 3 14:43:53 2026] 127.0.0.1:50589 Closing +[Fri Apr 3 14:43:53 2026] 127.0.0.1:57384 Accepted +[Fri Apr 3 14:43:53 2026] 127.0.0.1:57384 [200]: GET /images/star16x16.png +[Fri Apr 3 14:43:53 2026] 127.0.0.1:61503 Accepted +[Fri Apr 3 14:43:53 2026] 127.0.0.1:61503 [200]: GET /images/star16x16_rays.png +[Fri Apr 3 14:43:53 2026] 127.0.0.1:57384 Closing +[Fri Apr 3 14:43:53 2026] 127.0.0.1:61503 Closing +[Fri Apr 3 14:43:53 2026] 127.0.0.1:63593 Accepted +[Fri Apr 3 14:43:55 2026] 127.0.0.1:63593 [200]: GET /favicon.ico +[Fri Apr 3 14:43:55 2026] 127.0.0.1:63593 Closing diff --git a/public/monatsvorhersage_old.php b/public/monatsvorhersage_old.php index d18dbba..ab041ff 100644 --- a/public/monatsvorhersage_old.php +++ b/public/monatsvorhersage_old.php @@ -63,6 +63,7 @@ $eclipseEvents = []; $moonApsisEvents = []; $sunApsisEvents = []; $innerPlanetElongationEvents = []; +$outerPlanetEvents = []; $moonOccultations = []; $seasonChanges = []; $monthEventList = []; @@ -422,6 +423,23 @@ if (is_array($elongationDecoded) && ($elongationDecoded['ok'] ?? false)) { $innerPlanetElongationEvents = is_array($elongationDecoded['events'] ?? null) ? $elongationDecoded['events'] : []; } +$outerPlanetOutput = []; +$outerPlanetExitCode = 0; +$outerPlanetArgs = [ + $pythonScriptPath, + 'outer_planet_events_for_month', + (string) $selectedYear, + (string) $selectedMonth, + $chartTimezone, +]; +$outerPlanetCommand = $pythonExecutable . ' ' . implode(' ', array_map('escapeshellarg', $outerPlanetArgs)) . ' 2>&1'; +exec($outerPlanetCommand, $outerPlanetOutput, $outerPlanetExitCode); +$outerPlanetRaw = trim(implode("\n", $outerPlanetOutput)); +$outerPlanetDecoded = json_decode($outerPlanetRaw, true); +if (is_array($outerPlanetDecoded) && ($outerPlanetDecoded['ok'] ?? false)) { + $outerPlanetEvents = is_array($outerPlanetDecoded['events'] ?? null) ? $outerPlanetDecoded['events'] : []; +} + $moonPlanetOutput = []; $moonPlanetExitCode = 0; $moonPlanetArgs = [ @@ -640,6 +658,20 @@ foreach ($innerPlanetElongationEvents as $elongationEvent) { ]; } +foreach ($outerPlanetEvents as $outerPlanetEvent) { + if (!is_array($outerPlanetEvent)) { + continue; + } + + $monthEventList[] = [ + 'event' => (string) ($outerPlanetEvent['label'] ?? 'Planetenereignis'), + 'date' => (string) ($outerPlanetEvent['local_date'] ?? ''), + 'time' => (string) ($outerPlanetEvent['local_time'] ?? ''), + 'local_iso' => (string) ($outerPlanetEvent['local_iso'] ?? ''), + 'type' => 'outer_planet_event', + ]; +} + foreach ($moonPlanetApproaches as $approachEvent) { if (!is_array($approachEvent)) { continue; diff --git a/public/py/__pycache__/api.cpython-314.pyc b/public/py/__pycache__/api.cpython-314.pyc index 40ecfa3..ede6ca3 100644 Binary files a/public/py/__pycache__/api.cpython-314.pyc and b/public/py/__pycache__/api.cpython-314.pyc differ diff --git a/public/py/api.py b/public/py/api.py index f46121e..86b5d86 100644 --- a/public/py/api.py +++ b/public/py/api.py @@ -1230,6 +1230,84 @@ def action_inner_planet_elongations_for_month(args: list[str]) -> dict: } +def action_outer_planet_events_for_month(args: list[str]) -> dict: + if len(args) != 3: + fail( + "Aktion outer_planet_events_for_month erwartet 3 Argumente: year month timezone", + extra={"argv": args}, + ) + + try: + year = int(args[0]) + month = int(args[1]) + except ValueError as exc: + fail("Jahr oder Monat sind ungueltig.", extra={"details": str(exc), "argv": args}) + + if month < 1 or month > 12: + fail("Monat muss zwischen 1 und 12 liegen.", extra={"month": month}) + + timezone_name = args[2] + try: + tz = ZoneInfo(timezone_name) + except Exception as exc: + fail("Zeitzone ist ungueltig oder auf dem Server nicht verfuegbar.", extra={"details": str(exc)}) + + local_start = datetime(year, month, 1, 0, 0, 0, tzinfo=tz) + if month == 12: + local_end = datetime(year + 1, 1, 1, 0, 0, 0, tzinfo=tz) + else: + local_end = datetime(year, month + 1, 1, 0, 0, 0, tzinfo=tz) + + utc_start = local_start.astimezone(timezone.utc) + scan_start = dt_to_time(utc_start - timedelta(days=450)) + + planet_defs = [ + ("Mars", astronomy.Body.Mars, "mars"), + ("Jupiter", astronomy.Body.Jupiter, "jupiter"), + ("Saturn", astronomy.Body.Saturn, "saturn"), + ("Uranus", astronomy.Body.Uranus, "uranus"), + ("Neptun", astronomy.Body.Neptune, "neptune"), + ] + + events: list[dict] = [] + for label, body, key in planet_defs: + for event_kind, target_lon, event_label in [ + ("opposition", 0.0, "Opposition"), + ("conjunction", 180.0, "Konjunktion"), + ]: + event_time = astronomy.SearchRelativeLongitude(body, target_lon, scan_start) + while True: + event_dt_utc = time_to_datetime(event_time) + local_dt = event_dt_utc.astimezone(tz) + if local_dt >= local_end: + break + if local_dt >= local_start: + events.append({ + "planet_key": key, + "planet_label": label, + "kind": event_kind, + "label": f"{label} in {event_label}", + "utc_iso": event_dt_utc.isoformat().replace("+00:00", "Z"), + "local_iso": local_dt.isoformat(), + "local_date": local_dt.strftime("%d.%m.%Y"), + "local_time": local_dt.strftime("%H:%M"), + }) + event_time = astronomy.SearchRelativeLongitude(body, target_lon, event_time.AddDays(10.0)) + + events.sort(key=lambda item: item["local_iso"]) + + return { + "ok": True, + "action": "outer_planet_events_for_month", + "selected": { + "year": year, + "month": month, + "timezone": timezone_name, + }, + "events": events, + } + + def action_moon_star_occultations_for_month(args: list[str]) -> dict: if len(args) != 7: fail( @@ -2286,7 +2364,7 @@ def action_satellite_passes(args: list[str]) -> dict: def main() -> None: if len(sys.argv) < 2: - fail("Es wurde keine Aktion uebergeben.", extra={"available_actions": ["sun_moon_rise_set", "moon_star_occultations", "moon_phase_details", "satellite_passes", "planet_rise_set", "month_sky_context", "moon_phases_for_month", "season_changes_for_month", "moon_planet_approaches", "planet_conjunctions_for_month", "eclipses_for_month", "moon_apsides_for_month", "sun_apsides_for_month", "inner_planet_elongations_for_month", "moon_star_occultations_for_month"]}) + fail("Es wurde keine Aktion uebergeben.", extra={"available_actions": ["sun_moon_rise_set", "moon_star_occultations", "moon_phase_details", "satellite_passes", "planet_rise_set", "month_sky_context", "moon_phases_for_month", "season_changes_for_month", "moon_planet_approaches", "planet_conjunctions_for_month", "eclipses_for_month", "moon_apsides_for_month", "sun_apsides_for_month", "inner_planet_elongations_for_month", "outer_planet_events_for_month", "moon_star_occultations_for_month"]}) action = sys.argv[1] args = sys.argv[2:] @@ -2361,12 +2439,17 @@ def main() -> None: print(json.dumps(result, ensure_ascii=False)) return + if action == "outer_planet_events_for_month": + result = action_outer_planet_events_for_month(args) + print(json.dumps(result, ensure_ascii=False)) + return + if action == "moon_star_occultations_for_month": result = action_moon_star_occultations_for_month(args) print(json.dumps(result, ensure_ascii=False)) return - fail("Unbekannte Aktion.", extra={"action": action, "available_actions": ["sun_moon_rise_set", "moon_star_occultations", "moon_phase_details", "satellite_passes", "planet_rise_set", "month_sky_context", "moon_phases_for_month", "season_changes_for_month", "moon_planet_approaches", "planet_conjunctions_for_month", "eclipses_for_month", "moon_apsides_for_month", "sun_apsides_for_month", "inner_planet_elongations_for_month", "moon_star_occultations_for_month"]}) + fail("Unbekannte Aktion.", extra={"action": action, "available_actions": ["sun_moon_rise_set", "moon_star_occultations", "moon_phase_details", "satellite_passes", "planet_rise_set", "month_sky_context", "moon_phases_for_month", "season_changes_for_month", "moon_planet_approaches", "planet_conjunctions_for_month", "eclipses_for_month", "moon_apsides_for_month", "sun_apsides_for_month", "inner_planet_elongations_for_month", "outer_planet_events_for_month", "moon_star_occultations_for_month"]}) if __name__ == "__main__":