From e7dae6667fbf7ca60788c4afeb9e2481b3cff049 Mon Sep 17 00:00:00 2001 From: Eskimue Date: Fri, 3 Apr 2026 14:52:18 +0200 Subject: [PATCH] Opposition und Konjunktion eingebaut --- .codex-temp/php-server.err.log | 141 ++++++++++++++++++++++ public/monatsvorhersage_old.php | 32 +++++ public/py/__pycache__/api.cpython-314.pyc | Bin 123041 -> 126731 bytes public/py/api.py | 87 ++++++++++++- 4 files changed, 258 insertions(+), 2 deletions(-) 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 40ecfa3d06eec4cd6fd42e6f985526f48f7ff8bb..ede6ca3ff5c0a2870af6d8facde7888aeb28e1f3 100644 GIT binary patch delta 8463 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 delta 7045 zcmbtZ33OCN*6#b#uRBSHkUe2b2nh)t%nGs-5+JOJflgQ=OQ(}`nn2PWs$U3U84{7* z4WCZQk|2(Nh=|eyPsf8OIOFfIE2#5C1(X?K6x3gT9TDfhw>l)i@i_lEf6mF5s#~{i z-MaVIty?b}J~3~9(;V7Av`er7fByZ#shUXp#?Uwz^m6JV3AnFKIxM9>Wt$vpuocD{ zYQt(l8EY%D-IocrVx&zGG)XD2O~sy#dg^*vPn&D7!9+l-FrF`r+k!ASOg9w=G8jzY_vpGF2BU^KFkIVIvWg1-8ert%`Q7?Fno@ zDcW^&+_v8jnQ1Uoq4qrubLtWe1N~AB38+Al__c2Gxy=iwf=j(HvjKv9)5|UZM5u#j z4UoEky8LDz^^sZe5bxVN3xXg}-B&fHhXo7<7J}f#UqcEDM`WSc*0a@Z)d_0rdl71` zGY-Pk8P0bhR!ytUg><#1dOFD%TIOhxig&k`q$tanEmX zS1L6gx0f-sd23UGaLFOki~PbUE}25mKv34c~X9J1c8z z>b*|3pVn(tyB^L)G5LoR;$9#oqf%4nw3=8SQsgya+3#C?_#5c`8!fN6Mbho5{mFJ24IYY0Np(Su&4wx)8Plg%ft1q7`Ky1CKmRh-PNo1G5P5T0+K z%c-}E9X)t-o7(rQlCVIUP)xF?5R|KVH*$LXMo6gVzACuGpnb2s0!P(PuGuXoNt7^X zj1n)>ARc@X0J<@(hCtqtI80L<3BGJK482%l<(>83czU^rvc_L|{2 z40=927)}IIqObz%&ih*+S?+@zfm*2rVgbUm+7MVJK{@|66q5RP9Aw>G<#aKp)2kaD zl^(A(m?h&Z)|ViKAeHBJg|Wfnz90zG9_b44AoY{P9Ru;&i7=Q8T_|O-G@M}#V*UA$ z2uKRMN~DgJSSDW(0VCy+$P>@^M!?Aq87X{gB<#MW{U{Fk(4D)YpsPF@nNzf-Q6K?i zXupew1i&q{#lS=u%fE<$NpcZ#WN3q9VJg7A+PXMc7yyjl=mA3p(@MIrs>Z9JPT~@J zguJ$rpcuzkM`F^A==6G)OCuxr{GO04Pe+D(wWoW6528CVksesh93nxo8GK$mWWy|N zb3CL$d_J;=Oyr1z5r%5wgIgl=AUx?dCscHg>eiTkx>w#XUtIp|Gy#93BxnLzfk_4IZ0+i^|{wE1e z0X(4nr7!#lB~_%06QL9}ok5*y0vEwNf*J&?>@N#M<|mEua;xx)dI3v-I%0DZcnIow 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 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__":