add(core): re-apply the naming scheme to imported titles
This commit is contained in:
@@ -687,3 +687,136 @@ def test_search_passes_language_to_the_provider(client, monkeypatch):
|
||||
}).json()
|
||||
assert seen == {"query": "Game of Thrones", "language": "english"}
|
||||
assert res[0]["language"] == "english"
|
||||
|
||||
|
||||
def test_folder_of_separate_books_is_flagged(client):
|
||||
"""One book per file (a series bought as single titles) still scans as one
|
||||
entry - but gets flagged so the UI can offer to split it."""
|
||||
got = client.downloads / "George R. R. Martin" / "A Game of Thrones"
|
||||
got.mkdir(parents=True)
|
||||
for name in ("1 - A Game of Thrones- A Song of Ice and Fire, Book 1 (Unabridged)",
|
||||
"2 - A Clash of Kings- A Song of Ice and Fire, Book 2 (Unabridged)",
|
||||
"A - The World of Ice & Fire - The Untold History of Westeros"):
|
||||
with open(got / f"{name}.mp3", "wb") as f:
|
||||
f.truncate(700 * 1024 * 1024) # sparse, costs no disk space
|
||||
|
||||
chapters = client.downloads / "Ein Hoerbuch"
|
||||
chapters.mkdir()
|
||||
for i, title in enumerate(["Prolog", "Die Ankunft", "Das Ende"], 1):
|
||||
with open(chapters / f"{i:02d} - {title}.mp3", "wb") as f:
|
||||
f.truncate(25 * 1024 * 1024)
|
||||
|
||||
tracks = client.downloads / "Folge 100"
|
||||
tracks.mkdir()
|
||||
for i in (1, 2, 3):
|
||||
with open(tracks / f"{i:02d} Track.mp3", "wb") as f:
|
||||
f.truncate(200 * 1024 * 1024)
|
||||
|
||||
flags = {i["name"]: i["maybe_separate"]
|
||||
for i in client.get("/api/import/scan").json()["items"]}
|
||||
assert flags == {
|
||||
"A Game of Thrones": True, # different titles, each big enough
|
||||
"Ein Hoerbuch": False, # different titles, but chapter sized
|
||||
"Folge 100": False, # same name beyond the index
|
||||
}
|
||||
|
||||
|
||||
def test_split_dirs_still_lists_every_file(client):
|
||||
got = client.downloads / "A Game of Thrones"
|
||||
got.mkdir()
|
||||
for n in (1, 2, 3):
|
||||
(got / f"{n} - Book {n}.mp3").write_bytes(b"")
|
||||
items = client.get("/api/import/scan", params={"split_dirs": True}).json()["items"]
|
||||
assert len(items) == 3
|
||||
assert all(not i["is_dir"] for i in items)
|
||||
|
||||
|
||||
def test_relocate_after_fixing_the_series(client):
|
||||
"""Audible files Harry Potter under "Wizarding World"; after correcting the
|
||||
series the folder on disk should follow."""
|
||||
root = client.tmp_path / "library" / "english"
|
||||
lib_id = client.post("/api/libraries", json={
|
||||
"name": "english", "media_type": "audiobook", "root_path": str(root),
|
||||
"folder_template": "{Series}/{Title}", "file_template": "{Title}",
|
||||
}).json()["id"]
|
||||
req_id = client.post("/api/requests", json={
|
||||
"library_id": lib_id, "title": "Philosopher's Stone",
|
||||
"series": "Wizarding World", "volume": 1,
|
||||
}).json()["id"]
|
||||
|
||||
src = client.downloads / "hp1"
|
||||
src.mkdir()
|
||||
for i in (1, 2):
|
||||
(src / f"{i:02d}.mp3").write_bytes(b"")
|
||||
dest = client.post("/api/import", json={"items": [{
|
||||
"path": str(src), "is_dir": True,
|
||||
"files": [str(f) for f in sorted(src.iterdir())], "request_id": req_id,
|
||||
}]}).json()["results"][0]["dest"]
|
||||
assert Path(dest) == root / "Wizarding World" / "Philosopher's Stone"
|
||||
# a cover dropped next to the audio must survive the move
|
||||
(Path(dest) / "cover.jpg").write_bytes(b"")
|
||||
|
||||
client.put(f"/api/requests/{req_id}", json={
|
||||
"library_id": lib_id, "title": "Philosopher's Stone",
|
||||
"series": "Harry Potter", "volume": 1,
|
||||
})
|
||||
res = client.post(f"/api/requests/{req_id}/relocate").json()
|
||||
assert res["ok"] and res["moved"]
|
||||
new = root / "Harry Potter" / "Philosopher's Stone"
|
||||
assert Path(res["dest"]) == new
|
||||
assert sorted(p.name for p in new.iterdir()) == [
|
||||
"Philosopher's Stone - Part 01.mp3", "Philosopher's Stone - Part 02.mp3", "cover.jpg",
|
||||
]
|
||||
assert not (root / "Wizarding World").exists() # emptied parent is gone
|
||||
assert client.get("/api/requests", params={"status": "imported"}).json()[0][
|
||||
"imported_path"] == str(new)
|
||||
|
||||
|
||||
def test_relocate_is_a_no_op_when_nothing_changed(client):
|
||||
root = client.tmp_path / "library" / "l"
|
||||
lib_id = client.post("/api/libraries", json={
|
||||
"name": "L", "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": "Ein Buch"}).json()["id"]
|
||||
src = client.downloads / "buch"
|
||||
src.mkdir()
|
||||
for i in (1, 2):
|
||||
(src / f"{i:02d}.mp3").write_bytes(b"")
|
||||
client.post("/api/import", json={"items": [{
|
||||
"path": str(src), "is_dir": True,
|
||||
"files": [str(f) for f in sorted(src.iterdir())], "request_id": req_id,
|
||||
}]})
|
||||
res = client.post(f"/api/requests/{req_id}/relocate").json()
|
||||
assert res["ok"] and not res["moved"]
|
||||
assert sorted(p.name for p in (root / "Ein Buch").iterdir()) == [
|
||||
"Ein Buch - Part 01.mp3", "Ein Buch - Part 02.mp3",
|
||||
]
|
||||
|
||||
|
||||
def test_relocate_refuses_to_overwrite(client):
|
||||
root = client.tmp_path / "library" / "l"
|
||||
lib_id = client.post("/api/libraries", json={
|
||||
"name": "L", "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": "Erstes"}).json()["id"]
|
||||
src = client.downloads / "b"
|
||||
src.mkdir()
|
||||
(src / "01.mp3").write_bytes(b"")
|
||||
(src / "02.mp3").write_bytes(b"")
|
||||
client.post("/api/import", json={"items": [{
|
||||
"path": str(src), "is_dir": True,
|
||||
"files": [str(f) for f in sorted(src.iterdir())], "request_id": req_id,
|
||||
}]})
|
||||
occupied = root / "Zweites"
|
||||
occupied.mkdir(parents=True)
|
||||
(occupied / "fremd.mp3").write_bytes(b"")
|
||||
|
||||
client.put(f"/api/requests/{req_id}", json={"library_id": lib_id, "title": "Zweites"})
|
||||
res = client.post(f"/api/requests/{req_id}/relocate")
|
||||
assert res.status_code == 409
|
||||
assert (occupied / "fremd.mp3").exists()
|
||||
assert (root / "Erstes" / "Erstes - Part 01.mp3").exists()
|
||||
|
||||
Reference in New Issue
Block a user