normalise isbn on local book search

- uppercase ISBN before checking it's a number to account for trailing 'x'
- check maybe_isbn for search_identifiers search. Without this we are only searching external connectors, not locally!
This commit is contained in:
Hugh Rundle 2022-08-30 20:00:09 +10:00
parent 68d91086ed
commit 1ee2ff4811
3 changed files with 8 additions and 3 deletions

View file

@ -7,6 +7,7 @@ from django.contrib.postgres.search import SearchRank, SearchQuery
from django.db.models import OuterRef, Subquery, F, Q
from bookwyrm import models
from bookwyrm import connectors
from bookwyrm.settings import MEDIA_FULL_URL
@ -74,6 +75,10 @@ def format_search_result(search_result):
def search_identifiers(query, *filters, return_first=False):
"""tries remote_id, isbn; defined as dedupe fields on the model"""
if connectors.maybe_isbn(query):
# Oh did you think the 'S' in ISBN stood for 'standard'?
normalized_isbn = query.strip().upper().rjust(10, "0")
query = normalized_isbn
# pylint: disable=W0212
or_filters = [
{f.name: query}

View file

@ -1,6 +1,6 @@
""" bring connectors into the namespace """
from .settings import CONNECTORS
from .abstract_connector import ConnectorException
from .abstract_connector import get_data, get_image
from .abstract_connector import get_data, get_image, maybe_isbn
from .connector_manager import search, first_search_result

View file

@ -328,10 +328,10 @@ def maybe_isbn(query):
"""check if a query looks like an isbn"""
isbn = re.sub(r"[\W_]", "", query) # removes filler characters
# ISBNs must be numeric except an ISBN10 checkdigit can be 'X'
if not isbn.rstrip("X").isnumeric():
if not isbn.upper().rstrip("X").isnumeric():
return False
return len(isbn) in [
9,
10,
13,
] # ISBN10 or ISBN13, or maybe ISBN10 missing a prepended zero
] # ISBN10 or ISBN13, or maybe ISBN10 missing a leading zero