5d60d33db1
Volledige Foodlinkk Command Center uitbreiding met social automatisering, reclamefolder filters, Proxmox monitoring en documentatie.
81 lines
3.5 KiB
Python
81 lines
3.5 KiB
Python
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),
|
|
)
|