- Python 95.1%
- HTML 3.2%
- CSS 0.9%
- Dockerfile 0.8%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
Only that runner hands the host's Docker socket to a job; PR CI and Renovate run without it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
| .forgejo/workflows | ||
| deploy | ||
| scripts | ||
| src/ps5tracker | ||
| tests | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| .python-version | ||
| CHANGELOG.md | ||
| CLAUDE.md | ||
| config.yaml | ||
| Dockerfile | ||
| Idee.txt | ||
| PLAN.md | ||
| PROGRESS.md | ||
| pyproject.toml | ||
| README.md | ||
| SPEC.md | ||
| uv.lock | ||
| VORBEREITUNG.md | ||
PS5-Pro-Tracker
Überwacht Vergleichsseiten, Shops und Blogs auf eine lagernde PS5 Pro unter einem
Preislimit und meldet sie sofort per Telegram und E-Mail mit Direktlink. Unklare Seiten liest
eine KI (GLM über das kilo.ai-Gateway). Zwei unabhängige Instanzen: heim (services-tools) und
eltern (VM auf pve-offsite).
Fachliche Regeln: SPEC.md · Etappen und Aufbau: PLAN.md · Stand und bewusste Lücken: PROGRESS.md · Änderungen: CHANGELOG.md
Wann kommt ein Alarm?
Alle Bedingungen müssen erfüllt sein:
- PS5 Pro (Konsole, auch als Bundle oder gebraucht), kein reines Zubehör
- Artikelpreis ohne Versand strikt unter dem Limit (Standard 1.000 €)
- lieferbar mit höchstens 7 Tagen Lieferzeit
- verkauft vom Shop selbst, nicht von einem Marketplace-Händler
Meldet eine Quelle nur „verfügbar“ ohne Lieferzeit (wo-gibts-die-ps5, nowinstock, konsolenticker, Blogs), prüft der Tracker die Lieferzeit vorher auf der Shop-Seite. So löst Amazons „versandfertig in 3 bis 7 Monaten“ keinen Alarm aus. Geht die Prüfung nicht, kommt der Alarm mit dem Hinweis „Lieferzeit nicht geprüft“.
Solange ein Angebot relevant bleibt, kommt alle 5 Minuten eine Erinnerung. „✅ Gekauft“ pausiert die Instanz, „🔕 Stumm“ schweigt für dieses eine Angebot, bis es verschwindet.
Quellen
| Art | Quellen |
|---|---|
| Vergleichsseiten | Geizhals (4 Produktseiten, per Browser), wo-gibts-die-ps5 (Firebase-Daten), konsolenticker (status.json), nowinstock |
| Shops | MediaMarkt, Saturn, Müller, Völkner (2 Listings), Amazon, Amazon Warehouse/Resale, rebuy |
| Blogs (KI) | pcgames, gamepro |
| abgeschaltet | Otto (Kasada), Galaxus (Akamai): blocken auch den Browser, indirekt über wo-gibts-die-ps5 und Geizhals abgedeckt |
Telegram
Jede Instanz hat ihren eigenen Bot; beide schreiben in „PS5 Deals“ und „PS5 Tracker Fehler“.
Befehle nimmt ein Bot nur von PS5_TELEGRAM_ADMIN_IDS an. In der Gruppe mit beiden Bots
spricht /status@botname eine Instanz gezielt an.
| Befehl | Wirkung |
|---|---|
/status |
Quellen, aktive Angebote, günstigste lieferbare Preise |
/limit 850 |
Preislimit in € |
/reminder 10 |
Erinnerung alle x Minuten |
/maxdays 5 |
maximale Lieferzeit in Tagen |
/pause, /resume |
Deal-Alarme pausieren / fortsetzen |
/muted |
stumme Angebote anzeigen und wieder einschalten |
/reset |
Limit, Erinnerung und Lieferzeit zurück auf config.yaml |
/test |
Test-Alarm über Telegram und E-Mail |
/help |
diese Übersicht |
Im Fehler-Kanal landen: Quellen, die 3-mal in Folge scheitern (und die Entwarnung), KI-Fehler (höchstens stündlich), Parser, die dauerhaft nur noch über die KI laufen, gescheiterter Mailversand, Startmeldungen und täglich um 09:00 der Tagesreport.
Dashboard
http://<server>:8095 im LAN, ohne Login: Übersicht, Preisverlauf, KI-Log (mit der Eingabe, die
die KI gesehen hat), Konfiguration.
Betrieb
Deployt wird das Image aus der Forgejo-Registry; jeder Tag vX.Y.Z baut es.
# auf dem Server, im Ordner mit compose.yaml und .env (heim: ~/docker-compose-files/ps5)
export IMAGE_TAG=0.8.0 # oder weglassen für :latest
docker compose pull && docker compose up -d
docker compose logs -f tracker
docker compose exec tracker printenv APP_VERSION
.env= Kopie vonheim.envbzw.eltern.env(chmod 600). Vorlage:.env.example.- Daten (SQLite, Browser-Profile, KI-Rohdaten) liegen im Volume
ps5-tracker_data. - Die Konfiguration steckt im Image (
config.yaml); die Instanz wähltPS5_INSTANCE. - Mail:
heimüber das Relay192.168.20.10:25,elternüber Hetzner mit Login.
Parser kaputt – was tun?
Ändert ein Shop sein Layout, merkt man es so: Im Fehler-Kanal steht „🛠 Parser für … versteht die Seite nicht mehr“, im Dashboard laufen KI-Aufrufe für diese Quelle auf. Die KI übernimmt so lange, es gehen also keine Deals verloren.
- Seite aufnehmen:
uv run ps5tracker snapshot <quelle>(landet intests/fixtures/<typ>/). - Struktur ansehen und den Parser in
src/ps5tracker/sources/<typ>.pyanpassen. - Das neue Fixture unter dem festen Namen
<quelle>.htmlablegen und Tests ergänzen. uv run ps5tracker check <quelle>gegen die echte Seite, dannruff,mypy,pytest.- Version erhöhen,
CHANGELOG.mdergänzen, taggen, deployen.
Blockt eine Quelle dauerhaft (⛔ im Dashboard), hilft oft ein längeres Intervall oder ein frisches
Browser-Profil je Abruf (options.fresh_session in config.yaml, so läuft Geizhals). Notfalls
die Quelle mit enabled: false abschalten.
Entwicklung
uv sync
uv run ruff check . && uv run ruff format --check . && uv run mypy && uv run pytest
uv run ps5tracker sources # alle Quellen
uv run ps5tracker check geizhals # eine Quelle einmal prüfen (ohne Speichern/Alarm)
uv run ps5tracker test-notify # Test-Nachricht über alle Kanäle
uv run ps5tracker --env-file eltern.env … # mit den Secrets der Eltern-Instanz
uv run pytest -m live # Tests gegen das echte KI-Gateway
Konventionen (Sprache, Commits, Tests, Releases) stehen in CLAUDE.md.