| """Build the playable URL for a recording, for local serving or archive.org streaming. |
| |
| - ``local`` mode -> ``/audio/<encoded-source_file>`` (served by StaticFiles from disk). |
| - ``archive`` mode -> ``https://archive.org/download/<item>/<path>`` where the local |
| ``source_file`` (whose ``%5C`` are path separators) is remapped: drop the configured |
| local prefix, prepend the configured archive path prefix. Verified to range-seek (206). |
| """ |
| from __future__ import annotations |
|
|
| from typing import Optional |
| from urllib.parse import quote |
|
|
| from app.config import Config, get_config |
|
|
|
|
| def _archive_url(source_file: str, arch: dict) -> str: |
| rel = source_file.replace("%5C", "/") |
| prefix = (arch.get("strip_local_prefix") or "").strip("/") |
| if prefix and rel.startswith(prefix + "/"): |
| rel = rel[len(prefix) + 1:] |
| path_prefix = (arch.get("archive_path_prefix") or "").strip("/") |
| path = f"{path_prefix}/{rel}" if path_prefix else rel |
| base = (arch.get("base_url") or "https://archive.org/download").rstrip("/") |
| item = arch.get("item_id", "") |
| parts = ([item] if item else []) + path.split("/") |
| return base + "/" + "/".join(quote(seg) for seg in parts) |
|
|
|
|
| def audio_url(source_file: str, cfg: Optional[Config] = None) -> str: |
| cfg = cfg or get_config() |
| audio = cfg.get("audio", {}) or {} |
| if audio.get("mode", "local") == "archive": |
| return _archive_url(source_file, audio.get("archive", {}) or {}) |
| route = cfg.server["audio_route"] |
| encoded = "/".join(quote(seg) for seg in source_file.split("/")) |
| return f"{route}/{encoded}" |
|
|