<commit_before>require 'cedilla/author'
require 'cedilla/resource'

require 'oclc/auth'

class DiscoveryService < CedillaService

  # -------------------------------------------------------------------------
  # All implementations of CedillaService should load their own config and pass
  # it along to the base class
  # -------------------------------------------------------------------------
  def initialize
    begin
      @config = YAML.load_file('./config/worldcat_discovery.yaml')
    
      super(@config)
      
      #@auth_target = @config['auth_target']
      @wskey = OCLC::Auth::WSKey.new(@config['auth_key'], @config['auth_secret'])
      
    rescue Exception => e
      $stdout.puts "Unable to load configuration file!"
    end
    
  end
  
  # -------------------------------------------------------------------------
  # All CoverThing cares about is the ISBN, so overriding the base class
  # -------------------------------------------------------------------------
  def add_citation_to_target(citation)
    ret = "#{build_target}"
    
    title = citation.title unless citation.title.nil?
    title = citation.book_title unless citation.book_title.nil?
    title = citation.journal_title unless citation.journal_title.nil?
    title = citation.article_title unless citation.article_title.nil?
    
    if citation.oclc.nil? and citation.isbn.nil? and citation.eisbn.nil? and citation.issn.nil? and
                                                  citation.eissn.nil? and citation.lccn.nil?
                                                  
      ret += "/search?q=name:#{CGI.escape(title)}"
      ret += "&au=#{citation.authors.first.last_name}" unless citation.authors.first.nil?
      
    else
      id = citation.oclc unless citation.oclc.nil?
      id = citation.eisbn unless citation.eisbn.nil?
      id = citation.isbn unless citation.isbn.nil?
      id = citation.eissn unless citation.eissn.nil?
      id = citation.issn unless citation.issn.nil?
      id = citation.lccn unless citation.lccn.nil?
      
      ret += "/data/#{CGI.escape(id)}"
    end

    LOGGER.info "calling: #{ret}"

    ret
  end
  
  # -------------------------------------------------------------------------
  def process_request(citation, headers)
    # Add on the Worldcat WSKey and tell them we want JSON
    headers['authorization'] = @wskey.hmac_signature('GET', add_citation_to_target(citation))
    headers['accept'] = 'application/json'
    
    begin
      super(citation, headers)
      
    rescue Exception => e
      puts e
      
      if @response_status == 404
        return [Cedilla::Citation.new({})]
        
      else
        LOGGER.debug "Exception in process_request(): " + e.message
        LOGGER.debug e.backtrace
        
        raise e
      end
    end
  end
  
  # -------------------------------------------------------------------------
  # Each implementation of a CedillaService MUST override this method!
  # -------------------------------------------------------------------------
  def process_response(status, headers, body)
    ret = {'citations' => []}
    attributes = {}
    
    LOGGER.debug "response status: #{status}"
    LOGGER.debug "response headers: #{headers.collect{ |k,v| "#{k}=#{v}" }.join(', ')}"
    LOGGER.debug "response body: #{body}"
    
    json = JSON.parse(body)  
  
    json['@graph'].each do |graph|
      graph['schema:significantLink'].each do |citation|
        
        if citation.is_a?(Hash)
          process_section(citation['schema:author']) unless citation['schema:author'].nil?
        
          ret['citations'] << process_section(citation['schema:about']) unless citation['schema:about'].nil?
        end
      end        
    end
    
    ret
  end
  
private
  # -------------------------------------------------------------------------
  def process_section(section)
    ret = nil
    citation_attributes = {}
    resource_attributes = {:source => 'worldcat'}
    authors = []
    
    section.each do |key, value|
      
      if key == '@id'
        resource_attributes[:local_id] = value
      
      elsif key == '@type'
        resource_attributes[:format] = value
        
      elsif key.include?('displayPosition')
        resource_attributes[:rating] = value['@value'] if value.is_a?(Hash)
        
      elsif key == 'schema:numberOfPages'
        citation_attributes[:pages] = value
        
      elsif key.include?('oclcnum')
        citation_attributes[:oclc] = value['@value'] if value.is_a?(Hash)<commit_msg>fix to worldcat_discovery for single item requests<commit_after>require 'cedilla/author'
require 'cedilla/resource'

require 'oclc/auth'

