blacklight_oai_provider 0.0.1pre1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,4 @@
1
+ require 'rake'
2
+ require 'bundler'
3
+
4
+ Bundler::GemHelper.install_tasks
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
@@ -0,0 +1,5 @@
1
+ # We want to add a new collection action to Catalog, without over-writing
2
+ # what's already there. This SEEMS to do it.
3
+ Rails.application.routes.draw do
4
+ end
5
+
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,13 @@
1
+ module BlacklightOaiProvider
2
+ module RouteSets
3
+ protected
4
+ def catalog
5
+ add_routes do |options|
6
+ match 'catalog/oai' => 'catalog#oai', :as => 'oai_provider'
7
+ end
8
+
9
+ super
10
+ end
11
+ end
12
+ end
13
+
@@ -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,10 @@
1
+ module BlacklightOaiProvider
2
+ unless BlacklightOaiProvider.const_defined? :VERSION
3
+ def self.version
4
+ @version ||= File.read(File.join(File.dirname(__FILE__), '..', '..', 'VERSION')).chomp
5
+ end
6
+
7
+ VERSION = self.version
8
+ end
9
+ end
10
+
@@ -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: []