module Ref2bibtex

require 'serrano'

Constants

CROSSREF_URI

By default sorts by score

DEFAULT_CUTOFF
USER_EMAIL
USER_EMAIL_ENV
USER_EMAIL_FILE
USER_EMAIL_FILE_PATH
VERSION

Public Class Methods

citation2bibtex(citation) click to toggle source

Pass a citation, get a String in BibTeX back

# File lib/ref2bibtex.rb, line 103
def self.citation2bibtex(citation)
  get_bibtex(get_doi(citation) )
end
Also aliased as: get
cutoff() click to toggle source
# File lib/ref2bibtex.rb, line 31
def self.cutoff
  @@cutoff
end
cutoff=(value) click to toggle source
# File lib/ref2bibtex.rb, line 35
def self.cutoff=(value)
  @@cutoff = value
end
get(citation)
Alias for: citation2bibtex
get_bibtex(doi) click to toggle source

@params doi [String] @return [String, false]

# File lib/ref2bibtex.rb, line 55
def self.get_bibtex(doi)
  return false if !doi

  doi = Addressable::URI.parse(doi).normalize.to_s
  uri = URI(doi)
  return false if uri.class == URI::Generic

  # Serrano.content_negotiation(ids: doi).first

  Ref2bibtex.request(uri, headers: {'Accept' => 'application/x-bibtex' }, protocol: 'GET', process_response_as: 'text') 
end
get_doi(citation) click to toggle source

@param citation [String] @return [String, false] Pass a String citation, get a DOI back

# File lib/ref2bibtex.rb, line 70
def self.get_doi(citation)
  citation = validate_query(citation)
  response = Ref2bibtex.request(payload: citation) 
  return false unless has_match?(response) 
  return false if response['results'][0]['score'] < @@cutoff
  response['results'][0]['doi']
end
get_score(citation) click to toggle source

@param citation [String] @return [Float, -1.0 Pass a String citation, get a score back

# File lib/ref2bibtex.rb, line 81
def self.get_score(citation)
  citation = validate_query(citation)
  response = Ref2bibtex.request(payload: citation) 
  if has_match?(response)
    response['results'].first['score']
  else
    -1.0
  end
end
has_match?(response) click to toggle source
# File lib/ref2bibtex.rb, line 91
def self.has_match?(response)
  response['query_ok'] && response['results']&.first['match']
end
parse_json(string) click to toggle source

Parse the response into json

# File lib/ref2bibtex.rb, line 44
def self.parse_json(string)
  begin
    @json = JSON.parse(string) 
  rescue JSON::ParserError => e
    puts e.message
    ap request
  end
end
request(url = CROSSREF_URI, payload: nil, headers: {'content-type' => 'application/json' }, protocol: 'POST', process_response_as: 'json', redirect_limit: 10) click to toggle source
# File lib/ref2bibtex.rb, line 111
def self.request(url = CROSSREF_URI, payload: nil, headers: {'content-type' => 'application/json' }, protocol: 'POST', process_response_as: 'json', redirect_limit: 10)
  raise 'Infinite redirect?' if redirect_limit == 0

  body = request_body(protocol, payload)
  request = new_request(protocol, url, headers)

  response = Net::HTTP.start(request.uri.hostname, request.uri.port, use_ssl: request.uri.scheme == 'https') do |http|
    request.body = body 
    http.request(request)
  end

  case response
  when Net::HTTPSuccess 
    response = response
  when Net::HTTPRedirection 

    url = URI(response['location'])
    request = Net::HTTP::Get.new(url, initheader = {'Accept' => 'application/x-bibtex'}) 

    response = Net::HTTP.start(request.uri.hostname, request.uri.port, use_ssl: request.uri.scheme == 'https') do |http|
      http.request(request) 
    end
  else

    response = response.value
  end

  process_response(response, process_response_as)
end
reset_cutoff() click to toggle source
# File lib/ref2bibtex.rb, line 39
def self.reset_cutoff
  @@cutoff = DEFAULT_CUTOFF
end
validate_query(citation) click to toggle source
# File lib/ref2bibtex.rb, line 95
def self.validate_query(citation)
  return [citation] if citation.kind_of?(String) && citation.length > 0
  raise 'citation is not String or Array' if !citation.kind_of?(Array) 
  raise 'citation in array is empty' if citation.empty? || citation.select{|a| a.length == 0}.size > 0
  citation
end

Protected Class Methods

interpret_response(response) click to toggle source
# File lib/ref2bibtex.rb, line 143
def self.interpret_response(response)
end
new_request(protocol, url, headers) click to toggle source
# File lib/ref2bibtex.rb, line 155
def self.new_request(protocol, url, headers)
  case protocol
  when 'POST'
    Net::HTTP::Post.new(url, initheader = headers) 
  when 'GET'
    Net::HTTP::Get.new(url, initheader = headers) 
  else
    raise 'invalid protocol'
  end
end
process_response(response, as) click to toggle source
# File lib/ref2bibtex.rb, line 166
def self.process_response(response, as)
  case as
  when 'text' 
    response.body
  when 'json'
    parse_json(response.body)
  else
    raise 'response process type not provided'
  end
end
request_body(protocol, payload) click to toggle source
# File lib/ref2bibtex.rb, line 146
def self.request_body(protocol, payload)
  if protocol == 'POST'
    payload = {} if payload.nil?
    JSON.generate(payload) # Json.new(payload) # utf-8 encoding?
  else
    nil
  end
end