Platform bundle: marketing publish, IT ops, packaging, agents mesh.
Volledige Foodlinkk Command Center uitbreiding met social automatisering, reclamefolder filters, Proxmox monitoring en documentatie.
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
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),
|
||||
)
|
||||
Reference in New Issue
Block a user