feat(video_analysis): download_video.py with TDD (5 tests)

This commit is contained in:
ed
2026-06-21 15:32:46 -04:00
parent 94f4a4eee9
commit 45a5e81406
2 changed files with 125 additions and 0 deletions
+75
View File
@@ -0,0 +1,75 @@
from __future__ import annotations
import subprocess
from dataclasses import dataclass
from pathlib import Path
from typing import Any
from scripts.video_analysis.error_types import ErrorInfo, make_error
@dataclass
class _Ok:
value: Any
def is_ok(self) -> bool:
return True
def is_err(self) -> bool:
return False
@dataclass
class _Err:
err: ErrorInfo
def is_ok(self) -> bool:
return False
def is_err(self) -> bool:
return True
def ok(value: Any) -> _Ok:
return _Ok(value)
def err(error: ErrorInfo) -> _Err:
return _Err(error)
def validate_output_path(path: Path) -> _Ok | _Err:
if path.exists() and path.is_dir():
return err(make_error("OutputIsDirectory", "validate_output_path", str(path)))
path.parent.mkdir(parents=True, exist_ok=True)
return ok(path)
def build_ydl_args(url: str, output: Path) -> list[str]:
return [
"yt-dlp",
"--format", "bestvideo[ext=mp4]/best",
"--output", str(output),
"--no-warnings",
"--quiet",
url,
]
def download_video(url: str, output: Path) -> _Ok | _Err:
validated = validate_output_path(output)
if validated.is_err():
return validated
completed = subprocess.run(
build_ydl_args(url, output),
capture_output=True,
text=True,
)
log_path = output.with_suffix(".log")
log_path.write_text(
f"# yt-dlp log\n# url: {url}\n# output: {output}\n# returncode: {completed.returncode}\n\nstdout:\n{completed.stdout}\n\nstderr:\n{completed.stderr}\n",
encoding="utf-8",
)
if completed.returncode != 0:
return err(make_error("YtdlpError", "download_video", completed.stderr[:500]))
return ok({"output": str(output), "log": str(log_path), "returncode": completed.returncode})