| import json |
| from pathlib import Path |
| from uuid import uuid4 |
|
|
| from app.core.config import Settings |
| from app.models.schemas import ChannelProfile, JobSnapshot, utc_now |
|
|
|
|
| class JobStore: |
| def __init__(self, settings: Settings) -> None: |
| self.settings = settings |
| self.root = settings.storage_dir |
| self.jobs_root = self.root / "jobs" |
| self.jobs_root.mkdir(parents=True, exist_ok=True) |
|
|
| def create_job(self, profile: ChannelProfile, source: dict) -> JobSnapshot: |
| job_id = uuid4().hex |
| job_dir = self.job_dir(job_id) |
| job_dir.mkdir(parents=True, exist_ok=True) |
| snapshot = JobSnapshot( |
| id=job_id, |
| status="queued", |
| progress=0, |
| message="Queued", |
| source=source, |
| profile=profile, |
| ) |
| self.save_job(snapshot) |
| return snapshot |
|
|
| def job_dir(self, job_id: str) -> Path: |
| return self.jobs_root / job_id |
|
|
| def media_url(self, job_id: str, filename: str) -> str: |
| return f"/media/jobs/{job_id}/{filename}" |
|
|
| def save_job(self, snapshot: JobSnapshot) -> JobSnapshot: |
| snapshot.updated_at = utc_now() |
| path = self.job_dir(snapshot.id) / "job.json" |
| path.write_text(snapshot.model_dump_json(indent=2), encoding="utf-8") |
| return snapshot |
|
|
| def get_job(self, job_id: str) -> JobSnapshot: |
| path = self.job_dir(job_id) / "job.json" |
| if not path.exists(): |
| raise FileNotFoundError(job_id) |
| data = json.loads(path.read_text(encoding="utf-8")) |
| return JobSnapshot.model_validate(data) |
|
|
| def update_job(self, job_id: str, **updates) -> JobSnapshot: |
| snapshot = self.get_job(job_id) |
| updated = snapshot.model_copy(update=updates) |
| return self.save_job(updated) |
|
|
| def write_json(self, job_id: str, filename: str, payload: object) -> Path: |
| path = self.job_dir(job_id) / filename |
| path.write_text(json.dumps(payload, indent=2, ensure_ascii=False), encoding="utf-8") |
| return path |
|
|