First Commit
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
import logging
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class UnpaywallResolver:
|
||||
def __init__(self, email: str, timeout=(10, 30)):
|
||||
self.email = (email or "").strip()
|
||||
self.timeout = timeout
|
||||
self.base_url = "https://api.unpaywall.org/v2"
|
||||
|
||||
def resolve(self, paper):
|
||||
if not paper.doi:
|
||||
return paper
|
||||
|
||||
if not self.email:
|
||||
log.warning(
|
||||
"Unpaywall email missing; OA lookup skipped: %s",
|
||||
paper.title,
|
||||
)
|
||||
return paper
|
||||
|
||||
doi = paper.doi.strip()
|
||||
|
||||
try:
|
||||
response = requests.get(
|
||||
f"{self.base_url}/{doi}",
|
||||
params={"email": self.email},
|
||||
timeout=self.timeout,
|
||||
)
|
||||
response.raise_for_status()
|
||||
|
||||
except requests.exceptions.HTTPError as exc:
|
||||
status = exc.response.status_code if exc.response else None
|
||||
|
||||
# DOI not present in Unpaywall is not fatal.
|
||||
if status == 404:
|
||||
paper.oa_status = "not_found"
|
||||
return paper
|
||||
|
||||
raise
|
||||
|
||||
data = response.json()
|
||||
|
||||
paper.oa_status = str(
|
||||
data.get("oa_status") or ""
|
||||
)
|
||||
|
||||
best = data.get("best_oa_location") or {}
|
||||
|
||||
pdf_url = best.get("url_for_pdf") or ""
|
||||
|
||||
# Some OA records do not expose url_for_pdf but do expose a landing URL.
|
||||
# We intentionally do NOT treat url as a PDF here.
|
||||
paper.pdf_url = str(pdf_url).strip()
|
||||
|
||||
return paper
|
||||
Reference in New Issue
Block a user