from __future__ import annotations from datetime import datetime, timedelta from typing import Optional from psycopg2.extras import RealDictCursor from app.db import get_connection def sentiment_score(text: str) -> float: try: from textblob import TextBlob blob = TextBlob(text) score = (blob.sentiment.polarity + 1) * 2 + 1 except Exception: t = text.lower() neg = sum(1 for w in ("bad", "teleurgest", "klacht", "lang", "duur", "fout") if w in t) pos = sum(1 for w in ("geweldig", "aanrader", "fantast", "mooi", "lekker", "top") if w in t) raw = 3.0 + (pos - neg) * 0.5 score = max(1.0, min(5.0, raw)) return max(1.0, min(5.0, round(float(score), 2))) def evaluate_agent_rules(mention_id: Optional[int] = None) -> None: with get_connection() as conn: with conn.cursor(cursor_factory=RealDictCursor) as cur: cur.execute("SELECT * FROM agent_rules WHERE is_active = TRUE") rules = cur.fetchall() for rule in rules: if rule["condition_type"] == "sentiment_below": threshold = rule["threshold"] or 2.0 if mention_id: cur.execute( "SELECT id, text, sentiment_score FROM social_mentions WHERE id = %s AND sentiment_score < %s", (mention_id, threshold), ) else: cur.execute( "SELECT id, text, sentiment_score FROM social_mentions WHERE sentiment_score < %s ORDER BY created_at DESC LIMIT 5", (threshold,), ) matches = cur.fetchall() for m in matches: cur.execute( "SELECT 1 FROM agent_logs WHERE rule_id = %s AND message LIKE %s", (rule["id"], f"%mention #{m['id']}%"), ) if cur.fetchone(): continue msg = ( f"ALERT [{rule['name']}]: Negatief sentiment ({m['sentiment_score']}/5) " f"op mention #{m['id']}: {(m['text'] or '')[:120]}" ) cur.execute( "INSERT INTO agent_logs (rule_id, message) VALUES (%s, %s)", (rule["id"], msg), ) elif rule["condition_type"] == "mention_spike": threshold = int(rule["threshold"] or 5) since = datetime.now() - timedelta(hours=24) cur.execute( "SELECT COUNT(*) AS cnt FROM social_mentions WHERE created_at > %s", (since,), ) count = cur.fetchone()["cnt"] if count >= threshold: msg = f"ALERT [{rule['name']}]: {count} mentions in 24u (drempel: {threshold})" cur.execute( "SELECT 1 FROM agent_logs WHERE rule_id = %s AND message = %s AND created_at > %s", (rule["id"], msg, since), ) if not cur.fetchone(): cur.execute( "INSERT INTO agent_logs (rule_id, message) VALUES (%s, %s)", (rule["id"], msg), )