Automatischer Push: 2 Datei(en) geändert

- .vault-tools/trading-plattform-pruefung/LIESMICH.md
- .vault-tools/trading-plattform-pruefung/ntfy_lesen.py

Erzeugt vom PostToolUse-Hook .vault-tools/auto-push/auto_push.py.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
Pascal MichelandClaude Opus 5 committed 2026-10-09 04:00:01 +02:00
1 parent 3784322a76
commit fca08de1c5
2 files changed
+67 -12

No files matched your search

@@ -1,36 +1,90 @@
"""Liest nur zurueck, was in der letzten Stunde bei ntfy unter dem Thema der Maschine ankam.
"""Liest zurueck, was bei ntfy unter dem Thema der Maschine ankam, mit maskierten Ziffern.
Koordinator-Skript, nicht Teil des Repos. Schickt nichts. Das Thema wird nie ausgegeben -- weder
hier noch in einer Fehlermeldung. Aufruf aus dem Projektordner (WSL): python ntfy_lesen.py
hier noch in einer Fehlermeldung. Aufruf aus dem Projektordner (WSL):
python -B ntfy_lesen.py [--seit 12h | --seit 2026-10-07T20:00]
Exit 0 gelesen, 1 Netzfehler, 3 kein Thema, 4 Weiterleitung oder Fehlerstatus.
"""
import argparse
import json
import os
import re
import sys
from datetime import datetime
from pathlib import Path
from zoneinfo import ZoneInfo
sys.path.insert(0, str(Path.cwd()))
# Ohne Login-Shell fehlt die Variable (LIESMICH, Abschnitt zu den Geheimnissen); der Pfad selbst
# ist kein Geheimnis, sein Inhalt schon.
os.environ.setdefault("TRADING_GEHEIMNISSE", "/home/claude/.config/trading-plattform/secrets.toml")
import requests
from trading import geheimnisse
from trading.paper.melder import lade_melder_config
from trading.paper.melder import lies_ntfy_geheimnisse
BERLIN = ZoneInfo("Europe/Berlin")
# ntfy nimmt fuer since eine Dauer (12h, 30m) oder einen Unix-Zeitstempel (docs.ntfy.sh/subscribe/api).
DAUER = re.compile(r"^\d+[smhd]$")
def main() -> int:
config = lade_melder_config("config/paper.toml", secrets_pfad=None)
thema, token = lies_ntfy_geheimnisse()
def seit_parameter(wert: str) -> str:
"""Eine Dauer bleibt, wie sie ist; eine Ortszeit ohne Zone gilt als Berliner Zeit."""
if DAUER.match(wert):
return wert
zeit = datetime.fromisoformat(wert)
if zeit.tzinfo is None:
zeit = zeit.replace(tzinfo=BERLIN)
return str(int(zeit.timestamp()))
def maskiert(text: object) -> str:
"""Jede Ziffernfolge als #, weil eine Meldung einen Betrag tragen kann."""
return re.sub(r"\d+", "#", str(text))
def main(argv: list[str] | None = None) -> int:
teiler = argparse.ArgumentParser(description="ntfy zuruecklesen, ohne das Thema zu zeigen.")
teiler.add_argument(
"--seit", default="12h",
help="Dauer wie 12h oder Berliner Ortszeit JJJJ-MM-TTTHH:MM; ntfy.sh haelt Meldungen nur Stunden.",
)
args = teiler.parse_args(argv)
try:
seit = seit_parameter(args.seit)
except ValueError:
print(f"--seit nicht lesbar: {args.seit}")
return 2
try:
# Beide lesen die Geheimnisdatei; fehlt sie, wirft schon die Konfiguration.
config = lade_melder_config("config/paper.toml", secrets_pfad=None)
thema, token = lies_ntfy_geheimnisse()
except OSError as ausnahme:
print(f"Geheimnisdatei nicht lesbar ({type(ausnahme).__name__}): {geheimnisse.beschreibung()}")
return 3
if not thema:
# Mit leerem Thema hiesse die Adresse .../json; genau das endete am 2026-10-07 mit HTTP 307.
print(f"Kein Thema in der Geheimnisdatei: {geheimnisse.beschreibung()}")
return 3
kopf = {"Authorization": f"Bearer {token}"} if token else {}
try:
antwort = requests.get(
f"{config.ntfy_url}/{thema}/json", params={"poll": "1", "since": "1h"},
f"{config.ntfy_url}/{thema}/json", params={"poll": "1", "since": seit},
headers=kopf, timeout=10, allow_redirects=False,
)
except Exception as ausnahme:
# Nur der Typ: Die Ausnahme von requests traegt die Adresse und damit das Thema.
print(f"Ruecklesen gescheitert: {type(ausnahme).__name__}")
return 1
print(f"Ruecklesen: HTTP {antwort.status_code}")
print(f"Ruecklesen seit {args.seit}: HTTP {antwort.status_code}")
if antwort.status_code >= 300:
# Einer Weiterleitung folgen hiesse, das Token an ein anderes Ziel zu schicken.
print("Kein Ergebnis: Weiterleitung oder Fehlerstatus, nicht gefolgt.")
return 4
anzahl = 0
for zeile in antwort.text.splitlines():
try:
@@ -40,11 +94,12 @@ def main() -> int:
if eintrag.get("event") != "message":
continue
anzahl += 1
zeit = datetime.fromtimestamp(eintrag.get("time", 0), BERLIN).strftime("%Y-%m-%d %H:%M:%S")
erste = (str(eintrag.get("message", "")).splitlines() or [""])[0]
# Ohne Angabe fuehrt ntfy die Prioritaet 3 (default) und laesst das Feld weg.
print(f" bei ntfy: Titel '{eintrag.get('title')}', Prioritaet {eintrag.get('priority', 3)}, "
f"Zeit {datetime.fromtimestamp(eintrag.get('time', 0)).isoformat()}, "
f"erste Zeile '{str(eintrag.get('message', '')).splitlines()[0][:70]}'")
print(f"{anzahl} Meldung(en) in der letzten Stunde.")
print(f" {zeit} Prioritaet {eintrag.get('priority', 3)} Titel '{maskiert(eintrag.get('title'))}' "
f"erste Zeile '{maskiert(erste)[:70]}'")
print(f"{anzahl} Meldung(en).")
return 0