File size: 1,587 Bytes
4cdc522
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
"""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}"