-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #15 from MITLibraries/engx244-lookups
Adds data lookup for detected standard identifiers
- Loading branch information
Showing
26 changed files
with
1,095 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
LINKRESOLVER_BASEURL=https://mit.primo.exlibrisgroup.com/discovery/openurl?institution=01MIT_INST&rfr_id=info:sid/mit.tacos.api&vid=01MIT_INST:MIT | ||
UNPAYWALL_EMAIL=timdex@mit.edu |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,7 @@ | ||
# tacos | ||
# tacos | ||
|
||
## Required Environment Variables | ||
|
||
`LINKRESOLVER_BASEURL`: base url for our link resolver. `https://mit.primo.exlibrisgroup.com/discovery/openurl?institution=01MIT_INST&rfr_id=info:sid/mit.tacos.api&vid=01MIT_INST:MIT` is probably the best value unless you are doing something interesting. | ||
|
||
`UNPAYWALL_EMAIL`: email address to include in API call as required in their [documentation](https://unpaywall.org/products/api). Your personal email is appropriate for development. Deployed and for tests, use the timdex moira list email. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# frozen_string_literal: true | ||
|
||
module Types | ||
class DetailsType < Types::BaseObject | ||
field :title, String | ||
field :authors, [String] | ||
field :date, String | ||
field :publisher, String | ||
field :oa, Boolean | ||
field :oa_status, String | ||
field :best_oa_location, String | ||
field :issns, [String] | ||
field :journal_name, String | ||
field :doi, String | ||
field :link_resolver_url, String | ||
|
||
def issns | ||
@object[:journal_issns]&.split(',') | ||
end | ||
|
||
def authors | ||
@object[:authors]&.split(',') | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# frozen_string_literal: true | ||
|
||
class LookupDoi | ||
def info(doi) | ||
external_data = fetch(doi) | ||
return if external_data == 'Error' | ||
|
||
metadata = extract_metadata(external_data) | ||
metadata[:doi] = doi | ||
metadata[:link_resolver_url] = link_resolver_url(metadata) | ||
metadata | ||
end | ||
|
||
private | ||
|
||
# NOTE: authors are available as objects within `'z_authors` but is somewhat | ||
# complicated so wasn't implemented during this initial work | ||
def extract_metadata(external_data) | ||
{ | ||
genre: external_data['genre'], | ||
title: external_data['title'], | ||
date: external_data['year'], | ||
publisher: external_data['publisher'], | ||
oa: external_data['is_oa'], | ||
oa_status: external_data['oa_status'], | ||
best_oa_location: external_data['best_oa_location'], | ||
journal_issns: external_data['journal_issns'], | ||
journal_name: external_data['journal_name'] | ||
} | ||
end | ||
|
||
def url(doi) | ||
"https://api.unpaywall.org/v2/#{doi}?email=#{ENV.fetch('UNPAYWALL_EMAIL')}" | ||
end | ||
|
||
def fetch(doi) | ||
resp = HTTP.headers(accept: 'application/json').get(url(doi)) | ||
if resp.status == 200 | ||
JSON.parse(resp.to_s) | ||
else | ||
Rails.logger.debug("Fact lookup error. DOI #{doi} detected but unpaywall returned no data or otherwise errored") | ||
Rails.logger.debug("URL: #{url(doi)}") | ||
'Error' | ||
end | ||
end | ||
|
||
def link_resolver_url(metadata) | ||
"#{ENV.fetch('LINKRESOLVER_BASEURL')}&rft.atitle=#{metadata[:title]}&rft.date=#{metadata[:year]}&rft.genre=#{metadata[:genre]}&rft.jtitle=#{metadata[:journal_name]}&rft_id=info:doi/#{metadata[:doi]}" | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# frozen_string_literal: true | ||
|
||
class LookupIsbn | ||
def info(isbn) | ||
json = fetch_isbn(isbn) | ||
return if json == 'Error' | ||
|
||
{ | ||
title: json['title'], | ||
date: json['publish_date'], | ||
publisher: json['publishers'].join(','), | ||
authors: fetch_authors(json), | ||
link_resolver_url: link_resolver_url(isbn) | ||
} | ||
end | ||
|
||
def base_url | ||
'https://openlibrary.org' | ||
end | ||
|
||
def fetch_isbn(isbn) | ||
url = [base_url, "/isbn/#{isbn}.json"].join | ||
parse_response(url) | ||
end | ||
|
||
def fetch_authors(isbn_json) | ||
return unless isbn_json['authors'] | ||
|
||
authors = isbn_json['authors'].map { |a| a['key'] } | ||
author_names = authors.map do |author| | ||
url = [base_url, author, '.json'].join | ||
json = parse_response(url) | ||
json['name'] | ||
end | ||
author_names.join(' ; ') | ||
end | ||
|
||
def parse_response(url) | ||
resp = HTTP.headers(accept: 'application/json', 'Content-Type': 'application/json').follow.get(url) | ||
|
||
if resp.status == 200 | ||
JSON.parse(resp.to_s) | ||
else | ||
Rails.logger.debug('Fact lookup error: openlibrary returned no data') | ||
Rails.logger.debug("URL: #{url}") | ||
'Error' | ||
end | ||
end | ||
|
||
def link_resolver_url(isbn) | ||
"#{ENV.fetch('LINKRESOLVER_BASEURL')}&rft.isbn=#{isbn}" | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# frozen_string_literal: true | ||
|
||
# LookupIssn assumes the ISSN being supplied has been validated prior to this Class being used. | ||
# In this application, we only LookupIssns that have been detected in StandardIdentifiers which performs | ||
# that validation for us. If extracting this logic to be used elsewhere, it is highly recommended to validate | ||
# ISSNs before doing an external lookup. | ||
class LookupIssn | ||
def info(issn) | ||
json = fetch(issn) | ||
return if json == 'Error' | ||
|
||
metadata = extract_metadata(json) | ||
metadata[:link_resolver_url] = openurl(issn) | ||
metadata | ||
end | ||
|
||
def extract_metadata(response) | ||
{ | ||
journal_name: response['message']['title'], | ||
publisher: response['message']['publisher'], | ||
journal_issns: response['message']['ISSN'].join(',') | ||
} | ||
end | ||
|
||
def url(issn) | ||
"https://api.crossref.org/journals/#{issn}" | ||
end | ||
|
||
def fetch(issn) | ||
resp = HTTP.headers(accept: 'application/json').get(url(issn)) | ||
if resp.status == 200 | ||
JSON.parse(resp.to_s) | ||
else | ||
Rails.logger.debug("ISSN Lookup error. ISSN #{issn} detected but crossref returned no data") | ||
Rails.logger.debug("URL: #{url(issn)}") | ||
'Error' | ||
end | ||
end | ||
|
||
def openurl(issn) | ||
"#{ENV.fetch('LINKRESOLVER_BASEURL')}&rft.issn=#{issn}" | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# frozen_string_literal: true | ||
|
||
class LookupPmid | ||
def info(pmid) | ||
xml = fetch(pmid) | ||
return if xml == 'Error' | ||
|
||
metadata = extract_metadata(xml) | ||
metadata[:pmid] = pmid | ||
metadata[:link_resolver_url] = link_resolver_url(metadata) | ||
|
||
if metadata.reject { |_k, v| v.empty? }.present? | ||
metadata | ||
else | ||
Rails.logger.debug("Fact lookup error. PMID #{pmid} detected but ncbi returned no data") | ||
nil | ||
end | ||
end | ||
|
||
def extract_metadata(xml) | ||
{ | ||
title: xml.xpath('//ArticleTitle').text, | ||
journal_name: xml.xpath('//Journal/Title').text, | ||
journal_volume: xml.xpath('//Journal/JournalIssue/Volume').text, | ||
date: xml.xpath('//Journal/JournalIssue/PubDate/Year').text, | ||
doi: xml.xpath('//PubmedData/ArticleIdList/ArticleId[@IdType="doi"]').text | ||
} | ||
end | ||
|
||
def url(pmid) | ||
"https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&id=#{pmid}&retmode=xml" | ||
end | ||
|
||
def fetch(pmid) | ||
resp = HTTP.headers(accept: 'application/xml').get(url(pmid)) | ||
|
||
if resp.status == 200 | ||
Nokogiri::XML(resp.to_s) | ||
else | ||
Rails.logger.debug("Fact lookup error. PMID #{pmid} detected but ncbi an error status") | ||
Rails.logger.debug("URL: #{url(pmid)}") | ||
'Error' | ||
end | ||
end | ||
|
||
def link_resolver_url(metadata) | ||
"#{ENV.fetch('LINKRESOLVER_BASEURL')}&rft.atitle=#{metadata[:title]}&rft.date=#{metadata[:date]}&rft.jtitle=#{metadata[:journal_name]}&rft_id=info:doi/#{metadata[:doi]}" | ||
end | ||
end |
Oops, something went wrong.