pdf-quiz-generator/backend/app/tasks/pdf_tasks.py
ifedan-ed b876f13fac Initial commit: PDF Quiz Generator app
- FastAPI backend with JWT auth, roles (admin/moderator/user)
- PDF upload (up to 500MB) with streaming, PyMuPDF text extraction
- ChromaDB vectorization per page with metadata
- LiteLLM AI question extraction from PDF (not generation)
- Image extraction from PDF pages, graceful fallback
- Quiz modes: timed (countdown timer) + learning (answers shown inline)
- Page-by-page question navigation with dot navigator
- TTS endpoint using LiteLLM (Google Vertex / OpenAI voices)
- Admin dashboard: AI model management per task, user role management
- Moderator role: upload PDFs, create sections, generate quizzes
- Spaced repetition reminders via SMTP email (SM-2 intervals)
- APScheduler daily reminder jobs
- Celery + Redis for background PDF processing
- React frontend with all pages
- Docker Compose deployment (nginx + backend + celery + redis)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 20:04:53 +00:00

53 lines
1.6 KiB
Python

import logging
from app.tasks import celery_app
from app.database import SessionLocal
from app.models.pdf_document import PDFDocument
from app.services import pdf_service, vector_service
logger = logging.getLogger(__name__)
@celery_app.task(name="process_pdf")
def process_pdf(document_id: int, file_path: str):
"""Background task: extract PDF text and store in ChromaDB."""
db = SessionLocal()
try:
doc = db.query(PDFDocument).filter(PDFDocument.id == document_id).first()
if not doc:
logger.error(f"Document {document_id} not found")
return
# Get page count
total_pages = pdf_service.get_page_count(file_path)
doc.total_pages = total_pages
db.commit()
# Extract text from all pages
pages = pdf_service.extract_text_by_page(file_path)
if not pages:
doc.status = "error"
doc.error_message = "No text could be extracted from the PDF"
db.commit()
return
# Store in ChromaDB
vector_service.store_pages(document_id, pages)
# Mark as ready
doc.status = "ready"
db.commit()
logger.info(f"Document {document_id} processed: {total_pages} pages, {len(pages)} with text")
except Exception as e:
logger.exception(f"Error processing document {document_id}")
try:
doc = db.query(PDFDocument).filter(PDFDocument.id == document_id).first()
if doc:
doc.status = "error"
doc.error_message = str(e)[:500]
db.commit()
except Exception:
pass
finally:
db.close()