"""Editorial Calendar router. Espone endpoint per il calendario editoriale con awareness levels e formati narrativi. """ import csv import io from typing import Optional from fastapi import APIRouter, Depends from fastapi.responses import StreamingResponse from pydantic import BaseModel from sqlalchemy.orm import Session from ..auth import get_current_user from ..database import get_db from ..services.calendar_service import CalendarService, FORMATI_NARRATIVI, AWARENESS_LEVELS router = APIRouter( prefix="/api/editorial", tags=["editorial"], dependencies=[Depends(get_current_user)], ) _calendar_service = CalendarService() # === Schemas locali === class CalendarGenerateRequest(BaseModel): topics: list[str] format_narrativo: Optional[str] = None awareness_level: Optional[int] = None num_posts: int = 7 start_date: Optional[str] = None character_id: Optional[int] = None class ExportCsvRequest(BaseModel): slots: list[dict] # === Endpoints === @router.get("/formats") def get_formats(): """Restituisce i format narrativi disponibili con i relativi awareness levels.""" return { "formats": _calendar_service.get_formats(), "awareness_levels": [ {"value": k, "label": v} for k, v in AWARENESS_LEVELS.items() ], } @router.post("/generate-calendar") def generate_calendar(request: CalendarGenerateRequest, db: Session = Depends(get_db)): """Genera un calendario editoriale con awareness levels.""" if not request.topics: return {"slots": [], "totale_post": 0} slots = _calendar_service.generate_calendar( topics=request.topics, num_posts=request.num_posts, format_narrativo=request.format_narrativo, awareness_level=request.awareness_level, start_date=request.start_date, ) return { "slots": slots, "totale_post": len(slots), } @router.post("/export-csv") def export_csv(request: ExportCsvRequest): """Esporta il calendario editoriale come CSV per Canva.""" output = io.StringIO() fieldnames = [ "indice", "data_pubblicazione", "topic", "formato_narrativo", "awareness_level", "awareness_label", "note", ] writer = csv.DictWriter(output, fieldnames=fieldnames, extrasaction="ignore") writer.writeheader() for slot in request.slots: writer.writerow({ "indice": slot.get("indice", ""), "data_pubblicazione": slot.get("data_pubblicazione", ""), "topic": slot.get("topic", ""), "formato_narrativo": slot.get("formato_narrativo", ""), "awareness_level": slot.get("awareness_level", ""), "awareness_label": slot.get("awareness_label", ""), "note": slot.get("note", ""), }) output.seek(0) return StreamingResponse( iter([output.getvalue()]), media_type="text/csv", headers={ "Content-Disposition": "attachment; filename=calendario_editoriale.csv" }, )