P42 Dashboard: erster Stand

FastAPI-Backend und React-Frontend mit Konten, Sendungsverfolgung,
Projekt-Artikeln, Vorrat & Einkauf mit Rezeptabgleich, Reise-Weltkarte,
Kanban-Projekten mit Priorität, Server-Monitoring und den Designs
Matrix und Blackwall. Betrieb per Docker hinter nginx (siehe DEPLOY.md).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
guyg1474andClaude Opus 5.5 committed 2026-10-14 14:08:11 +02:00
commit dd58b3d1f8
75 files changed
+11418

No files matched your search

+37
View File
@@ -0,0 +1,37 @@
"""Erkennt anhand des Nummernformats, welche Paketdienste in Frage kommen.
Viele Formate überschneiden sich, deshalb kann es mehrere Treffer geben.
"""
import re
from urllib.parse import quote
def universal_link(number: str) -> str:
return f"https://t.17track.net/de#nums={quote(number)}"
_DHL = "https://www.dhl.de/de/privatkunden/pakete-empfangen/verfolgen.html?piececode={}"
CARRIERS = [
("dhl", "DHL", [r"\d{12}", r"\d{20}", r"(JJD|JVGL)\d{8,}", r"00340\d{15}", r"\d{10}"], _DHL),
("deutschepost", "Deutsche Post", [r"[A-Z]{2}\d{9}DE"], _DHL),
("ups", "UPS", [r"1Z[0-9A-Z]{16}"], "https://www.ups.com/track?loc=de_DE&tracknum={}"),
("hermes", "Hermes", [r"\d{14}", r"\d{16}", r"H\d{19}"],
"https://www.myhermes.de/empfangen/sendungsverfolgung/sendungsinformation#{}"),
("dpd", "DPD", [r"\d{14}", r"\d{27,28}"], "https://tracking.dpd.de/status/de_DE/parcel/{}"),
("gls", "GLS", [r"\d{11,12}", r"[A-Z0-9]{8}"], "https://gls-group.com/DE/de/paketverfolgung?match={}"),
("fedex", "FedEx", [r"\d{12}", r"\d{15}"], "https://www.fedex.com/fedextrack/?trknbr={}"),
("amazon", "Amazon Logistics", [r"TBA\d{9,}"], "https://www.amazon.de/gp/your-account/order-history"),
("upu", "Internationale Post (UPU)", [r"[A-Z]{2}\d{9}(?!DE)[A-Z]{2}"], None),
]
_COMPILED = [(cid, name, [re.compile(p) for p in patterns], link) for cid, name, patterns, link in CARRIERS]
def detect_carriers(number: str) -> list[dict]:
result = []
for cid, name, patterns, link in _COMPILED:
if any(p.fullmatch(number) for p in patterns):
url = link.format(quote(number)) if link else universal_link(number)
result.append({"id": cid, "name": name, "link": url})
return result