imap-mail-filter-service/app/main.py

131 lines
4.2 KiB
Python

import logging
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from app.config import settings
from app.database import Base, engine
logging.basicConfig(
level=getattr(logging, settings.log_level.upper(), logging.INFO),
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
)
logger = logging.getLogger(__name__)
@asynccontextmanager
async def lifespan(app: FastAPI):
logger.info("Starte IMAP Mail Filter Service...")
# Datenbank-Migration mit Alembic
from alembic.config import Config
from alembic import command
alembic_cfg = Config("alembic.ini")
command.upgrade(alembic_cfg, "head")
logger.info("Datenbank-Migration abgeschlossen.")
if settings.yaml_sync_on_startup:
from app.services.yaml_service import import_from_file
result = import_from_file()
logger.info("YAML-Startup-Import: %s", result)
from app.services.scheduler import start_scheduler, stop_scheduler
start_scheduler()
yield
stop_scheduler()
logger.info("Service wird beendet.")
app = FastAPI(title="IMAP Mail Filter Service", lifespan=lifespan)
app.mount("/static", StaticFiles(directory="app/static"), name="static")
templates = Jinja2Templates(directory="app/templates")
from fastapi import Depends, Request # noqa: E402
from sqlalchemy.orm import Session # noqa: E402
from app.database import get_db # noqa: E402
from app.models.db_models import Account # noqa: E402
from app.routers import accounts, filters, logs, yaml_sync # noqa: E402
app.include_router(accounts.router)
app.include_router(filters.router)
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 ---
@app.get("/")
def dashboard(request: Request, db: Session = Depends(get_db)):
accs = db.query(Account).order_by(Account.name).all()
account_list = []
for acc in accs:
account_list.append({
"id": acc.id,
"name": acc.name,
"username": acc.username,
"imap_host": acc.imap_host,
"enabled": acc.enabled,
"poll_interval_seconds": acc.poll_interval_seconds,
"last_poll_at": acc.last_poll_at,
"filter_rule_count": len(acc.filter_rules),
})
return templates.TemplateResponse("dashboard.html", {"request": request, "accounts": account_list})
@app.get("/accounts")
def accounts_page(request: Request, db: Session = Depends(get_db)):
accs = db.query(Account).order_by(Account.name).all()
return templates.TemplateResponse("accounts.html", {"request": request, "accounts": accs})
@app.get("/accounts/new")
def new_account_page(request: Request):
return templates.TemplateResponse("account_form.html", {"request": request, "account": None})
@app.get("/accounts/{account_id}/edit")
def edit_account_page(account_id: int, request: Request, db: Session = Depends(get_db)):
account = db.get(Account, account_id)
return templates.TemplateResponse("account_form.html", {"request": request, "account": account})
@app.get("/filters")
def filters_page(request: Request, account_id: int = 0, db: Session = Depends(get_db)):
accs = db.query(Account).order_by(Account.name).all()
return templates.TemplateResponse("filters.html", {
"request": request,
"accounts": accs,
"selected_account_id": account_id,
})
@app.get("/yaml")
def yaml_page(request: Request):
return templates.TemplateResponse("yaml.html", {"request": request})
@app.get("/logs")
def logs_page(request: Request, db: Session = Depends(get_db)):
accs = db.query(Account).order_by(Account.name).all()
return templates.TemplateResponse("logs.html", {"request": request, "accounts": accs})