[33e88f42] Keine Zusammenfassung angegeben.

Keine Zusammenfassung angegeben.
This commit is contained in:
2026-04-10 21:51:12 +00:00
parent c2f614d7ad
commit 5e0186c534
8 changed files with 460 additions and 22 deletions

View File

@@ -746,14 +746,16 @@ def process_reminder_analysis(task_id: str, job_id: str, account_type: str):
from fastapi import FastAPI, HTTPException, Depends, BackgroundTasks, UploadFile, File, Form
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse, JSONResponse
from fastapi.responses import FileResponse, JSONResponse, RedirectResponse
from typing import List, Dict, Any, Optional
from pydantic import BaseModel
from sqlalchemy.orm import Session
from database import get_db, Job as DBJob, engine, Base
import math
import uuid
from qr_generator import get_calendly_events, overlay_text_on_pdf, get_calendly_event_types
from gmail_service import GmailService
# --- API Endpoints ---
@@ -914,6 +916,31 @@ async def download_latest_file():
async def health_check():
return {"status": "ok"}
# --- Gmail API Endpoints ---
@app.get("/api/auth/google")
async def get_google_auth_url(db: Session = Depends(get_db)):
service = GmailService(db)
return {"url": service.get_auth_url()}
@app.get("/api/auth/callback")
async def google_auth_callback(code: str, db: Session = Depends(get_db)):
service = GmailService(db)
try:
service.handle_callback(code)
# Redirect back to frontend
# The frontend lives at /fotograf-de/ through NGINX
frontend_url = os.getenv("FRONTEND_URL", "https://floke-ai.duckdns.org/fotograf-de/")
return RedirectResponse(url=frontend_url)
except Exception as e:
logger.error(f"Auth callback failed: {e}")
return JSONResponse(status_code=500, content={"message": f"Authentifizierung fehlgeschlagen: {str(e)}"})
@app.get("/api/gmail/status")
async def get_gmail_status(db: Session = Depends(get_db)):
service = GmailService(db)
return {"authenticated": service.is_authenticated()}
@app.get("/api/jobs", response_model=List[Dict[str, Any]])
async def get_jobs(account_type: str, force_refresh: bool = False, db: Session = Depends(get_db)):
logger.info(f"API Request: GET /api/jobs for {account_type} (force_refresh={force_refresh})")
@@ -1034,6 +1061,34 @@ async def download_task_csv(task_id: str):
logger.error(f"Export error: {e}")
raise HTTPException(status_code=500, detail="CSV Export fehlgeschlagen.")
class BulkEmailRequest(BaseModel):
emails: List[Dict[str, str]]
@app.post("/api/gmail/send-bulk")
async def send_bulk_emails(request: BulkEmailRequest, db: Session = Depends(get_db)):
service = GmailService(db)
if not service.is_authenticated():
raise HTTPException(status_code=401, detail="Gmail nicht authentifiziert.")
success_count = 0
failed_emails = []
for email_data in request.emails:
to = email_data.get("to")
subject = email_data.get("subject")
body = email_data.get("body")
if service.send_email(to, subject, body):
success_count += 1
else:
failed_emails.append(to)
return {
"total": len(request.emails),
"success": success_count,
"failed": failed_emails
}
@app.get("/api/jobs/{job_id}/generate-pdf")
async def generate_pdf(job_id: str, account_type: str, db: Session = Depends(get_db)):
logger.info(f"API Request: Generate PDF for job {job_id} ({account_type})")