fix(import): treat cd1/cd2 folders as one audiobook
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import importlib
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
@@ -214,8 +215,9 @@ def test_scan_rel_dir_and_request_update(client):
|
||||
for i in range(2):
|
||||
(nested / f"t{i}.mp3").write_bytes(b"")
|
||||
item = client.get("/api/import/scan").json()["items"][0]
|
||||
assert item["name"] == "CD1"
|
||||
assert item["rel_dir"] == "Sammlung/Sonderfolgen"
|
||||
# a disc subfolder is folded into its parent, which carries the title
|
||||
assert item["name"] == "Sonderfolgen"
|
||||
assert item["rel_dir"] == "Sammlung"
|
||||
|
||||
req = client.post("/api/requests", json={"library_id": lib_id, "title": "X"}).json()
|
||||
updated = client.put(f"/api/requests/{req['id']}", json={
|
||||
@@ -264,3 +266,48 @@ def test_retag_after_update(client):
|
||||
assert str(tags["TXXX:SERIES"]) == "Rowling Kinderbücher"
|
||||
assert str(tags["TXXX:SERIES-PART"]) == "2"
|
||||
assert str(tags["TCOM"]) == "Ben Becker"
|
||||
|
||||
|
||||
def test_multi_disc_folder_is_one_audiobook(client):
|
||||
root = client.tmp_path / "library" / "dr3i"
|
||||
lib_id = client.post("/api/libraries", json={
|
||||
"name": "DR3i", "media_type": "audiobook", "root_path": str(root),
|
||||
"folder_template": "{Title}", "file_template": "{Title}",
|
||||
}).json()["id"]
|
||||
req_id = client.post("/api/requests", json={
|
||||
"library_id": lib_id, "title": "Die dr3i - Böses Erwachen",
|
||||
}).json()["id"]
|
||||
|
||||
folder = client.downloads / "DiE DR3i - Boeses Erwachen"
|
||||
for disc, tracks in (("CD 1", 3), ("CD2", 2)):
|
||||
d = folder / disc
|
||||
d.mkdir(parents=True)
|
||||
for i in range(1, tracks + 1):
|
||||
(d / f"Track {i}.mp3").write_bytes(b"")
|
||||
|
||||
items = client.get("/api/import/scan").json()["items"]
|
||||
assert len(items) == 1
|
||||
item = items[0]
|
||||
assert item["name"] == "DiE DR3i - Boeses Erwachen"
|
||||
assert item["is_dir"] and len(item["files"]) == 5
|
||||
# discs in order, tracks naturally sorted within a disc
|
||||
assert [Path(f).parent.name for f in item["files"]] == ["CD 1"] * 3 + ["CD2"] * 2
|
||||
assert item["suggested_request_id"] == req_id
|
||||
|
||||
res = client.post("/api/import", json={"items": [{
|
||||
"path": item["path"], "is_dir": True, "files": item["files"],
|
||||
"request_id": req_id,
|
||||
}]}).json()["results"][0]
|
||||
assert res["ok"], res
|
||||
dest = sorted(p.name for p in Path(res["dest"]).iterdir())
|
||||
assert dest == [f"Die dr3i - Böses Erwachen - Part 0{i}.mp3" for i in range(1, 6)]
|
||||
assert not folder.exists()
|
||||
|
||||
|
||||
def test_natural_track_order_in_flat_folder(client):
|
||||
folder = client.downloads / "Folge 12"
|
||||
folder.mkdir(parents=True)
|
||||
for i in (1, 2, 10):
|
||||
(folder / f"track{i}.mp3").write_bytes(b"")
|
||||
item = client.get("/api/import/scan").json()["items"][0]
|
||||
assert [Path(f).name for f in item["files"]] == ["track1.mp3", "track2.mp3", "track10.mp3"]
|
||||
|
||||
@@ -47,3 +47,26 @@ def test_volume_number_must_match():
|
||||
"media_type": "audiobook", "is_dir": False, "files": ["/d/f.mp3"]}]
|
||||
out = best_matches(items, [r1, r123])
|
||||
assert out[0]["suggested_request_id"] == 2
|
||||
|
||||
|
||||
def test_leetspeak_title_matches():
|
||||
assert normalize("DiE DR3i - Folge 03") == "die drei folge 03"
|
||||
# digits at a word edge stay put, they carry the episode number
|
||||
assert normalize("Folge03 v2 [m4b]") == "folge03"
|
||||
|
||||
r = req(1, "Die dr3i - Böses Erwachen", media_type="audiobook")
|
||||
r.volume = 2
|
||||
items = [{"path": "/d/x", "name": "Die drei 02 - Boeses Erwachen",
|
||||
"media_type": "audiobook", "is_dir": True, "files": ["/d/x/a.mp3"]}]
|
||||
out = best_matches(items, [r])
|
||||
assert out[0]["suggested_request_id"] == 1
|
||||
|
||||
|
||||
def test_digit_inside_word_is_not_a_volume():
|
||||
from wordarr.importer.matcher import score
|
||||
r = req(1, "Die dr3i - Folge 5", media_type="audiobook")
|
||||
r.volume = 5
|
||||
# "dr3i" must not contribute a "3" that satisfies the volume check
|
||||
r3 = req(2, "Die dr3i - Folge 3", media_type="audiobook")
|
||||
r3.volume = 3
|
||||
assert score("DiE DR3i - 05 - Der Fall", r) > score("DiE DR3i - 05 - Der Fall", r3)
|
||||
|
||||
Reference in New Issue
Block a user