oaipmh 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README +129 -3
- data/Rakefile +7 -5
- data/lib/oaipmh.rb +5 -6
- data/lib/oaipmh/constants.rb +2 -0
- data/lib/oaipmh/extensions/camping.rb +3 -3
- data/lib/oaipmh/metadata.rb +0 -2
- data/lib/oaipmh/provider.rb +43 -34
- data/lib/oaipmh/set.rb +30 -0
- data/lib/oaipmh/version.rb +1 -1
- data/test/oaipmh_test.rb +72 -2
- data/test/test_helper.rb +104 -0
- metadata +37 -10
data/README
CHANGED
@@ -1,3 +1,129 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
# = README
|
2
|
+
#
|
3
|
+
# Copyright (C) 2006 William Groppe
|
4
|
+
#
|
5
|
+
# Will Groppe mailto:wfg@artstor.org
|
6
|
+
#
|
7
|
+
# Open Archives Initiative - Protocol for Metadata Harvesting see
|
8
|
+
# http://www.openarchives.org/
|
9
|
+
#
|
10
|
+
# === Features
|
11
|
+
# * Easily setup a simple repository
|
12
|
+
# * Simple integration with ActiveRecord
|
13
|
+
# * Dublin Core metadata format included
|
14
|
+
# * Easily add addition metadata formats
|
15
|
+
# * Adaptable to any data source
|
16
|
+
#
|
17
|
+
#
|
18
|
+
# === Current shortcomings
|
19
|
+
# * No resumption tokens
|
20
|
+
# * Doesn't validate metadata
|
21
|
+
# * No deletion support
|
22
|
+
# * Many others I can't think of right now. :-)
|
23
|
+
#
|
24
|
+
#
|
25
|
+
# === ActiveRecord integration
|
26
|
+
#
|
27
|
+
# To successfully use ActiveRecord as a OAI PMH datasource the database table
|
28
|
+
# should include an updated_at column so that updates to the table are
|
29
|
+
# tracked by ActiveRecord. This provides much of the base functionality for
|
30
|
+
# selecting update periods.
|
31
|
+
#
|
32
|
+
# To understand how the data is extracted from the AR model it's best to just
|
33
|
+
# go thru the logic:
|
34
|
+
#
|
35
|
+
# Does the model respond to 'to_{prefix}'? Where prefix is the
|
36
|
+
# metadata prefix. If it does then just include the response from
|
37
|
+
# the model. So if you want to provide custom or complex metadata you can
|
38
|
+
# simply define a 'to_{prefix}' method on your model.
|
39
|
+
#
|
40
|
+
# Example:
|
41
|
+
#
|
42
|
+
# class Record < ActiveRecord::Base
|
43
|
+
#
|
44
|
+
# def to_oai_dc
|
45
|
+
# xml = Builder::XmlMarkup.new
|
46
|
+
# xml.tag!('oai_dc:dc',
|
47
|
+
# 'xmlns:oai_dc' => "http://www.openarchives.org/OAI/2.0/oai_dc/",
|
48
|
+
# 'xmlns:dc' => "http://purl.org/dc/elements/1.1/",
|
49
|
+
# 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
|
50
|
+
# 'xsi:schemaLocation' =>
|
51
|
+
# %{http://www.openarchives.org/OAI/2.0/oai_dc/
|
52
|
+
# http://www.openarchives.org/OAI/2.0/oai_dc.xsd}) do
|
53
|
+
#
|
54
|
+
# xml.oai_dc :title, title
|
55
|
+
# xml.oai_dc :subject, subject
|
56
|
+
# end
|
57
|
+
# xml.to_s
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
# If the model doesn't define a 'to_{prefix}' then start iterating thru
|
63
|
+
# the defined metadata fields.
|
64
|
+
#
|
65
|
+
# Grab a mapping if one exists by trying to call 'map_{prefix}'.
|
66
|
+
#
|
67
|
+
# Now do the iteration and try calling methods on the model that match
|
68
|
+
# the field names, or the mapped field names.
|
69
|
+
#
|
70
|
+
# So with Dublin Core we end up with the following:
|
71
|
+
#
|
72
|
+
# 1. Check for 'title' mapped to a different method.
|
73
|
+
# 2. Call model.titles - try plural
|
74
|
+
# 3. Call model.title - try singular last
|
75
|
+
#
|
76
|
+
# Extremely contrived Blog example:
|
77
|
+
#
|
78
|
+
# class Post < ActiveRecord::Base
|
79
|
+
# def map_oai_dc
|
80
|
+
# {:subject => :tags,
|
81
|
+
# :description => :text,
|
82
|
+
# :creator => :user,
|
83
|
+
# :contibutor => :comments}
|
84
|
+
# end
|
85
|
+
# end
|
86
|
+
#
|
87
|
+
# === Supporting custom metadata
|
88
|
+
#
|
89
|
+
# See OaiPmh::Metadata for details.
|
90
|
+
#
|
91
|
+
# == Examples
|
92
|
+
#
|
93
|
+
# === Sub classing a provider
|
94
|
+
#
|
95
|
+
# class MyProvider < OaiPmh::Provider
|
96
|
+
# name 'My little OAI provider'
|
97
|
+
# url 'http://localhost/provider'
|
98
|
+
# prefix 'oai:localhost'
|
99
|
+
# email 'root@localhost' # String or Array
|
100
|
+
# deletes 'no' # future versions will support deletes
|
101
|
+
# granularity 'YYYY-MM-DDThh:mm:ssZ' # update resolution
|
102
|
+
# model MyModel # Class to get data from
|
103
|
+
# end
|
104
|
+
#
|
105
|
+
# # Now use it
|
106
|
+
#
|
107
|
+
# provider = MyProvider.new
|
108
|
+
# provider.identify
|
109
|
+
# provider.list_sets
|
110
|
+
# provider.list_metadata_formats
|
111
|
+
# # these verbs require a working model
|
112
|
+
# provider.list_identifiers
|
113
|
+
# provider.list_records
|
114
|
+
# provider.get_record('oai:localhost/1')
|
115
|
+
#
|
116
|
+
#
|
117
|
+
# === Configuring the default provider
|
118
|
+
#
|
119
|
+
# class OaiPmh::Provider
|
120
|
+
# name 'My little OAI Provider'
|
121
|
+
# url 'http://localhost/provider'
|
122
|
+
# prefix 'oai:localhost'
|
123
|
+
# email 'root@localhost' # String or Array
|
124
|
+
# deletes 'no' # future versions will support deletes
|
125
|
+
# granularity 'YYYY-MM-DDThh:mm:ssZ' # update resolution
|
126
|
+
# model MyModel # Class to get data from
|
127
|
+
# end
|
128
|
+
#
|
129
|
+
#
|
data/Rakefile
CHANGED
@@ -10,9 +10,9 @@ require 'fileutils'
|
|
10
10
|
include FileUtils
|
11
11
|
require File.join(File.dirname(__FILE__), 'lib', 'oaipmh', 'version')
|
12
12
|
|
13
|
-
AUTHOR = "
|
14
|
-
EMAIL = "
|
15
|
-
DESCRIPTION = "
|
13
|
+
AUTHOR = "Will Groppe"
|
14
|
+
EMAIL = "will.groppe@gmail.com"
|
15
|
+
DESCRIPTION = "OAI-PMH Provider"
|
16
16
|
RUBYFORGE_PROJECT = "oaipmh"
|
17
17
|
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
18
18
|
BIN_FILES = %w( )
|
@@ -57,8 +57,10 @@ spec =
|
|
57
57
|
s.require_path = "lib"
|
58
58
|
s.autorequire = "oaipmh"
|
59
59
|
|
60
|
-
|
61
|
-
|
60
|
+
s.add_dependency('activesupport', '>=1.3.1')
|
61
|
+
s.add_dependency('chronic', '>=0.1.4')
|
62
|
+
s.add_dependency('builder', '>=2.0.0')
|
63
|
+
s.required_ruby_version = '>= 1.8.2'
|
62
64
|
|
63
65
|
s.files = %w(README CHANGELOG Rakefile) +
|
64
66
|
Dir.glob("{bin,doc,test,lib,templates,generator,extras,website,script}/**/*") +
|
data/lib/oaipmh.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
#
|
1
|
+
require 'rubygems'
|
2
|
+
require 'active_support'
|
3
|
+
require 'builder'
|
4
|
+
require 'chronic'
|
6
5
|
|
7
|
-
Dir[File.join(File.dirname(__FILE__), 'oaipmh
|
6
|
+
Dir[File.join(File.dirname(__FILE__), 'oaipmh/*.rb')].sort.each do |lib|
|
8
7
|
require lib
|
9
8
|
end
|
data/lib/oaipmh/constants.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
require 'oaipmh'
|
2
2
|
|
3
3
|
module OaiPmh
|
4
|
-
module
|
5
|
-
module
|
4
|
+
module Goes
|
5
|
+
module Camping
|
6
6
|
|
7
7
|
def self.included(mod)
|
8
|
-
instance_eval(%{module
|
8
|
+
instance_eval(%{module ::#{mod}::Controllers
|
9
9
|
class Oai
|
10
10
|
def get
|
11
11
|
@headers['Content-Type'] = 'text/xml'
|
data/lib/oaipmh/metadata.rb
CHANGED
data/lib/oaipmh/provider.rb
CHANGED
@@ -132,28 +132,31 @@ module OaiPmh
|
|
132
132
|
class Provider
|
133
133
|
include Helpers
|
134
134
|
|
135
|
-
@@options = {}
|
136
|
-
|
137
135
|
AVAILABLE_FORMATS = {}
|
138
136
|
|
139
137
|
class << self
|
140
|
-
|
141
|
-
|
142
|
-
class_eval %{
|
143
|
-
def #{field}(value)
|
144
|
-
@@options[:#{field}] = value
|
145
|
-
end
|
146
|
-
}
|
147
|
-
end
|
148
|
-
|
138
|
+
attr_accessor :options
|
139
|
+
|
149
140
|
def model(value)
|
150
|
-
|
141
|
+
self.options ||={}
|
142
|
+
self.options[:model] = value
|
151
143
|
end
|
152
|
-
|
144
|
+
|
153
145
|
end
|
154
146
|
|
147
|
+
OaiPmh::Const::DEFAULTS.keys.each do |field|
|
148
|
+
class_eval %{
|
149
|
+
def self.#{field}(value)
|
150
|
+
self.options ||={}
|
151
|
+
self.options[:#{field}] = value
|
152
|
+
end
|
153
|
+
}
|
154
|
+
end
|
155
|
+
|
155
156
|
def initialize
|
156
|
-
@config =
|
157
|
+
@config = self.class.options ?
|
158
|
+
OaiPmh::Const::DEFAULTS.merge(self.class.options) :
|
159
|
+
OaiPmh::Const::DEFAULTS
|
157
160
|
end
|
158
161
|
|
159
162
|
def identify
|
@@ -235,12 +238,13 @@ module OaiPmh
|
|
235
238
|
end
|
236
239
|
|
237
240
|
def list_sets_response
|
238
|
-
raise SetException.new unless
|
241
|
+
raise SetException.new unless @model && @model.oai_sets
|
239
242
|
@xml.ListSets do |ls|
|
240
|
-
oai_sets.each do |ms|
|
243
|
+
@model.oai_sets.each do |ms|
|
241
244
|
@xml.set do |set|
|
242
245
|
@xml.setSpec ms.spec
|
243
246
|
@xml.setName ms.name
|
247
|
+
@xml.setDescription(ms.description) if ms.respond_to?(:description)
|
244
248
|
end
|
245
249
|
end
|
246
250
|
end
|
@@ -250,19 +254,19 @@ module OaiPmh
|
|
250
254
|
@xml.ListMetadataFormats do
|
251
255
|
@config[:formats].each_pair do |key, format|
|
252
256
|
@xml.metadataFormat do
|
253
|
-
@xml.metadataPrefix
|
254
|
-
@xml.schema
|
255
|
-
@xml.metadataNamespace
|
257
|
+
@xml.metadataPrefix format.send(:prefix)
|
258
|
+
@xml.schema format.send(:schema)
|
259
|
+
@xml.metadataNamespace format.send(:namespace)
|
256
260
|
end
|
257
261
|
end
|
258
262
|
end
|
259
263
|
end
|
260
264
|
|
261
265
|
def list_identifiers_response
|
262
|
-
raise
|
266
|
+
raise FormatException.new unless @config[:formats].include? @format
|
263
267
|
records = find :all
|
264
268
|
|
265
|
-
raise
|
269
|
+
raise NoMatchException.new if records.nil? || records.empty?
|
266
270
|
|
267
271
|
@xml.ListIdentifiers do
|
268
272
|
records.each do |record|
|
@@ -350,10 +354,12 @@ module OaiPmh
|
|
350
354
|
|
351
355
|
# emit record header
|
352
356
|
def metadata_header(record)
|
353
|
-
@xml.header do
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
+
@xml.header do
|
358
|
+
@xml.identifier "#{@config[:prefix]}/#{record.id}"
|
359
|
+
@xml.datestamp record.updated_at.utc.xmlschema
|
360
|
+
record.sets.each do |set|
|
361
|
+
@xml.setSpec set.spec
|
362
|
+
end if record.respond_to?(:sets)
|
357
363
|
end
|
358
364
|
end
|
359
365
|
|
@@ -369,8 +375,8 @@ module OaiPmh
|
|
369
375
|
@xml << str
|
370
376
|
end
|
371
377
|
else
|
372
|
-
map =
|
373
|
-
|
378
|
+
map = @model.respond_to?("map_#{@format}") ?
|
379
|
+
@model.send("map_#{@format}") : {}
|
374
380
|
|
375
381
|
mdformat = @config[:formats][@format]
|
376
382
|
@xml.metadata do
|
@@ -378,7 +384,7 @@ module OaiPmh
|
|
378
384
|
mdformat.fields.each do |field|
|
379
385
|
set = value_for(field, record, map)
|
380
386
|
set.each do |mdv|
|
381
|
-
|
387
|
+
@xml.tag! "#{mdformat.element_ns}:#{field}", mdv
|
382
388
|
end
|
383
389
|
end
|
384
390
|
end
|
@@ -397,17 +403,20 @@ module OaiPmh
|
|
397
403
|
# 4) Try calling the singular name method on the model, if it's not a
|
398
404
|
# reserved word.
|
399
405
|
def value_for(field, record, map)
|
400
|
-
if map.keys.include?(field)
|
401
|
-
|
402
|
-
|
406
|
+
if map.keys.include?(field.intern)
|
407
|
+
value = record.send(map[field.intern])
|
408
|
+
if value.kind_of?(String)
|
409
|
+
return [value]
|
410
|
+
end
|
411
|
+
return value.to_a
|
403
412
|
end
|
404
413
|
|
405
414
|
begin
|
406
|
-
return record.send(
|
407
|
-
rescue
|
415
|
+
return record.send(field.pluralize).to_a
|
416
|
+
rescue
|
408
417
|
unless OaiPmh::Const::RESERVED_WORDS.include?(field)
|
409
418
|
begin
|
410
|
-
return record.send(
|
419
|
+
return [record.send(field)]
|
411
420
|
rescue
|
412
421
|
return []
|
413
422
|
end
|
data/lib/oaipmh/set.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# = set.rb
|
2
|
+
#
|
3
|
+
# Copyright (C) 2006 William Groppe
|
4
|
+
#
|
5
|
+
# Will Groppe mailto: wfg@artstor.org
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# Implementing a set from scratch requires overridding two methods from
|
9
|
+
# OaiPmh::Set
|
10
|
+
#
|
11
|
+
# * name - descriptive name of this set
|
12
|
+
# * spec - short name of set
|
13
|
+
#
|
14
|
+
# and optionally
|
15
|
+
#
|
16
|
+
# * description - long description of the set
|
17
|
+
#
|
18
|
+
module OaiPmh
|
19
|
+
class Set
|
20
|
+
|
21
|
+
def name
|
22
|
+
"unknown"
|
23
|
+
end
|
24
|
+
|
25
|
+
def spec
|
26
|
+
"set"
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
data/lib/oaipmh/version.rb
CHANGED
data/test/oaipmh_test.rb
CHANGED
@@ -1,11 +1,81 @@
|
|
1
|
+
require 'rexml/document'
|
1
2
|
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
3
|
|
4
|
+
class MappedProvider < OaiPmh::Provider
|
5
|
+
name 'Mapped Provider'
|
6
|
+
prefix 'oai:test'
|
7
|
+
model MappedModel
|
8
|
+
end
|
9
|
+
|
10
|
+
class SimpleProvider < OaiPmh::Provider
|
11
|
+
name 'Test Provider'
|
12
|
+
prefix 'oai:test'
|
13
|
+
model SimpleModel
|
14
|
+
end
|
15
|
+
|
3
16
|
class OaipmhTest < Test::Unit::TestCase
|
4
17
|
|
5
18
|
def setup
|
19
|
+
@simple_provider = SimpleProvider.new
|
20
|
+
@mapped_provider = MappedProvider.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_indentify
|
24
|
+
doc = REXML::Document.new(@simple_provider.identify)
|
25
|
+
assert doc.elements["/OAI-PMH/Identify/repositoryName"].text == 'Test Provider'
|
26
|
+
assert doc.elements["/OAI-PMH/Identify/earliestDatestamp"].text == SimpleModel.oai_earliest.to_s
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_list_sets
|
30
|
+
doc = REXML::Document.new(@simple_provider.list_sets)
|
31
|
+
sets = doc.elements["/OAI-PMH/ListSets"]
|
32
|
+
assert sets.size == 2
|
33
|
+
assert sets[0].elements["//setName"].text == "Test Set"
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_metadata_formats
|
37
|
+
assert_nothing_raised { REXML::Document.new(@simple_provider.list_metadata_formats) }
|
38
|
+
doc = REXML::Document.new(@simple_provider.list_metadata_formats)
|
39
|
+
assert doc.elements['/OAI-PMH/ListMetadataFormats/metadataFormat/metadataPrefix'].text == 'oai_dc'
|
6
40
|
end
|
7
41
|
|
8
|
-
def
|
9
|
-
|
42
|
+
def test_list_records
|
43
|
+
assert_nothing_raised { REXML::Document.new(@simple_provider.list_records) }
|
44
|
+
doc = REXML::Document.new(@simple_provider.list_records)
|
45
|
+
assert_equal 5, doc.elements['OAI-PMH/ListRecords'].to_a.size
|
46
|
+
doc = REXML::Document.new(@simple_provider.list_records(:set => 'A'))
|
47
|
+
assert_equal 5, doc.elements['OAI-PMH/ListRecords'].to_a.size
|
48
|
+
doc = REXML::Document.new(@simple_provider.list_records(:set => 'A:B'))
|
49
|
+
assert_equal 2, doc.elements['OAI-PMH/ListRecords'].to_a.size
|
10
50
|
end
|
51
|
+
|
52
|
+
def test_list_identifiers
|
53
|
+
assert_nothing_raised { REXML::Document.new(@simple_provider.list_identifiers) }
|
54
|
+
doc = REXML::Document.new(@simple_provider.list_identifiers)
|
55
|
+
assert_equal 5, doc.elements['OAI-PMH/ListIdentifiers'].to_a.size
|
56
|
+
doc = REXML::Document.new(@simple_provider.list_identifiers(:set => 'A'))
|
57
|
+
assert_equal 5, doc.elements['OAI-PMH/ListIdentifiers'].to_a.size
|
58
|
+
doc = REXML::Document.new(@simple_provider.list_identifiers(:set => 'A:B'))
|
59
|
+
assert_equal 2, doc.elements['OAI-PMH/ListIdentifiers'].to_a.size
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_get_record
|
63
|
+
assert_nothing_raised { REXML::Document.new(@simple_provider.get_record('oai:test/1')) }
|
64
|
+
doc = REXML::Document.new(@simple_provider.get_record('oai:test/1'))
|
65
|
+
assert_equal 'oai:test/1', doc.elements['OAI-PMH/GetRecord/record/header/identifier'].text
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_mapped_source
|
69
|
+
assert_nothing_raised { REXML::Document.new(@mapped_provider.list_records) }
|
70
|
+
doc = REXML::Document.new(@mapped_provider.list_records)
|
71
|
+
assert_equal "title 1", doc.elements['OAI-PMH/ListRecords/record/metadata/oai_dc:dc/dc:creator'].text
|
72
|
+
assert_equal "creator", doc.elements['OAI-PMH/ListRecords/record/metadata/oai_dc:dc/dc:title'].text
|
73
|
+
assert_equal "tag 1", doc.elements['OAI-PMH/ListRecords/record/metadata/oai_dc:dc/dc:subject'].text
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_verb_exception
|
77
|
+
doc = REXML::Document.new(@simple_provider.process_verb('NoVerb'))
|
78
|
+
assert doc.elements["/OAI-PMH/error"].attributes["code"] == 'badVerb'
|
79
|
+
end
|
80
|
+
|
11
81
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,2 +1,106 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
require File.dirname(__FILE__) + '/../lib/oaipmh'
|
3
|
+
|
4
|
+
class Record
|
5
|
+
attr_accessor :id, :titles, :creator, :tags, :sets, :updated_at
|
6
|
+
|
7
|
+
def initialize(id, titles, creator, tags, sets)
|
8
|
+
@id = id;
|
9
|
+
@titles = titles
|
10
|
+
@creator = creator
|
11
|
+
@tags = tags
|
12
|
+
@sets = sets
|
13
|
+
@updated_at = Time.new.utc
|
14
|
+
end
|
15
|
+
|
16
|
+
# Override Object.id
|
17
|
+
def id
|
18
|
+
@id
|
19
|
+
end
|
20
|
+
|
21
|
+
def in_set(spec)
|
22
|
+
@sets.each { |set| return true if set.spec == spec }
|
23
|
+
false
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
class OneSet < OaiPmh::Set
|
29
|
+
|
30
|
+
def name
|
31
|
+
"Test Set"
|
32
|
+
end
|
33
|
+
|
34
|
+
def spec
|
35
|
+
"A"
|
36
|
+
end
|
37
|
+
|
38
|
+
def description
|
39
|
+
"A long winded description of this set."
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
class TwoSet < OaiPmh::Set
|
45
|
+
|
46
|
+
def name
|
47
|
+
"Not so test Set"
|
48
|
+
end
|
49
|
+
|
50
|
+
def spec
|
51
|
+
"A:B"
|
52
|
+
end
|
53
|
+
|
54
|
+
def description
|
55
|
+
"A short winded description of this set."
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
class SimpleModel
|
64
|
+
include OaiPmh::Model
|
65
|
+
|
66
|
+
RECORDS = [
|
67
|
+
Record.new(1, ['title 1', 'title 2'], 'creator', ['tag 1', 'tag 2'], [OneSet.new]),
|
68
|
+
Record.new(2, ['title 3', 'title 4'], 'creator', ['tag 3', 'tag 4'], [OneSet.new]),
|
69
|
+
Record.new(3, ['title 5', 'title 6'], 'creator', ['tag 5', 'tag 6'], [OneSet.new]),
|
70
|
+
Record.new(4, ['title 7', 'title 8'], 'creator', ['tag 9', 'tag 8'], [OneSet.new, TwoSet.new]),
|
71
|
+
Record.new(5, ['title 9', 'title 10'], 'creator', ['tag 9', 'tag 10'], [OneSet.new, TwoSet.new]),
|
72
|
+
]
|
73
|
+
|
74
|
+
class << self
|
75
|
+
def oai_earliest
|
76
|
+
Time.parse("2006-10-31T00:00:00Z")
|
77
|
+
end
|
78
|
+
|
79
|
+
def oai_sets
|
80
|
+
[OneSet.new, TwoSet.new]
|
81
|
+
end
|
82
|
+
|
83
|
+
def oai_find(selector, opts = {})
|
84
|
+
if selector == :all
|
85
|
+
if opts[:set]
|
86
|
+
return RECORDS.select { |rec| rec.in_set(opts[:set]) }
|
87
|
+
else
|
88
|
+
return RECORDS
|
89
|
+
end
|
90
|
+
else
|
91
|
+
RECORDS.each do |record|
|
92
|
+
return record if record.id.to_s == selector
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
class MappedModel < SimpleModel
|
100
|
+
|
101
|
+
def self.map_oai_dc
|
102
|
+
{:title => :creator, :creator => :titles, :subject => :tags}
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
metadata
CHANGED
@@ -3,31 +3,31 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: oaipmh
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
7
|
-
date: 2006-11-
|
8
|
-
summary:
|
6
|
+
version: 0.0.2
|
7
|
+
date: 2006-11-07 00:00:00 -05:00
|
8
|
+
summary: OAI-PMH Provider
|
9
9
|
require_paths:
|
10
10
|
- lib
|
11
|
-
email:
|
11
|
+
email: will.groppe@gmail.com
|
12
12
|
homepage: http://oaipmh.rubyforge.org
|
13
13
|
rubyforge_project: oaipmh
|
14
|
-
description:
|
14
|
+
description: OAI-PMH Provider
|
15
15
|
autorequire: oaipmh
|
16
16
|
default_executable:
|
17
17
|
bindir: bin
|
18
18
|
has_rdoc: true
|
19
19
|
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
20
|
requirements:
|
21
|
-
- - "
|
21
|
+
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version:
|
23
|
+
version: 1.8.2
|
24
24
|
version:
|
25
25
|
platform: ruby
|
26
26
|
signing_key:
|
27
27
|
cert_chain:
|
28
28
|
post_install_message:
|
29
29
|
authors:
|
30
|
-
-
|
30
|
+
- Will Groppe
|
31
31
|
files:
|
32
32
|
- README
|
33
33
|
- CHANGELOG
|
@@ -44,6 +44,7 @@ files:
|
|
44
44
|
- lib/oaipmh/metadata.rb
|
45
45
|
- lib/oaipmh/model.rb
|
46
46
|
- lib/oaipmh/provider.rb
|
47
|
+
- lib/oaipmh/set.rb
|
47
48
|
- lib/oaipmh/version.rb
|
48
49
|
- lib/oaipmh/extensions/camping.rb
|
49
50
|
- lib/oaipmh/metadata/oai_dc.rb
|
@@ -70,5 +71,31 @@ extensions: []
|
|
70
71
|
|
71
72
|
requirements: []
|
72
73
|
|
73
|
-
dependencies:
|
74
|
-
|
74
|
+
dependencies:
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: activesupport
|
77
|
+
version_requirement:
|
78
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.3.1
|
83
|
+
version:
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: chronic
|
86
|
+
version_requirement:
|
87
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: 0.1.4
|
92
|
+
version:
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: builder
|
95
|
+
version_requirement:
|
96
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: 2.0.0
|
101
|
+
version:
|