- Fix admin sidebar: remove duplicate Teams, add Storage nav item - Analytics: client-scoped queries, super_admin sees all (including NULL client_id) - Storage management: list/download/delete presentations with file metadata - Settings page with brand config router - AI usage tracking: new AIUsageModel, ai_usage_service, analytics endpoint - Master deck → template bridge: _register_as_template creates TemplateModel + PresentationLayoutCodeModel so parsed layouts appear in template picker - Multi-provider LLM vision in parser: Anthropic/Google/OpenAI with asyncio.to_thread - Fix PPTX upload 400: accept by .pptx extension (browser sends octet-stream) - Fix reparse FK violation: presentation_id=None for parse_master_deck jobs - Worker job_timeout increased to 1800s for LLM-heavy master deck parsing - PYTHONUNBUFFERED=1 in docker-compose worker for real-time log output - Auth: clientId in /me response, dev-login cookie improvements - Frontend: auth slice clientId, master-deck thumbnails, storage page Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
58 lines
1.9 KiB
Python
58 lines
1.9 KiB
Python
"""ARQ worker task: parse a master deck PPTX."""
|
|
import traceback
|
|
import uuid
|
|
from datetime import datetime
|
|
|
|
from models.sql.job import JobModel
|
|
from services.database import async_session_maker
|
|
from services.master_deck_parser_service import parse_master_deck
|
|
from services.redis_service import publish_job_progress
|
|
|
|
|
|
async def parse_master_deck_task(ctx: dict, job_id: str, deck_id: str = "") -> None:
|
|
"""ARQ task: parse a master deck via the existing parser service."""
|
|
job_uuid = uuid.UUID(job_id)
|
|
|
|
async with async_session_maker() as session:
|
|
job = await session.get(JobModel, job_uuid)
|
|
if not job:
|
|
return
|
|
|
|
try:
|
|
job.status = "processing"
|
|
job.started_at = datetime.utcnow()
|
|
job.progress = 10
|
|
job.progress_message = "Parsing master deck"
|
|
await session.commit()
|
|
|
|
try:
|
|
await publish_job_progress(job_uuid, 10, "Parsing master deck")
|
|
except Exception:
|
|
pass
|
|
|
|
# Parse the master deck by its own ID
|
|
await parse_master_deck(uuid.UUID(deck_id))
|
|
|
|
job.status = "completed"
|
|
job.progress = 100
|
|
job.progress_message = "Parsing complete"
|
|
job.completed_at = datetime.utcnow()
|
|
await session.commit()
|
|
|
|
try:
|
|
await publish_job_progress(job_uuid, 100, "Parsing complete", "completed")
|
|
except Exception:
|
|
pass
|
|
|
|
except Exception as e:
|
|
traceback.print_exc()
|
|
job.status = "failed"
|
|
job.error_message = str(e)[:500]
|
|
job.progress_message = "Parsing failed"
|
|
job.completed_at = datetime.utcnow()
|
|
await session.commit()
|
|
|
|
try:
|
|
await publish_job_progress(job_uuid, job.progress, "Parsing failed", "failed")
|
|
except Exception:
|
|
pass
|