Skip to content

Commit 576d5cb

Browse files
committed
Move edition resolution + availability attach to get_items_and_add_availability()
1 parent 1bcea0a commit 576d5cb

3 files changed

Lines changed: 54 additions & 36 deletions

File tree

openlibrary/core/lending.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Module for providing core functionality of lending on Open Library.
22
"""
3-
from typing import Literal, TypedDict, cast
3+
from typing import TYPE_CHECKING, Literal, TypedDict, cast
44

55
import web
66
import datetime
@@ -21,6 +21,11 @@
2121
from . import ia
2222
from . import helpers as h
2323

24+
25+
if TYPE_CHECKING:
26+
from openlibrary.core.models import Edition
27+
28+
2429
logger = logging.getLogger(__name__)
2530

2631
S3_LOAN_URL = 'https://%s/services/loans/loan/'
@@ -513,6 +518,29 @@ def get_availability_of_ocaids(
513518
return get_availability('identifier', ocaids)
514519

515520

521+
def get_items_and_add_availability(ocaids: list[str]) -> dict[str, "Edition"]:
522+
"""
523+
Get Editions from OCAIDs and attach their availabiliity.
524+
525+
Returns a dict of the form: `{"ocaid1": edition1, "ocaid2": edition2, ...}`
526+
"""
527+
ocaid_availability = get_availability_of_ocaids(ocaids=ocaids)
528+
editions = web.ctx.site.get_many(
529+
[
530+
f"/books/{item.get('openlibrary_edition')}"
531+
for item in ocaid_availability.values()
532+
if item.get('openlibrary_edition')
533+
]
534+
)
535+
536+
# Attach availability
537+
for edition in editions:
538+
if edition.ocaid in ocaids:
539+
edition.availability = ocaid_availability.get(edition.ocaid)
540+
541+
return {edition.ocaid: edition for edition in editions if edition.ocaid}
542+
543+
516544
def is_loaned_out(identifier):
517545
"""Returns True if the given identifier is loaned out.
518546

openlibrary/macros/IABook.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
$def with (doc, ia_base_url="https://archive.org")
2-
$ ocaid = doc.get('identifier')
2+
$ ocaid = doc.get('ocaid')
33
<li class="searchResultItem">
44
<span class="bookcover">
55
$ cover = "%s/services/img/%s" % (ia_base_url, ocaid)
@@ -15,7 +15,7 @@
1515
<div class="details">
1616
<div class="resultTitle">
1717
<h3 itemprop="name" class="booktitle">
18-
<a itemprop="url" href="$ia_base_url/details/$ocaid" class="results">Borrowed from Internet Archive: $doc.get('identifier')</a>
18+
<a itemprop="url" href="$ia_base_url/details/$ocaid" class="results">Borrowed from Internet Archive: $ocaid</a>
1919
</h3>
2020
</div>
2121
</div>

openlibrary/plugins/upstream/account.py

Lines changed: 23 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import json
33
import logging
44
import re
5-
from typing import Any, Final
5+
from typing import TYPE_CHECKING, Any, Final
66
from collections.abc import Callable
77
from collections.abc import Iterable, Mapping
88

@@ -27,6 +27,7 @@
2727
from openlibrary.core.bookshelves import Bookshelves
2828
from openlibrary.core.lending import (
2929
get_availability_of_ocaids,
30+
get_items_and_add_availability,
3031
s3_loan_api,
3132
)
3233
from openlibrary.core.observations import Observations
@@ -45,6 +46,10 @@
4546
from openlibrary.plugins.upstream import borrow, forms, utils
4647
from openlibrary.utils.dateutil import elapsed_time
4748

49+
50+
if TYPE_CHECKING:
51+
from openlibrary.core.models import Edition
52+
4853
logger = logging.getLogger("openlibrary.account")
4954

5055
CONFIG_IA_DOMAIN: Final = config.get('ia_base_url', 'https://archive.org')
@@ -1184,7 +1189,7 @@ def process_goodreads_csv(i):
11841189
return books, books_wo_isbns
11851190

11861191

1187-
def get_loan_history_data(page: int, mb: "MyBooksTemplate") -> dict[str, str | int]:
1192+
def get_loan_history_data(page: int, mb: "MyBooksTemplate") -> dict[str, Any]:
11881193
"""
11891194
Retrieve IA loan history data for page `page` of the patron's history.
11901195
@@ -1219,43 +1224,28 @@ def get_loan_history_data(page: int, mb: "MyBooksTemplate") -> dict[str, str | i
12191224
loan_history.pop()
12201225

12211226
ocaids = [loan_record['identifier'] for loan_record in loan_history]
1222-
ocaid_availability = get_availability_of_ocaids(ocaids)
12231227
loan_history_map = {
12241228
loan_record['identifier']: loan_record for loan_record in loan_history
12251229
}
1226-
editions = web.ctx.site.get_many(
1227-
[
1228-
f"/books/{item.get('openlibrary_edition')}"
1229-
for item in ocaid_availability.values()
1230-
if item.get('openlibrary_edition')
1231-
]
1232-
)
12331230

1234-
# Create 'placeholder' editions for items in the Internet Archive loan
1235-
# history, but absent from Open Library.
1236-
ia_only_loans = [
1237-
loan
1238-
for loan in ocaid_availability.values()
1239-
if not loan.get('openlibrary_edition')
1240-
]
1241-
1242-
# Attach availability and loan history info (for sorting) to both editions and
1243-
# ia-only items.
1244-
for ed in editions:
1245-
if ed.ocaid in ocaids:
1246-
ed.availability = ocaid_availability.get(ed.ocaid)
1247-
ed.last_loan_date = loan_history_map[ed.ocaid].get('updatedate')
1248-
1249-
for ia_only in ia_only_loans:
1250-
# ia_only['loan'] isn't set because `LoanStatus.html` reads it as a
1251-
# current loan. No apparenty way to distinguish between current and
1252-
# past loans from this API call.
1253-
loan = loan_history_map[ia_only['identifier']]
1254-
ia_only['last_loan_date'] = loan.get('updatedate', '')
1231+
# Get editions and attach their loan history.
1232+
editions_map = get_items_and_add_availability(ocaids=ocaids)
1233+
for edition in editions_map.values():
1234+
edition.last_loan_date = loan_history_map[edition.ocaid].get('updatedate')
1235+
1236+
# Create 'placeholders' for items in the Internet Archive loan history, but
1237+
# absent from Open Library, and then add loan history.
1238+
# ia_only['loan'] isn't set because `LoanStatus.html` reads it as a current
1239+
# loan. No apparenty way to distinguish between current and past loans with
1240+
# this API call.
1241+
ia_only_loans = [{'ocaid': ocaid} for ocaid in ocaids if ocaid not in editions_map]
1242+
for ia_only_loan in ia_only_loans:
1243+
loan_data = loan_history_map[ia_only_loan['ocaid']]
1244+
ia_only_loan['last_loan_date'] = loan_data.get('updatedate', '')
12551245
# Determine the macro to load for loan-history items only.
1256-
ia_only['ia_only'] = True # type: ignore[typeddict-unknown-key]
1246+
ia_only_loan['ia_only'] = True # type: ignore[typeddict-unknown-key]
12571247

1258-
editions_and_ia_loans = editions + ia_only_loans
1248+
editions_and_ia_loans = list(editions_map.values()) + ia_only_loans
12591249
editions_and_ia_loans.sort(
12601250
key=lambda item: item.get('last_loan_date', ''), reverse=True
12611251
)

0 commit comments

Comments
 (0)