class DiscoveryService < CedillaService

  # -------------------------------------------------------------------------
  # All implementations of CedillaService should load their own config and pass
  # it along to the base class
  # -------------------------------------------------------------------------
  def initialize
    begin
      @config = YAML.load_file('./config/worldcat_discovery.yaml')
    
      super(@config)
      
      #@auth_target = @config['auth_target']
      @wskey = OCLC::Auth::WSKey.new(@config['auth_key'], @config['auth_secret'])
      
    rescue Exception => e
      $stdout.puts "Unable to load configuration file!"
    end
    
  end
  
  # -------------------------------------------------------------------------
  # All CoverThing cares about is the ISBN, so overriding the base class
  # -------------------------------------------------------------------------
  def add_citation_to_target(citation)
    ret = "#{build_target}"
    
    title = citation.title unless citation.title.nil?
    title = citation.book_title unless citation.book_title.nil?
    title = citation.journal_title unless citation.journal_title.nil?
    title = citation.article_title unless citation.article_title.nil?
    
    if citation.oclc.nil? and citation.isbn.nil? and citation.eisbn.nil? and citation.issn.nil? and
                                                  citation.eissn.nil? and citation.lccn.nil?
                                                  
      ret += "/search?q=name:#{CGI.escape(title)}"
      ret += "&au=#{citation.authors.first.last_name}" unless citation.authors.first.nil?
      
    else
      id = citation.oclc unless citation.oclc.nil?
#      id = citation.eisbn unless citation.eisbn.nil?
#      id = citation.isbn unless citation.isbn.nil?
#      id = citation.eissn unless citation.eissn.nil?
#      id = citation.issn unless citation.issn.nil?
#      id = citation.lccn unless citation.lccn.nil?
      
      ret += "/data/#{CGI.escape(id)}"
    end

    LOGGER.info "calling: #{ret}"

    ret
  end
  
  # -------------------------------------------------------------------------
  def process_request(citation, headers)
    # Add on the Worldcat WSKey and tell them we want JSON
    headers['authorization'] = @wskey.hmac_signature('GET', add_citation_to_target(citation))
    headers['accept'] = 'application/json'
    
    begin
      super(citation, headers)
      
    rescue Exception => e
      puts e
      
      if @response_status == 404
        return [Cedilla::Citation.new({})]
        
      else
        LOGGER.debug "Exception in process_request(): " + e.message
        LOGGER.debug e.backtrace
        
        raise e
      end
    end
  end
  
  # -------------------------------------------------------------------------
  # Each implementation of a CedillaService MUST override this method!
  # -------------------------------------------------------------------------
  def process_response(status, headers, body)
    ret = {'citations' => []}
    attributes = {}
    
    LOGGER.debug "response status: #{status}"
    LOGGER.debug "response headers: #{headers.collect{ |k,v| "#{k}=#{v}" }.join(', ')}"
    LOGGER.debug "response body: #{body}"
    
    json = JSON.parse(body)  
  
    json['@graph'].each do |graph|
      if graph['schema:significantLink'].nil?
        
        unless graph['schema:about'].nil?
          ret['citations'] << process_section(graph['schema:about'])
        end
        
      else
        # We got back multiple OCLC matches!
        graph['schema:significantLink'].each do |citation|
        
          if citation.is_a?(Hash)
            #process_section(citation['schema:author']) unless citation['schema:author'].nil?
        
            ret['citations'] << process_section(citation['schema:about']) unless citation['schema:about'].nil?
          end
        end 
      end       
    end
    
    ret
  end
  
private
  # -------------------------------------------------------------------------
  def process_section(section)
    ret = nil
    citation_attributes = {}
    resource_attributes = {:source => 'worldcat'}
    authors = []
    
    section.each do |key, value|
      
      puts "looking at #{key} -> #{value}"
      
      
      if key == '@id'
        resource_attributes[:local_id] = value
      
      elsif key == '@type'
        resource_attributes[:format] = value
        
      elsif key.include?('displayPosition')
        resource_attributes[:rating] = value['@value'] if value.is_a?(Hash)
        
      elsif key == 'schema:numberOfPages'
        citation_attributes[:pages] = value
        
      elsif key.include?('oclcnum')
        citation_attributes[:oclc] = value['@value'] if value.is_a?(Hash)
{'fraction_non_alphanumeric': 0.2257036643653744, 'fraction_numerical': 0.0006372809346787042, 'mean_word_length': 1.6018237082066868, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5388789', 'n_tokens_mistral': 2587, 'n_tokens_neox': 2472, 'n_words': 565}