feat: #out detection sets category=ausverkauft + Spieltitel-Extraktion

- WhatsApp-Webhook: Neue Nachrichten mit #out setzen category='ausverkauft',
  Spieltitel wird nach #out extrahiert (abgeschnitten an Satzzeichen/Trennern)
- Thread-Append: #out in Folgenachrichten aktualisiert category + spiel_titel
- Web-Form-Submit: #out im Text setzt category='ausverkauft' + extrahiert Titel
- Fix: lokales 'import re' in api_submit entfernt (globale 're' reicht)
- Frontend: Filter-Dropdown zeigt 'ausverkauft' dynamisch, Badge auf Karten +
  Detailseite
This commit is contained in:
Hermes Agent
2026-06-18 00:06:57 +02:00
parent 1153c170a5
commit 05e934dd66
+32 -4
View File
@@ -596,6 +596,14 @@ def whatsapp_webhook():
else: else:
content = f"[{msg_type}]" content = f"[{msg_type}]"
# #out detection: set category to "ausverkauft" and extract game title
if "#out" in content.lower():
category_override = "ausverkauft"
idx = content.lower().find("#out")
after = content[idx + 4:].strip()
if after:
spiel_titel = re.split(r'[.!?\n]| - | | — | ist | war | in ', after, maxsplit=1)[0].strip()[:200]
# GDPR: "Meine Daten löschen" trigger # GDPR: "Meine Daten löschen" trigger
if msg_type == "text" and content.strip().lower() == "meine daten löschen": if msg_type == "text" and content.strip().lower() == "meine daten löschen":
_gdpr_delete_sender(db, sender_id) _gdpr_delete_sender(db, sender_id)
@@ -649,6 +657,17 @@ def whatsapp_webhook():
"UPDATE submissions SET content=?, halle=?, created_at=CURRENT_TIMESTAMP WHERE id=?", "UPDATE submissions SET content=?, halle=?, created_at=CURRENT_TIMESTAMP WHERE id=?",
(new_content, new_halle, recent["id"]), (new_content, new_halle, recent["id"]),
) )
# Check for #out in appended content — update category + spiel_titel
if "#out" in content.lower():
out_title = None
idx = content.lower().find("#out")
after = content[idx + 4:].strip()
if after:
out_title = re.split(r'[.!?\n]| - | | — | ist | war | in ', after, maxsplit=1)[0].strip()[:200]
db.execute(
"UPDATE submissions SET category=?, spiel_titel=? WHERE id=?",
("ausverkauft", out_title, recent["id"]),
)
# Merge media paths (keep all, separated by ||) # Merge media paths (keep all, separated by ||)
if media_path: if media_path:
merged_media = media_path merged_media = media_path
@@ -3040,18 +3059,27 @@ def api_submit():
# Validate halle # Validate halle
halle_valid = None halle_valid = None
if halle: if halle:
import re
if re.match(r'^H[1-7]\s*[A-Z]\d{1,4}$', halle, re.IGNORECASE): if re.match(r'^H[1-7]\s*[A-Z]\d{1,4}$', halle, re.IGNORECASE):
halle_valid = halle.upper() halle_valid = halle.upper()
sender_id = 'web_' + (name.replace(' ', '_') if name else 'anonym') sender_id = 'web_' + (name.replace(' ', '_') if name else 'anonym')
sender_name = name or None sender_name = name or None
# #out detection for web form
category = None
if text and "#out" in text.lower():
category = "ausverkauft"
if not spiel_titel:
idx = text.lower().find("#out")
after = text[idx + 4:].strip()
if after:
spiel_titel = re.split(r'[.!?\n]| - | | — | ist | war | in ', after, maxsplit=1)[0].strip()[:200]
db.execute( db.execute(
"""INSERT INTO submissions """INSERT INTO submissions
(channel, sender_id, sender_name, type, content, media_path, status, halle, spiel_titel) (channel, sender_id, sender_name, type, content, media_path, status, halle, category, spiel_titel)
VALUES (?, ?, ?, ?, ?, ?, 'new', ?, ?)""", VALUES (?, ?, ?, ?, ?, ?, 'new', ?, ?, ?)""",
('web', sender_id, sender_name, msg_type, text or None, media_path, halle_valid, spiel_titel or None), ('web', sender_id, sender_name, msg_type, text or None, media_path, halle_valid, category, spiel_titel or None),
) )
db.commit() db.commit()
sub_id = db.execute("SELECT last_insert_rowid()").fetchone()[0] sub_id = db.execute("SELECT last_insert_rowid()").fetchone()[0]