fixed omnibus for audio books

This commit is contained in:
2026-06-10 16:33:16 -04:00
parent 62483e7894
commit c25f973d4a
3 changed files with 41 additions and 2 deletions
+17 -1
View File
@@ -44,6 +44,7 @@ class ConversionConfig:
dry_run: bool dry_run: bool
overwrite: bool overwrite: bool
work_directory_name: str = ".audible_convert" work_directory_name: str = ".audible_convert"
dry_run_directory_name: str = "dry-run"
temp_directory_name: str = "tmp" temp_directory_name: str = "tmp"
log_directory_name: str = "logs" log_directory_name: str = "logs"
review_directory_name: str = "review" review_directory_name: str = "review"
@@ -73,7 +74,10 @@ def main(
input_directory: Annotated[Path, typer.Argument(help="Directory audible-cli downloads AAX files into.")], input_directory: Annotated[Path, typer.Argument(help="Directory audible-cli downloads AAX files into.")],
output_directory: Annotated[Path, typer.Argument(help="Audiobook output directory.")], output_directory: Annotated[Path, typer.Argument(help="Audiobook output directory.")],
*, *,
dry_run: Annotated[bool, typer.Option("--dry-run", help="Print planned output files without converting.")] = False, dry_run: Annotated[
bool,
typer.Option("--dry-run", help="Print planned output files and write marker files without converting."),
] = False,
overwrite: Annotated[bool, typer.Option("--overwrite", help="Overwrite existing M4B files.")] = False, overwrite: Annotated[bool, typer.Option("--overwrite", help="Overwrite existing M4B files.")] = False,
) -> None: ) -> None:
"""Convert AAX files from a download directory into M4B files.""" """Convert AAX files from a download directory into M4B files."""
@@ -271,6 +275,18 @@ def dry_run_aax_file_with_agent(
) )
typer.echo(f"{aax_file} -> REVIEW {review_file}") typer.echo(f"{aax_file} -> REVIEW {review_file}")
else: else:
stem = output_stem(metadata)
dry_run_file = (
config.resolved_output / config.work_directory_name / config.dry_run_directory_name / stem / f"{stem}.m4b"
)
dry_run_file.parent.mkdir(parents=True, exist_ok=True)
dry_run_file.write_text(f"{destination}\n", encoding="utf-8")
write_agent_log(
log_file,
"dry_run_file_written",
destination=str(destination),
path=str(dry_run_file),
)
typer.echo(f"{aax_file} -> {destination}") typer.echo(f"{aax_file} -> {destination}")
+6
View File
@@ -468,6 +468,12 @@ Rules:
- title must be a canonical title slug using lower-case words separated by hyphens. - title must be a canonical title slug using lower-case words separated by hyphens.
- Use series_id null and series_index 0 for standalone books. - Use series_id null and series_index 0 for standalone books.
- If you use a series_id, series_index must be an integer greater than or equal to 1. - If you use a series_id, series_index must be an integer greater than or equal to 1.
- Detect omnibus or box-set editions that contain multiple numbered novels, books, or novellas.
- For an omnibus, make a best-effort range from the filename, tags, and catalog rows. Keep series_index as the
first covered book number and include the range in the title when the source title includes it, for example
books-1-3.
- Be careful with omnibuses of novels or novellas later published as one book: keep the omnibus as the audiobook's
book record unless catalog rows clearly identify a better match.
- Do not create publisher collections or author collections as series unless the book metadata clearly gives a - Do not create publisher collections or author collections as series unless the book metadata clearly gives a
numbered series. numbered series.
- Series belong to authors. Use a series_id only when it belongs to the selected author_id. - Series belong to authors. Use a series_id only when it belongs to the selected author_id.
+18 -1
View File
@@ -190,6 +190,14 @@ def test_write_agent_log_serializes_metadata_as_json_object(tmp_path) -> None:
assert record["path"] == str(tmp_path) assert record["path"] == str(tmp_path)
def test_system_prompt_instructs_agent_to_detect_omnibuses() -> None:
prompt = metadata_agent.system_prompt()
assert "Detect omnibus or box-set editions" in prompt
assert "books-1-3" in prompt
assert "Keep series_index as the" in prompt
def test_standard_book_metadata_accepts_valid_tool_output(tmp_path, monkeypatch, audiobook_engine) -> None: def test_standard_book_metadata_accepts_valid_tool_output(tmp_path, monkeypatch, audiobook_engine) -> None:
install_fake_ollama( install_fake_ollama(
monkeypatch, monkeypatch,
@@ -928,7 +936,16 @@ def test_main_dry_run_prints_outputs_without_converting(tmp_path, monkeypatch, c
assert calls == [] assert calls == []
assert capsys.readouterr().out == ( assert capsys.readouterr().out == (
f"{source} -> " f"{source} -> {output_directory / 'charles_lamb-alice_01-alice' / 'charles_lamb-alice_01-alice.m4b'}\n"
)
dry_run_file = (
output_directory
/ ".audible_convert"
/ "dry-run"
/ "charles_lamb-alice_01-alice"
/ "charles_lamb-alice_01-alice.m4b"
)
assert dry_run_file.read_text(encoding="utf-8") == (
f"{output_directory / 'charles_lamb-alice_01-alice' / 'charles_lamb-alice_01-alice.m4b'}\n" f"{output_directory / 'charles_lamb-alice_01-alice' / 'charles_lamb-alice_01-alice.m4b'}\n"
) )
assert (output_directory / ".audible_convert" / "logs").is_dir() assert (output_directory / ".audible_convert" / "logs").is_dir()