[epub-tts] Add EPUB sample submodules and download entrypoints
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2025-2026 Renato Xavier da Silveira Rosa
|
||||
# See [LICENSE](./LICENSE) or [BSD-3-Clause-Clear](https://spdx.org/licenses/BSD-3-Clause-Clear.html)
|
||||
|
||||
"""Download EPUB sample files from a vendored samples repository and package them as EPUB archives."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import shutil
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from epub_tts.vendor_utils import get_repo_path
|
||||
|
||||
|
||||
def get_project_root() -> Path:
|
||||
return Path(__file__).resolve().parents[1].parent
|
||||
|
||||
|
||||
def get_temp_sample_root() -> Path:
|
||||
return get_project_root() / ".tmp-samples"
|
||||
|
||||
|
||||
def get_sample_directory(with_media_overlay: bool) -> Path:
|
||||
sample_name = "moby-dick-mo" if with_media_overlay else "moby-dick"
|
||||
sample_dir = get_repo_path("epub3-samples") / "30" / sample_name
|
||||
if not sample_dir.exists():
|
||||
raise FileNotFoundError(
|
||||
f"Sample directory not found: {sample_dir}. Ensure the epub3-samples submodule is initialized."
|
||||
)
|
||||
return sample_dir
|
||||
|
||||
|
||||
def get_minimal_sample_file() -> Path:
|
||||
sample_file = get_repo_path("sample-epub-minimal") / "minimal.epub"
|
||||
if not sample_file.exists():
|
||||
raise FileNotFoundError(
|
||||
f"Sample EPUB file not found: {sample_file}. Ensure the sample-epub-minimal submodule is initialized."
|
||||
)
|
||||
return sample_file
|
||||
|
||||
|
||||
def copy_sample_to_temp(sample_dir: Path) -> Path:
|
||||
temp_root = get_temp_sample_root()
|
||||
temp_root.mkdir(parents=True, exist_ok=True)
|
||||
dest_dir = temp_root / sample_dir.name
|
||||
if dest_dir.exists():
|
||||
shutil.rmtree(dest_dir)
|
||||
shutil.copytree(sample_dir, dest_dir)
|
||||
return dest_dir
|
||||
|
||||
|
||||
def copy_file_to_temp(sample_file: Path) -> Path:
|
||||
temp_root = get_temp_sample_root()
|
||||
temp_root.mkdir(parents=True, exist_ok=True)
|
||||
dest_file = temp_root / sample_file.name
|
||||
shutil.copy2(sample_file, dest_file)
|
||||
return dest_file
|
||||
|
||||
|
||||
def zip_sample_directory(sample_dir: Path, output_path: Path) -> Path:
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
if output_path.exists():
|
||||
output_path.unlink()
|
||||
|
||||
mimetype_file = sample_dir / "mimetype"
|
||||
with zipfile.ZipFile(output_path, mode="w", compression=zipfile.ZIP_DEFLATED) as archive:
|
||||
if mimetype_file.exists():
|
||||
archive.write(mimetype_file, "mimetype", compress_type=zipfile.ZIP_STORED)
|
||||
for path in sorted(sample_dir.rglob("*")):
|
||||
if path.is_file() and path != mimetype_file:
|
||||
archive.write(path, path.relative_to(sample_dir).as_posix())
|
||||
|
||||
return output_path
|
||||
|
||||
|
||||
def download_sample_moby_dick(
|
||||
output: Optional[str] = None,
|
||||
with_media_overlay: bool = False,
|
||||
) -> Path:
|
||||
sample_dir = get_sample_directory(with_media_overlay=with_media_overlay)
|
||||
temp_sample_dir = copy_sample_to_temp(sample_dir)
|
||||
default_output = get_temp_sample_root() / f"{sample_dir.name}.epub"
|
||||
output_path = Path(output) if output else default_output
|
||||
output_path = output_path.with_suffix(".epub")
|
||||
return zip_sample_directory(temp_sample_dir, output_path)
|
||||
|
||||
|
||||
def download_minimal_epub_sample(output: Optional[str] = None) -> Path:
|
||||
sample_file = get_minimal_sample_file()
|
||||
temp_sample_file = copy_file_to_temp(sample_file)
|
||||
default_output = get_temp_sample_root() / sample_file.name
|
||||
output_path = Path(output) if output else default_output
|
||||
output_path = output_path.with_suffix(".epub")
|
||||
if temp_sample_file != output_path:
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copy2(temp_sample_file, output_path)
|
||||
return output_path
|
||||
|
||||
|
||||
def main(argv: Optional[list[str]] = None) -> int:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Download the Moby Dick EPUB sample and package it as an EPUB file."
|
||||
)
|
||||
parser.add_argument(
|
||||
"-o",
|
||||
"--output",
|
||||
help="Output EPUB file path. Defaults to .tmp-samples/moby-dick.epub or .tmp-samples/moby-dick-mo.epub.",
|
||||
)
|
||||
args = parser.parse_args(argv)
|
||||
output_path = download_sample_moby_dick(
|
||||
output=args.output,
|
||||
with_media_overlay=False,
|
||||
)
|
||||
print(f"Created EPUB sample archive: {output_path}")
|
||||
return 0
|
||||
|
||||
|
||||
def main_with_media_overlay(argv: Optional[list[str]] = None) -> int:
|
||||
parser = argparse.ArgumentParser(
|
||||
description=(
|
||||
"Download the Moby Dick EPUB sample with media overlay and package it as an EPUB file."
|
||||
)
|
||||
)
|
||||
parser.add_argument(
|
||||
"-o",
|
||||
"--output",
|
||||
help="Output EPUB file path. Defaults to .tmp-samples/moby-dick-mo.epub.",
|
||||
)
|
||||
args = parser.parse_args(argv)
|
||||
output_path = download_sample_moby_dick(
|
||||
output=args.output,
|
||||
with_media_overlay=True,
|
||||
)
|
||||
print(f"Created EPUB sample archive: {output_path}")
|
||||
return 0
|
||||
|
||||
|
||||
def main_minimal_epub(argv: Optional[list[str]] = None) -> int:
|
||||
parser = argparse.ArgumentParser(
|
||||
description=(
|
||||
"Download the minimal EPUB sample and copy it to an EPUB file."
|
||||
)
|
||||
)
|
||||
parser.add_argument(
|
||||
"-o",
|
||||
"--output",
|
||||
help="Output EPUB file path. Defaults to .tmp-samples/minimal.epub.",
|
||||
)
|
||||
args = parser.parse_args(argv)
|
||||
output_path = download_minimal_epub_sample(output=args.output)
|
||||
print(f"Created minimal EPUB sample archive: {output_path}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user