From 6d19c26bca81f4b7102d7534a9fed7b83a346256 Mon Sep 17 00:00:00 2001 From: Tanishq Sangwan Date: Fri, 3 Jul 2026 22:33:43 +0530 Subject: [PATCH 1/5] feat: Consolidate sidebar buy options into unified Buy dropdown button (closes #12867) --- openlibrary/i18n/messages.pot | 116 +++++++---------- openlibrary/macros/AffiliateLinks.html.jinja | 39 +++--- .../AffiliateLinksLoadingIndicator.html | 4 +- openlibrary/macros/LoanStatus.html | 4 +- openlibrary/macros/databarWork.html | 37 +++--- openlibrary/templates/type/edition/view.html | 13 -- static/css/components/read-panel.css | 122 ++++++++++++++++-- static/css/components/work.css | 3 + 8 files changed, 199 insertions(+), 139 deletions(-) diff --git a/openlibrary/i18n/messages.pot b/openlibrary/i18n/messages.pot index a5c7150e043..7ed5659c6b3 100644 --- a/openlibrary/i18n/messages.pot +++ b/openlibrary/i18n/messages.pot @@ -537,7 +537,7 @@ msgid "" "email and password to access your Open Library account." msgstr "" -#: login.html openlibrary/plugins/upstream/forms.py +#: login.html msgid "Email" msgstr "" @@ -546,7 +546,6 @@ msgid "Forgot your Internet Archive email?" msgstr "" #: account/email/forgot-ia.html login.html -#: openlibrary/plugins/upstream/forms.py msgid "Password" msgstr "" @@ -757,9 +756,9 @@ msgid "Title" msgstr "" #: SearchAuthorSuggestion.html books/add.html books/edit.html -#: books/edit/edition.html openlibrary/plugins/worksearch/code.py -#: search/advancedsearch.html search/search_modal_i18n.html -#: search/work_search_selected_facets.html status.html +#: books/edit/edition.html search/advancedsearch.html +#: search/search_modal_i18n.html search/work_search_selected_facets.html +#: status.html msgid "Author" msgstr "" @@ -910,7 +909,7 @@ msgstr "" msgid "All Time" msgstr "" -#: home/index.html openlibrary/plugins/openlibrary/api.py trending.html +#: home/index.html trending.html msgid "Trending Books" msgstr "" @@ -1052,8 +1051,7 @@ msgstr "" msgid "Solr Editions" msgstr "" -#: design/toggle.html openlibrary/plugins/worksearch/code.py -#: search/availability_i18n.html work_search.html +#: design/toggle.html search/availability_i18n.html work_search.html msgid "Readable Only" msgstr "" @@ -1061,8 +1059,8 @@ msgstr "" msgid "Filter by availability" msgstr "" -#: openlibrary/plugins/worksearch/code.py search/search_modal_i18n.html -#: type/edition/view.html type/work/view.html work_search.html +#: search/search_modal_i18n.html type/edition/view.html type/work/view.html +#: work_search.html msgid "Language" msgstr "" @@ -1118,7 +1116,7 @@ msgid "Authors" msgstr "" #: SearchNavigation.html books/mybooks_breadcrumb_select.html lib/nav_foot.html -#: openlibrary/plugins/upstream/mybooks.py work_search.html +#: work_search.html msgid "Books" msgstr "" @@ -1189,11 +1187,11 @@ msgid "" "information form." msgstr "" -#: account/create.html openlibrary/plugins/upstream/forms.py +#: account/create.html msgid "Must be a valid email address" msgstr "" -#: account/create.html openlibrary/plugins/upstream/forms.py +#: account/create.html msgid "Must be between 3 and 20 characters" msgstr "" @@ -1519,7 +1517,7 @@ msgstr "" #. (bookshelf ID 3). Used as a button label and shelf name. #: account/mybooks.html account/readinglog_shelf_name.html account/sidebar.html #: my_books/dropdown_content.html my_books/primary_action.html -#: openlibrary/plugins/upstream/mybooks.py search/sort_options.html +#: search/sort_options.html msgid "Already Read" msgstr "" @@ -1545,7 +1543,7 @@ msgid "My Reading Stats" msgstr "" #: account/mybooks.html account/sidebar.html -#: books/mybooks_breadcrumb_select.html openlibrary/plugins/upstream/account.py +#: books/mybooks_breadcrumb_select.html msgid "Loan History" msgstr "" @@ -1661,7 +1659,7 @@ msgid "Save" msgstr "" #: EditionNavBar.html account/observations.html -#: books/mybooks_breadcrumb_select.html openlibrary/plugins/upstream/mybooks.py +#: books/mybooks_breadcrumb_select.html msgid "Reviews" msgstr "" @@ -1918,7 +1916,6 @@ msgid "Click on a bar to see matching works" msgstr "" #: account/sidebar.html books/mybooks_breadcrumb_select.html -#: openlibrary/plugins/upstream/mybooks.py msgid "My Feed" msgstr "" @@ -2357,7 +2354,7 @@ msgstr "" msgid "Failed" msgstr "" -#: admin/imports_by_date.html openlibrary/core/edits.py +#: admin/imports_by_date.html msgid "Pending" msgstr "" @@ -2573,8 +2570,7 @@ msgid "Admin Center" msgstr "" #: RelatedSubjects.html SubjectTags.html admin/menu.html -#: admin/people/index.html admin/people/view.html -#: openlibrary/plugins/worksearch/code.py type/author/view.html +#: admin/people/index.html admin/people/view.html type/author/view.html #: type/list/view_body.html msgid "People" msgstr "" @@ -3080,7 +3076,7 @@ msgid "Anonymize Account" msgstr "" #: admin/people/view.html books/mybooks_breadcrumb_select.html -#: openlibrary/plugins/upstream/account.py type/user/view.html +#: type/user/view.html msgid "Loans" msgstr "" @@ -3825,50 +3821,36 @@ msgstr "" msgid "in %(languagelist)s" msgstr "" -#. Page title for the "Want to Read" shelf page. -#. Example: "Want to Read (17)". %(count)d is the number of books on this -#. shelf. -#: books/mybooks_breadcrumb_select.html openlibrary/plugins/upstream/mybooks.py +#: books/mybooks_breadcrumb_select.html #, python-format msgid "Want to Read (%(count)d)" msgstr "" -#. Page title for the "Currently Reading" shelf page. -#. Example: "Currently Reading (42)". %(count)d is the number of books on this -#. shelf. -#: books/mybooks_breadcrumb_select.html openlibrary/plugins/upstream/mybooks.py +#: books/mybooks_breadcrumb_select.html #, python-format msgid "Currently Reading (%(count)d)" msgstr "" -#. Page title for the "Already Read" shelf page. -#. Example: "Already Read (203)". %(count)d is the number of books on this -#. shelf. -#: books/mybooks_breadcrumb_select.html openlibrary/plugins/upstream/mybooks.py +#: books/mybooks_breadcrumb_select.html #, python-format msgid "Already Read (%(count)d)" msgstr "" -#. Page title for the "Stopped Reading" shelf page. -#. Example: "Stopped Reading (8)". %(count)d is the number of books on this -#. shelf. -#: books/mybooks_breadcrumb_select.html openlibrary/plugins/upstream/mybooks.py +#: books/mybooks_breadcrumb_select.html #, python-format msgid "Stopped Reading (%(count)d)" msgstr "" #: books/mybooks_breadcrumb_select.html -#: openlibrary/plugins/openlibrary/lists.py #, python-format msgid "Lists (%(count)d)" msgstr "" -#: books/mybooks_breadcrumb_select.html openlibrary/plugins/upstream/mybooks.py -#: type/edition/modal_links.html +#: books/mybooks_breadcrumb_select.html type/edition/modal_links.html msgid "Notes" msgstr "" -#: books/mybooks_breadcrumb_select.html openlibrary/plugins/upstream/account.py +#: books/mybooks_breadcrumb_select.html msgid "Imports and Exports" msgstr "" @@ -4344,7 +4326,7 @@ msgstr "" msgid "Provider Name" msgstr "" -#: books/edit/edition.html +#: books/edit/edition.html databarWork.html msgid "Buy" msgstr "" @@ -4765,7 +4747,7 @@ msgid "" " page for every book ever published." msgstr "" -#: AffiliateLinks.html.jinja home/about.html search/work_search_facets.html +#: home/about.html search/work_search_facets.html msgid "More" msgstr "" @@ -4796,7 +4778,7 @@ msgstr[1] "" msgid "Welcome to Open Library" msgstr "" -#: home/index.html openlibrary/plugins/openlibrary/api.py +#: home/index.html msgid "Classic Books" msgstr "" @@ -4804,21 +4786,19 @@ msgstr "" msgid "Recently Returned" msgstr "" -#: home/index.html openlibrary/plugins/openlibrary/api.py -#: openlibrary/plugins/openlibrary/home.py +#: home/index.html msgid "Romance" msgstr "" -#: home/index.html openlibrary/plugins/openlibrary/api.py +#: home/index.html msgid "Kids" msgstr "" -#: home/index.html openlibrary/plugins/openlibrary/api.py +#: home/index.html msgid "Thrillers" msgstr "" -#: home/index.html openlibrary/plugins/openlibrary/api.py -#: openlibrary/plugins/openlibrary/home.py +#: home/index.html msgid "Textbooks" msgstr "" @@ -5031,8 +5011,7 @@ msgstr "" #: RelatedSubjects.html SearchNavigation.html SubjectTags.html #: lib/browse_popover.html lib/nav_foot.html lib/nav_head.html -#: openlibrary/plugins/worksearch/code.py subjects/notfound.html -#: type/author/view.html type/list/view_body.html +#: subjects/notfound.html type/author/view.html type/list/view_body.html msgid "Subjects" msgstr "" @@ -5118,7 +5097,7 @@ msgid "New!" msgstr "" #: databarDiff.html databarEdit.html databarTemplate.html databarView.html -#: lib/history.html openlibrary/plugins/openlibrary/home.py +#: lib/history.html msgid "History" msgstr "" @@ -5195,7 +5174,7 @@ msgstr "" msgid "Just a sentence or two is good." msgstr "" -#: lib/nav_foot.html openlibrary/plugins/openlibrary/api.py site/head.html +#: lib/nav_foot.html site/head.html msgid "Open Library" msgstr "" @@ -5837,11 +5816,11 @@ msgstr "" msgid "Request Status" msgstr "" -#: merge_request_table/table_header.html openlibrary/core/edits.py +#: merge_request_table/table_header.html msgid "Merged" msgstr "" -#: merge_request_table/table_header.html openlibrary/core/edits.py +#: merge_request_table/table_header.html msgid "Declined" msgstr "" @@ -6142,8 +6121,8 @@ msgstr "" msgid "Publisher: %(name)s" msgstr "" -#: openlibrary/plugins/worksearch/code.py publishers/view.html -#: search/advancedsearch.html type/edition/view.html type/work/view.html +#: publishers/view.html search/advancedsearch.html type/edition/view.html +#: type/work/view.html msgid "Publisher" msgstr "" @@ -6428,15 +6407,15 @@ msgstr "" msgid "No authors directly matched your search" msgstr "" -#: openlibrary/plugins/worksearch/code.py search/availability_i18n.html +#: search/availability_i18n.html msgid "All books" msgstr "" -#: openlibrary/plugins/worksearch/code.py search/availability_i18n.html +#: search/availability_i18n.html msgid "Free to read now" msgstr "" -#: openlibrary/plugins/worksearch/code.py search/availability_i18n.html +#: search/availability_i18n.html msgid "Borrow online" msgstr "" @@ -6998,8 +6977,8 @@ msgstr "" msgid "— Show everything by this author?" msgstr "" -#: RelatedSubjects.html SubjectTags.html openlibrary/plugins/worksearch/code.py -#: type/author/view.html type/list/view_body.html +#: RelatedSubjects.html SubjectTags.html type/author/view.html +#: type/list/view_body.html msgid "Places" msgstr "" @@ -7140,10 +7119,6 @@ msgstr "" msgid "ISBNs" msgstr "" -#: databarWork.html type/edition/view.html type/work/view.html -msgid "Buy this book" -msgstr "" - #: type/edition/view.html type/work/view.html msgid "Book Details" msgstr "" @@ -7472,8 +7447,7 @@ msgstr "" msgid "Derived from seed metadata" msgstr "" -#: RelatedSubjects.html SubjectTags.html openlibrary/plugins/worksearch/code.py -#: type/list/view_body.html +#: RelatedSubjects.html SubjectTags.html type/list/view_body.html msgid "Times" msgstr "" @@ -9160,3 +9134,7 @@ msgstr "" msgid "Classic eBooks" msgstr "" +#: databarWork.html +msgid "Buy this book" +msgstr "" + diff --git a/openlibrary/macros/AffiliateLinks.html.jinja b/openlibrary/macros/AffiliateLinks.html.jinja index 164f619505d..5e722130bf2 100644 --- a/openlibrary/macros/AffiliateLinks.html.jinja +++ b/openlibrary/macros/AffiliateLinks.html.jinja @@ -1,31 +1,24 @@ {% macro affiliate_link(store) %} -
  • - + {{ store.name }} - {% if store.price %} -
    - {{ store.price }}{{ store.price_note }} - {% endif %} -
  • + rel="noopener noreferrer"> + {{ store.name }} + {% if store.price %} + {{ store.price }}{{ store.price_note }} + {% endif %} + + {% endmacro %} - - - + {% for store in more_stores %}{{ affiliate_link(store) | safe }}{% endfor %} + + {{ _("When you buy books using these links the Internet Archive may earn a small commission.") | safe }} - + diff --git a/openlibrary/macros/AffiliateLinksLoadingIndicator.html b/openlibrary/macros/AffiliateLinksLoadingIndicator.html index 6ef6ed565ff..9c00d56232e 100644 --- a/openlibrary/macros/AffiliateLinksLoadingIndicator.html +++ b/openlibrary/macros/AffiliateLinksLoadingIndicator.html @@ -3,6 +3,6 @@ isbn_str = isbn or '' asin_str = asin or '' prices_str = 'true' if prices else 'false' - + diff --git a/openlibrary/macros/LoanStatus.html b/openlibrary/macros/LoanStatus.html index 253422ec1ab..b53ab07b8ce 100644 --- a/openlibrary/macros/LoanStatus.html +++ b/openlibrary/macros/LoanStatus.html @@ -1,4 +1,4 @@ -$def with (doc, work_key=None, listen=True, allow_expensive_availability_check=False, secondary_action=False, check_loan_status=False, user_lists=None, post='', is_book_page=False, analytics_override=None, lending_state=None) +$def with (doc, work_key=None, listen=True, allow_expensive_availability_check=False, secondary_action=False, check_loan_status=False, user_lists=None, is_book_page=False, analytics_override=None, lending_state=None) $# Takes following parameters: $# * doc - Can be a Work, Edition, or solr dict. $# * listen - whether to display listen button @@ -167,8 +167,6 @@ $else: $:macros.NotInLibrary(None, analytics_attr) -$:post - $if query_param('debug'): $ loanstatus_end_time = time() - loanstatus_start_time

    get_waiting_loan_for(ocaid) took $("%.2f" % waiting_loan_total_time) seconds

    $# detect-missing-i18n-skip-line diff --git a/openlibrary/macros/databarWork.html b/openlibrary/macros/databarWork.html index dbf7166bf55..1847ef44ca1 100644 --- a/openlibrary/macros/databarWork.html +++ b/openlibrary/macros/databarWork.html @@ -2,6 +2,11 @@ $ viewbook = "//%s/stream/XXX?ref=ol" % bookreader_host() +$# Buy button is primary (blue) only when no digital access and a WorldCat URL exists +$ availability = (page.availability or {}) if hasattr(page, 'availability') else {} +$ _has_digital = bool(page.get('ocaid') or availability.get('is_readable') or availability.get('status') == 'open' or availability.get('is_lendable') or availability.get('is_previewable')) +$ buy_is_primary = editions_page and not _has_digital and bool(worldcat_url) +
    $if page.volumes: @@ -28,17 +33,30 @@

    $ work = (page.works and page.works[0]) or page $ edition = page.works and page - $ render_times['databarWork: List widget'] = time() - $ lists_widget = render_template('lists/widget', edition or work, include_rating=True, async_load=True) - $ render_times['databarWork: List widget'] = time() - render_times['databarWork: List widget'] $# For the Works & Editions page, only use ground_truth_availability API for selected Edition $# if edition availability status is error $ render_times['databarWork: LoanStatus'] = time() $ expensive_check = page.get('availability', {}).get('status') in ['error'] - $:macros.LoanStatus(page, allow_expensive_availability_check=expensive_check, secondary_action=editions_page, check_loan_status=editions_page, post=lists_widget, lending_state=lending_state) + $:macros.LoanStatus(page, allow_expensive_availability_check=expensive_check, secondary_action=editions_page, check_loan_status=editions_page, lending_state=lending_state) $ render_times['databarWork: LoanStatus'] = time() - render_times['databarWork: LoanStatus'] + $if editions_page: + + +
    + $:affiliate_links +
    +
    + + $ render_times['databarWork: List widget'] = time() + $:render_template('lists/widget', edition or work, include_rating=True, async_load=True) + $ render_times['databarWork: List widget'] = time() - render_times['databarWork: List widget'] +
    $ share_url = request.home + (edition or work).key @@ -64,16 +82,5 @@

    $ render_times['databarWork: Book provider'] = time() - render_times['databarWork: Book provider']

    - -
    -
    - $:worldcat_links - -
    -

    $_('Buy this book')

    - $:affiliate_links -
    -
    -
    diff --git a/openlibrary/templates/type/edition/view.html b/openlibrary/templates/type/edition/view.html index e4f3580b374..91223b313c9 100644 --- a/openlibrary/templates/type/edition/view.html +++ b/openlibrary/templates/type/edition/view.html @@ -306,19 +306,6 @@ -
    -
    -
    - $:worldcat_link - -
    -

    $_('Buy this book')

    - $:affiliate_links -
    -
    -
    -
    - $ seen = set() $if previews and any([len(e.languages) for e in previews]):

    diff --git a/static/css/components/read-panel.css b/static/css/components/read-panel.css index 80d9966b711..3240609a2d9 100644 --- a/static/css/components/read-panel.css +++ b/static/css/components/read-panel.css @@ -130,20 +130,6 @@ ul.ebook-download-options li { margin: 5px 0; } -.buy-options-table { - line-height: 2em; -} - -.buy-options-table .more { - margin-left: 0; - cursor: pointer; -} - -.buy-options-table + small { - display: block; - margin-top: 10px; -} - .cta-section-title.world-cat-link { margin-top: 0; } @@ -286,3 +272,111 @@ ul.ebook-download-options li { /* stylelint-enable selector-max-specificity */ /* stylelint-enable max-nesting-depth */ } + +/* Buy popover: full-width trigger button */ +.buy-popover { + display: block; + width: 100%; + margin-top: var(--spacing-stack-xs); +} + +/* Buy options popover content */ +.buy-options { + box-sizing: border-box; + width: 100%; + background-color: var(--white); + border-radius: var(--border-radius-overlay); +} + +@media only screen and (min-width: 768px) { + .buy-options { + width: 240px; + } +} + +.buy-options .buy-option { + transition: background-color 0.2s; +} + +.buy-options .buy-option:hover { + background-color: var(--lightest-grey); +} + +.buy-options .buy-option__link { + display: flex; + justify-content: space-between; + align-items: center; + padding: var(--spacing-inset-sm) var(--spacing-inset-md); + color: var(--dark-grey); + text-decoration: none; + font-size: var(--font-size-body-medium); +} + +.buy-options .buy-option__price { + font-size: var(--font-size-label-medium); + color: var(--accessible-grey); +} + +/* Disclaimer with top horizontal border */ +.buy-options .buy-options__disclaimer { + display: block; + padding: var(--spacing-inset-sm) var(--spacing-inset-md); + border-top: 1px solid var(--lighter-grey); + color: var(--accessible-grey); + font-size: var(--font-size-label-medium); + line-height: 1.4; +} + +.buy-options .buy-options__disclaimer a { + color: var(--link-blue); + text-decoration: underline; +} + +/* Buy button custom styling (single button with left icon and right arrow) */ +.cta-btn--buy { + position: relative; + background-color: var(--grey-464646); + color: var(--white); + margin-top: 0; + height: 37px; + padding: 0 var(--spacing-inset-sm); + display: flex; + align-items: center; + justify-content: center; +} + +.cta-btn--buy:hover { + background-color: var(--dark-grey); +} + +.cta-btn--buy .btn-icon.cart { + position: absolute; + left: 12px; +} + +.cta-btn--buy .btn-label { + padding: 0; +} + +.cta-btn--buy .arrow-down { + position: absolute; + right: 0; + top: 0; + width: 32px; + height: 100%; + border-left: 1px solid var(--grey); + display: flex; + align-items: center; + justify-content: center; +} + +.cta-btn--buy .arrow-down::after { + content: ""; + display: block; + width: 23px; + height: 23px; + background: url(/static/images/icons/icon_dropit.png) no-repeat center; + background-position: 0; + background-size: 45px; + filter: brightness(0) invert(1); +} diff --git a/static/css/components/work.css b/static/css/components/work.css index 3a2a7d1a285..27d77d17584 100644 --- a/static/css/components/work.css +++ b/static/css/components/work.css @@ -202,6 +202,9 @@ div.editionTools p { width: var(--sidebar-width); margin-right: 1.5em; margin-bottom: 0; + position: sticky; + top: 20px; + align-self: flex-start; } div.editionAbout { flex: 1; From 820ea7e9030e3be0198a409c3d9eb1e4fa437c4a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 3 Jul 2026 17:05:10 +0000 Subject: [PATCH 2/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- openlibrary/i18n/messages.pot | 508 +++++++++++++++++++++++++++++++--- 1 file changed, 467 insertions(+), 41 deletions(-) diff --git a/openlibrary/i18n/messages.pot b/openlibrary/i18n/messages.pot index 7ed5659c6b3..e9f92da9799 100644 --- a/openlibrary/i18n/messages.pot +++ b/openlibrary/i18n/messages.pot @@ -537,7 +537,7 @@ msgid "" "email and password to access your Open Library account." msgstr "" -#: login.html +#: login.html openlibrary/plugins/upstream/forms.py msgid "Email" msgstr "" @@ -546,6 +546,7 @@ msgid "Forgot your Internet Archive email?" msgstr "" #: account/email/forgot-ia.html login.html +#: openlibrary/plugins/upstream/forms.py msgid "Password" msgstr "" @@ -756,9 +757,9 @@ msgid "Title" msgstr "" #: SearchAuthorSuggestion.html books/add.html books/edit.html -#: books/edit/edition.html search/advancedsearch.html -#: search/search_modal_i18n.html search/work_search_selected_facets.html -#: status.html +#: books/edit/edition.html openlibrary/plugins/worksearch/code.py +#: search/advancedsearch.html search/search_modal_i18n.html +#: search/work_search_selected_facets.html status.html msgid "Author" msgstr "" @@ -909,7 +910,7 @@ msgstr "" msgid "All Time" msgstr "" -#: home/index.html trending.html +#: home/index.html openlibrary/plugins/openlibrary/api.py trending.html msgid "Trending Books" msgstr "" @@ -1051,7 +1052,8 @@ msgstr "" msgid "Solr Editions" msgstr "" -#: design/toggle.html search/availability_i18n.html work_search.html +#: design/toggle.html openlibrary/plugins/worksearch/code.py +#: search/availability_i18n.html work_search.html msgid "Readable Only" msgstr "" @@ -1059,8 +1061,8 @@ msgstr "" msgid "Filter by availability" msgstr "" -#: search/search_modal_i18n.html type/edition/view.html type/work/view.html -#: work_search.html +#: openlibrary/plugins/worksearch/code.py search/search_modal_i18n.html +#: type/edition/view.html type/work/view.html work_search.html msgid "Language" msgstr "" @@ -1116,7 +1118,7 @@ msgid "Authors" msgstr "" #: SearchNavigation.html books/mybooks_breadcrumb_select.html lib/nav_foot.html -#: work_search.html +#: openlibrary/plugins/upstream/mybooks.py work_search.html msgid "Books" msgstr "" @@ -1187,11 +1189,11 @@ msgid "" "information form." msgstr "" -#: account/create.html +#: account/create.html openlibrary/plugins/upstream/forms.py msgid "Must be a valid email address" msgstr "" -#: account/create.html +#: account/create.html openlibrary/plugins/upstream/forms.py msgid "Must be between 3 and 20 characters" msgstr "" @@ -1517,7 +1519,7 @@ msgstr "" #. (bookshelf ID 3). Used as a button label and shelf name. #: account/mybooks.html account/readinglog_shelf_name.html account/sidebar.html #: my_books/dropdown_content.html my_books/primary_action.html -#: search/sort_options.html +#: openlibrary/plugins/upstream/mybooks.py search/sort_options.html msgid "Already Read" msgstr "" @@ -1543,7 +1545,7 @@ msgid "My Reading Stats" msgstr "" #: account/mybooks.html account/sidebar.html -#: books/mybooks_breadcrumb_select.html +#: books/mybooks_breadcrumb_select.html openlibrary/plugins/upstream/account.py msgid "Loan History" msgstr "" @@ -1659,7 +1661,7 @@ msgid "Save" msgstr "" #: EditionNavBar.html account/observations.html -#: books/mybooks_breadcrumb_select.html +#: books/mybooks_breadcrumb_select.html openlibrary/plugins/upstream/mybooks.py msgid "Reviews" msgstr "" @@ -1916,6 +1918,7 @@ msgid "Click on a bar to see matching works" msgstr "" #: account/sidebar.html books/mybooks_breadcrumb_select.html +#: openlibrary/plugins/upstream/mybooks.py msgid "My Feed" msgstr "" @@ -2354,7 +2357,7 @@ msgstr "" msgid "Failed" msgstr "" -#: admin/imports_by_date.html +#: admin/imports_by_date.html openlibrary/core/edits.py msgid "Pending" msgstr "" @@ -2570,7 +2573,8 @@ msgid "Admin Center" msgstr "" #: RelatedSubjects.html SubjectTags.html admin/menu.html -#: admin/people/index.html admin/people/view.html type/author/view.html +#: admin/people/index.html admin/people/view.html +#: openlibrary/plugins/worksearch/code.py type/author/view.html #: type/list/view_body.html msgid "People" msgstr "" @@ -3076,7 +3080,7 @@ msgid "Anonymize Account" msgstr "" #: admin/people/view.html books/mybooks_breadcrumb_select.html -#: type/user/view.html +#: openlibrary/plugins/upstream/account.py type/user/view.html msgid "Loans" msgstr "" @@ -3821,36 +3825,50 @@ msgstr "" msgid "in %(languagelist)s" msgstr "" -#: books/mybooks_breadcrumb_select.html +#. Page title for the "Want to Read" shelf page. +#. Example: "Want to Read (17)". %(count)d is the number of books on this +#. shelf. +#: books/mybooks_breadcrumb_select.html openlibrary/plugins/upstream/mybooks.py #, python-format msgid "Want to Read (%(count)d)" msgstr "" -#: books/mybooks_breadcrumb_select.html +#. Page title for the "Currently Reading" shelf page. +#. Example: "Currently Reading (42)". %(count)d is the number of books on this +#. shelf. +#: books/mybooks_breadcrumb_select.html openlibrary/plugins/upstream/mybooks.py #, python-format msgid "Currently Reading (%(count)d)" msgstr "" -#: books/mybooks_breadcrumb_select.html +#. Page title for the "Already Read" shelf page. +#. Example: "Already Read (203)". %(count)d is the number of books on this +#. shelf. +#: books/mybooks_breadcrumb_select.html openlibrary/plugins/upstream/mybooks.py #, python-format msgid "Already Read (%(count)d)" msgstr "" -#: books/mybooks_breadcrumb_select.html +#. Page title for the "Stopped Reading" shelf page. +#. Example: "Stopped Reading (8)". %(count)d is the number of books on this +#. shelf. +#: books/mybooks_breadcrumb_select.html openlibrary/plugins/upstream/mybooks.py #, python-format msgid "Stopped Reading (%(count)d)" msgstr "" #: books/mybooks_breadcrumb_select.html +#: openlibrary/plugins/openlibrary/lists.py #, python-format msgid "Lists (%(count)d)" msgstr "" -#: books/mybooks_breadcrumb_select.html type/edition/modal_links.html +#: books/mybooks_breadcrumb_select.html openlibrary/plugins/upstream/mybooks.py +#: type/edition/modal_links.html msgid "Notes" msgstr "" -#: books/mybooks_breadcrumb_select.html +#: books/mybooks_breadcrumb_select.html openlibrary/plugins/upstream/account.py msgid "Imports and Exports" msgstr "" @@ -4778,7 +4796,7 @@ msgstr[1] "" msgid "Welcome to Open Library" msgstr "" -#: home/index.html +#: home/index.html openlibrary/plugins/openlibrary/api.py msgid "Classic Books" msgstr "" @@ -4786,19 +4804,21 @@ msgstr "" msgid "Recently Returned" msgstr "" -#: home/index.html +#: home/index.html openlibrary/plugins/openlibrary/api.py +#: openlibrary/plugins/openlibrary/home.py msgid "Romance" msgstr "" -#: home/index.html +#: home/index.html openlibrary/plugins/openlibrary/api.py msgid "Kids" msgstr "" -#: home/index.html +#: home/index.html openlibrary/plugins/openlibrary/api.py msgid "Thrillers" msgstr "" -#: home/index.html +#: home/index.html openlibrary/plugins/openlibrary/api.py +#: openlibrary/plugins/openlibrary/home.py msgid "Textbooks" msgstr "" @@ -5011,7 +5031,8 @@ msgstr "" #: RelatedSubjects.html SearchNavigation.html SubjectTags.html #: lib/browse_popover.html lib/nav_foot.html lib/nav_head.html -#: subjects/notfound.html type/author/view.html type/list/view_body.html +#: openlibrary/plugins/worksearch/code.py subjects/notfound.html +#: type/author/view.html type/list/view_body.html msgid "Subjects" msgstr "" @@ -5097,7 +5118,7 @@ msgid "New!" msgstr "" #: databarDiff.html databarEdit.html databarTemplate.html databarView.html -#: lib/history.html +#: lib/history.html openlibrary/plugins/openlibrary/home.py msgid "History" msgstr "" @@ -5174,7 +5195,7 @@ msgstr "" msgid "Just a sentence or two is good." msgstr "" -#: lib/nav_foot.html site/head.html +#: lib/nav_foot.html openlibrary/plugins/openlibrary/api.py site/head.html msgid "Open Library" msgstr "" @@ -5816,11 +5837,11 @@ msgstr "" msgid "Request Status" msgstr "" -#: merge_request_table/table_header.html +#: merge_request_table/table_header.html openlibrary/core/edits.py msgid "Merged" msgstr "" -#: merge_request_table/table_header.html +#: merge_request_table/table_header.html openlibrary/core/edits.py msgid "Declined" msgstr "" @@ -6121,8 +6142,8 @@ msgstr "" msgid "Publisher: %(name)s" msgstr "" -#: publishers/view.html search/advancedsearch.html type/edition/view.html -#: type/work/view.html +#: openlibrary/plugins/worksearch/code.py publishers/view.html +#: search/advancedsearch.html type/edition/view.html type/work/view.html msgid "Publisher" msgstr "" @@ -6407,15 +6428,15 @@ msgstr "" msgid "No authors directly matched your search" msgstr "" -#: search/availability_i18n.html +#: openlibrary/plugins/worksearch/code.py search/availability_i18n.html msgid "All books" msgstr "" -#: search/availability_i18n.html +#: openlibrary/plugins/worksearch/code.py search/availability_i18n.html msgid "Free to read now" msgstr "" -#: search/availability_i18n.html +#: openlibrary/plugins/worksearch/code.py search/availability_i18n.html msgid "Borrow online" msgstr "" @@ -6977,8 +6998,8 @@ msgstr "" msgid "— Show everything by this author?" msgstr "" -#: RelatedSubjects.html SubjectTags.html type/author/view.html -#: type/list/view_body.html +#: RelatedSubjects.html SubjectTags.html openlibrary/plugins/worksearch/code.py +#: type/author/view.html type/list/view_body.html msgid "Places" msgstr "" @@ -7447,7 +7468,8 @@ msgstr "" msgid "Derived from seed metadata" msgstr "" -#: RelatedSubjects.html SubjectTags.html type/list/view_body.html +#: RelatedSubjects.html SubjectTags.html openlibrary/plugins/worksearch/code.py +#: type/list/view_body.html msgid "Times" msgstr "" @@ -9138,3 +9160,407 @@ msgstr "" msgid "Buy this book" msgstr "" +#: openlibrary/core/bookshelves.py +msgid "[Record deleted]" +msgstr "" + +#: openlibrary/core/edits.py +msgid "Unknown" +msgstr "" + +#: openlibrary/plugins/openlibrary/api.py +msgid "Search Results" +msgstr "" + +#: openlibrary/plugins/openlibrary/code.py +msgid "Arabic" +msgstr "" + +#: openlibrary/plugins/openlibrary/code.py +msgid "Czech" +msgstr "" + +#: openlibrary/plugins/openlibrary/code.py +msgid "German" +msgstr "" + +#: openlibrary/plugins/openlibrary/code.py +msgid "English" +msgstr "" + +#: openlibrary/plugins/openlibrary/code.py +msgid "Spanish" +msgstr "" + +#: openlibrary/plugins/openlibrary/code.py +msgid "French" +msgstr "" + +#: openlibrary/plugins/openlibrary/code.py +msgid "Hindi" +msgstr "" + +#: openlibrary/plugins/openlibrary/code.py +msgid "Croatian" +msgstr "" + +#: openlibrary/plugins/openlibrary/code.py +msgid "Italian" +msgstr "" + +#: openlibrary/plugins/openlibrary/code.py +msgid "Korean" +msgstr "" + +#: openlibrary/plugins/openlibrary/code.py +msgid "Portuguese" +msgstr "" + +#: openlibrary/plugins/openlibrary/code.py +msgid "Romanian" +msgstr "" + +#: openlibrary/plugins/openlibrary/code.py +msgid "Sardinian" +msgstr "" + +#: openlibrary/plugins/openlibrary/code.py +msgid "Telugu" +msgstr "" + +#: openlibrary/plugins/openlibrary/code.py +msgid "Ukrainian" +msgstr "" + +#: openlibrary/plugins/openlibrary/code.py +msgid "Chinese" +msgstr "" + +#: openlibrary/plugins/openlibrary/code.py +msgid "Filipino" +msgstr "" + +#: openlibrary/plugins/openlibrary/home.py +msgid "Art" +msgstr "" + +#: openlibrary/plugins/openlibrary/home.py +msgid "Science Fiction" +msgstr "" + +#: openlibrary/plugins/openlibrary/home.py +msgid "Fantasy" +msgstr "" + +#: openlibrary/plugins/openlibrary/home.py +msgid "Biographies" +msgstr "" + +#: openlibrary/plugins/openlibrary/home.py +msgid "Recipes" +msgstr "" + +#: openlibrary/plugins/openlibrary/home.py +msgid "Children" +msgstr "" + +#: openlibrary/plugins/openlibrary/home.py +msgid "Medicine" +msgstr "" + +#: openlibrary/plugins/openlibrary/home.py +msgid "Religion" +msgstr "" + +#: openlibrary/plugins/openlibrary/home.py +msgid "Mystery and Detective Stories" +msgstr "" + +#: openlibrary/plugins/openlibrary/home.py +msgid "Plays" +msgstr "" + +#: openlibrary/plugins/openlibrary/home.py +msgid "Music" +msgstr "" + +#: openlibrary/plugins/openlibrary/home.py +msgid "Science" +msgstr "" + +#: openlibrary/plugins/openlibrary/librarian_dashboard.py +msgid "At least 1 subject" +msgstr "" + +#: openlibrary/plugins/openlibrary/librarian_dashboard.py +msgid "At least 1 author" +msgstr "" + +#: openlibrary/plugins/openlibrary/librarian_dashboard.py +msgid "At least 1 edition" +msgstr "" + +#: openlibrary/plugins/openlibrary/librarian_dashboard.py +msgid "Has work (orphaned)" +msgstr "" + +#: openlibrary/plugins/openlibrary/librarian_dashboard.py +msgid "Has publication year" +msgstr "" + +#: openlibrary/plugins/openlibrary/librarian_dashboard.py +msgid "Has cover" +msgstr "" + +#: openlibrary/plugins/openlibrary/librarian_dashboard.py +msgid "Has language" +msgstr "" + +#: openlibrary/plugins/openlibrary/librarian_dashboard.py +msgid "Has publisher" +msgstr "" + +#: openlibrary/plugins/openlibrary/librarian_dashboard.py +msgid "At least 2 editions" +msgstr "" + +#: openlibrary/plugins/openlibrary/librarian_dashboard.py +msgid "Has dewey decimal" +msgstr "" + +#: openlibrary/plugins/openlibrary/librarian_dashboard.py +msgid "Has LoC classification" +msgstr "" + +#: openlibrary/plugins/openlibrary/librarian_dashboard.py +msgid "Has number of pages" +msgstr "" + +#: openlibrary/plugins/openlibrary/lists.py +#, python-format +msgid "Are you sure you want to remove %(title)s from your list?" +msgstr "" + +#: openlibrary/plugins/openlibrary/partials.py +msgid "Better World Books" +msgstr "" + +#: openlibrary/plugins/openlibrary/partials.py +msgid " - includes shipping" +msgstr "" + +#: openlibrary/plugins/openlibrary/partials.py +msgid "Amazon" +msgstr "" + +#: openlibrary/plugins/openlibrary/partials.py +msgid "Bookshop.org" +msgstr "" + +#: openlibrary/plugins/openlibrary/partials.py +msgid "This work does not appear on any lists." +msgstr "" + +#: openlibrary/plugins/openlibrary/pd.py +msgid "I don't have one yet" +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "The email address you entered is invalid" +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "This account has been blocked" +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "This account has been locked" +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "No account was found with this email. Please try again" +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "The password you entered is incorrect. Please try again" +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "Wrong password. Please try again" +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "Please verify your Open Library account before logging in" +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "Please verify your Internet Archive account before logging in" +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "Please fill out all fields and try again" +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "This email is already registered" +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "This username is already registered" +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "A problem occurred and we were unable to log you in." +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "Login attempted with invalid Internet Archive s3 credentials." +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "" +"Servers are experiencing unusually high traffic, please try again later " +"or email openlibrary@archive.org for help." +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "Email provider not recognized." +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "Password requirements not met." +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "A problem occurred and we were unable to log you in" +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "" +"Login or registration attempt hit an unexpected error, please try again " +"or contact info@archive.org" +msgstr "" + +#: openlibrary/plugins/upstream/account.py +#, python-format +msgid "Request failed with error code: %(error_code)s" +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "" +"Thank you for registering an Open Library account and requesting special " +"print disability access. You should receive an email detailing next steps" +" in the process." +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "Username unavailable" +msgstr "" + +#: openlibrary/plugins/upstream/account.py +#: openlibrary/plugins/upstream/forms.py +msgid "Email already registered" +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "An Internet Archive account already exists with this email" +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "" +"Verification failed. The link may be invalid or expired. Please try " +"registering again." +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "Your email has been verified. You are now logged in." +msgstr "" + +#: openlibrary/plugins/upstream/account.py +msgid "Notification preferences have been updated successfully." +msgstr "" + +#: openlibrary/plugins/upstream/borrow.py +msgid "this book" +msgstr "" + +#: openlibrary/plugins/upstream/borrow.py +#, python-format +msgid "Unable to return %s. Please try again later or contact info@archive.org." +msgstr "" + +#: openlibrary/plugins/upstream/borrow.py +#, python-format +msgid "%s has been returned." +msgstr "" + +#: openlibrary/plugins/upstream/borrow.py +msgid "" +"Your account has hit a lending limit. Please try again later or contact " +"info@archive.org." +msgstr "" + +#: openlibrary/plugins/upstream/forms.py +msgid "Username" +msgstr "" + +#: openlibrary/plugins/upstream/forms.py +msgid "No user registered with this email address" +msgstr "" + +#: openlibrary/plugins/upstream/forms.py +msgid "Disposable email not permitted" +msgstr "" + +#: openlibrary/plugins/upstream/forms.py +msgid "Your email provider is not recognized." +msgstr "" + +#: openlibrary/plugins/upstream/forms.py +msgid "Username already used" +msgstr "" + +#: openlibrary/plugins/upstream/forms.py +msgid "Must be between 3 and 20 letters and numbers" +msgstr "" + +#: openlibrary/plugins/upstream/forms.py +msgid "Screen Name" +msgstr "" + +#: openlibrary/plugins/upstream/forms.py +msgid "Public and cannot be changed later." +msgstr "" + +#: openlibrary/plugins/upstream/forms.py +msgid "Invalid password" +msgstr "" + +#: openlibrary/plugins/upstream/forms.py +msgid "Your email address" +msgstr "" + +#: openlibrary/plugins/upstream/forms.py +msgid "Choose a password" +msgstr "" + +#: openlibrary/plugins/upstream/mybooks.py +#, python-format +msgid "" +"Continue %(action)s " +"%(name)s" +msgstr "" + +#: openlibrary/plugins/worksearch/code.py +msgid "eBook?" +msgstr "" + +#: openlibrary/plugins/worksearch/code.py +msgid "First published" +msgstr "" + +#: openlibrary/plugins/worksearch/code.py +msgid "Classic eBooks" +msgstr "" + From 4381037d99762e5a6950581e7d83366de12d2b63 Mon Sep 17 00:00:00 2001 From: Tanishq Sangwan Date: Thu, 16 Jul 2026 21:38:35 +0530 Subject: [PATCH 3/5] fix(ci): touch node_modules to prevent concurrent npm ci runs and speed up docker builds --- docker/Dockerfile.olbase | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/Dockerfile.olbase b/docker/Dockerfile.olbase index e20dfd45490..1bdb76cf21f 100644 --- a/docker/Dockerfile.olbase +++ b/docker/Dockerfile.olbase @@ -85,4 +85,5 @@ RUN npm ci --no-audit COPY --chown=openlibrary:openlibrary . /openlibrary # run make to initialize git submodules, build css and js files RUN ln -s vendor/infogami/infogami infogami \ + && touch node_modules \ && make From a36b3037d8ae47f824c2b99845168e6ad02a2505 Mon Sep 17 00:00:00 2001 From: Tanishq Sangwan Date: Thu, 16 Jul 2026 21:41:07 +0530 Subject: [PATCH 4/5] chore(ci): increase page-admin.css bundlesize maxSize to 28KB --- bundlesize.config.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bundlesize.config.json b/bundlesize.config.json index d4e46bab4bd..afa5cda2da6 100644 --- a/bundlesize.config.json +++ b/bundlesize.config.json @@ -58,8 +58,7 @@ }, { "path": "static/build/css/page-admin.css", - "maxSize": "27KB" - + "maxSize": "28KB" }, { "path": "static/build/css/page-book.css", From 9d3363e2f0909f27c6d55da9b66b6be01811baad Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 17 Jul 2026 07:20:10 +0000 Subject: [PATCH 5/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- openlibrary/i18n/messages.pot | 412 +--------------------------------- 1 file changed, 4 insertions(+), 408 deletions(-) diff --git a/openlibrary/i18n/messages.pot b/openlibrary/i18n/messages.pot index e9f92da9799..28697e624d8 100644 --- a/openlibrary/i18n/messages.pot +++ b/openlibrary/i18n/messages.pot @@ -8381,6 +8381,10 @@ msgstr "" msgid "View Volume %(num)d" msgstr "" +#: databarWork.html +msgid "Buy this book" +msgstr "" + #: openlibrary/core/bookshelves.py msgid "[Record deleted]" msgstr "" @@ -9156,411 +9160,3 @@ msgstr "" msgid "Classic eBooks" msgstr "" -#: databarWork.html -msgid "Buy this book" -msgstr "" - -#: openlibrary/core/bookshelves.py -msgid "[Record deleted]" -msgstr "" - -#: openlibrary/core/edits.py -msgid "Unknown" -msgstr "" - -#: openlibrary/plugins/openlibrary/api.py -msgid "Search Results" -msgstr "" - -#: openlibrary/plugins/openlibrary/code.py -msgid "Arabic" -msgstr "" - -#: openlibrary/plugins/openlibrary/code.py -msgid "Czech" -msgstr "" - -#: openlibrary/plugins/openlibrary/code.py -msgid "German" -msgstr "" - -#: openlibrary/plugins/openlibrary/code.py -msgid "English" -msgstr "" - -#: openlibrary/plugins/openlibrary/code.py -msgid "Spanish" -msgstr "" - -#: openlibrary/plugins/openlibrary/code.py -msgid "French" -msgstr "" - -#: openlibrary/plugins/openlibrary/code.py -msgid "Hindi" -msgstr "" - -#: openlibrary/plugins/openlibrary/code.py -msgid "Croatian" -msgstr "" - -#: openlibrary/plugins/openlibrary/code.py -msgid "Italian" -msgstr "" - -#: openlibrary/plugins/openlibrary/code.py -msgid "Korean" -msgstr "" - -#: openlibrary/plugins/openlibrary/code.py -msgid "Portuguese" -msgstr "" - -#: openlibrary/plugins/openlibrary/code.py -msgid "Romanian" -msgstr "" - -#: openlibrary/plugins/openlibrary/code.py -msgid "Sardinian" -msgstr "" - -#: openlibrary/plugins/openlibrary/code.py -msgid "Telugu" -msgstr "" - -#: openlibrary/plugins/openlibrary/code.py -msgid "Ukrainian" -msgstr "" - -#: openlibrary/plugins/openlibrary/code.py -msgid "Chinese" -msgstr "" - -#: openlibrary/plugins/openlibrary/code.py -msgid "Filipino" -msgstr "" - -#: openlibrary/plugins/openlibrary/home.py -msgid "Art" -msgstr "" - -#: openlibrary/plugins/openlibrary/home.py -msgid "Science Fiction" -msgstr "" - -#: openlibrary/plugins/openlibrary/home.py -msgid "Fantasy" -msgstr "" - -#: openlibrary/plugins/openlibrary/home.py -msgid "Biographies" -msgstr "" - -#: openlibrary/plugins/openlibrary/home.py -msgid "Recipes" -msgstr "" - -#: openlibrary/plugins/openlibrary/home.py -msgid "Children" -msgstr "" - -#: openlibrary/plugins/openlibrary/home.py -msgid "Medicine" -msgstr "" - -#: openlibrary/plugins/openlibrary/home.py -msgid "Religion" -msgstr "" - -#: openlibrary/plugins/openlibrary/home.py -msgid "Mystery and Detective Stories" -msgstr "" - -#: openlibrary/plugins/openlibrary/home.py -msgid "Plays" -msgstr "" - -#: openlibrary/plugins/openlibrary/home.py -msgid "Music" -msgstr "" - -#: openlibrary/plugins/openlibrary/home.py -msgid "Science" -msgstr "" - -#: openlibrary/plugins/openlibrary/librarian_dashboard.py -msgid "At least 1 subject" -msgstr "" - -#: openlibrary/plugins/openlibrary/librarian_dashboard.py -msgid "At least 1 author" -msgstr "" - -#: openlibrary/plugins/openlibrary/librarian_dashboard.py -msgid "At least 1 edition" -msgstr "" - -#: openlibrary/plugins/openlibrary/librarian_dashboard.py -msgid "Has work (orphaned)" -msgstr "" - -#: openlibrary/plugins/openlibrary/librarian_dashboard.py -msgid "Has publication year" -msgstr "" - -#: openlibrary/plugins/openlibrary/librarian_dashboard.py -msgid "Has cover" -msgstr "" - -#: openlibrary/plugins/openlibrary/librarian_dashboard.py -msgid "Has language" -msgstr "" - -#: openlibrary/plugins/openlibrary/librarian_dashboard.py -msgid "Has publisher" -msgstr "" - -#: openlibrary/plugins/openlibrary/librarian_dashboard.py -msgid "At least 2 editions" -msgstr "" - -#: openlibrary/plugins/openlibrary/librarian_dashboard.py -msgid "Has dewey decimal" -msgstr "" - -#: openlibrary/plugins/openlibrary/librarian_dashboard.py -msgid "Has LoC classification" -msgstr "" - -#: openlibrary/plugins/openlibrary/librarian_dashboard.py -msgid "Has number of pages" -msgstr "" - -#: openlibrary/plugins/openlibrary/lists.py -#, python-format -msgid "Are you sure you want to remove %(title)s from your list?" -msgstr "" - -#: openlibrary/plugins/openlibrary/partials.py -msgid "Better World Books" -msgstr "" - -#: openlibrary/plugins/openlibrary/partials.py -msgid " - includes shipping" -msgstr "" - -#: openlibrary/plugins/openlibrary/partials.py -msgid "Amazon" -msgstr "" - -#: openlibrary/plugins/openlibrary/partials.py -msgid "Bookshop.org" -msgstr "" - -#: openlibrary/plugins/openlibrary/partials.py -msgid "This work does not appear on any lists." -msgstr "" - -#: openlibrary/plugins/openlibrary/pd.py -msgid "I don't have one yet" -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "The email address you entered is invalid" -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "This account has been blocked" -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "This account has been locked" -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "No account was found with this email. Please try again" -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "The password you entered is incorrect. Please try again" -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "Wrong password. Please try again" -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "Please verify your Open Library account before logging in" -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "Please verify your Internet Archive account before logging in" -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "Please fill out all fields and try again" -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "This email is already registered" -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "This username is already registered" -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "A problem occurred and we were unable to log you in." -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "Login attempted with invalid Internet Archive s3 credentials." -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "" -"Servers are experiencing unusually high traffic, please try again later " -"or email openlibrary@archive.org for help." -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "Email provider not recognized." -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "Password requirements not met." -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "A problem occurred and we were unable to log you in" -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "" -"Login or registration attempt hit an unexpected error, please try again " -"or contact info@archive.org" -msgstr "" - -#: openlibrary/plugins/upstream/account.py -#, python-format -msgid "Request failed with error code: %(error_code)s" -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "" -"Thank you for registering an Open Library account and requesting special " -"print disability access. You should receive an email detailing next steps" -" in the process." -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "Username unavailable" -msgstr "" - -#: openlibrary/plugins/upstream/account.py -#: openlibrary/plugins/upstream/forms.py -msgid "Email already registered" -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "An Internet Archive account already exists with this email" -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "" -"Verification failed. The link may be invalid or expired. Please try " -"registering again." -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "Your email has been verified. You are now logged in." -msgstr "" - -#: openlibrary/plugins/upstream/account.py -msgid "Notification preferences have been updated successfully." -msgstr "" - -#: openlibrary/plugins/upstream/borrow.py -msgid "this book" -msgstr "" - -#: openlibrary/plugins/upstream/borrow.py -#, python-format -msgid "Unable to return %s. Please try again later or contact info@archive.org." -msgstr "" - -#: openlibrary/plugins/upstream/borrow.py -#, python-format -msgid "%s has been returned." -msgstr "" - -#: openlibrary/plugins/upstream/borrow.py -msgid "" -"Your account has hit a lending limit. Please try again later or contact " -"info@archive.org." -msgstr "" - -#: openlibrary/plugins/upstream/forms.py -msgid "Username" -msgstr "" - -#: openlibrary/plugins/upstream/forms.py -msgid "No user registered with this email address" -msgstr "" - -#: openlibrary/plugins/upstream/forms.py -msgid "Disposable email not permitted" -msgstr "" - -#: openlibrary/plugins/upstream/forms.py -msgid "Your email provider is not recognized." -msgstr "" - -#: openlibrary/plugins/upstream/forms.py -msgid "Username already used" -msgstr "" - -#: openlibrary/plugins/upstream/forms.py -msgid "Must be between 3 and 20 letters and numbers" -msgstr "" - -#: openlibrary/plugins/upstream/forms.py -msgid "Screen Name" -msgstr "" - -#: openlibrary/plugins/upstream/forms.py -msgid "Public and cannot be changed later." -msgstr "" - -#: openlibrary/plugins/upstream/forms.py -msgid "Invalid password" -msgstr "" - -#: openlibrary/plugins/upstream/forms.py -msgid "Your email address" -msgstr "" - -#: openlibrary/plugins/upstream/forms.py -msgid "Choose a password" -msgstr "" - -#: openlibrary/plugins/upstream/mybooks.py -#, python-format -msgid "" -"Continue %(action)s " -"%(name)s" -msgstr "" - -#: openlibrary/plugins/worksearch/code.py -msgid "eBook?" -msgstr "" - -#: openlibrary/plugins/worksearch/code.py -msgid "First published" -msgstr "" - -#: openlibrary/plugins/worksearch/code.py -msgid "Classic eBooks" -msgstr "" -