Sommer Winterzeit drin
This commit is contained in:
@@ -782,3 +782,123 @@ Stack trace:
|
||||
[Fri Apr 3 15:39:27 2026] 127.0.0.1:55947 Accepted
|
||||
[Fri Apr 3 15:39:29 2026] 127.0.0.1:55947 [200]: GET /favicon.ico
|
||||
[Fri Apr 3 15:39:29 2026] 127.0.0.1:55947 Closing
|
||||
[Fri Apr 3 15:45:36 2026] 127.0.0.1:59896 Accepted
|
||||
[Fri Apr 3 15:45:44 2026] 127.0.0.1:59896 [200]: GET /monatsvorhersage_old.php?year=2026&month=9
|
||||
[Fri Apr 3 15:45:44 2026] 127.0.0.1:59896 Closing
|
||||
[Fri Apr 3 15:49:51 2026] 127.0.0.1:53418 Accepted
|
||||
[Fri Apr 3 15:50:00 2026] 127.0.0.1:53418 [200]: GET /monatsvorhersage_old.php?year=2026&month=9
|
||||
[Fri Apr 3 15:50:00 2026] 127.0.0.1:53418 Closing
|
||||
[Fri Apr 3 15:50:00 2026] 127.0.0.1:57283 Accepted
|
||||
[Fri Apr 3 15:50:00 2026] 127.0.0.1:60076 Accepted
|
||||
[Fri Apr 3 15:50:00 2026] 127.0.0.1:57283 [200]: GET /css/style.css
|
||||
[Fri Apr 3 15:50:00 2026] 127.0.0.1:60076 [200]: GET /js/astronomy.browser.min.js
|
||||
[Fri Apr 3 15:50:00 2026] 127.0.0.1:57283 Closing
|
||||
[Fri Apr 3 15:50:00 2026] 127.0.0.1:60076 Closing
|
||||
[Fri Apr 3 15:50:00 2026] 127.0.0.1:62073 Accepted
|
||||
[Fri Apr 3 15:50:00 2026] 127.0.0.1:62073 [200]: GET /images/star16x16.png
|
||||
[Fri Apr 3 15:50:00 2026] 127.0.0.1:51356 Accepted
|
||||
[Fri Apr 3 15:50:00 2026] 127.0.0.1:51356 [200]: GET /images/star16x16_rays.png
|
||||
[Fri Apr 3 15:50:00 2026] 127.0.0.1:62073 Closing
|
||||
[Fri Apr 3 15:50:00 2026] 127.0.0.1:51356 Closing
|
||||
[Fri Apr 3 15:50:00 2026] 127.0.0.1:56915 Accepted
|
||||
[Fri Apr 3 15:50:01 2026] 127.0.0.1:56915 [200]: GET /favicon.ico
|
||||
[Fri Apr 3 15:50:01 2026] 127.0.0.1:56915 Closing
|
||||
[Fri Apr 3 15:52:41 2026] 127.0.0.1:54040 Accepted
|
||||
[Fri Apr 3 15:52:49 2026] 127.0.0.1:54040 [200]: GET /monatsvorhersage_old.php?year=2026&month=9
|
||||
[Fri Apr 3 15:52:49 2026] 127.0.0.1:54040 Closing
|
||||
[Fri Apr 3 15:53:10 2026] 127.0.0.1:65142 Accepted
|
||||
[Fri Apr 3 15:53:19 2026] 127.0.0.1:65142 [200]: GET /monatsvorhersage_old.php?year=2026&month=9
|
||||
[Fri Apr 3 15:53:19 2026] 127.0.0.1:65142 Closing
|
||||
[Fri Apr 3 15:53:19 2026] 127.0.0.1:50833 Accepted
|
||||
[Fri Apr 3 15:53:19 2026] 127.0.0.1:50833 [200]: GET /css/style.css
|
||||
[Fri Apr 3 15:53:19 2026] 127.0.0.1:50833 Closing
|
||||
[Fri Apr 3 15:53:19 2026] 127.0.0.1:52437 Accepted
|
||||
[Fri Apr 3 15:53:19 2026] 127.0.0.1:52437 [200]: GET /js/astronomy.browser.min.js
|
||||
[Fri Apr 3 15:53:19 2026] 127.0.0.1:52437 Closing
|
||||
[Fri Apr 3 15:53:19 2026] 127.0.0.1:62874 Accepted
|
||||
[Fri Apr 3 15:53:19 2026] 127.0.0.1:62874 [200]: GET /images/star16x16.png
|
||||
[Fri Apr 3 15:53:19 2026] 127.0.0.1:49611 Accepted
|
||||
[Fri Apr 3 15:53:19 2026] 127.0.0.1:49611 [200]: GET /images/star16x16_rays.png
|
||||
[Fri Apr 3 15:53:19 2026] 127.0.0.1:62874 Closing
|
||||
[Fri Apr 3 15:53:19 2026] 127.0.0.1:49611 Closing
|
||||
[Fri Apr 3 15:53:19 2026] 127.0.0.1:63993 Accepted
|
||||
[Fri Apr 3 15:53:20 2026] 127.0.0.1:63993 [200]: GET /favicon.ico
|
||||
[Fri Apr 3 15:53:20 2026] 127.0.0.1:63993 Closing
|
||||
[Fri Apr 3 15:53:36 2026] 127.0.0.1:52820 Accepted
|
||||
[Fri Apr 3 15:53:45 2026] 127.0.0.1:52820 [200]: GET /monatsvorhersage_old.php?year=2026&month=7
|
||||
[Fri Apr 3 15:53:45 2026] 127.0.0.1:52820 Closing
|
||||
[Fri Apr 3 15:53:45 2026] 127.0.0.1:50899 Accepted
|
||||
[Fri Apr 3 15:53:45 2026] 127.0.0.1:50899 [200]: GET /css/style.css
|
||||
[Fri Apr 3 15:53:45 2026] 127.0.0.1:50899 Closing
|
||||
[Fri Apr 3 15:53:45 2026] 127.0.0.1:61600 Accepted
|
||||
[Fri Apr 3 15:53:45 2026] 127.0.0.1:61600 [200]: GET /js/astronomy.browser.min.js
|
||||
[Fri Apr 3 15:53:45 2026] 127.0.0.1:61600 Closing
|
||||
[Fri Apr 3 15:53:45 2026] 127.0.0.1:59909 Accepted
|
||||
[Fri Apr 3 15:53:45 2026] 127.0.0.1:62643 Accepted
|
||||
[Fri Apr 3 15:53:45 2026] 127.0.0.1:59909 [200]: GET /images/star16x16.png
|
||||
[Fri Apr 3 15:53:45 2026] 127.0.0.1:62643 [200]: GET /images/star16x16_rays.png
|
||||
[Fri Apr 3 15:53:45 2026] 127.0.0.1:59909 Closing
|
||||
[Fri Apr 3 15:53:45 2026] 127.0.0.1:62643 Closing
|
||||
[Fri Apr 3 15:53:45 2026] 127.0.0.1:58844 Accepted
|
||||
[Fri Apr 3 15:53:46 2026] 127.0.0.1:58844 [200]: GET /favicon.ico
|
||||
[Fri Apr 3 15:53:46 2026] 127.0.0.1:58844 Closing
|
||||
[Fri Apr 3 15:55:14 2026] 127.0.0.1:56372 Accepted
|
||||
[Fri Apr 3 15:55:23 2026] 127.0.0.1:56372 [200]: GET /monatsvorhersage_old.php?year=2026&month=9
|
||||
[Fri Apr 3 15:55:23 2026] 127.0.0.1:56372 Closing
|
||||
[Fri Apr 3 15:56:00 2026] 127.0.0.1:64711 Accepted
|
||||
[Fri Apr 3 15:56:09 2026] 127.0.0.1:64711 [200]: GET /monatsvorhersage_old.php?year=2026&month=9
|
||||
[Fri Apr 3 15:56:09 2026] 127.0.0.1:64711 Closing
|
||||
[Fri Apr 3 15:56:09 2026] 127.0.0.1:63571 Accepted
|
||||
[Fri Apr 3 15:56:10 2026] 127.0.0.1:63571 [200]: GET /favicon.ico
|
||||
[Fri Apr 3 15:56:10 2026] 127.0.0.1:63571 Closing
|
||||
[Fri Apr 3 16:01:09 2026] 127.0.0.1:58142 Accepted
|
||||
[Fri Apr 3 16:01:18 2026] 127.0.0.1:58142 [200]: GET /monatsvorhersage_old.php?year=2026&month=9
|
||||
[Fri Apr 3 16:01:18 2026] 127.0.0.1:58142 Closing
|
||||
[Fri Apr 3 16:03:02 2026] 127.0.0.1:62323 Accepted
|
||||
[Fri Apr 3 16:03:16 2026] 127.0.0.1:62323 [200]: GET /monatsvorhersage_old.php?year=2026&month=3
|
||||
[Fri Apr 3 16:03:16 2026] 127.0.0.1:62323 Closing
|
||||
[Fri Apr 3 16:03:16 2026] 127.0.0.1:62462 Accepted
|
||||
[Fri Apr 3 16:03:16 2026] 127.0.0.1:61754 Accepted
|
||||
[Fri Apr 3 16:03:16 2026] 127.0.0.1:62462 [200]: GET /css/style.css
|
||||
[Fri Apr 3 16:03:16 2026] 127.0.0.1:61754 [200]: GET /js/astronomy.browser.min.js
|
||||
[Fri Apr 3 16:03:16 2026] 127.0.0.1:62462 Closing
|
||||
[Fri Apr 3 16:03:16 2026] 127.0.0.1:61754 Closing
|
||||
[Fri Apr 3 16:03:16 2026] 127.0.0.1:57741 Accepted
|
||||
[Fri Apr 3 16:03:16 2026] 127.0.0.1:51820 Accepted
|
||||
[Fri Apr 3 16:03:16 2026] 127.0.0.1:57741 [200]: GET /images/star16x16.png
|
||||
[Fri Apr 3 16:03:16 2026] 127.0.0.1:51820 [200]: GET /images/star16x16_rays.png
|
||||
[Fri Apr 3 16:03:16 2026] 127.0.0.1:57741 Closing
|
||||
[Fri Apr 3 16:03:16 2026] 127.0.0.1:51820 Closing
|
||||
[Fri Apr 3 16:03:16 2026] 127.0.0.1:60434 Accepted
|
||||
[Fri Apr 3 16:03:18 2026] 127.0.0.1:60434 [200]: GET /favicon.ico
|
||||
[Fri Apr 3 16:03:18 2026] 127.0.0.1:60434 Closing
|
||||
[Fri Apr 3 16:07:00 2026] 127.0.0.1:54937 Accepted
|
||||
[Fri Apr 3 16:07:15 2026] 127.0.0.1:54937 [200]: GET /monatsvorhersage_old.php?year=2026&month=3
|
||||
[Fri Apr 3 16:07:15 2026] 127.0.0.1:54937 Closing
|
||||
[Fri Apr 3 16:07:15 2026] 127.0.0.1:54939 Accepted
|
||||
[Fri Apr 3 16:07:24 2026] 127.0.0.1:54939 [200]: GET /monatsvorhersage_old.php?year=2026&month=9
|
||||
[Fri Apr 3 16:07:24 2026] 127.0.0.1:54939 Closing
|
||||
[Fri Apr 3 16:08:54 2026] 127.0.0.1:50294 Accepted
|
||||
[Fri Apr 3 16:09:03 2026] 127.0.0.1:50294 [200]: GET /monatsvorhersage_old.php?year=2026&month=12
|
||||
[Fri Apr 3 16:09:03 2026] 127.0.0.1:50294 Closing
|
||||
[Fri Apr 3 16:09:03 2026] 127.0.0.1:53963 Accepted
|
||||
[Fri Apr 3 16:09:03 2026] 127.0.0.1:53963 [200]: GET /css/style.css
|
||||
[Fri Apr 3 16:09:03 2026] 127.0.0.1:64822 Accepted
|
||||
[Fri Apr 3 16:09:03 2026] 127.0.0.1:53963 Closing
|
||||
[Fri Apr 3 16:09:03 2026] 127.0.0.1:64822 [200]: GET /js/astronomy.browser.min.js
|
||||
[Fri Apr 3 16:09:03 2026] 127.0.0.1:64822 Closing
|
||||
[Fri Apr 3 16:09:03 2026] 127.0.0.1:57513 Accepted
|
||||
[Fri Apr 3 16:09:03 2026] 127.0.0.1:57513 [200]: GET /images/star16x16.png
|
||||
[Fri Apr 3 16:09:03 2026] 127.0.0.1:50161 Accepted
|
||||
[Fri Apr 3 16:09:03 2026] 127.0.0.1:50161 [200]: GET /images/star16x16_rays.png
|
||||
[Fri Apr 3 16:09:03 2026] 127.0.0.1:57513 Closing
|
||||
[Fri Apr 3 16:09:03 2026] 127.0.0.1:50161 Closing
|
||||
[Fri Apr 3 16:09:03 2026] 127.0.0.1:53090 Accepted
|
||||
[Fri Apr 3 16:09:05 2026] 127.0.0.1:53090 [200]: GET /favicon.ico
|
||||
[Fri Apr 3 16:09:05 2026] 127.0.0.1:53090 Closing
|
||||
[Fri Apr 3 16:10:03 2026] 127.0.0.1:58129 Accepted
|
||||
[Fri Apr 3 16:10:12 2026] 127.0.0.1:58129 [200]: GET /monatsvorhersage_old.php?year=2026&month=12
|
||||
[Fri Apr 3 16:10:12 2026] 127.0.0.1:58129 Closing
|
||||
[Fri Apr 3 16:13:22 2026] 127.0.0.1:62960 Accepted
|
||||
[Fri Apr 3 16:13:31 2026] 127.0.0.1:62960 [200]: GET /monatsvorhersage_old.php?year=2026&month=12
|
||||
[Fri Apr 3 16:13:31 2026] 127.0.0.1:62960 Closing
|
||||
|
||||
@@ -69,6 +69,7 @@ $outerPlanetEvents = [];
|
||||
$outerPlanetStationEvents = [];
|
||||
$moonOccultations = [];
|
||||
$seasonChanges = [];
|
||||
$timeChanges = [];
|
||||
$monthEventList = [];
|
||||
$starDataError = null;
|
||||
|
||||
@@ -372,6 +373,23 @@ if (is_array($seasonDecoded) && ($seasonDecoded['ok'] ?? false)) {
|
||||
$seasonChanges = is_array($seasonDecoded['changes'] ?? null) ? $seasonDecoded['changes'] : [];
|
||||
}
|
||||
|
||||
$timeChangeOutput = [];
|
||||
$timeChangeExitCode = 0;
|
||||
$timeChangeArgs = [
|
||||
$pythonScriptPath,
|
||||
'time_changes_for_month',
|
||||
(string) $selectedYear,
|
||||
(string) $selectedMonth,
|
||||
$chartTimezone,
|
||||
];
|
||||
$timeChangeCommand = $pythonExecutable . ' ' . implode(' ', array_map('escapeshellarg', $timeChangeArgs)) . ' 2>&1';
|
||||
exec($timeChangeCommand, $timeChangeOutput, $timeChangeExitCode);
|
||||
$timeChangeRaw = trim(implode("\n", $timeChangeOutput));
|
||||
$timeChangeDecoded = json_decode($timeChangeRaw, true);
|
||||
if (is_array($timeChangeDecoded) && ($timeChangeDecoded['ok'] ?? false)) {
|
||||
$timeChanges = is_array($timeChangeDecoded['events'] ?? null) ? $timeChangeDecoded['events'] : [];
|
||||
}
|
||||
|
||||
$eclipseOutput = [];
|
||||
$eclipseExitCode = 0;
|
||||
$eclipseArgs = [
|
||||
@@ -647,6 +665,30 @@ foreach ($seasonChanges as $seasonChange) {
|
||||
];
|
||||
}
|
||||
|
||||
foreach ($timeChanges as $timeChange) {
|
||||
if (!is_array($timeChange)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$timeChangeKind = (string) ($timeChange['kind'] ?? '');
|
||||
$timeChangeLabel = $timeChangeKind === 'dst_start'
|
||||
? 'Beginn der Sommerzeit (Uhren von 02:00 auf 03:00 Uhr vorstellen)'
|
||||
: ($timeChangeKind === 'dst_end'
|
||||
? 'Beginn der Normalzeit (Uhren von 03:00 auf 02:00 Uhr zurueckstellen)'
|
||||
: 'Zeitumstellung');
|
||||
$timeChangeTime = $timeChangeKind === 'dst_start'
|
||||
? '02:00'
|
||||
: ($timeChangeKind === 'dst_end' ? '03:00' : (string) ($timeChange['local_time'] ?? ''));
|
||||
|
||||
$monthEventList[] = [
|
||||
'event' => $timeChangeLabel,
|
||||
'date' => (string) ($timeChange['local_date'] ?? ''),
|
||||
'time' => $timeChangeTime,
|
||||
'local_iso' => (string) ($timeChange['local_iso'] ?? ''),
|
||||
'type' => 'time_change',
|
||||
];
|
||||
}
|
||||
|
||||
foreach ($eclipseEvents as $eclipseEvent) {
|
||||
if (!is_array($eclipseEvent)) {
|
||||
continue;
|
||||
|
||||
+92
-2
@@ -650,6 +650,91 @@ def action_season_changes_for_month(args: list[str]) -> dict:
|
||||
}
|
||||
|
||||
|
||||
def action_time_changes_for_month(args: list[str]) -> dict:
|
||||
if len(args) != 3:
|
||||
fail(
|
||||
"Aktion time_changes_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) - timedelta(days=2)
|
||||
utc_end = local_end.astimezone(timezone.utc) + timedelta(days=2)
|
||||
|
||||
def utc_offset_seconds(dt_utc: datetime) -> int:
|
||||
return int(dt_utc.astimezone(tz).utcoffset().total_seconds())
|
||||
|
||||
def refine_transition(left_utc: datetime, right_utc: datetime) -> datetime:
|
||||
left = left_utc
|
||||
right = right_utc
|
||||
left_offset = utc_offset_seconds(left)
|
||||
while (right - left) > timedelta(seconds=1):
|
||||
mid = left + (right - left) / 2
|
||||
if utc_offset_seconds(mid) == left_offset:
|
||||
left = mid
|
||||
else:
|
||||
right = mid
|
||||
return right
|
||||
|
||||
events = []
|
||||
previous_utc = utc_start
|
||||
previous_offset = utc_offset_seconds(previous_utc)
|
||||
current_utc = previous_utc + timedelta(hours=1)
|
||||
while current_utc <= utc_end:
|
||||
current_offset = utc_offset_seconds(current_utc)
|
||||
if current_offset != previous_offset:
|
||||
transition_utc = refine_transition(previous_utc, current_utc)
|
||||
local_dt = transition_utc.astimezone(tz)
|
||||
if local_dt.year == year and local_dt.month == month:
|
||||
delta_seconds = current_offset - previous_offset
|
||||
kind = "dst_start" if delta_seconds > 0 else "dst_end"
|
||||
events.append({
|
||||
"kind": kind,
|
||||
"offset_before_hours": previous_offset / 3600.0,
|
||||
"offset_after_hours": current_offset / 3600.0,
|
||||
"utc_iso": transition_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"),
|
||||
})
|
||||
previous_utc = current_utc
|
||||
previous_offset = current_offset
|
||||
current_utc += timedelta(hours=1)
|
||||
|
||||
events.sort(key=lambda item: item["local_iso"])
|
||||
|
||||
return {
|
||||
"ok": True,
|
||||
"action": "time_changes_for_month",
|
||||
"selected": {
|
||||
"year": year,
|
||||
"month": month,
|
||||
"timezone": timezone_name,
|
||||
},
|
||||
"events": events,
|
||||
}
|
||||
|
||||
|
||||
def moon_planet_separation_deg(
|
||||
body: astronomy.Body,
|
||||
observer: astronomy.Observer,
|
||||
@@ -2702,7 +2787,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", "golden_handle_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", "venus_peak_magnitude_for_month", "outer_planet_events_for_month", "outer_planet_stations_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", "golden_handle_for_month", "season_changes_for_month", "time_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", "venus_peak_magnitude_for_month", "outer_planet_events_for_month", "outer_planet_stations_for_month", "moon_star_occultations_for_month"]})
|
||||
|
||||
action = sys.argv[1]
|
||||
args = sys.argv[2:]
|
||||
@@ -2722,6 +2807,11 @@ def main() -> None:
|
||||
print(json.dumps(result, ensure_ascii=False))
|
||||
return
|
||||
|
||||
if action == "time_changes_for_month":
|
||||
result = action_time_changes_for_month(args)
|
||||
print(json.dumps(result, ensure_ascii=False))
|
||||
return
|
||||
|
||||
if action == "moon_phase_details":
|
||||
result = action_moon_phase_details(args)
|
||||
print(json.dumps(result, ensure_ascii=False))
|
||||
@@ -2802,7 +2892,7 @@ def main() -> None:
|
||||
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", "golden_handle_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", "venus_peak_magnitude_for_month", "outer_planet_events_for_month", "outer_planet_stations_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", "golden_handle_for_month", "season_changes_for_month", "time_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", "venus_peak_magnitude_for_month", "outer_planet_events_for_month", "outer_planet_stations_for_month", "moon_star_occultations_for_month"]})
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user