autoace / src /batch.py
edwixx's picture
Deploy AutoAce voice tone dashboard
c3eb7ea verified
Raw
History Blame Contribute Delete
2.17 kB
import tempfile
import zipfile
from pathlib import Path
import pandas as pd
from . import pipeline
from .logger import log
SUPPORTED_EXTS = {".wav", ".mp3", ".ogg", ".flac", ".m4a"}
def _resolve_root(input_path: str) -> Path:
p = Path(input_path)
if p.is_dir():
return p
if p.suffix.lower() == ".zip":
tmp = Path(tempfile.mkdtemp())
with zipfile.ZipFile(p) as zf:
zf.extractall(tmp)
entries = list(tmp.iterdir())
if len(entries) == 1 and entries[0].is_dir():
return entries[0]
return tmp
raise ValueError(f"Expected a folder or .zip file, got: {input_path}")
def process_batch(input_path: str, on_progress=None) -> tuple[pd.DataFrame, list[dict]]:
root = _resolve_root(input_path)
errors: list[dict] = []
csv_files = list(root.glob("*.csv"))
manifest_names: set[str] | None = None
if csv_files:
manifest = pd.read_csv(csv_files[0])
if "name" in manifest.columns:
manifest_names = set(manifest["name"])
else:
errors.append(
{"file": csv_files[0].name, "error": "manifest is missing the required 'name' column"}
)
audio_files = sorted(f for f in root.iterdir() if f.suffix.lower() in SUPPORTED_EXTS)
if not audio_files:
errors.append({"file": "", "error": "no supported audio files found in the batch"})
if manifest_names is not None:
found_names = {f.name for f in audio_files}
for missing in sorted(manifest_names - found_names):
errors.append({"file": missing, "error": "listed in manifest but not found in the uploaded batch"})
rows = []
for i, f in enumerate(audio_files, start=1):
try:
result = pipeline.analyze_one(str(f))
rows.append({"name": f.name, **result.model_dump(mode="json")})
except Exception as e:
log.exception("failed to process %s: %s", f.name, e)
errors.append({"file": f.name, "error": f"{type(e).__name__}: {e}"})
if on_progress:
on_progress(i, len(audio_files), f.name)
return pd.DataFrame(rows), errors