From 954821ccc306ca8ba80d7a32b884abf57938e13f Mon Sep 17 00:00:00 2001 From: MirSob Date: Sun, 26 Apr 2026 00:37:20 +0200 Subject: [PATCH] first commit --- .codex | 0 .vscode/settings.json | 6 + .../generate_abs_mock_report.cpython-311.pyc | Bin 0 -> 53739 bytes data/verified_author_overrides.tsv | 58 ++ reports/audiobookshelf_mock_paths.txt | 846 +++++++++++++++++ reports/audiobookshelf_mock_report.tsv | 847 ++++++++++++++++++ ...obookshelf_mock_report_audiobooki_nowe.tsv | 49 + reports/custom_audibooki-new.tsv | 49 + ...t_generate_abs_mock_report.cpython-311.pyc | Bin 0 -> 6744 bytes tests/test_generate_abs_mock_report.py | 88 ++ 10 files changed, 1943 insertions(+) create mode 100644 .codex create mode 100644 .vscode/settings.json create mode 100644 __pycache__/generate_abs_mock_report.cpython-311.pyc create mode 100644 data/verified_author_overrides.tsv create mode 100644 reports/audiobookshelf_mock_paths.txt create mode 100644 reports/audiobookshelf_mock_report.tsv create mode 100644 reports/audiobookshelf_mock_report_audiobooki_nowe.tsv create mode 100644 reports/custom_audibooki-new.tsv create mode 100644 tests/__pycache__/test_generate_abs_mock_report.cpython-311.pyc create mode 100644 tests/test_generate_abs_mock_report.py diff --git a/.codex b/.codex new file mode 100644 index 0000000..e69de29 diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7c9f10c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "gitea.instanceURL": "https://gitea.sic.pl", + "gitea.owner": "ms", + "gitea.repo": "audiobookshelf", + "gitea.token": "4352ab238941c7d48b3f2c2b07828e5f84e8acdf" +} \ No newline at end of file diff --git a/__pycache__/generate_abs_mock_report.cpython-311.pyc b/__pycache__/generate_abs_mock_report.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c4f69ec0b168c1895e179bafe5e9929343f19c4e GIT binary patch literal 53739 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 literal 0 HcmV?d00001 diff --git a/tests/test_generate_abs_mock_report.py b/tests/test_generate_abs_mock_report.py new file mode 100644 index 0000000..2769a8a --- /dev/null +++ b/tests/test_generate_abs_mock_report.py @@ -0,0 +1,88 @@ +import tempfile +import unittest +from pathlib import Path + +import generate_abs_mock_report as report + + +class InferBookTests(unittest.TestCase): + def infer_row(self, relative_book_path: str, filenames: list[str]) -> dict[str, str]: + with tempfile.TemporaryDirectory() as tmpdir: + library_root = Path(tmpdir) / "library" + book_root = library_root / relative_book_path + book_root.mkdir(parents=True) + + for filename in filenames: + (book_root / filename).write_bytes(b"") + + audio_files = sorted(book_root.glob("*.mp3")) + return report.infer_book(book_root, library_root, audio_files) + + def test_splits_author_from_title_context_in_folder_name(self) -> None: + row = self.infer_row( + "Biblioteka 2024/Bartos_Jolanta_Krzyk_Ciszy", + ["001_Krzyk_ciszy.mp3", "002_Krzyk_ciszy.mp3"], + ) + + self.assertEqual(report.signature(row["title"]), "krzyk ciszy") + self.assertNotIn("krzyk", report.signature(row["author"])) + self.assertTrue(row["proposed_abs_path"].endswith("/Krzyk Ciszy")) + + def test_normalizes_author_order_from_current_directory(self) -> None: + row = self.infer_row( + "Ahnhem Stefan/Stefan Ahnhem - Kain I Abel", + ["001_Kain_I_Abel.mp3"], + ) + + self.assertEqual(row["author"], "Stefan Ahnhem") + self.assertTrue(row["proposed_abs_path"].startswith("Stefan Ahnhem/")) + + def test_normalizes_author_order_from_audio_filename(self) -> None: + row = self.infer_row( + "Archer_Jeffrey/Kain_I_Abel", + [ + "001_Jeffrey_Archer_-_Kain_I_Abel.mp3", + "002_Jeffrey_Archer_-_Kain_I_Abel.mp3", + ], + ) + + self.assertEqual(row["author"], "Jeffrey Archer") + self.assertTrue(row["proposed_abs_path"].startswith("Jeffrey Archer/")) + + def test_handles_hyphenated_surname_in_mixed_folder_name(self) -> None: + row = self.infer_row( + "Adler-Olsen/Jussi Adler-Olsen - Departament Q tom 1-8/Adler-Olsen Jussi - Departament Q 04. Kartoteka 64", + ["01 - Kartoteka_64.mp3"], + ) + + self.assertEqual(row["author"], "Jussi Adler-Olsen") + self.assertEqual(row["series"], "Departament Q") + self.assertEqual(row["sequence"], "04") + self.assertEqual(row["title"], "Kartoteka 64") + self.assertTrue(row["proposed_abs_path"].startswith("Jussi Adler-Olsen/")) + + def test_extracts_series_from_nested_mixed_folder(self) -> None: + row = self.infer_row( + "Adler-Olsen/Jussi Adler-Olsen - Departament Q tom 1-8/Adler-Olsen Jussi - Departament Q Tom 01 Kobieta w klatce/Adler - Olsen Jussi - Kobieta w klatce (czyta Janusz Zadura)", + ["01.mp3"], + ) + + self.assertEqual(row["author"], "Jussi Adler-Olsen") + self.assertEqual(row["series"], "Departament Q") + self.assertEqual(row["sequence"], "01") + self.assertEqual(row["title"], "Kobieta w klatce") + + def test_extracts_series_from_inline_series_number_title(self) -> None: + row = self.infer_row( + "Adler-Olsen/Jussi Adler-Olsen - Departament Q tom 1-8/Adler-Olsen Jussi - Departament Q 05 Pogrzebany", + ["01.mp3"], + ) + + self.assertEqual(row["author"], "Jussi Adler-Olsen") + self.assertEqual(row["series"], "Departament Q") + self.assertEqual(row["sequence"], "05") + self.assertEqual(row["title"], "Pogrzebany") + + +if __name__ == "__main__": + unittest.main()