blacklight_oai_provider 0.1.0 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rubocop.yml +39 -0
- data/.rubocop_todo.yml +130 -0
- data/.solr_wrapper +8 -0
- data/.travis.yml +16 -0
- data/Gemfile +34 -2
- data/README.md +131 -0
- data/Rakefile +25 -0
- data/VERSION +1 -1
- data/app/assets/{xsl → stylesheets/blacklight_oai_provider}/oai2.xsl +12 -5
- data/app/controllers/concerns/blacklight_oai_provider/controller.rb +38 -0
- data/app/models/concerns/blacklight_oai_provider/solr_document.rb +23 -0
- data/blacklight_oai_provider.gemspec +17 -10
- data/config/initializers/oai_patches.rb +20 -0
- data/lib/blacklight_oai_provider/engine.rb +15 -2
- data/lib/blacklight_oai_provider/exceptions.rb +9 -0
- data/lib/blacklight_oai_provider/resumption_token.rb +51 -0
- data/lib/blacklight_oai_provider/routes.rb +15 -0
- data/lib/blacklight_oai_provider/solr_document_provider.rb +2 -2
- data/lib/blacklight_oai_provider/solr_document_wrapper.rb +55 -27
- data/lib/blacklight_oai_provider/version.rb +1 -2
- data/lib/blacklight_oai_provider.rb +16 -14
- data/lib/generators/blacklight_oai_provider/install_generator.rb +27 -0
- data/lib/railties/blacklight_oai_provider.rake +14 -0
- data/solr/conf/_rest_managed.json +3 -0
- data/solr/conf/admin-extra.html +31 -0
- data/solr/conf/elevate.xml +36 -0
- data/solr/conf/mapping-ISOLatin1Accent.txt +246 -0
- data/solr/conf/protwords.txt +21 -0
- data/solr/conf/schema.xml +629 -0
- data/solr/conf/scripts.conf +24 -0
- data/solr/conf/solrconfig.xml +401 -0
- data/solr/conf/spellings.txt +2 -0
- data/solr/conf/stopwords.txt +58 -0
- data/solr/conf/stopwords_en.txt +58 -0
- data/solr/conf/synonyms.txt +31 -0
- data/solr/conf/xslt/example.xsl +132 -0
- data/solr/conf/xslt/example_atom.xsl +67 -0
- data/solr/conf/xslt/example_rss.xsl +66 -0
- data/solr/conf/xslt/luke.xsl +337 -0
- data/solr/sample_solr_documents.yml +2722 -0
- data/spec/controllers/catalog_controller_spec.rb +39 -0
- data/spec/features/html_rendering_spec.rb +24 -0
- data/spec/models/solr_document_spec.rb +43 -0
- data/spec/requests/get_record_spec.rb +47 -0
- data/spec/requests/identify_spec.rb +53 -0
- data/spec/requests/list_identifiers_spec.rb +80 -0
- data/spec/requests/list_metadata_formats_spec.rb +43 -0
- data/spec/requests/list_records_spec.rb +126 -0
- data/spec/spec_helper.rb +15 -38
- data/spec/test_app_templates/config/solr.yml +9 -0
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +86 -0
- metadata +146 -87
- data/Gemfile.lock +0 -187
- data/README.rdoc +0 -74
- data/config/routes.rb +0 -5
- data/lib/blacklight_oai_provider/README.rdoc +0 -0
- data/lib/blacklight_oai_provider/controller_extension.rb +0 -29
- data/lib/blacklight_oai_provider/route_sets.rb +0 -13
- data/lib/blacklight_oai_provider/solr_document_extension.rb +0 -10
- data/lib/generators/blacklight_oai_provider/blacklight_oai_provider_generator.rb +0 -27
- data/spec/acceptance/blacklight_oai_provider_spec.rb +0 -49
- data/spec/integration/blacklight_stub_spec.rb +0 -10
- data/spec/internal/app/controllers/application_controller.rb +0 -4
- data/spec/internal/app/models/solr_document.rb +0 -3
- data/spec/internal/config/database.yml +0 -3
- data/spec/internal/config/routes.rb +0 -6
- data/spec/internal/config/solr.yml +0 -18
- data/spec/internal/db/combustion_test.sqlite +0 -0
- data/spec/internal/db/schema.rb +0 -53
- data/spec/internal/log/.gitignore +0 -1
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/lib/solr_document_extension_spec.rb +0 -6
- data/spec/vcr_cassettes/solr.yml +0 -113
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3c8443a7d656487d8e2aa2cfd0ebd3b7b659d85b
|
4
|
+
data.tar.gz: 07f9b6fb1ca30e96915f1d9ea13f1afc962ec5a1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f0e3e076577da7493f9cb6ed7606720854e270892e85bef93d1e5959585c60cd61deb16790ee99c287625d5ddc971bacfb33446eea2b288b0108171eeb17fc21
|
7
|
+
data.tar.gz: f91efbafee6de242c66fb288b442b01cef71c70a123d6661209cc4a261ba22c1b6c0c598813e2a0b9e2ad77b396b7734fa5690d3d28d272fea29b7d3fd336258
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require: rubocop-rspec
|
2
|
+
|
3
|
+
inherit_from:
|
4
|
+
- .rubocop_todo.yml
|
5
|
+
|
6
|
+
AllCops:
|
7
|
+
DisplayCopNames: true
|
8
|
+
Exclude:
|
9
|
+
- "blacklight_oai_provider.gemspec"
|
10
|
+
|
11
|
+
Rails:
|
12
|
+
Enabled: true
|
13
|
+
|
14
|
+
Metrics/BlockLength:
|
15
|
+
Exclude:
|
16
|
+
- 'spec/**/*'
|
17
|
+
- "lib/railties/blacklight_oai_provider.rake"
|
18
|
+
|
19
|
+
Metrics/LineLength:
|
20
|
+
Max: 200
|
21
|
+
|
22
|
+
Style/StringLiterals:
|
23
|
+
Enabled: false
|
24
|
+
|
25
|
+
Layout/IndentationConsistency:
|
26
|
+
EnforcedStyle: normal
|
27
|
+
|
28
|
+
Rails/OutputSafety:
|
29
|
+
Enabled: false
|
30
|
+
|
31
|
+
# engine_cart block includes conditional, not duplication
|
32
|
+
Bundler/DuplicatedGem:
|
33
|
+
Exclude:
|
34
|
+
- 'Gemfile'
|
35
|
+
|
36
|
+
# engine_cart block is following default Rails order
|
37
|
+
Bundler/OrderedGems:
|
38
|
+
Exclude:
|
39
|
+
- 'Gemfile'
|
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2017-10-26 15:19:14 -0400 using RuboCop version 0.50.0.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 2
|
10
|
+
# Cop supports --auto-correct.
|
11
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
12
|
+
# SupportedStyles: empty_lines, no_empty_lines
|
13
|
+
Layout/EmptyLinesAroundBlockBody:
|
14
|
+
Exclude:
|
15
|
+
- 'spec/requests/list_metadata_formats_spec.rb'
|
16
|
+
|
17
|
+
# Offense count: 4
|
18
|
+
Metrics/AbcSize:
|
19
|
+
Max: 25
|
20
|
+
|
21
|
+
# Offense count: 2
|
22
|
+
# Configuration parameters: CountComments.
|
23
|
+
Metrics/MethodLength:
|
24
|
+
Max: 39
|
25
|
+
|
26
|
+
# Offense count: 2
|
27
|
+
RSpec/BeforeAfterAll:
|
28
|
+
Exclude:
|
29
|
+
- 'spec/spec_helper.rb'
|
30
|
+
- 'spec/rails_helper.rb'
|
31
|
+
- 'spec/support/**/*.rb'
|
32
|
+
- 'spec/requests/list_identifiers_spec.rb'
|
33
|
+
|
34
|
+
# Offense count: 6
|
35
|
+
RSpec/DescribeClass:
|
36
|
+
Exclude:
|
37
|
+
- 'spec/features/html_rendering_spec.rb'
|
38
|
+
- 'spec/requests/get_record_spec.rb'
|
39
|
+
- 'spec/requests/identify_spec.rb'
|
40
|
+
- 'spec/requests/list_identifiers_spec.rb'
|
41
|
+
- 'spec/requests/list_metadata_formats_spec.rb'
|
42
|
+
- 'spec/requests/list_records_spec.rb'
|
43
|
+
|
44
|
+
# Offense count: 1
|
45
|
+
# Configuration parameters: CustomIncludeMethods.
|
46
|
+
RSpec/EmptyExampleGroup:
|
47
|
+
Exclude:
|
48
|
+
- 'spec/requests/list_records_spec.rb'
|
49
|
+
|
50
|
+
# Offense count: 1
|
51
|
+
# Configuration parameters: Max.
|
52
|
+
RSpec/ExampleLength:
|
53
|
+
Exclude:
|
54
|
+
- 'spec/controllers/catalog_controller_spec.rb'
|
55
|
+
|
56
|
+
# Offense count: 6
|
57
|
+
RSpec/MultipleExpectations:
|
58
|
+
Max: 2
|
59
|
+
|
60
|
+
# Offense count: 2
|
61
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
62
|
+
# SupportedStyles: strict, flexible
|
63
|
+
Rails/TimeZone:
|
64
|
+
Exclude:
|
65
|
+
- 'spec/requests/identify_spec.rb'
|
66
|
+
|
67
|
+
# Offense count: 1
|
68
|
+
# Cop supports --auto-correct.
|
69
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles, ProceduralMethods, FunctionalMethods, IgnoredMethods.
|
70
|
+
# SupportedStyles: line_count_based, semantic, braces_for_chaining
|
71
|
+
# ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object
|
72
|
+
# FunctionalMethods: let, let!, subject, watch
|
73
|
+
# IgnoredMethods: lambda, proc, it
|
74
|
+
Style/BlockDelimiters:
|
75
|
+
Exclude:
|
76
|
+
- 'spec/models/solr_document_spec.rb'
|
77
|
+
|
78
|
+
# Offense count: 3
|
79
|
+
# Cop supports --auto-correct.
|
80
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
81
|
+
# SupportedStyles: braces, no_braces, context_dependent
|
82
|
+
Style/BracesAroundHashParameters:
|
83
|
+
Exclude:
|
84
|
+
- 'lib/blacklight_oai_provider/solr_document_wrapper.rb'
|
85
|
+
- 'spec/models/solr_document_spec.rb'
|
86
|
+
|
87
|
+
# Offense count: 12
|
88
|
+
Style/Documentation:
|
89
|
+
Exclude:
|
90
|
+
- 'spec/**/*'
|
91
|
+
- 'test/**/*'
|
92
|
+
- 'app/controllers/concerns/blacklight_oai_provider/controller.rb'
|
93
|
+
- 'app/models/concerns/blacklight_oai_provider/solr_document.rb'
|
94
|
+
- 'lib/blacklight_oai_provider.rb'
|
95
|
+
- 'lib/blacklight_oai_provider/engine.rb'
|
96
|
+
- 'lib/blacklight_oai_provider/exceptions.rb'
|
97
|
+
- 'lib/blacklight_oai_provider/resumption_token.rb'
|
98
|
+
- 'lib/blacklight_oai_provider/routes.rb'
|
99
|
+
- 'lib/blacklight_oai_provider/solr_document_provider.rb'
|
100
|
+
- 'lib/blacklight_oai_provider/solr_document_wrapper.rb'
|
101
|
+
- 'lib/blacklight_oai_provider/version.rb'
|
102
|
+
- 'lib/generators/blacklight_oai_provider/install_generator.rb'
|
103
|
+
|
104
|
+
# Offense count: 24
|
105
|
+
# Cop supports --auto-correct.
|
106
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
107
|
+
# SupportedStyles: when_needed, always, never
|
108
|
+
Style/FrozenStringLiteralComment:
|
109
|
+
Enabled: false
|
110
|
+
|
111
|
+
# Offense count: 2
|
112
|
+
# Configuration parameters: MinBodyLength.
|
113
|
+
Style/GuardClause:
|
114
|
+
Exclude:
|
115
|
+
- 'lib/generators/blacklight_oai_provider/install_generator.rb'
|
116
|
+
|
117
|
+
# Offense count: 1
|
118
|
+
# Cop supports --auto-correct.
|
119
|
+
# Configuration parameters: MinSize, SupportedStyles.
|
120
|
+
# SupportedStyles: percent, brackets
|
121
|
+
Style/SymbolArray:
|
122
|
+
EnforcedStyle: brackets
|
123
|
+
|
124
|
+
# Offense count: 1
|
125
|
+
# Cop supports --auto-correct.
|
126
|
+
# Configuration parameters: IgnoredMethods.
|
127
|
+
# IgnoredMethods: respond_to, define_method
|
128
|
+
Style/SymbolProc:
|
129
|
+
Exclude:
|
130
|
+
- 'spec/spec_helper.rb'
|
data/.solr_wrapper
ADDED
data/.travis.yml
ADDED
data/Gemfile
CHANGED
@@ -2,5 +2,37 @@ source 'http://rubygems.org'
|
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
# BEGIN ENGINE_CART BLOCK
|
6
|
+
# engine_cart: 1.1.0
|
7
|
+
# engine_cart stanza: 0.10.0
|
8
|
+
# the below comes from engine_cart, a gem used to test this Rails engine gem in the context of a Rails app.
|
9
|
+
file = File.expand_path('Gemfile', ENV['ENGINE_CART_DESTINATION'] || ENV['RAILS_ROOT'] || File.expand_path('.internal_test_app', File.dirname(__FILE__)))
|
10
|
+
if File.exist?(file)
|
11
|
+
begin
|
12
|
+
eval_gemfile file
|
13
|
+
rescue Bundler::GemfileError => e
|
14
|
+
Bundler.ui.warn '[EngineCart] Skipping Rails application dependencies:'
|
15
|
+
Bundler.ui.warn e.message
|
16
|
+
end
|
17
|
+
else
|
18
|
+
Bundler.ui.warn "[EngineCart] Unable to find test application dependencies in #{file}, using placeholder dependencies"
|
19
|
+
|
20
|
+
if ENV['RAILS_VERSION']
|
21
|
+
if ENV['RAILS_VERSION'] == 'edge'
|
22
|
+
gem 'rails', github: 'rails/rails'
|
23
|
+
ENV['ENGINE_CART_RAILS_OPTIONS'] = '--edge --skip-turbolinks'
|
24
|
+
else
|
25
|
+
gem 'rails', ENV['RAILS_VERSION']
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
case ENV['RAILS_VERSION']
|
30
|
+
when /^4.2/
|
31
|
+
gem 'responders', '~> 2.0'
|
32
|
+
gem 'sass-rails', '>= 5.0'
|
33
|
+
gem 'coffee-rails', '~> 4.1.0'
|
34
|
+
when /^4.[01]/
|
35
|
+
gem 'sass-rails', '< 5.0'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
# END ENGINE_CART BLOCK
|
data/README.md
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
# BlacklightOaiProvider
|
2
|
+
OAI-PMH service endpoint for Blacklight applications
|
3
|
+
|
4
|
+
## Description
|
5
|
+
The BlacklightOaiProvider plugin provides an [Open Archives Initiative Protocol for Metadata Harvesting (OAI-PMH)](http://www.openarchives.org/pmh/) data provider endpoint, using the [ruby-oai gem](https://github.com/code4lib/ruby-oai). This endpoint enables service providers harvest a data provider's metadata.
|
6
|
+
|
7
|
+
### Versioning
|
8
|
+
Starting `v4.1` major plugin versions are synced with major Blacklight versions. The last known version to work with Blacklight 3.x/Rails 3.x is `v0.1.0`.
|
9
|
+
|
10
|
+
A few maintenance branches have been left in place in case there is interest to add support for older versions of Rails/Blacklight:
|
11
|
+
|
12
|
+
`v3.x` -> Support for Blacklight 3.0
|
13
|
+
|
14
|
+
`v4.x` -> Support for Blacklight 4.0 and Rails 3.0
|
15
|
+
|
16
|
+
## Requirements
|
17
|
+
A Rails app running Rails 4.x and Blacklight 4.x.
|
18
|
+
|
19
|
+
OAI-PMH requires a timestamp field for all records. The Solr index should include an appropriate field. This field should be able to support date range queries. By default, the name of this field is `timestamp` (more on how to configure this below).
|
20
|
+
|
21
|
+
A properly configured documentHandler in the blacklight/solr configuration.
|
22
|
+
|
23
|
+
## Installation
|
24
|
+
|
25
|
+
Add
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
gem 'blacklight_oai_provider', git: 'https://github.com/projectblacklight/blacklight_oai_provider'
|
29
|
+
```
|
30
|
+
|
31
|
+
to your Gemfile and run `bundle install`.
|
32
|
+
|
33
|
+
Then run
|
34
|
+
```ruby
|
35
|
+
rails generate blacklight_oai_provider:install
|
36
|
+
```
|
37
|
+
to install the appropriate extensions into your `CatalogController` and `SolrDocument` classes. If you want to do customize the way this installs, instead you may:
|
38
|
+
|
39
|
+
- add this to your Solr Document model:
|
40
|
+
```ruby
|
41
|
+
include BlacklightOaiProvider::SolrDocument
|
42
|
+
```
|
43
|
+
- add this to your Controller:
|
44
|
+
```ruby
|
45
|
+
include BlacklightOaiProvider::Controller
|
46
|
+
```
|
47
|
+
|
48
|
+
## Configuration
|
49
|
+
|
50
|
+
While the plugin provides some sensible (albeit generic) defaults out of the box, you probably will want to customize the OAI provider configuration.
|
51
|
+
|
52
|
+
### Blacklight configuration
|
53
|
+
You can provide OAI-PMH provider parameters by placing the following in your blacklight configuration (most likely in `app/controllers/catalog_controller.rb`)
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
configure_blacklight do |config|
|
57
|
+
|
58
|
+
# ...
|
59
|
+
|
60
|
+
config.oai = {
|
61
|
+
:provider => {
|
62
|
+
:repository_name => 'Test',
|
63
|
+
:repository_url => 'http://localhost',
|
64
|
+
:record_prefix => '',
|
65
|
+
:admin_email => 'root@localhost'
|
66
|
+
},
|
67
|
+
:document => {
|
68
|
+
:model => SolrDocument, # SolrDocument class you are using.
|
69
|
+
:limit => 25
|
70
|
+
}
|
71
|
+
}
|
72
|
+
|
73
|
+
# ...
|
74
|
+
|
75
|
+
end
|
76
|
+
```
|
77
|
+
|
78
|
+
The "provider" configuration is documented as part of the ruby-oai gem at http://oai.rubyforge.org/
|
79
|
+
|
80
|
+
_Note:_ The document handler in your blacklight controller must be configured properly for this plugin to correctly look up records.
|
81
|
+
|
82
|
+
### SolrDocument configuration
|
83
|
+
To change the name of the timestamp solr field in your `SolrDocument` model change the following attribute:
|
84
|
+
```ruby
|
85
|
+
self.timestamp_key = 'record_creation_date' # Default: 'timestamp'
|
86
|
+
```
|
87
|
+
|
88
|
+
The metadata displayed in the xml serialization of each record is based off the `field_semantics` hash in the `SolrDocument` model. To update/change these fields add something like the following to your model:
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
field_semantics.merge!(
|
92
|
+
creator: "author_display",
|
93
|
+
date: "pub_date",
|
94
|
+
subject: "subject_topic_facet",
|
95
|
+
title: "title_display",
|
96
|
+
language: "language_facet",
|
97
|
+
format: "format"
|
98
|
+
)
|
99
|
+
```
|
100
|
+
|
101
|
+
The fields used by the dublin core serialization are:
|
102
|
+
```ruby
|
103
|
+
[:contributor, :coverage, :creator, :date, :description, :format, :identifier, :language, :publisher, :relation, :rights, :source, :subject, :title, :type]
|
104
|
+
```
|
105
|
+
|
106
|
+
## Injection
|
107
|
+
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.
|
108
|
+
|
109
|
+
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.
|
110
|
+
|
111
|
+
In any initializer, you can set:
|
112
|
+
```ruby
|
113
|
+
BlacklightOaiProvider.omit_inject = true
|
114
|
+
```
|
115
|
+
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.
|
116
|
+
|
117
|
+
You can also turn off injection of individual components, which could be more useful:
|
118
|
+
```ruby
|
119
|
+
BlacklightOaiProvider.omit_inject = {
|
120
|
+
:routes => false,
|
121
|
+
}
|
122
|
+
```
|
123
|
+
## Tests
|
124
|
+
We use `engine_cart` and `solr_wrapper` to run tests on a dummy instance of an app using this plugin.
|
125
|
+
|
126
|
+
To run the entire test suite:
|
127
|
+
```ruby
|
128
|
+
rake ci
|
129
|
+
```
|
130
|
+
|
131
|
+
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/
|
data/Rakefile
CHANGED
@@ -2,3 +2,28 @@ require 'rake'
|
|
2
2
|
require 'bundler'
|
3
3
|
|
4
4
|
Bundler::GemHelper.install_tasks
|
5
|
+
|
6
|
+
require 'engine_cart/rake_task'
|
7
|
+
require 'solr_wrapper'
|
8
|
+
|
9
|
+
task default: [:rubocop, :ci]
|
10
|
+
|
11
|
+
require 'rspec/core/rake_task'
|
12
|
+
RSpec::Core::RakeTask.new
|
13
|
+
|
14
|
+
require 'rubocop/rake_task'
|
15
|
+
RuboCop::RakeTask.new(:rubocop)
|
16
|
+
|
17
|
+
EngineCart.fingerprint_proc = EngineCart.rails_fingerprint_proc
|
18
|
+
|
19
|
+
desc 'Run test suite'
|
20
|
+
task ci: ['engine_cart:generate'] do
|
21
|
+
SolrWrapper.wrap do |solr|
|
22
|
+
solr.with_collection(name: 'blacklight-core', dir: File.join(File.expand_path(__dir__), "solr", "conf")) do
|
23
|
+
within_test_app do
|
24
|
+
system "RAILS_ENV=test rake blacklight_oai_provider:index:seed"
|
25
|
+
end
|
26
|
+
Rake::Task['spec'].invoke
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
4.1.0
|
@@ -528,13 +528,20 @@ p.intro {
|
|
528
528
|
<!-- oai resumptionToken -->
|
529
529
|
|
530
530
|
<xsl:template match="oai:resumptionToken">
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
531
|
+
<xsl:choose>
|
532
|
+
<xsl:when test="self::node()[text()]">
|
533
|
+
<p>There are more results.</p>
|
534
|
+
<table class="values">
|
535
|
+
<tr><td class="key">resumptionToken:</td>
|
536
|
+
<td class="value"><xsl:value-of select="."/>
|
535
537
|
<xsl:text> </xsl:text>
|
536
538
|
<a class="link" href="?verb={/oai:OAI-PMH/oai:request/@verb}&resumptionToken={.}">Resume</a></td></tr>
|
537
|
-
|
539
|
+
</table>
|
540
|
+
</xsl:when>
|
541
|
+
<xsl:otherwise>
|
542
|
+
<p>End of results.</p>
|
543
|
+
</xsl:otherwise>
|
544
|
+
</xsl:choose>
|
538
545
|
</xsl:template>
|
539
546
|
|
540
547
|
<!-- unknown metadata format -->
|
@@ -0,0 +1,38 @@
|
|
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
|
5
|
+
module Controller
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
helper_method :oai_config
|
10
|
+
end
|
11
|
+
|
12
|
+
# Action method of our own!
|
13
|
+
# Delivers a _partial_ that's a display of a single fields range facets.
|
14
|
+
# Used when we need a second Solr query to get range facets, after the
|
15
|
+
# first found min/max from result set.
|
16
|
+
def oai
|
17
|
+
options = params.delete_if { |k, _| %w[controller action].include?(k) }
|
18
|
+
body = oai_provider
|
19
|
+
.process_request(options)
|
20
|
+
.gsub('<?xml version="1.0" encoding="UTF-8"?>') do |m|
|
21
|
+
"#{m}\n<?xml-stylesheet type=\"text/xsl\" href=\"#{ActionController::Base.helpers.asset_path('blacklight_oai_provider/oai2.xsl')}\"?>\n"
|
22
|
+
end
|
23
|
+
render text: body, content_type: 'text/xml'
|
24
|
+
end
|
25
|
+
|
26
|
+
# Uses Blacklight.config, needs to be modified when
|
27
|
+
# that changes to be controller-based. This is the only method
|
28
|
+
# in this plugin that accesses Blacklight.config, single point
|
29
|
+
# of contact.
|
30
|
+
def oai_config
|
31
|
+
blacklight_config.oai || {}
|
32
|
+
end
|
33
|
+
|
34
|
+
def oai_provider
|
35
|
+
@oai_provider ||= BlacklightOaiProvider::SolrDocumentProvider.new(self, oai_config)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module BlacklightOaiProvider
|
2
|
+
module SolrDocument
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def timestamp
|
6
|
+
timestamp = get(self.class.timestamp_key)
|
7
|
+
raise BlacklightOaiProvider::Exceptions::MissingTimestamp if timestamp.blank?
|
8
|
+
Time.zone.parse(timestamp) # Solr timestamps are all in UTC.
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_oai_dc
|
12
|
+
export_as('oai_dc_xml')
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
attr_writer :timestamp_key
|
17
|
+
|
18
|
+
def timestamp_key
|
19
|
+
@timestamp_key ||= 'timestamp'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,15 +1,19 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
1
|
require File.join(File.dirname(__FILE__), "lib/blacklight_oai_provider/version")
|
3
2
|
|
4
3
|
Gem::Specification.new do |s|
|
5
4
|
s.name = "blacklight_oai_provider"
|
6
5
|
s.version = BlacklightOaiProvider::VERSION
|
7
6
|
s.platform = Gem::Platform::RUBY
|
8
|
-
s.authors = ["Chris Beer"]
|
9
|
-
s.email = ["chris@cbeer.info"]
|
7
|
+
s.authors = ["Chris Beer", "Carla Galarza"]
|
8
|
+
s.email = ["chris@cbeer.info", "cmg2228@columbia.edu"]
|
10
9
|
s.homepage = "http://projectblacklight.org/"
|
11
10
|
s.summary = "Blacklight Oai Provider plugin"
|
12
11
|
|
12
|
+
s.post_install_message = %q{
|
13
|
+
BlacklightOaiProvider v4.1 implements configuration changes. Please visit README for more information.
|
14
|
+
|
15
|
+
}
|
16
|
+
|
13
17
|
s.rubyforge_project = "blacklight"
|
14
18
|
|
15
19
|
s.files = `git ls-files`.split("\n")
|
@@ -17,13 +21,16 @@ Gem::Specification.new do |s|
|
|
17
21
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
22
|
s.require_paths = ["lib"]
|
19
23
|
|
20
|
-
|
21
|
-
s.add_dependency "
|
22
|
-
s.add_dependency "blacklight", "~> 3.2"
|
24
|
+
s.add_dependency "rails", "~> 4.0"
|
25
|
+
s.add_dependency "blacklight", "~> 4.0"
|
23
26
|
s.add_dependency "oai"
|
24
|
-
s.add_development_dependency 'rspec'
|
25
|
-
s.add_development_dependency 'rspec-rails'
|
27
|
+
s.add_development_dependency 'rspec-rails', "~> 3.0"
|
26
28
|
s.add_development_dependency 'capybara'
|
27
|
-
s.add_development_dependency '
|
28
|
-
s.add_development_dependency '
|
29
|
+
s.add_development_dependency 'solr_wrapper'
|
30
|
+
s.add_development_dependency 'engine_cart'
|
31
|
+
s.add_development_dependency "chromedriver-helper"
|
32
|
+
s.add_development_dependency "selenium-webdriver"
|
33
|
+
s.add_development_dependency 'byebug'
|
34
|
+
s.add_development_dependency 'rubocop', '~> 0.50.0'
|
35
|
+
s.add_development_dependency "rubocop-rspec", '~> 1.18.0'
|
29
36
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Fix the OAI gem resource identifier format
|
2
|
+
# See: https://github.com/code4lib/ruby-oai/issues/38
|
3
|
+
|
4
|
+
Rails.application.config.to_prepare do
|
5
|
+
OAI::Provider::Response::RecordResponse.class_eval do
|
6
|
+
private
|
7
|
+
|
8
|
+
def identifier_for(record)
|
9
|
+
"#{provider.prefix}:#{record.id}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
OAI::Provider::Response::Base.class_eval do
|
14
|
+
private
|
15
|
+
|
16
|
+
def extract_identifier(id)
|
17
|
+
id.sub("#{provider.prefix}:", '')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -4,14 +4,27 @@ require 'rails'
|
|
4
4
|
|
5
5
|
module BlacklightOaiProvider
|
6
6
|
class Engine < Rails::Engine
|
7
|
-
|
8
7
|
# Do these things in a to_prepare block, to try and make them work
|
9
8
|
# in development mode with class-reloading. The trick is we can't
|
10
9
|
# be sure if the controllers we're modifying are being reloaded in
|
11
10
|
# 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.
|
11
|
+
# local, they won't be. But we do our best.
|
13
12
|
config.to_prepare do
|
14
13
|
BlacklightOaiProvider.inject!
|
15
14
|
end
|
15
|
+
|
16
|
+
# Add XSL Stylesheet to list of assets to be precompiled.
|
17
|
+
initializer "blacklight_oai_provider.assets.precompile" do |app|
|
18
|
+
app.config.assets.precompile += %w[blacklight_oai_provider/oai2.xsl]
|
19
|
+
end
|
20
|
+
|
21
|
+
# Load rake tasks.
|
22
|
+
rake_tasks do
|
23
|
+
Dir.chdir(File.expand_path(File.join(File.dirname(__FILE__), '..'))) do
|
24
|
+
Dir.glob(File.join('railties', '*.rake')).each do |railtie|
|
25
|
+
load railtie
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
16
29
|
end
|
17
30
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module BlacklightOaiProvider
|
2
|
+
class ResumptionToken < ::OAI::Provider::ResumptionToken
|
3
|
+
# parses a token string and returns a ResumptionToken
|
4
|
+
def self.parse(token_string)
|
5
|
+
options = {}
|
6
|
+
total = nil
|
7
|
+
matches = /(.+):(\d+)$/.match(token_string)
|
8
|
+
options[:last] = matches.captures[1].to_i
|
9
|
+
|
10
|
+
parts = matches.captures[0].split('.')
|
11
|
+
options[:metadata_prefix] = parts.shift
|
12
|
+
parts.each do |part|
|
13
|
+
case part
|
14
|
+
when /^s/
|
15
|
+
options[:set] = part.sub(/^s\(/, '').sub(/\)$/, '')
|
16
|
+
when /^f/
|
17
|
+
options[:from] = parse_date(part.sub(/^f\(/, '').sub(/\)$/, ''))
|
18
|
+
when /^u/
|
19
|
+
options[:until] = parse_date(part.sub(/^u\(/, '').sub(/\)$/, ''))
|
20
|
+
when /^t/
|
21
|
+
total = part.sub(/^t\(/, '').sub(/\)$/, '').to_i
|
22
|
+
end
|
23
|
+
end
|
24
|
+
new(options, nil, total)
|
25
|
+
rescue StandardError
|
26
|
+
raise OAI::ResumptionTokenException
|
27
|
+
end
|
28
|
+
|
29
|
+
# Force date to be in UTC. If date does not have a timezone UTC is assumed.
|
30
|
+
# If date is a different timezone it is converted to UTC.
|
31
|
+
def self.parse_date(str)
|
32
|
+
ActiveSupport::TimeZone.new('UTC').parse(str)
|
33
|
+
end
|
34
|
+
|
35
|
+
def encode_conditions
|
36
|
+
encoded_token = @prefix.to_s.dup
|
37
|
+
encoded_token << ".s(#{set})" if set
|
38
|
+
encoded_token << ".f(#{from.utc.xmlschema})" if from
|
39
|
+
encoded_token << ".u(#{self.until.utc.xmlschema})" if self.until
|
40
|
+
encoded_token << ".t(#{total})" if total
|
41
|
+
encoded_token << ":#{last}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_xml
|
45
|
+
xml = Builder::XmlMarkup.new
|
46
|
+
token = total && (last > total) ? '' : encode_conditions
|
47
|
+
xml.resumptionToken(token, hash_of_attributes)
|
48
|
+
xml.target!
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|