from __future__ import annotations import hashlib import json import os import shutil import sqlite3 import threading import time import uuid from pathlib import Path from asrpipe import graph, lexicon, providers, refine, review, revise, vault from asrpipe.config import CFG from asrpipe.locking import acquire_recording_lock from . import db from .config import ( DATA, DRAFTS, FAILED, INBOX, LOGS, MAX_ATTEMPTS, POLL_SECONDS, PROCESSED, PROCESSING, PUBLIC_URL, REVISION_QUEUE, STABLE_SECONDS, STATE, SUPPORTED, TRANSCRIPTS, ensure_dirs, ) from .notify import send _RECORDING_LOCK = None def log(message: str) -> None: ensure_dirs() with (LOGS / "worker.log").open("a", encoding="utf-8") as stream: stream.write(time.strftime("[%Y-%m-%d %H:%M:%S] ") + message + "\n") def sha256(path: Path) -> str: h = hashlib.sha256() with path.open("rb") as stream: for chunk in iter(lambda: stream.read(1024 * 1024), b""): h.update(chunk) return h.hexdigest() def transcript_from_response(payload: dict) -> str: """Backward-compatible helper for qwen3cam JSON responses.""" return providers.transcript_from_qwen3cam_response(payload) def transcribe( audio: Path, job_id: str, *, provider: str = "", model: str = "", title: str = "", user_context: str = "", ) -> tuple[Path, providers.TranscribeResult]: res = providers.transcribe_audio( audio, provider=provider or CFG.asr_provider, model=model, title=title, user_context=user_context, ) response_path = TRANSCRIPTS / f"{job_id}.asr.json" try: response_path.write_text( json.dumps(res.raw_response, ensure_ascii=False, indent=2), encoding="utf-8", ) except Exception: pass transcript = TRANSCRIPTS / f"{job_id}.txt" transcript.write_text(res.transcript_text, encoding="utf-8") return transcript, res def intake_header(payload: dict) -> str: blob = json.dumps(payload, ensure_ascii=False).replace("--", "- -") return f"" def replace_intake(raw: str, header: str) -> str: if raw.startswith("