Skip to content

Commit 3f2d9ec

Browse files
authored
Merge pull request #11379 from cdrini/feature/opds-endpoint
Add OPDS endpoint
2 parents 267b401 + d20f192 commit 3f2d9ec

File tree

9 files changed

+396
-58
lines changed

9 files changed

+396
-58
lines changed

openlibrary/book_providers.py

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import functools
12
import logging
23
import typing
34
from collections.abc import Callable, Iterator
@@ -55,6 +56,16 @@ def from_acquisition_access(literal: AcquisitionAccessLiteral) -> 'EbookAccess':
5556
else:
5657
raise ValueError(f'Unknown access literal: {literal}')
5758

59+
def to_acquisition_access_literal(self) -> AcquisitionAccessLiteral | None:
60+
if self == EbookAccess.PRINTDISABLED:
61+
return 'sample'
62+
elif self == EbookAccess.PUBLIC:
63+
return 'open-access'
64+
elif self == EbookAccess.BORROWABLE:
65+
return 'borrow'
66+
else:
67+
return None
68+
5869

5970
@dataclass
6071
class Acquisition:
@@ -353,13 +364,24 @@ def get_access(
353364
def get_acquisitions(
354365
self,
355366
ed_or_solr: Edition | dict,
367+
db_edition: Edition | None = None,
356368
) -> list[Acquisition]:
369+
access: AcquisitionAccessLiteral | None = None
370+
371+
if solr_ebook_access := ed_or_solr.get('ebook_access'):
372+
access = EbookAccess.from_solr_str(
373+
solr_ebook_access
374+
).to_acquisition_access_literal()
375+
376+
if not access:
377+
return []
378+
357379
return [
358380
Acquisition(
359-
access='open-access',
381+
access=access,
360382
format='web',
361383
price=None,
362-
url=f'https://archive.org/details/{self.get_best_identifier(ed_or_solr)}',
384+
url=f'https://archive.org/details/{self.get_best_identifier(db_edition or ed_or_solr)}',
363385
provider_name=self.short_name,
364386
)
365387
]
@@ -594,6 +616,46 @@ def get_acquisitions(self, ed_or_solr: Edition | dict) -> list[Acquisition]:
594616
]
595617

596618

619+
class BetterWorldBooksProvider(AbstractBookProvider):
620+
short_name = 'betterworldbooks'
621+
long_name = 'Better World Books'
622+
identifier_key = 'betterworldbooks'
623+
624+
def is_own_ocaid(self, ocaid: str) -> bool:
625+
return False
626+
627+
def get_identifiers(self, ed_or_solr: Edition | dict) -> list[str]:
628+
# basically just check if it has an isbn?
629+
return (ed_or_solr.get('isbn') or ed_or_solr.get('isbn_10') or []) + (
630+
ed_or_solr.get('isbn_13') or []
631+
)
632+
633+
@functools.cached_property
634+
def bwb_acquisitions(self) -> dict[str, Acquisition]:
635+
from infogami import config
636+
637+
results = {
638+
key: Acquisition.from_json(acq)
639+
for key, acq in getattr(config, 'bwb_test_holdings', {}).items()
640+
}
641+
642+
for acq in results.values():
643+
acq.provider_name = "Better World Books"
644+
645+
return results
646+
647+
def get_acquisitions(
648+
self,
649+
ed_or_solr: Edition | dict,
650+
) -> list[Acquisition]:
651+
key = cast(str, ed_or_solr['key'])
652+
653+
if acq := self.bwb_acquisitions.get(key):
654+
return [acq]
655+
656+
return []
657+
658+
597659
PROVIDER_ORDER: list[AbstractBookProvider] = [
598660
# These providers act essentially as their own publishers, so link to the first when
599661
# we're on an edition page
@@ -607,6 +669,8 @@ def get_acquisitions(self, ed_or_solr: Edition | dict) -> list[Acquisition]:
607669
WikisourceProvider(),
608670
# Then link to IA
609671
InternetArchiveProvider(),
672+
# Then link to purchase options
673+
BetterWorldBooksProvider(),
610674
]
611675

612676

@@ -729,6 +793,18 @@ def get_book_provider(ed_or_solr: Edition | dict) -> AbstractBookProvider | None
729793
return next(get_book_providers(ed_or_solr), None)
730794

731795

