49 lines
2.4 KiB
Python
Executable file
49 lines
2.4 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
"""Open Library search — the "English RSL" for author works lists.
|
|
|
|
Usage: tools/ol.py "Neumann, Erich" [title_words] [limit]
|
|
|
|
Output: one line per title: title | years | languages | sample publishers | sample ISBN.
|
|
Open Library aggregates all editions of a work into one doc (author_name, publish_year[],
|
|
language[], publisher[], isbn[]) — i.e. it answers "what did this EN author write" and
|
|
"which languages/years exist" — the missing half of our RSL (RU-only) pipeline.
|
|
NO RU editions are indexed (checked: language=rus → 0 for known RU books) — RU hunting
|
|
still goes through RSL/libgen/flibusta.
|
|
"""
|
|
import json, sys, time, urllib.parse, urllib.request
|
|
|
|
UA = "research-tools/1.0 (jung booklist research; contact: dmitry@kokorin.org)"
|
|
|
|
def ol_search(q, fields="title,author_name,publish_year,language,publisher,isbn,original_title", limit=40):
|
|
url = "https://openlibrary.org/search.json?" + urllib.parse.urlencode({
|
|
"q": q, "fields": fields, "limit": min(limit, 100)})
|
|
req = urllib.request.Request(url, headers={"User-Agent": UA})
|
|
with urllib.request.urlopen(req, timeout=40) as r:
|
|
return json.load(r)
|
|
|
|
def main():
|
|
if len(sys.argv) < 2:
|
|
sys.exit(__doc__)
|
|
first = sys.argv[1]
|
|
# raw query passthrough (e.g. 'title:"..."'); else treat as author name
|
|
if first.startswith(("title:", "subject:", "isbn:", "publisher:")):
|
|
q = " ".join(sys.argv[1:-1]) if sys.argv[-1].isdigit() else " ".join(sys.argv[1:])
|
|
else:
|
|
rest = " ".join(sys.argv[2:-1]) if sys.argv[-1].isdigit() else " ".join(sys.argv[2:])
|
|
q = f"author:{first}" + (f" title:{rest}" if rest else "")
|
|
limit = int(sys.argv[-1]) if sys.argv[-1].isdigit() else 40
|
|
d = ol_search(q, limit=limit)
|
|
print(f"numFound: {d.get('numFound')}")
|
|
for doc in d.get("docs", []):
|
|
years = sorted(set(doc.get("publish_year") or []))
|
|
ys = f"{years[0]}-{years[-1]}" if len(years) > 1 else (str(years[0]) if years else "?")
|
|
langs = ",".join(doc.get("language") or [])
|
|
pubs = sorted(set(p[:30] for p in (doc.get("publisher") or [])))[:3]
|
|
isbns = (doc.get("isbn") or [])[:2]
|
|
ot = doc.get("original_title") or ""
|
|
an = ", ".join(doc.get("author_name") or [])
|
|
print(f"- {doc.get('title')} | {an} | {ys} | {langs} | {'; '.join(pubs)} | {isbns} | {doc.get('key','')} | {ot}")
|
|
time.sleep(1)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|