feat: Add alert processing functionality and UI feedback
This commit is contained in:
@@ -142,6 +142,8 @@ def process_alerts(db: Session, cfg: dict) -> List[int]:
|
|||||||
}
|
}
|
||||||
for m in get_thread_messages(db, t.id)[-4:]
|
for m in get_thread_messages(db, t.id)[-4:]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
print(f"These are the messages: {msgs}")
|
||||||
ai = analyze_thread(t.subject or "", msgs)
|
ai = analyze_thread(t.subject or "", msgs)
|
||||||
|
|
||||||
# Persist AI decision on thread
|
# Persist AI decision on thread
|
||||||
|
|||||||
+13
-4
@@ -49,7 +49,12 @@ app.mount("/static", StaticFiles(directory="static"), name="static")
|
|||||||
|
|
||||||
|
|
||||||
@app.get("/", response_class=HTMLResponse)
|
@app.get("/", response_class=HTMLResponse)
|
||||||
def home(request: Request, db: Session = Depends(get_db), account: str | None = None):
|
def home(
|
||||||
|
request: Request,
|
||||||
|
db: Session = Depends(get_db),
|
||||||
|
account: str | None = None,
|
||||||
|
alerts_processed: int | None = None,
|
||||||
|
):
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from sqlalchemy import func
|
from sqlalchemy import func
|
||||||
@@ -109,6 +114,7 @@ def home(request: Request, db: Session = Depends(get_db), account: str | None =
|
|||||||
"threads": threads_with_info,
|
"threads": threads_with_info,
|
||||||
"account": account or "",
|
"account": account or "",
|
||||||
"status": _status_for_templates(),
|
"status": _status_for_templates(),
|
||||||
|
"alerts_processed": alerts_processed,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -335,7 +341,8 @@ async def config_save(request: Request):
|
|||||||
def process(db: Session = Depends(get_db)):
|
def process(db: Session = Depends(get_db)):
|
||||||
cfg = load_config()
|
cfg = load_config()
|
||||||
alerted = process_alerts(db, cfg)
|
alerted = process_alerts(db, cfg)
|
||||||
return {"alerted_threads": alerted}
|
# Redirect back to main page with success indicator
|
||||||
|
return RedirectResponse(url=f"/?alerts_processed={len(alerted)}", status_code=303)
|
||||||
|
|
||||||
|
|
||||||
def _sync_emails_once(cfg: dict) -> int:
|
def _sync_emails_once(cfg: dict) -> int:
|
||||||
@@ -357,7 +364,7 @@ def _sync_emails_once(cfg: dict) -> int:
|
|||||||
days_back = max(1, delta_days)
|
days_back = max(1, delta_days)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
max_results = 100
|
max_results = 5
|
||||||
client = ZohoClient(
|
client = ZohoClient(
|
||||||
email=cfg.get("zoho_email") or account_email,
|
email=cfg.get("zoho_email") or account_email,
|
||||||
app_password=cfg.get("zoho_app_password"),
|
app_password=cfg.get("zoho_app_password"),
|
||||||
@@ -413,7 +420,9 @@ def _sync_emails_background_task():
|
|||||||
{
|
{
|
||||||
"sync_in_progress": False,
|
"sync_in_progress": False,
|
||||||
"last_sync_status": "success",
|
"last_sync_status": "success",
|
||||||
"last_sync_at": datetime.now(timezone.utc).strftime("%d/%m/%y %I:%M %p"),
|
"last_sync_at": datetime.now(timezone.utc).strftime(
|
||||||
|
"%d/%m/%y %I:%M %p"
|
||||||
|
),
|
||||||
"last_sync_count": count,
|
"last_sync_count": count,
|
||||||
"last_sync_error": None,
|
"last_sync_error": None,
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -156,7 +156,7 @@ class ZohoClient:
|
|||||||
|
|
||||||
# Get email body snippet
|
# Get email body snippet
|
||||||
body = self._get_email_body(email_message)
|
body = self._get_email_body(email_message)
|
||||||
snippet = body[:200] + "..." if len(body) > 200 else body
|
|
||||||
|
|
||||||
email_data = {
|
email_data = {
|
||||||
"id": num.decode(),
|
"id": num.decode(),
|
||||||
@@ -168,11 +168,11 @@ class ZohoClient:
|
|||||||
"messageId": message_id,
|
"messageId": message_id,
|
||||||
"inReplyTo": in_reply_to,
|
"inReplyTo": in_reply_to,
|
||||||
"folder": folder,
|
"folder": folder,
|
||||||
"snippet": snippet,
|
"snippet": body,
|
||||||
}
|
}
|
||||||
|
|
||||||
emails.append(email_data)
|
emails.append(email_data)
|
||||||
|
logging.info(f"Long body: {body}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"❌ Error processing email {num}: {e}")
|
print(f"❌ Error processing email {num}: {e}")
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -112,3 +112,26 @@ button {
|
|||||||
box-shadow: 0 6px 18px rgba(63, 99, 183, 0.35);
|
box-shadow: 0 6px 18px rgba(63, 99, 183, 0.35);
|
||||||
}
|
}
|
||||||
button:hover { filter: brightness(1.05); }
|
button:hover { filter: brightness(1.05); }
|
||||||
|
|
||||||
|
/* Alert styles */
|
||||||
|
.alert {
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
.alert.success {
|
||||||
|
background: rgba(34, 197, 94, 0.1);
|
||||||
|
border-color: var(--success);
|
||||||
|
color: #4ade80;
|
||||||
|
}
|
||||||
|
.alert.warn {
|
||||||
|
background: rgba(245, 158, 11, 0.1);
|
||||||
|
border-color: var(--warn);
|
||||||
|
color: #fbbf24;
|
||||||
|
}
|
||||||
|
.alert.danger {
|
||||||
|
background: rgba(239, 68, 68, 0.1);
|
||||||
|
border-color: var(--danger);
|
||||||
|
color: #f87171;
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,6 +16,9 @@
|
|||||||
<form action="/sync_emails" method="post" style="display:inline-block; margin-left:12px;">
|
<form action="/sync_emails" method="post" style="display:inline-block; margin-left:12px;">
|
||||||
<button type="submit">Process Emails</button>
|
<button type="submit">Process Emails</button>
|
||||||
</form>
|
</form>
|
||||||
|
<form action="/process" method="post" style="display:inline-block; margin-left:12px;">
|
||||||
|
<button type="submit">Process Alerts</button>
|
||||||
|
</form>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|||||||
@@ -4,6 +4,11 @@
|
|||||||
<div class="col">
|
<div class="col">
|
||||||
<h2>Threads{% if account %} for {{ account }}{% endif %}</h2>
|
<h2>Threads{% if account %} for {{ account }}{% endif %}</h2>
|
||||||
<p class="muted">Latest updated threads. Click an ID to view details and AI analysis.</p>
|
<p class="muted">Latest updated threads. Click an ID to view details and AI analysis.</p>
|
||||||
|
{% if alerts_processed is not none %}
|
||||||
|
<div class="alert success" style="margin-bottom:12px;">
|
||||||
|
✓ Alerts processed! {{ alerts_processed }} thread(s) were checked for alerts.
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
{% if status %}
|
{% if status %}
|
||||||
<div class="muted" style="margin-top:6px;">
|
<div class="muted" style="margin-top:6px;">
|
||||||
{% if status.sync_in_progress %}
|
{% if status.sync_in_progress %}
|
||||||
|
|||||||
Reference in New Issue
Block a user