796+
def get_acquisitions(solr_edition: dict, edition: Edition) -> list[Acquisition]:
797+
acquisitions: list[Acquisition] = []
798+
for provider in get_book_providers(edition):
799+
if isinstance(provider, InternetArchiveProvider):
800+
acquisitions.extend(
801+
provider.get_acquisitions(solr_edition, db_edition=edition)
802+
)
803+
else:
804+
acquisitions.extend(provider.get_acquisitions(edition))
805+
return acquisitions
806+
807+
732808
def get_best_edition(
733809
editions: list[Edition],
734810
) -> tuple[Edition | None, AbstractBookProvider | None]:

openlibrary/coverstore/code.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
)
5353
app = web.application(urls, locals())
5454

55-
app.add_processor(CORSProcessor())
55+
app.add_processor(CORSProcessor(cors_everything=True))
5656

5757

5858
def get_cover_id(olkeys):

openlibrary/i18n/messages.pot

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,40 @@ msgstr ""
10661066
msgid "Buy this book"
10671067
msgstr ""
10681068

1069+
#: openlibrary/plugins/openlibrary/api.py
1070+
msgid "Search Results"
1071+
msgstr ""
1072+
1073+
#: home/index.html home/welcome.html openlibrary/plugins/openlibrary/api.py
1074+
msgid "Welcome to Open Library"
1075+
msgstr ""
1076+
1077+
#: home/index.html openlibrary/plugins/openlibrary/api.py trending.html
1078+
msgid "Trending Books"
1079+
msgstr ""
1080+
1081+
#: home/index.html openlibrary/plugins/openlibrary/api.py
1082+
msgid "Classic Books"
1083+
msgstr ""
1084+
1085+
#: home/index.html openlibrary/plugins/openlibrary/api.py
1086+
#: openlibrary/plugins/openlibrary/home.py
1087+
msgid "Romance"
1088+
msgstr ""
1089+
1090+
#: home/index.html openlibrary/plugins/openlibrary/api.py
1091+
msgid "Kids"
1092+
msgstr ""
1093+
1094+
#: home/index.html openlibrary/plugins/openlibrary/api.py
1095+
msgid "Thrillers"
1096+
msgstr ""
1097+
1098+
#: home/index.html openlibrary/plugins/openlibrary/api.py
1099+
#: openlibrary/plugins/openlibrary/home.py
1100+
msgid "Textbooks"
1101+
msgstr ""
1102+
10691103
#: openlibrary/plugins/openlibrary/code.py
10701104
msgid "Arabic"
10711105
msgstr ""
@@ -1146,14 +1180,6 @@ msgstr ""
11461180
msgid "Recipes"
11471181
msgstr ""
11481182

1149-
#: home/index.html openlibrary/plugins/openlibrary/home.py
1150-
msgid "Romance"
1151-
msgstr ""
1152-
1153-
#: home/index.html openlibrary/plugins/openlibrary/home.py
1154-
msgid "Textbooks"
1155-
msgstr ""
1156-
11571183
#: openlibrary/plugins/openlibrary/home.py
11581184
msgid "Children"
11591185
msgstr ""
@@ -2261,10 +2287,6 @@ msgstr ""
22612287
msgid "All Time"
22622288
msgstr ""
22632289

2264-
#: home/index.html trending.html
2265-
msgid "Trending Books"
2266-
msgstr ""
2267-
22682290
#: trending.html
22692291
msgid "See what readers from the community are adding to their bookshelves"
22702292
msgstr ""
@@ -5580,26 +5602,10 @@ msgid_plural "%(count)s Books"
55805602
msgstr[0] ""
55815603
msgstr[1] ""
55825604

5583-
#: home/index.html home/welcome.html
5584-
msgid "Welcome to Open Library"
5585-
msgstr ""
5586-
5587-
#: home/index.html
5588-
msgid "Classic Books"
5589-
msgstr ""
5590-
55915605
#: home/index.html
55925606
msgid "Recently Returned"
55935607
msgstr ""
55945608

5595-
#: home/index.html
5596-
msgid "Kids"
5597-
msgstr ""
5598-
5599-
#: home/index.html
5600-
msgid "Thrillers"
5601-
msgstr ""
5602-
56035609
#: home/index.html
56045610
msgid "Authors Alliance & MIT Press"
56055611
msgstr ""

0 commit comments

Comments
 (0)