feat: add week 3 audio and timeline enhancements

This commit is contained in:
2026-04-18 22:10:48 +08:00
parent 4d54c144a8
commit 70efaf3ccf
20 changed files with 606 additions and 56 deletions

View File

@@ -2,11 +2,23 @@
from __future__ import annotations
from dataclasses import dataclass
from datetime import datetime, timezone
from pathlib import Path
from app.core.config import settings
@dataclass(frozen=True)
class AudioCacheMetadata:
"""Metadata about one cached story audio file."""
exists: bool
path: str | None = None
size_bytes: int | None = None
updated_at: datetime | None = None
def build_story_audio_path(story_id: int) -> str:
"""Build the cache path for a story audio file."""
@@ -25,6 +37,39 @@ def read_audio_cache(audio_path: str) -> bytes:
return Path(audio_path).read_bytes()
def get_audio_cache_metadata(audio_path: str | None) -> AudioCacheMetadata:
"""Return cache metadata without reading the audio bytes."""
if not audio_path:
return AudioCacheMetadata(exists=False)
path = Path(audio_path)
if not path.is_file():
return AudioCacheMetadata(exists=False, path=str(path))
stat = path.stat()
return AudioCacheMetadata(
exists=True,
path=str(path),
size_bytes=stat.st_size,
updated_at=datetime.fromtimestamp(stat.st_mtime, tz=timezone.utc),
)
def delete_audio_cache(audio_path: str | None) -> bool:
"""Delete cached story audio if it exists."""
if not audio_path:
return False
path = Path(audio_path)
if not path.is_file():
return False
path.unlink()
return True
def write_story_audio_cache(story_id: int, audio_data: bytes) -> str:
"""Persist story audio and return the saved file path."""