blacklight_oai_provider 0.0.1pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +73 -0
- data/Rakefile +4 -0
- data/VERSION +1 -0
- data/blacklight_oai_provider.gemspec +24 -0
- data/config/routes.rb +5 -0
- data/lib/blacklight_oai_provider/README.rdoc +0 -0
- data/lib/blacklight_oai_provider/controller_extension.rb +29 -0
- data/lib/blacklight_oai_provider/engine.rb +17 -0
- data/lib/blacklight_oai_provider/route_sets.rb +13 -0
- data/lib/blacklight_oai_provider/solr_document_extension.rb +10 -0
- data/lib/blacklight_oai_provider/solr_document_provider.rb +19 -0
- data/lib/blacklight_oai_provider/solr_document_wrapper.rb +58 -0
- data/lib/blacklight_oai_provider/version.rb +10 -0
- data/lib/blacklight_oai_provider.rb +33 -0
- data/lib/generators/blacklight_oai_provider/blacklight_oai_provider_generator.rb +27 -0
- metadata +96 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 [name of plugin creator]
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
BlacklightOaiProvider: OAI-PMH service endpoint for Blacklight applications
|
2
|
+
|
3
|
+
= Description
|
4
|
+
|
5
|
+
The BlacklightOaiProvider plugin provides an Open Archives Initiative Protocolo for Metadata Harvesting (OAI-PMH) <http://www.openarchives.org/pmh/> data provider endpoint, using the ruby-oai gem, that let serice providers harvest that metadata.
|
6
|
+
|
7
|
+
= Requirements
|
8
|
+
|
9
|
+
A Rails app using Blacklight 3.x.
|
10
|
+
|
11
|
+
OAI-PMH requires a timestamp field for all records, so your Solr index should include an appropriate field. By default, the name of this field is simply 'timestamp'.
|
12
|
+
|
13
|
+
= Installation
|
14
|
+
|
15
|
+
Add
|
16
|
+
|
17
|
+
gem "blacklight_oai_provider"
|
18
|
+
|
19
|
+
to your Gemfile and run "bundle install".
|
20
|
+
|
21
|
+
Then run "rails generate blacklight_oai_provider" to install the appropriate extensions into your CatalogController and SolrDocument classes. In you want to do customize the way this installs, instead you may:
|
22
|
+
|
23
|
+
- add this to your Solr Document model:
|
24
|
+
|
25
|
+
use_extension(BlacklightOaiProvider::SolrDocumentExtension)
|
26
|
+
|
27
|
+
- add this to your Controler:
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
= Configuration
|
32
|
+
|
33
|
+
While the plugin provides some sensible (albeit generic) defaults out of the box, you probably will want to customize the OAI provider configuration. You can provide OAI-PMH provider parameters by placing the following in your blacklight configuration (in ./config/initializers/blacklight_config.rb), e.g.:
|
34
|
+
|
35
|
+
config[:oai] = {
|
36
|
+
:provider => {
|
37
|
+
:repository_name => 'Test',
|
38
|
+
:repository_url => 'http://localhost',
|
39
|
+
:record_prefix => '',
|
40
|
+
:admin_email => 'root@localhost'
|
41
|
+
},
|
42
|
+
:document => {
|
43
|
+
:timestamp => 'timestamp',
|
44
|
+
:limit => 25
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
The "provider" configuration is documented as part of the ruby-oai gem at http://oai.rubyforge.org/
|
49
|
+
|
50
|
+
|
51
|
+
== Injection
|
52
|
+
|
53
|
+
This plugin assumes it is in a Blacklight Rails app, uses Blacklight methods, Rails methods, and standard ruby module includes to inject it's behaviors into the app.
|
54
|
+
|
55
|
+
You can turn off this injection if you like, although it will make the plugin less (or non-) functional unless you manually do similar injection. See lib/blacklight_oai_provider.rb#inject! to see exactly what's going on.
|
56
|
+
|
57
|
+
In any initializer, you can set:
|
58
|
+
|
59
|
+
BlacklightOaiProvider.omit_inject = true
|
60
|
+
|
61
|
+
to turn off all injection. The plugin will be completely non-functional if you do this, of course. But perhaps you could try to re-use some of it's classes in a non-Blacklight, highly hacked Blacklight, or even non-Rails application this way.
|
62
|
+
|
63
|
+
You can also turn off injection of individual components, which could be more useful:
|
64
|
+
|
65
|
+
BlacklightOaiProvider.omit_inject = {
|
66
|
+
:routes => false,
|
67
|
+
}
|
68
|
+
|
69
|
+
= Tests
|
70
|
+
|
71
|
+
There are none. This is bad I know, sorry. You can test OAI-PMH conformance against http://www.openarchives.org/data/registerasprovider.html#Protocol_Conformance_Testing or browse the data at http://re.cs.uct.ac.za/
|
72
|
+
|
73
|
+
|
data/Rakefile
ADDED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1pre1
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.join(File.dirname(__FILE__), "lib/blacklight_oai_provider/version")
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "blacklight_oai_provider"
|
6
|
+
s.version = BlacklightOaiProvider::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ["Chris Beer"]
|
9
|
+
s.email = ["chris_beer@wgbh.org"]
|
10
|
+
s.homepage = "http://projectblacklight.org/"
|
11
|
+
s.summary = "Blacklight Oai Provider plugin"
|
12
|
+
|
13
|
+
s.rubyforge_project = "blacklight"
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
|
21
|
+
s.add_dependency "rails", "~> 3.0"
|
22
|
+
s.add_dependency "blacklight"
|
23
|
+
s.add_dependency "oai"
|
24
|
+
end
|
data/config/routes.rb
ADDED
File without changes
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Meant to be applied on top of a controller that implements
|
2
|
+
# Blacklight::SolrHelper. Will inject range limiting behaviors
|
3
|
+
# to solr parameters creation.
|
4
|
+
module BlacklightOaiProvider::ControllerExtension
|
5
|
+
def self.included(some_class)
|
6
|
+
some_class.helper_method :oai_config
|
7
|
+
end
|
8
|
+
|
9
|
+
# Action method of our own!
|
10
|
+
# Delivers a _partial_ that's a display of a single fields range facets.
|
11
|
+
# Used when we need a second Solr query to get range facets, after the
|
12
|
+
# first found min/max from result set.
|
13
|
+
def oai
|
14
|
+
options = params.delete_if { |k,v| %w{controller action}.include?(k) }
|
15
|
+
render :text => oai_provider.process_request(options), :content_type => 'text/xml'
|
16
|
+
end
|
17
|
+
|
18
|
+
# Uses Blacklight.config, needs to be modified when
|
19
|
+
# that changes to be controller-based. This is the only method
|
20
|
+
# in this plugin that accesses Blacklight.config, single point
|
21
|
+
# of contact.
|
22
|
+
def oai_config
|
23
|
+
Blacklight.config[:oai] || {}
|
24
|
+
end
|
25
|
+
|
26
|
+
def oai_provider
|
27
|
+
@oai_provider ||= BlacklightOaiProvider::SolrDocumentProvider.new(self, oai_config)
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'blacklight'
|
2
|
+
require 'blacklight_range_limit'
|
3
|
+
require 'rails'
|
4
|
+
|
5
|
+
module BlacklightOaiProvider
|
6
|
+
class Engine < Rails::Engine
|
7
|
+
|
8
|
+
# Do these things in a to_prepare block, to try and make them work
|
9
|
+
# in development mode with class-reloading. The trick is we can't
|
10
|
+
# be sure if the controllers we're modifying are being reloaded in
|
11
|
+
# dev mode, if they are in the BL plugin and haven't been copied to
|
12
|
+
# local, they won't be. But we do our best.
|
13
|
+
config.to_prepare do
|
14
|
+
BlacklightOaiProvider.inject!
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# Meant to be applied on top of SolrDocument to implement
|
2
|
+
# methods required by the ruby-oai provider
|
3
|
+
module BlacklightOaiProvider::SolrDocumentExtension
|
4
|
+
def timestamp
|
5
|
+
Time.parse get('timestamp')
|
6
|
+
end
|
7
|
+
def to_oai_dc
|
8
|
+
export_as('oai_dc_xml')
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module BlacklightOaiProvider
|
2
|
+
class SolrDocumentProvider < ::OAI::Provider::Base
|
3
|
+
attr_accessor :options
|
4
|
+
def initialize controller, options = {}
|
5
|
+
|
6
|
+
options[:provider] ||= {}
|
7
|
+
options[:document] ||= {}
|
8
|
+
|
9
|
+
self.class.model = SolrDocumentWrapper.new(controller, options[:document])
|
10
|
+
|
11
|
+
options[:repository_name] ||= controller.view_context.send(:application_name)
|
12
|
+
options[:repository_url] ||= controller.view_context.send(:oai_provider_url)
|
13
|
+
|
14
|
+
options[:provider].each do |k,v|
|
15
|
+
self.class.send k, v
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module BlacklightOaiProvider
|
2
|
+
class SolrDocumentWrapper < ::OAI::Provider::Model
|
3
|
+
attr_reader :model, :timestamp_field
|
4
|
+
attr_accessor :options, :extra_controller_params
|
5
|
+
def initialize(controller, options = {})
|
6
|
+
@controller = controller
|
7
|
+
|
8
|
+
defaults = { :timestamp => 'timestamp', :limit => 15}
|
9
|
+
@options = defaults.merge options
|
10
|
+
|
11
|
+
@timestamp_field = @options[:timestamp]
|
12
|
+
@limit = @options[:limit]
|
13
|
+
@extra_controller_params = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def sets
|
17
|
+
end
|
18
|
+
|
19
|
+
def earliest
|
20
|
+
Time.parse @controller.get_search_results({:sort => @timestamp_field +' asc', :rows => 1}, extra_controller_params).last.first.get(@timestamp_field)
|
21
|
+
end
|
22
|
+
|
23
|
+
def latest
|
24
|
+
Time.parse @controller.get_search_results({:sort => @timestamp_field +' desc', :rows => 1}, extra_controller_params).last.first.get(@timestamp_field)
|
25
|
+
end
|
26
|
+
|
27
|
+
def find(selector, options={})
|
28
|
+
return next_set(options[:resumption_token]) if options[:resumption_token]
|
29
|
+
|
30
|
+
if :all == selector
|
31
|
+
response, records = @controller.get_search_results({:sort => @timestamp_field + ' asc', :per_page => @limit}, extra_controller_params)
|
32
|
+
|
33
|
+
if @limit && response.total >= @limit
|
34
|
+
return select_partial(OAI::Provider::ResumptionToken.new(options.merge({:last => 0})))
|
35
|
+
end
|
36
|
+
else
|
37
|
+
records = @controller.get_search_results({:phrase_filters => {:id => selector.split('/', 2).last}}, extra_controller_params).last.first
|
38
|
+
end
|
39
|
+
records
|
40
|
+
end
|
41
|
+
|
42
|
+
def select_partial token
|
43
|
+
records = @controller.get_search_results({:sort => @timestamp_field + ' asc', :per_page => @limit, :page => token.last}, extra_controller_params).last
|
44
|
+
|
45
|
+
raise ::OAI::ResumptionTokenException.new unless records
|
46
|
+
|
47
|
+
OAI::Provider::PartialResult.new(records, token.next(token.last+1))
|
48
|
+
end
|
49
|
+
|
50
|
+
def next_set(token_string)
|
51
|
+
raise ::OAI::ResumptionTokenException.new unless @limit
|
52
|
+
|
53
|
+
token = OAI::Provider::ResumptionToken.parse(token_string)
|
54
|
+
select_partial(token)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# BlacklightOaiProvider
|
2
|
+
|
3
|
+
module BlacklightOaiProvider
|
4
|
+
|
5
|
+
autoload :ControllerExtension, 'blacklight_oai_provider/controller_extension'
|
6
|
+
autoload :SolrDocumentExtension, 'blacklight_oai_provider/solr_document_extension'
|
7
|
+
autoload :SolrDocumentProvider, 'blacklight_oai_provider/solr_document_provider'
|
8
|
+
autoload :SolrDocumentWrapper, 'blacklight_oai_provider/solr_document_wrapper'
|
9
|
+
autoload :RouteSets, 'blacklight_oai_provider/route_sets'
|
10
|
+
|
11
|
+
require 'oai'
|
12
|
+
require 'blacklight_oai_provider/version'
|
13
|
+
require 'blacklight_oai_provider/engine'
|
14
|
+
|
15
|
+
@omit_inject = {}
|
16
|
+
def self.omit_inject=(value)
|
17
|
+
value = Hash.new(true) if value == true
|
18
|
+
@omit_inject = value
|
19
|
+
end
|
20
|
+
def self.omit_inject ; @omit_inject ; end
|
21
|
+
|
22
|
+
def self.inject!
|
23
|
+
unless BlacklightRangeLimit.omit_inject[:routes]
|
24
|
+
Blacklight::Routes.send(:include, BlacklightOaiProvider::RouteSets)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Add element to array only if it's not already there
|
29
|
+
def self.safe_arr_add(array, element)
|
30
|
+
array << element unless array.include?(element)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
class BlacklightOaiProviderGenerator < Rails::Generators::Base
|
4
|
+
|
5
|
+
argument :model_name, :type => :string, :default => "SolrDocument"
|
6
|
+
argument :controller_name, :type => :string, :default => "CatalogController"
|
7
|
+
|
8
|
+
def inject_solr_document_extension
|
9
|
+
file_path = "app/models/#{model_name.underscore}.rb"
|
10
|
+
|
11
|
+
if File.exists? file_path
|
12
|
+
inject_into_file file_path, :after => "include Blacklight::Solr::Document" do
|
13
|
+
"\n SolrDocument.use_extension( BlacklightOaiProvider::SolrDocumentExtension )\n"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def inject_catalog_controller_extension
|
19
|
+
file_path = "app/controllers/#{controller_name.underscore}.rb"
|
20
|
+
if File.exists? file_path
|
21
|
+
inject_into_file file_path, :after => "include Blacklight::Catalog" do
|
22
|
+
"\n include BlacklightOaiProvider::ControllerExtension\n"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: blacklight_oai_provider
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1pre1
|
5
|
+
prerelease: 5
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Chris Beer
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-07-22 00:00:00.000000000 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rails
|
17
|
+
requirement: &2153081380 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ~>
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '3.0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *2153081380
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: blacklight
|
28
|
+
requirement: &2153080820 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *2153080820
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: oai
|
39
|
+
requirement: &2153080220 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
type: :runtime
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *2153080220
|
48
|
+
description:
|
49
|
+
email:
|
50
|
+
- chris_beer@wgbh.org
|
51
|
+
executables: []
|
52
|
+
extensions: []
|
53
|
+
extra_rdoc_files: []
|
54
|
+
files:
|
55
|
+
- MIT-LICENSE
|
56
|
+
- README.rdoc
|
57
|
+
- Rakefile
|
58
|
+
- VERSION
|
59
|
+
- blacklight_oai_provider.gemspec
|
60
|
+
- config/routes.rb
|
61
|
+
- lib/blacklight_oai_provider.rb
|
62
|
+
- lib/blacklight_oai_provider/README.rdoc
|
63
|
+
- lib/blacklight_oai_provider/controller_extension.rb
|
64
|
+
- lib/blacklight_oai_provider/engine.rb
|
65
|
+
- lib/blacklight_oai_provider/route_sets.rb
|
66
|
+
- lib/blacklight_oai_provider/solr_document_extension.rb
|
67
|
+
- lib/blacklight_oai_provider/solr_document_provider.rb
|
68
|
+
- lib/blacklight_oai_provider/solr_document_wrapper.rb
|
69
|
+
- lib/blacklight_oai_provider/version.rb
|
70
|
+
- lib/generators/blacklight_oai_provider/blacklight_oai_provider_generator.rb
|
71
|
+
has_rdoc: true
|
72
|
+
homepage: http://projectblacklight.org/
|
73
|
+
licenses: []
|
74
|
+
post_install_message:
|
75
|
+
rdoc_options: []
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ! '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ! '>'
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 1.3.1
|
90
|
+
requirements: []
|
91
|
+
rubyforge_project: blacklight
|
92
|
+
rubygems_version: 1.6.2
|
93
|
+
signing_key:
|
94
|
+
specification_version: 3
|
95
|
+
summary: Blacklight Oai Provider plugin
|
96
|
+
test_files: []
|