.oO SearXNG Developer Documentation Oo.
Loading...
Searching...
No Matches
openlibrary.py
Go to the documentation of this file.
1# SPDX-License-Identifier: AGPL-3.0-or-later
2"""`Open Library`_ is an open, editable library catalog, building towards a web
3page for every book ever published.
4
5.. _Open Library: https://openlibrary.org
6
7Configuration
8=============
9
10The service sometimes takes a very long time to respond, the ``timeout`` may
11need to be adjusted.
12
13.. code:: yaml
14
15 - name: openlibrary
16 engine: openlibrary
17 shortcut: ol
18 timeout: 10
19
20
21Implementations
22===============
23
24"""
25
26from datetime import datetime
27import typing as t
28
29from urllib.parse import urlencode
30from dateutil import parser
31
32from searx.result_types import EngineResults
33
34if t.TYPE_CHECKING:
35 from searx.extended_types import SXNG_Response
36 from searx.search.processors import OnlineParams
37
38about = {
39 "website": "https://openlibrary.org",
40 "wikidata_id": "Q1201876",
41 "require_api_key": False,
42 "use_official_api": False,
43 "official_api_documentation": "https://openlibrary.org/developers/api",
44}
45
46paging = True
47categories = ["general", "books"]
48
49base_url = "https://openlibrary.org"
50search_api = "https://openlibrary.org/search.json"
51"""The engine uses the API at the endpoint search.json_.
52
53.. _search.json: https://openlibrary.org/dev/docs/api/search
54"""
55results_per_page = 10
56
57
58def request(query: str, params: "OnlineParams") -> None:
59 args = {
60 "q": query,
61 "page": params["pageno"],
62 "limit": results_per_page,
63 "fields": "*",
64 }
65 params["url"] = f"{search_api}?{urlencode(args)}"
66 logger.debug("REST API: %s", params["url"])
67
68
69def response(resp: "SXNG_Response") -> EngineResults:
70 res = EngineResults()
71 json_data = resp.json()
72
73 for item in json_data.get("docs", []):
74 cover = ""
75 if "lending_identifier_s" in item:
76 cover = f"https://archive.org/services/img/{item['lending_identifier_s']}"
77
78 published = item.get("publish_date")
79 if published:
80 published_dates = [date for date in map(_parse_date, published) if date]
81 if published_dates:
82 published = min(published_dates)
83
84 if not published:
85 published = _parse_date(str(item.get("first_publish_year")))
86
87 content = " / ".join(item.get("first_sentence", []))
88 res.add(
89 res.types.Paper(
90 url=f"{base_url}/{item['key']}",
91 title=item["title"],
92 content=content,
93 isbn=item.get("isbn", [])[:5],
94 authors=item.get("author_name", []),
95 thumbnail=cover,
96 publishedDate=published,
97 tags=item.get("subject", [])[:10] + item.get("place", [])[:10],
98 )
99 )
100 return res
101
102
103def _parse_date(date: str) -> datetime | None:
104 if not date:
105 return None
106 try:
107 return parser.parse(date)
108 except parser.ParserError:
109 return None
datetime|None _parse_date(str date)
EngineResults response("SXNG_Response" resp)
None request(str query, "OnlineParams" params)