#!/usr/bin/env python3 """ Generate Kevin sound index JSON for Home Assistant. Run this on the NAS that stores / publishes the Kevin sound folders. It creates sounds_index.json inside the sound root so Nginx can serve it. Default assumptions used by the current Home Assistant configuration: filesystem root: /volume1/web/temp/kevin_sounds public base URL: http://192.168.1.208/temp/kevin_sounds Adjust SOUND_ROOT if your NAS path is different. """ from __future__ import annotations import json import os from datetime import datetime, timezone from pathlib import Path from urllib.parse import quote SOUND_ROOT = Path(os.environ.get("KEVIN_SOUND_ROOT", "/volume1/web/temp/kevin_sounds")) BASE_URL = os.environ.get("KEVIN_SOUND_BASE_URL", "http://192.168.1.208/temp/kevin_sounds").rstrip("/") OUTPUT_FILE = SOUND_ROOT / "sounds_index.json" CATEGORIES = ["matin", "apres_midi", "soir", "neutre", "system"] AUDIO_EXTENSIONS = {".mp3", ".wav", ".m4a", ".ogg", ".flac"} def public_url(category: str, path: Path) -> str: # URL-encode each path segment but keep directory separators intact. relative = path.relative_to(SOUND_ROOT / category) encoded = "/".join(quote(part) for part in relative.parts) return f"{BASE_URL}/{category}/{encoded}" def collect_category(category: str) -> list[str]: folder = SOUND_ROOT / category if not folder.exists(): return [] files = [] for path in folder.rglob("*"): if path.is_file() and path.suffix.lower() in AUDIO_EXTENSIONS: files.append(public_url(category, path)) return sorted(files, key=str.lower) def main() -> None: SOUND_ROOT.mkdir(parents=True, exist_ok=True) data = { "generated_at": datetime.now(timezone.utc).isoformat(), "base_url": BASE_URL, "categories": CATEGORIES, } counts = {} for category in CATEGORIES: entries = collect_category(category) data[category] = entries counts[category] = len(entries) data["counts"] = counts tmp = OUTPUT_FILE.with_suffix(".json.tmp") tmp.write_text(json.dumps(data, indent=2, ensure_ascii=False), encoding="utf-8") tmp.replace(OUTPUT_FILE) print(f"Wrote {OUTPUT_FILE}") print(json.dumps(counts, ensure_ascii=False)) if __name__ == "__main__": main()