135 lines
4.3 KiB
Python
135 lines
4.3 KiB
Python
from fastapi import APIRouter, Depends, HTTPException
|
|
from sqlalchemy.orm import Session
|
|
|
|
import logging
|
|
|
|
from app.database import get_db
|
|
from app.models.db_models import Account, FilterAction, FilterCondition, FilterRule, ProcessedMail
|
|
from app.schemas.schemas import FilterRuleCreate, FilterRuleResponse, FilterRuleUpdate
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def _reset_processed_for_rule(db: Session, rule_id: int) -> int:
|
|
"""Reset processed mails for a specific rule so they get re-evaluated."""
|
|
count = (
|
|
db.query(ProcessedMail)
|
|
.filter(ProcessedMail.rule_id == rule_id)
|
|
.delete()
|
|
)
|
|
if count:
|
|
logger.info("Filter geändert: %d verarbeitete Mails für Regel %d zurückgesetzt", count, rule_id)
|
|
return count
|
|
|
|
router = APIRouter(prefix="/api/filters", tags=["filters"])
|
|
|
|
|
|
@router.get("/account/{account_id}", response_model=list[FilterRuleResponse])
|
|
def list_filters(account_id: int, db: Session = Depends(get_db)):
|
|
account = db.get(Account, account_id)
|
|
if not account:
|
|
raise HTTPException(404, "Konto nicht gefunden")
|
|
rules = (
|
|
db.query(FilterRule)
|
|
.filter(FilterRule.account_id == account_id)
|
|
.order_by(FilterRule.priority)
|
|
.all()
|
|
)
|
|
return rules
|
|
|
|
|
|
@router.get("/{rule_id}", response_model=FilterRuleResponse)
|
|
def get_filter(rule_id: int, db: Session = Depends(get_db)):
|
|
rule = db.get(FilterRule, rule_id)
|
|
if not rule:
|
|
raise HTTPException(404, "Filterregel nicht gefunden")
|
|
return rule
|
|
|
|
|
|
@router.post("/", response_model=FilterRuleResponse, status_code=201)
|
|
def create_filter(data: FilterRuleCreate, db: Session = Depends(get_db)):
|
|
account = db.get(Account, data.account_id)
|
|
if not account:
|
|
raise HTTPException(404, "Konto nicht gefunden")
|
|
|
|
rule = FilterRule(
|
|
account_id=data.account_id,
|
|
name=data.name,
|
|
priority=data.priority,
|
|
enabled=data.enabled,
|
|
stop_processing=data.stop_processing,
|
|
source_folder=data.source_folder,
|
|
)
|
|
db.add(rule)
|
|
db.flush()
|
|
|
|
for cond_data in data.conditions:
|
|
cond = FilterCondition(rule_id=rule.id, **cond_data.model_dump())
|
|
db.add(cond)
|
|
for action_data in data.actions:
|
|
action = FilterAction(rule_id=rule.id, **action_data.model_dump())
|
|
db.add(action)
|
|
|
|
# Neue Regel → hat noch keinen processed-Status, wird automatisch alle Mails prüfen
|
|
|
|
db.commit()
|
|
db.refresh(rule)
|
|
return rule
|
|
|
|
|
|
@router.put("/{rule_id}", response_model=FilterRuleResponse)
|
|
def update_filter(rule_id: int, data: FilterRuleUpdate, db: Session = Depends(get_db)):
|
|
rule = db.get(FilterRule, rule_id)
|
|
if not rule:
|
|
raise HTTPException(404, "Filterregel nicht gefunden")
|
|
|
|
update_data = data.model_dump(exclude_unset=True)
|
|
|
|
# Update conditions if provided
|
|
if "conditions" in update_data:
|
|
for cond in rule.conditions:
|
|
db.delete(cond)
|
|
for cond_data in data.conditions:
|
|
cond = FilterCondition(rule_id=rule.id, **cond_data.model_dump())
|
|
db.add(cond)
|
|
del update_data["conditions"]
|
|
|
|
# Update actions if provided
|
|
if "actions" in update_data:
|
|
for action in rule.actions:
|
|
db.delete(action)
|
|
for action_data in data.actions:
|
|
action = FilterAction(rule_id=rule.id, **action_data.model_dump())
|
|
db.add(action)
|
|
del update_data["actions"]
|
|
|
|
for key, value in update_data.items():
|
|
setattr(rule, key, value)
|
|
|
|
# Regel geändert → nur diese Regel zurücksetzen
|
|
_reset_processed_for_rule(db, rule.id)
|
|
|
|
db.commit()
|
|
db.refresh(rule)
|
|
return rule
|
|
|
|
|
|
@router.delete("/{rule_id}", status_code=204)
|
|
def delete_filter(rule_id: int, db: Session = Depends(get_db)):
|
|
rule = db.get(FilterRule, rule_id)
|
|
if not rule:
|
|
raise HTTPException(404, "Filterregel nicht gefunden")
|
|
# processed-Einträge werden per CASCADE gelöscht
|
|
db.delete(rule)
|
|
db.commit()
|
|
|
|
|
|
@router.put("/reorder/{account_id}")
|
|
def reorder_filters(account_id: int, rule_ids: list[int], db: Session = Depends(get_db)):
|
|
for priority, rule_id in enumerate(rule_ids):
|
|
rule = db.get(FilterRule, rule_id)
|
|
if rule and rule.account_id == account_id:
|
|
rule.priority = priority
|
|
db.commit()
|
|
return {"message": "Reihenfolge aktualisiert"}
|