Skip to content

Instantly share code, notes, and snippets.

@cbeer
Created November 15, 2009 01:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cbeer/234911 to your computer and use it in GitHub Desktop.
Save cbeer/234911 to your computer and use it in GitHub Desktop.
require 'dispatcher'
require 'oai'
require 'rsolr'
require 'rsolr-ext'
module OAI_DocumentPatch
def self.included(base)
base.extend(ClassMethods)
base.send(:include, InstanceMethods)
end
module ClassMethods
end
module InstanceMethods
def to_oai_dc
xml = Builder::XmlMarkup.new
xml.tag!("oai_dc:dc",
'xmlns:oai_dc' => "http://www.openarchives.org/OAI/2.0/oai_dc/",
'xmlns:dc' => "http://purl.org/dc/elements/1.1/",
'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
'xsi:schemaLocation' =>
%{http://www.openarchives.org/OAI/2.0/oai_dc/
http://www.openarchives.org/OAI/2.0/oai_dc.xsd}) do
Blacklight.config[:oai][:map].each do |k, v|
f = get(k)
f = [f] if f.class != Array
begin
f.each { |r| xml.tag!(v, r) }
end
end
end
xml.target!
end
def timestamp
Time.parse get('timestamp')
end
end
end
module OAI
module Provider
class SolrDocumentWrapper < Model
attr_reader :model, :timestamp_field
def initialize(model, options={})
@model = model
@timestamp_field = options.delete(:timestamp_field) || 'timestamp'
@limit = options.delete(:limit)
unless options.empty?
raise ArgumentError.new(
"Unsupported options [#{options.keys.join(', ')}]"
)
end
end
def deleted? record
false
end
def earliest
Time.parse model.search({:sort => 'timestamp asc', :rows => 1}).docs[0].get('timestamp')
end
def find(selector, options={})
return next_set(options[:resumption_token]) if options[:resumption_token]
if :all == selector
records = model.search({:sort => 'timestamp asc', :rows => @limit}).docs
total = records.count
if @limit && total >= @limit
return select_partial ResumptionToken.new options.merge({:last => 0})
end
else
records = model.find_by_id({:id => selector}).docs[0]
end
records
end
def latest
Time.parse model.search({:sort => 'timestamp desc', :rows => 1}).docs[0].get('timestamp')
end
def sets
end
def select_partial token
records = model.search({:sort => 'timestamp asc', :rows => @limit, :start => token.last}).docs
raise OAI::ResumptionTokenException.new unless records
PartialResult.new(records, token.next(@limit + token.last))
end
def next_set(token_string)
raise OAI::ResumptionTokenException.new unless @limit
token = ResumptionToken.parse token_string
select_partial token
end
end
class SolrDocumentProvider < Base
repository_name 'My OAI Provider'
repository_url 'http://localhost:3000/oai/'
record_prefix 'info:fedora'
admin_email 'root@localhost'
source_model SolrDocumentWrapper.new(SolrDocument)
end
end
end
class OaiController < ApplicationController
def index
# Remove controller and action from the options. Rails adds them automatically.
options = params.delete_if { |k,v| %w{controller action}.include?(k) }
provider = OAI::Provider::SolrDocumentProvider.new
response = provider.process_request(options)
render :text => response, :content_type => 'text/xml'
end
end
Dispatcher.to_prepare do
SolrDocument.send(:include, OAI_DocumentPatch)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment