-
Notifications
You must be signed in to change notification settings - Fork 3
/
fetcher.rb
46 lines (39 loc) · 1.8 KB
/
fetcher.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# frozen_string_literal: true
module Pubmed
# For fetching single publications by pmid.
class Fetcher
# Searches locally (twice), then ScienceWire/WOS, then Pubmed for a publication by PubmedId
# Is paranoid, searches both publications and publication_identifiers identifiers for pmid
# @param [String] pmid Pubmed ID
# @return [Array<Hash>] publications in BibJson format or, if none found, an empty Array
def self.search_all_sources_by_pmid(pmid)
pub = Publication.find_by(pmid:) || Publication.find_by_pmid_pub_id(pmid)
return [pub.pub_hash] if pub&.authoritative_pmid_source?
result = fetch_remote_pubmed(pmid)
return result unless result.empty?
pub.blank? ? [] : [pub.pub_hash] # non-authoritative local hit if found
end
# @param [String] pmid Pubmed ID
# @return [Array<Hash>] pub_hashes or an empty Array
def self.fetch_remote_pubmed(pmid)
# NOTE: only works because all results expected to fit inside one "batch"
if Settings.WOS.enabled
result = WebOfScience.queries.retrieve_by_id(["MEDLINE:#{pmid}"]).next_batch.map { |rec| add_citation(rec.pub_hash) }
return result unless result.empty?
end
return [] unless Settings.PUBMED.lookup_enabled
# PubMed, oddly enough, the last resort
pm_xml = Pubmed.client.fetch_records_for_pmid_list(pmid)
Nokogiri::XML(pm_xml).xpath('//PubmedArticle').map do |doc|
add_citation(Pubmed::MapPubHash.map(doc.to_xml))
end
end
private_class_method :fetch_remote_pubmed
# @param [Hash] pub_hash modifies passed hash to include citation k/v pairs
# @return [Hash] the same modified hash
def self.add_citation(pub_hash)
pub_hash.update Csl::Citation.new(pub_hash).citations
end
private_class_method :add_citation
end
end