lib/service_adaptors/primo_service.rb in umlaut-3.0.0beta2 vs lib/service_adaptors/primo_service.rb in umlaut-3.0.0beta3
- old
+ new
@@ -117,13 +117,16 @@
# ------------------------------------------------------- total: 7.380000sec
#
# user system total real
# PrimoService Minimum Config: 3.470000 0.050000 3.520000 ( 4.567797)
# PrimoService Default Config: 3.420000 0.050000 3.470000 ( 3.990271)
-
class PrimoService < Service
+ require 'exlibris-primo'
+
required_config_params :base_url, :vid, :institution
+ # For matching purposes.
+ attr_reader :title, :author
# Overwrites Service#new.
def initialize(config)
# defaults
@holding_attributes = Exlibris::Primo::Holding.base_attributes
@@ -185,28 +188,29 @@
end
# Overwrites Service#handle.
def handle(request)
@identifier = request.referrer_id
- primo_id = @identifier.match(/primo-(.+)/)[1] if primo_identifier? unless @identifier.nil? or @identifier.match(/primo-(.+)/).nil?
+ @primo_id = @identifier.match(/primo-(.+)/)[1] if primo_identifier? unless @identifier.nil? or @identifier.match(/primo-(.+)/).nil?
# DEPRECATED
# Extend OpenURL standard to take Primo Doc Id
- primo_id = request.referent.metadata['primo'] unless request.referent.metadata['primo'].nil?
+ @primo_id = request.referent.metadata['primo'] unless request.referent.metadata['primo'].nil?
Rails.logger.warn("Use of 'rft.primo' is deprecated. Please use the identifier instead.") unless request.referent.metadata['primo'].nil?
# End DEPRECATED
searcher_setup = {
:base_url => @base_url, :vid => @vid, :institution => @institution,
:config => primo_config
}
# don't send mal-formed issn
- issn = request.referent.metadata['issn'] if request.referent.metadata['issn'] =~ /\d{4}(-)?\d{3}(\d|X)/
- title = title(request)
+ @issn = request.referent.metadata['issn'] if request.referent.metadata['issn'] =~ /\d{4}(-)?\d{3}(\d|X)/
+ @isbn = request.referent.metadata['isbn']
+ @title = title(request)
search_params = {
- :primo_id => primo_id,
- :isbn => request.referent.metadata['isbn'],
- :issn => issn,
- :title => title,
+ :primo_id => @primo_id,
+ :isbn => @isbn,
+ :issn => @issn,
+ :title => @title,
:author => author(request),
:genre => request.referent.metadata['genre']
}
begin
primo_searcher = Exlibris::Primo::Searcher.new(searcher_setup, search_params)
@@ -218,23 +222,23 @@
"Exlibris::Primo::Searcher raised the following exception:\n#{e}\n#{e.backtrace.inspect}")
return request.dispatched(self, true)
end
# Enhance the referent with metadata from Primo Searcher if primo id is present
# i.e. if we did our search with the Primo system number
- if primo_id and @service_types.include?("referent_enhance")
+ if @primo_id and @service_types.include?("referent_enhance")
@referent_enhancements.each do |key, options|
value = (options[:value].nil?) ? key.to_sym : options[:value].to_sym
request.referent.enhance_referent(
key.to_s, primo_searcher.method(value).call,
true, false, options
) if primo_searcher.respond_to? value and not primo_searcher.method(value).call.nil?
end
end
- # Get cover image only if primo_id is defined
+ # Get cover image only if @primo_id is defined
# TODO: make cover image service smarter and only
# include things that are actually URLs.
- if primo_id and @service_types.include?("cover_image")
+ if @primo_id and @service_types.include?("cover_image")
cover_image = primo_searcher.cover_image
unless cover_image.nil?
request.add_service_response(
:service => self,
:display_text => 'Cover Image',
@@ -251,10 +255,15 @@
next if @suppress_holdings.find {|suppress| suppress === holding.availlibrary}
service_data = {}
@holding_attributes.each do |attr|
service_data[attr] = holding.method(attr).call
end
+ # Umlaut specific attributes.
+ service_data[:match_reliability] =
+ (reliable_match?(:title => holding.title, :author => holding.author)) ?
+ ServiceResponse::MatchExact : ServiceResponse::MatchUnsure
+ service_data[:request_link_supports_ajax_call] = false
# Only add one service type, either "primo_source" OR "holding", not both.
service_type = (@service_types.include?("primo_source")) ? "primo_source" : "holding"
# Add some other holding information for compatibility with default holding partial
service_data.merge!({
:call_number => holding.call_number, :collection => holding.collection,
@@ -270,16 +279,16 @@
end
# Provide title search functionality in the absence of available holdings.
if @service_types.include?("holding_search")
if holdings.empty? and
not primo_identifier? and
- not title.nil?
+ not @title.nil?
service_data = {}
service_data[:type] = "link_to_search"
service_data[:display_text] = (@holding_search_text.nil?) ? "Search for this title." : @holding_search_text
service_data[:note] = ""
- service_data[:url] = @base_url+"/primo_library/libweb/action/dlSearch.do?institution=#{@holding_search_institution}&vid=#{@vid}&onCampus=false&query=#{CGI::escape("title,exact,"+title)}&indx=1&bulkSize=10&group=GUEST"
+ service_data[:url] = @base_url+"/primo_library/libweb/action/dlSearch.do?institution=#{@holding_search_institution}&vid=#{@vid}&onCampus=false&query=#{CGI::escape("title,exact,"+@title)}&indx=1&bulkSize=10&group=GUEST"
request.add_service_response(
service_data.merge(
:service => self,
:service_type_value => 'holding_search'
)
@@ -388,9 +397,25 @@
source_parameters[attr] = service_response.data_values[attr] }
return Exlibris::Primo::Holding.new(source_parameters).to_source
end
private
+ # Determine how sure we are that this is a match.
+ # Dynamically compares record metadata to input values
+ # based on the values passed in.
+ # Minimum requirement is to check title.
+ def reliable_match?(record_metadata)
+ return true unless (@primo_id.nil? or @primo_id.empty?)
+ return true unless (@issn.nil? or @issn.empty?) and (@isbn.nil? or @isbn.empty?)
+ return false if (record_metadata.nil? or record_metadata.empty? or record_metadata[:title].nil? or record_metadata[:title].empty?)
+ # Titles must be equal
+ return false unless record_metadata[:title].downcase.eql?(@title.downcase)
+ # Compare record metadata with metadata that was passed in.
+ # Only check if the record metadata value contains the input value since we can't be too strict.
+ record_metadata.each { |type, value| return false if value.downcase.match("#{self.method(type).call}".downcase).nil?}
+ return true
+ end
+
def primo_config
default_file = "#{Rails.root}/config/primo.yml"
config_file = @primo_config.nil? ? default_file : "#{Rails.root}/config/"+ @primo_config
Rails.logger.warn("Primo config file not found: #{config_file}.") and return {} unless File.exists?(config_file)
config_hash = YAML.load_file(config_file)