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 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
require 'open-uri'
require 'json'
require 'yaml'
ACCEPT_CITE_JSON = {"Accept" => "application/citeproc+json"}
def doi_fetch_and_convert(doi, fuzzy: false, verbose: false, site: "https://dx.doi.org")
doipath = doi.sub(/^([0-9.]+)_/) {"#$1/"} # convert initial _ back to /
# warn "** SUB #{doi} #{doipath}" if doi != doipath
begin
cite = JSON.parse(URI("#{site}/#{doipath}").open(ACCEPT_CITE_JSON).read)
puts cite.to_yaml if verbose
doi_citeproc_to_lit(cite, fuzzy)
rescue OpenURI::HTTPError => e
begin
site = "https://dl.acm.org"
percent_escaped = doipath.gsub("/", "%2F")
path = "#{site}/action/exportCiteProcCitation?targetFile=custom-bibtex&format=bibTex&dois=#{percent_escaped}"
op = URI(path).open # first get a cookie, ignore result
# warn [:META, op.meta].inspect
cook = op.meta['set-cookie'].split('; ', 2)[0]
cite = JSON.parse(URI(path).open("Cookie" => cook).read)
cite = cite["items"].first[doipath]
puts cite.to_yaml if verbose
doi_citeproc_to_lit(cite, fuzzy)
rescue
raise e
end
end
end
def doi_citeproc_to_lit(cite, fuzzy)
lit = {}
ser = lit["seriesinfo"] = {}
refcontent = []
lit["title"] = cite["title"]
if (st = cite["subtitle"]) && Array === st # defensive
st.delete('')
if st != []
lit["title"] << ": " << st.join("; ")
end
end
if authors = cite["author"]
lit["author"] = authors.map do |au|
lau = {}
if (f = au["family"])
if (g = au["given"])
lau["name"] = "#{g} #{f}"
lau["ins"] = "#{g[0]}. #{f}"
else
lau["name"] = "#{f}"
# lau["ins"] = "#{g[0]}. #{f}"
end
end
if (f = au["affiliation"]) && Array === f
names = f.map { |affn|
if Hash === affn && (n = affn["name"]) && String === n
n
end
}.compact
if names.size > 0
lau["org"] = names.join("; ")
end
end
lau
end
end
if iss = cite["issued"]
if dp = iss["date-parts"]
if Integer === (dp = dp[0])[0]
lit["date"] = ["%04d" % dp[0], *dp[1..-1].map {|p| "%02d" % p}].join("-")
end
end
end
if !lit.key?("date") && fuzzy && (iss = cite["created"])
if dp = iss["date-parts"]
if Integer === (dp = dp[0])[0]
lit["date"] = ["%04d" % dp[0], *dp[1..-1].map {|p| "%02d" % p}].join("-")
end
end
end
if (ct = cite["container-title"]) && ct != []
info = []
if v = cite["volume"]
vi = "vol. #{v}"
if (v = cite["journal-issue"]) && (issue = v["issue"])
vi << ", no. #{issue}"
end
info << vi
end
if p = cite["page"]
info << "pp. #{p}"
end
rhs = info.join(", ")
if info != []
ser[ct] = rhs
else
spl = ct.split(" ")
ser[spl[0..-2].join(" ")] = spl[-1]
end
end
if pub = cite["publisher"]
refcontent << pub
# info = []
# if t = cite["type"]
# info << t
# end
# rhs = info.join(", ")
# if info != []
# ser[pub] = rhs
# else
# spl = pub.split(" ")
# ser[spl[0..-2].join(" ")] = spl[-1]
# end
end
["DOI", "ISBN"].each do |st|
if a = cite[st]
ser[st] = a
end
end
if refcontent != []
lit["refcontent"] = refcontent.join(", ")
end
lit
end
|