mirror of
https://github.com/calibrain/shelfmark.git
synced 2026-11-14 16:48:24 +00:00
- **Open Library (#1451): keep the work unless the search matched a translation.** Open Library shows an English edition whenever one matches the query. So "Mistborn" returned the 2023 "Mistborn" reissue (2023) instead of "The Final Empire" (2001), and "Children of Dune" returned "Children of Dune (Dune Chronicles, Book 3)" (1987). The matched edition's title, ISBNs, cover, language and year now win only when the edition is in another language and the query doesn't name the work's own title. Checked against live Open Library: "Children of Dune" and "Mistborn" give the v1.4.0 results again, and "Der Weg der Könige" and "Kinder des Nebels" still return the German editions. - **Google Books (#1434): the ISBN cache decorator is back on `search_by_isbn`.** It had moved to the new `search_paginated`. Failed searches were cached as empty pages, and ISBN lookups lost their cache. - **Notifications: Test notification shows the plugin's failure reason again.** Apprise 2 delivers on its own worker threads, even for a single service when that service has a deadline. `_AppriseLogCapture` filtered records by thread id and dropped all of them, so the UI only said "json: delivery failed". Apprise runs those workers in a copy of the caller's context, so the capture now filters on a context variable. That still keeps concurrent dispatches apart. `AppriseAsset(async_mode=False)` would not fix this, because the sequential path also uses the worker pool when a service has a deadline. - **Activity: `activity_update` no longer sends the raw task id to non-admins.** The owner's `user_<id>` room got the raw task id. For a request-linked download that id can hold a private tracker's passkey. It now goes through `viewer_download_id`, the same mapping `/api/status` and `download_progress` use. The admins room still gets the raw id. - **SearchBar (#1476): Escape and an outside click close the homepage's inline options panel again,** as they did in v1.4.0. - **genDebug.sh: packages are listed through `importlib.metadata`,** since #1404 removed pip from the image. The script also now redacts: - `PROWLARR_MAM_ID` - `user:pass@` credentials in URLs (proxies), in both the environment and the config files - notification route URLs, which carry their service's token (Telegram, Discord and others) - `make python-checks`, `make python-test`, `make frontend-checks` and `make frontend-test` pass on top of current `main`. - New tests cover: - Open Library edition selection - Google Books caching - log capture against a real Apprise 2 delivery to a local server that answers 500, plus a concurrent dispatch on another thread - the `activity_update` payload sent to each room - genDebug redaction and the package listing Each one fails on the old code. - I checked the SearchBar fix in the running app, because the frontend has no DOM test setup: Escape closes the panel, an outside click closes it, and a click inside keeps it open. - I ran the genDebug redaction under GNU sed (Debian image) and BSD sed. The package listing ran in the pip-less image.
297 lines
11 KiB
Python
297 lines
11 KiB
Python
from shelfmark.metadata_providers.openlibrary import OpenLibraryProvider
|
|
|
|
|
|
class TestOpenLibraryParseSearchDoc:
|
|
def test_prefers_matched_edition_over_work_title(self):
|
|
"""Searching a translated title shouldn't surface the work's original title.
|
|
|
|
Open Library groups every edition (including translations) under one work
|
|
record, and reports the work's own `title` - usually the original-language
|
|
edition - regardless of which translation's text actually matched the query.
|
|
Querying "Der Weg der Könige" matches the German edition of Brandon
|
|
Sanderson's "The Way of Kings" by title, but the work-level title still says
|
|
"The Way of Kings". The nested `editions` block carries the edition whose own
|
|
fields satisfied the query, so that edition's title/isbn/cover/language
|
|
should win - otherwise both the displayed result and the downstream release
|
|
search (which uses `search_title`, see search_plan._pick_search_title) stay
|
|
in English even though the user searched for the German edition by name.
|
|
"""
|
|
provider = OpenLibraryProvider()
|
|
|
|
result = provider._parse_search_doc(
|
|
{
|
|
"key": "/works/OL15358691W",
|
|
"title": "The Way of Kings",
|
|
"author_name": ["Brandon Sanderson"],
|
|
"isbn": ["9780765326355", "0765326353"],
|
|
"cover_i": 14658316,
|
|
"language": ["eng"],
|
|
"editions": {
|
|
"docs": [
|
|
{
|
|
"key": "/books/OL32771812M",
|
|
"title": "Der Weg der Könige",
|
|
"cover_i": 14658425,
|
|
"language": ["ger"],
|
|
"isbn": ["9783453317109", "3453317106"],
|
|
"publish_year": [2015],
|
|
}
|
|
]
|
|
},
|
|
"first_publish_year": 2010,
|
|
}
|
|
)
|
|
|
|
assert result is not None
|
|
assert result.title == "Der Weg der Könige"
|
|
assert result.publish_year == 2015
|
|
assert result.search_title == "Der Weg der Könige"
|
|
assert result.language == "ger"
|
|
assert result.isbn_13 == "9783453317109"
|
|
assert result.isbn_10 == "3453317106"
|
|
assert result.cover_url == "https://covers.openlibrary.org/b/id/14658425-L.jpg"
|
|
|
|
def test_keeps_work_year_when_matched_edition_has_none(self):
|
|
provider = OpenLibraryProvider()
|
|
|
|
result = provider._parse_search_doc(
|
|
{
|
|
"key": "/works/OL15358691W",
|
|
"title": "The Way of Kings",
|
|
"author_name": ["Brandon Sanderson"],
|
|
"first_publish_year": 2010,
|
|
"editions": {
|
|
"docs": [
|
|
{
|
|
"key": "/books/OL32771812M",
|
|
"title": "Der Weg der Könige",
|
|
"language": ["ger"],
|
|
}
|
|
]
|
|
},
|
|
}
|
|
)
|
|
|
|
assert result is not None
|
|
assert result.title == "Der Weg der Könige"
|
|
assert result.publish_year == 2010
|
|
|
|
def test_falls_back_to_work_title_without_a_matched_edition(self):
|
|
provider = OpenLibraryProvider()
|
|
|
|
result = provider._parse_search_doc(
|
|
{
|
|
"key": "/works/OL15358691W",
|
|
"title": "The Way of Kings",
|
|
"author_name": ["Brandon Sanderson"],
|
|
"isbn": ["9780765326355"],
|
|
"cover_i": 14658316,
|
|
"language": ["eng"],
|
|
}
|
|
)
|
|
|
|
assert result is not None
|
|
assert result.title == "The Way of Kings"
|
|
assert result.search_title is None
|
|
assert result.language == "eng"
|
|
|
|
def test_ignores_matched_edition_identical_to_work_title(self):
|
|
"""An edition that happens to share the work's title adds nothing new."""
|
|
provider = OpenLibraryProvider()
|
|
|
|
result = provider._parse_search_doc(
|
|
{
|
|
"key": "/works/OL15358691W",
|
|
"title": "The Way of Kings",
|
|
"author_name": ["Brandon Sanderson"],
|
|
"isbn": ["9780765326355"],
|
|
"cover_i": 14658316,
|
|
"language": ["eng"],
|
|
"editions": {
|
|
"docs": [
|
|
{
|
|
"key": "/books/OL1M",
|
|
"title": "The Way of Kings",
|
|
"language": ["eng"],
|
|
}
|
|
]
|
|
},
|
|
}
|
|
)
|
|
|
|
assert result is not None
|
|
assert result.search_title is None
|
|
assert result.isbn_13 == "9780765326355"
|
|
|
|
def test_keeps_work_for_an_english_edition_with_another_title(self):
|
|
"""Open Library shows an English edition whenever one matches the query.
|
|
|
|
Searching "Mistborn" picks the 2023 "Mistborn" reissue of "The Final
|
|
Empire", which is the same book under a different English title, so the
|
|
result keeps the work's title, ISBNs and first publication year.
|
|
"""
|
|
provider = OpenLibraryProvider()
|
|
|
|
result = provider._parse_search_doc(
|
|
{
|
|
"key": "/works/OL5738148W",
|
|
"title": "The Final Empire",
|
|
"author_name": ["Brandon Sanderson"],
|
|
"isbn": ["9780765311788"],
|
|
"cover_i": 14658160,
|
|
"language": ["fre", "ger", "eng"],
|
|
"first_publish_year": 2001,
|
|
"editions": {
|
|
"docs": [
|
|
{
|
|
"key": "/books/OL62594701M",
|
|
"title": "Mistborn",
|
|
"language": ["eng"],
|
|
"isbn": ["9781250318541"],
|
|
"cover_i": 1,
|
|
"publish_year": [2023],
|
|
}
|
|
]
|
|
},
|
|
},
|
|
"Mistborn",
|
|
)
|
|
|
|
assert result is not None
|
|
assert result.title == "The Final Empire"
|
|
assert result.search_title is None
|
|
assert result.publish_year == 2001
|
|
assert result.isbn_13 == "9780765311788"
|
|
assert result.cover_url == "https://covers.openlibrary.org/b/id/14658160-L.jpg"
|
|
|
|
def test_keeps_work_for_a_subtitled_reprint(self):
|
|
provider = OpenLibraryProvider()
|
|
|
|
result = provider._parse_search_doc(
|
|
{
|
|
"key": "/works/OL893516W",
|
|
"title": "Children of Dune",
|
|
"author_name": ["Frank Herbert"],
|
|
"first_publish_year": 1976,
|
|
"editions": {
|
|
"docs": [
|
|
{
|
|
"key": "/books/OL1M",
|
|
"title": "Children of Dune (Dune Chronicles, Book 3)",
|
|
"language": ["eng"],
|
|
"publish_year": [1987],
|
|
}
|
|
]
|
|
},
|
|
},
|
|
"Children of Dune",
|
|
)
|
|
|
|
assert result is not None
|
|
assert result.title == "Children of Dune"
|
|
assert result.search_title is None
|
|
assert result.publish_year == 1976
|
|
|
|
def test_keeps_work_when_the_query_names_the_work(self):
|
|
"""A `lang` preference shows a translation even for the work's own title."""
|
|
provider = OpenLibraryProvider()
|
|
|
|
result = provider._parse_search_doc(
|
|
{
|
|
"key": "/works/OL893516W",
|
|
"title": "Children of Dune",
|
|
"author_name": ["Frank Herbert"],
|
|
"first_publish_year": 1976,
|
|
"editions": {
|
|
"docs": [
|
|
{
|
|
"key": "/books/OL2M",
|
|
"title": "Dune-Zyklus",
|
|
"language": ["ger"],
|
|
"publish_year": [1985],
|
|
}
|
|
]
|
|
},
|
|
},
|
|
"children of dune",
|
|
)
|
|
|
|
assert result is not None
|
|
assert result.title == "Children of Dune"
|
|
assert result.search_title is None
|
|
assert result.publish_year == 1976
|
|
|
|
def test_keeps_work_for_an_edition_of_unknown_language(self):
|
|
provider = OpenLibraryProvider()
|
|
|
|
result = provider._parse_search_doc(
|
|
{
|
|
"key": "/works/OL5738148W",
|
|
"title": "The Final Empire",
|
|
"author_name": ["Brandon Sanderson"],
|
|
"first_publish_year": 2001,
|
|
"editions": {
|
|
"docs": [{"key": "/books/OL3M", "title": "Mistborn", "publish_year": [2023]}]
|
|
},
|
|
},
|
|
"Mistborn",
|
|
)
|
|
|
|
assert result is not None
|
|
assert result.title == "The Final Empire"
|
|
assert result.publish_year == 2001
|
|
|
|
def test_ignores_edition_differing_only_in_case_and_accents(self):
|
|
provider = OpenLibraryProvider()
|
|
|
|
result = provider._parse_search_doc(
|
|
{
|
|
"key": "/works/OL1W",
|
|
"title": "L’étranger",
|
|
"author_name": ["Albert Camus"],
|
|
"first_publish_year": 1942,
|
|
"editions": {
|
|
"docs": [
|
|
{
|
|
"key": "/books/OL4M",
|
|
"title": "L'Etranger",
|
|
"language": ["fre"],
|
|
"publish_year": [1995],
|
|
}
|
|
]
|
|
},
|
|
}
|
|
)
|
|
|
|
assert result is not None
|
|
assert result.title == "L’étranger"
|
|
assert result.publish_year == 1942
|
|
|
|
def test_prefers_translation_matched_by_query(self):
|
|
provider = OpenLibraryProvider()
|
|
|
|
result = provider._parse_search_doc(
|
|
{
|
|
"key": "/works/OL5738148W",
|
|
"title": "The Final Empire",
|
|
"author_name": ["Brandon Sanderson"],
|
|
"first_publish_year": 2001,
|
|
"editions": {
|
|
"docs": [
|
|
{
|
|
"key": "/books/OL5M",
|
|
"title": "Kinder des Nebels",
|
|
"language": ["ger"],
|
|
"publish_year": [2018],
|
|
}
|
|
]
|
|
},
|
|
},
|
|
"Kinder des Nebels",
|
|
)
|
|
|
|
assert result is not None
|
|
assert result.title == "Kinder des Nebels"
|
|
assert result.search_title == "Kinder des Nebels"
|
|
assert result.publish_year == 2018
|