Created
November 15, 2009 01:33
-
-
Save cbeer/234911 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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