Repository: internetarchive/openlibrary

Issue:
Replace `availability.js` with server-side LoanStatus button calls for lists and reading logs
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->

### Describe the problem that you'd like solved
<!-- A clear and concise description of what you want to happen. -->
`availability.js` is used to fetch books' loan availability and generate loan status buttons for lists and reading logs.  The logic used in this file to generate the loan status buttons is somewhat questionable, and the buttons may behave differently than the standard loan status buttons found in other components.

### Proposal & Constraints
<!-- What is the proposed solution / implementation? Is there a precedent of this approach succeeding elsewhere? -->
Replace `availability.js` with calls to the server which fetch LoanStatus button HTML.  If implemented, this will ensure that a book's loan status is consistent across components, and that the loan status buttons will behave predictably where ever they may be found..

<!-- Which suggestions or requirements should be considered for how feature needs to appear or be implemented? -->

### Additional context
<!-- Add any other context or screenshots about the feature request here. -->
#5407 must be completed before work begins on this issue.

### Stakeholders
<!-- @ tag stakeholders of this bug -->





Discussion:

Resolving patch:
diff --git a/openlibrary/core/lending.py b/openlibrary/core/lending.py
--- a/openlibrary/core/lending.py
+++ b/openlibrary/core/lending.py
@@ -361,7 +361,7 @@ def get_availability_of_editions(ol_edition_ids):
     return get_availability('openlibrary_edition', ol_edition_ids)
 
 @public
-def add_availability(items):
+def add_availability(items, mode="identifier"):
     """
     Adds API v2 'availability' key to dicts
     :param list of dict items: items with fields containing ocaids
@@ -394,12 +394,20 @@ def get_ocaid(item):
             if item.get(field):
                 return item[field][0] if isinstance(item[field], list) else item[field]
 
-    ocaids = [ocaid for ocaid in map(get_ocaid, items) if ocaid]
-    availabilities = get_availability_of_ocaids(ocaids)
-    for item in items:
-        ocaid = get_ocaid(item)
-        if ocaid:
-            item['availability'] = availabilities.get(ocaid)
+    if mode == "identifier":
+        ocaids = [ocaid for ocaid in map(get_ocaid, items) if ocaid]
+        availabilities = get_availability_of_ocaids(ocaids)
+        for item in items:
+            ocaid = get_ocaid(item)
+            if ocaid:
+                item['availability'] = availabilities.get(ocaid)
+    elif mode == "openlibrary_work":
+        _ids = [item['key'].split('/')[-1] for item in items]
+        availabilities = get_availability_of_works(_ids)
+        for item in items:
+            olid = item['key'].split('/')[-1]
+            if olid:
+                item['availability'] = availabilities.get(olid)
     return items
 
 @public
diff --git a/openlibrary/plugins/upstream/account.py b/openlibrary/plugins/upstream/account.py
--- a/openlibrary/plugins/upstream/account.py
+++ b/openlibrary/plugins/upstream/account.py
@@ -21,6 +21,7 @@
 from openlibrary.core.booknotes import Booknotes
 from openlibrary.core.bookshelves import Bookshelves
 from openlibrary.core.observations import Observations, convert_observation_ids
+from openlibrary.core.lending import add_availability
 from openlibrary.plugins.recaptcha import recaptcha
 from openlibrary.plugins import openlibrary as olib
 from openlibrary.accounts import (
@@ -843,9 +844,11 @@ def GET(self, username, key='loans'):
             elif key == 'observations' and is_logged_in_user:
                 books = PatronBooknotes(user).get_observations(page=int(i.page))
             else:
-                books = readlog.get_works(key, page=i.page,
-                                          sort='created', sort_order=i.sort)
-
+                books = add_availability(
+                    readlog.get_works(key, page=i.page,
+                                      sort='created', sort_order=i.sort),
+                    mode="openlibrary_work"
+                )
             booknotes_counts = PatronBooknotes.get_counts(username)
 
             return render['account/books'](


Test patch: