From 66b32ded369ee1a9e91501e121045d970b3b7a97 Mon Sep 17 00:00:00 2001 From: duffyduck Date: Sun, 5 Apr 2026 18:55:09 +0200 Subject: [PATCH] fixed, scheduler, added search to log, added advanced search --- app/main.py | 19 +++++++++++ app/routers/accounts.py | 6 ++++ app/routers/logs.py | 31 ++++++++++++++++++ app/templates/logs.html | 71 +++++++++++++++++++++++++++++++++++++++-- 4 files changed, 124 insertions(+), 3 deletions(-) diff --git a/app/main.py b/app/main.py index 330d93e..796b790 100644 --- a/app/main.py +++ b/app/main.py @@ -52,6 +52,25 @@ app.include_router(yaml_sync.router) app.include_router(logs.router) +# --- API: Scheduler-Status --- + + +@app.get("/api/scheduler/status") +def scheduler_status(): + from app.services.scheduler import scheduler + jobs = [] + for job in scheduler.get_jobs(): + jobs.append({ + "id": job.id, + "next_run": job.next_run_time.isoformat() if job.next_run_time else None, + "interval": str(job.trigger), + }) + return { + "running": scheduler.running, + "jobs": jobs, + } + + # --- Web-UI Routen --- diff --git a/app/routers/accounts.py b/app/routers/accounts.py index b49fc86..5054af3 100644 --- a/app/routers/accounts.py +++ b/app/routers/accounts.py @@ -46,6 +46,8 @@ def create_account(data: AccountCreate, db: Session = Depends(get_db)): db.add(account) db.commit() db.refresh(account) + from app.services.scheduler import add_account_job + add_account_job(account) return account @@ -62,6 +64,8 @@ def update_account(account_id: int, data: AccountUpdate, db: Session = Depends(g setattr(account, key, value) db.commit() db.refresh(account) + from app.services.scheduler import add_account_job + add_account_job(account) return account @@ -70,6 +74,8 @@ def delete_account(account_id: int, db: Session = Depends(get_db)): account = db.get(Account, account_id) if not account: raise HTTPException(404, "Konto nicht gefunden") + from app.services.scheduler import remove_account_job + remove_account_job(account_id) db.delete(account) db.commit() diff --git a/app/routers/logs.py b/app/routers/logs.py index c9dd7aa..506b05a 100644 --- a/app/routers/logs.py +++ b/app/routers/logs.py @@ -11,6 +11,13 @@ router = APIRouter(prefix="/api/logs", tags=["logs"]) def get_logs( account_id: int | None = None, level: str | None = None, + search: str | None = None, + search_subject: str | None = None, + search_from: str | None = None, + search_rule: str | None = None, + search_message: str | None = None, + search_details: str | None = None, + search_folder: str | None = None, limit: int = Query(default=100, le=500), offset: int = 0, db: Session = Depends(get_db), @@ -20,6 +27,30 @@ def get_logs( query = query.filter(FilterLog.account_id == account_id) if level: query = query.filter(FilterLog.level == level) + # Einfache Suche (ODER über alle Felder) + if search: + term = f"%{search}%" + query = query.filter( + FilterLog.message.ilike(term) + | FilterLog.mail_subject.ilike(term) + | FilterLog.mail_from.ilike(term) + | FilterLog.rule_name.ilike(term) + | FilterLog.details.ilike(term) + | FilterLog.folder.ilike(term) + ) + # Erweiterte Suche (UND pro Feld) + if search_subject: + query = query.filter(FilterLog.mail_subject.ilike(f"%{search_subject}%")) + if search_from: + query = query.filter(FilterLog.mail_from.ilike(f"%{search_from}%")) + if search_rule: + query = query.filter(FilterLog.rule_name.ilike(f"%{search_rule}%")) + if search_message: + query = query.filter(FilterLog.message.ilike(f"%{search_message}%")) + if search_details: + query = query.filter(FilterLog.details.ilike(f"%{search_details}%")) + if search_folder: + query = query.filter(FilterLog.folder.ilike(f"%{search_folder}%")) total = query.count() logs = query.offset(offset).limit(limit).all() return { diff --git a/app/templates/logs.html b/app/templates/logs.html index f1c5531..3945fe6 100644 --- a/app/templates/logs.html +++ b/app/templates/logs.html @@ -3,7 +3,7 @@ {% block content %}

Verarbeitungslog

-
+
+
- +
-
+
+ Erweiterte Suche (UND-verknüpft) +
+ + + +
+
+ + + +
+
+ + +
+
+
@@ -85,9 +125,24 @@ async function loadLogs(offset = 0) { const level = document.getElementById('log-level').value; const container = document.getElementById('log-container'); + const search = document.getElementById('log-search').value.trim(); + const searchSubject = document.getElementById('search-subject').value.trim(); + const searchFrom = document.getElementById('search-from').value.trim(); + const searchRule = document.getElementById('search-rule').value.trim(); + const searchMessage = document.getElementById('search-message').value.trim(); + const searchDetails = document.getElementById('search-details').value.trim(); + const searchFolder = document.getElementById('search-folder').value.trim(); + let url = `/api/logs/?limit=${PAGE_SIZE}&offset=${offset}`; if (accountId) url += `&account_id=${accountId}`; if (level) url += `&level=${level}`; + if (search) url += `&search=${encodeURIComponent(search)}`; + if (searchSubject) url += `&search_subject=${encodeURIComponent(searchSubject)}`; + if (searchFrom) url += `&search_from=${encodeURIComponent(searchFrom)}`; + if (searchRule) url += `&search_rule=${encodeURIComponent(searchRule)}`; + if (searchMessage) url += `&search_message=${encodeURIComponent(searchMessage)}`; + if (searchDetails) url += `&search_details=${encodeURIComponent(searchDetails)}`; + if (searchFolder) url += `&search_folder=${encodeURIComponent(searchFolder)}`; try { const resp = await fetch(url); @@ -196,6 +251,16 @@ function escapeHtml(text) { return div.innerHTML; } +function clearAdvancedSearch() { + document.getElementById('search-subject').value = ''; + document.getElementById('search-from').value = ''; + document.getElementById('search-rule').value = ''; + document.getElementById('search-message').value = ''; + document.getElementById('search-details').value = ''; + document.getElementById('search-folder').value = ''; + loadLogs(); +} + // Initial load loadLogs();