team-umlaut/umlaut-primo

View on GitHub
lib/umlaut_primo/primo_source.rb

Summary

Maintainability
A
3 hrs
Test Coverage
# == Overview
# PrimoSource is a PrimoService that converts primo_source service types into Primo source holdings.
# This mechanism allows linking to original data sources and their holdings information
# based on the given Primo sources and can be implemented per source.
#
# PrimoSources are not necessary to use the Primo service andthey require programming.
# They do, however, allow further customization and functionality.
#
# == Prerequisites
# First, the PrimoService must be configured with the primo_source service type instead of holding.
#
#   Primo: # Name of your choice
#     type: PrimoService
#     ...
#     service_types:
#       - primo_source
#       - holding_search
#       ...
#
# ==Available Parameters
# Several configurations parameters are available to be set in config/umlaut_services.yml.
#   PrimoSource: # Name of your choice
#     type: PrimoSource # Required
#     priority: 3 # Required. Must be run after PrimoService
#     base_url: http://primo.library.edu # Required
#     vid: VID # Required
#     institution: INST # Required
#     source_attributes: # Optional.
#       - request_link_supports_ajax_call
#       - requestability
#
# base_url:: _required_ host and port of Primo server for Primo display deep link
# vid:: _required_ view id for Primo display deep link
# institution:: _required_ institution id for Primo display deep link
# source_attributes::  _optional_ Array of Holding attribute readers to persist to
#   holding service_data; can be used to save custom source implementation attributes
#   for display by a custom holding partial
#
class PrimoSource < PrimoService

  # Overwrites PrimoService#new.
  def initialize(config)
    @service_types = ["holding"]
    @source_attributes = []
    super(config)
  end

  # Overwrites PrimoService#handle.
  def handle(request)
    primo_sources = request.get_service_type('primo_source', {:refresh => true})
    sources = [] # for de-duplicating holdings from catalog.
    primo_sources.each do |primo_source|
      # Call PrimoService#to_primo_source with the ServiceResponse
      source = primo_source.service.to_primo_source(primo_source)
      # There are some cases where source records may need to be de-duplicated against existing records
      # Check if we've already seen this record.
      next if sources.include?(source)
      # Include the source so that it's available for deduping
      sources << source
      # There may be multiple holdings mapped to one availlibrary here,
      # so we get the additional holdings and add them.
      source.expand.each do |holding|
        service_data = {}
        @holding_attributes.each do |attr|
          service_data[attr] = holding.send(attr.to_sym) if holding.respond_to?(attr.to_sym)
        end
        @source_attributes.each do |attr|
          service_data[attr.to_sym] = holding.send(attr.to_sym) if holding.respond_to?(attr.to_sym)
        end
        service_data.merge!({
          :url => (holding.respond_to? :url) ? holding.url : deep_link_display_url(holding),
          :collection_str => "#{holding.library} #{holding.collection}",
          :coverage_str => holding.coverage.join("<br />"),
          :coverage_str_array => holding.coverage,
          # :expired determines whether we show the holding in this service
          # Since this is fresh, the data has not yet expired.
          :expired => false,
          # :latest determines whether we show the holding in other services, e.g. txt and email.
          # It persists for one more cycle than :expired so services that run after
          # this one, but in the same resolution request have access to the latest holding data.
          :latest => true })
        request.add_service_response(
          service_data.merge(:service=>self,
            :service_type_value => "holding" ))
      end
    end
    return request.dispatched(self, true)
  end
end