enju_oai 0.0.1

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.
Files changed (51) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +3 -0
  3. data/Rakefile +46 -0
  4. data/app/views/manifestations/identify.oai.builder +16 -0
  5. data/app/views/manifestations/index.oai.builder +11 -0
  6. data/app/views/manifestations/list_identifiers.oai.builder +26 -0
  7. data/app/views/manifestations/list_metadata_formats.oai.builder +19 -0
  8. data/app/views/manifestations/list_records.oai.builder +57 -0
  9. data/app/views/manifestations/list_sets.oai.builder +15 -0
  10. data/app/views/manifestations/show.oai.builder +24 -0
  11. data/config/routes.rb +2 -0
  12. data/lib/enju_oai/engine.rb +14 -0
  13. data/lib/enju_oai/oai_controller.rb +109 -0
  14. data/lib/enju_oai/oai_model.rb +25 -0
  15. data/lib/enju_oai/version.rb +3 -0
  16. data/lib/enju_oai.rb +6 -0
  17. data/lib/tasks/enju_oai_tasks.rake +4 -0
  18. data/test/dummy/README.rdoc +261 -0
  19. data/test/dummy/Rakefile +7 -0
  20. data/test/dummy/app/assets/javascripts/application.js +15 -0
  21. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  22. data/test/dummy/app/controllers/application_controller.rb +3 -0
  23. data/test/dummy/app/helpers/application_helper.rb +2 -0
  24. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  25. data/test/dummy/config/application.rb +56 -0
  26. data/test/dummy/config/boot.rb +10 -0
  27. data/test/dummy/config/database.yml +25 -0
  28. data/test/dummy/config/environment.rb +5 -0
  29. data/test/dummy/config/environments/development.rb +37 -0
  30. data/test/dummy/config/environments/production.rb +67 -0
  31. data/test/dummy/config/environments/test.rb +37 -0
  32. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  33. data/test/dummy/config/initializers/inflections.rb +15 -0
  34. data/test/dummy/config/initializers/mime_types.rb +5 -0
  35. data/test/dummy/config/initializers/secret_token.rb +7 -0
  36. data/test/dummy/config/initializers/session_store.rb +8 -0
  37. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  38. data/test/dummy/config/locales/en.yml +5 -0
  39. data/test/dummy/config/routes.rb +58 -0
  40. data/test/dummy/config.ru +4 -0
  41. data/test/dummy/db/test.sqlite3 +0 -0
  42. data/test/dummy/log/test.log +6 -0
  43. data/test/dummy/public/404.html +26 -0
  44. data/test/dummy/public/422.html +26 -0
  45. data/test/dummy/public/500.html +25 -0
  46. data/test/dummy/public/favicon.ico +0 -0
  47. data/test/dummy/script/rails +6 -0
  48. data/test/enju_oai_test.rb +7 -0
  49. data/test/integration/navigation_test.rb +10 -0
  50. data/test/test_helper.rb +15 -0
  51. metadata +352 -0
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2012 Kosuke Tanabe
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,3 @@
1
+ = EnjuOai
2
+
3
+ This project rocks and uses MIT-LICENSE.
data/Rakefile ADDED
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'EnjuOai'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+
27
+
28
+ Bundler::GemHelper.install_tasks
29
+
30
+ require 'rake/testtask'
31
+
32
+ Rake::TestTask.new(:test) do |t|
33
+ t.libs << 'lib'
34
+ t.libs << 'test'
35
+ t.pattern = 'test/**/*_test.rb'
36
+ t.verbose = false
37
+ end
38
+
39
+ require 'rspec/core'
40
+ require 'rspec/core/rake_task'
41
+
42
+ RSpec::Core::RakeTask.new(:spec) do |spec|
43
+ spec.pattern = FileList['spec/**/*_spec.rb']
44
+ end
45
+
46
+ task :default => :spec
@@ -0,0 +1,16 @@
1
+ xml.instruct! :xml, :version=>"1.0"
2
+ xml.tag! "OAI-PMH", :xmlns => "http://www.openarchives.org/OAI/2.0/",
3
+ "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
4
+ "xsi:schemaLocation" => "http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd" do
5
+ xml.responseDate Time.zone.now.utc.iso8601
6
+ xml.request manifestations_url(:format => :oai), :verb => "Identify"
7
+ xml.Identify do
8
+ xml.repositoryName LibraryGroup.site_config.name
9
+ xml.baseURL manifestations_url(:format => :oai)
10
+ xml.protocolVersion "2.0"
11
+ xml.adminEmail LibraryGroup.site_config.email
12
+ xml.earliestDatestamp Manifestation.last.created_at.utc.iso8601 if Manifestation.last
13
+ xml.deletedRecord "no"
14
+ xml.granularity "YYYY-MM-DDThh:mm:ssZ"
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ xml.instruct! :xml, :version=>"1.0"
2
+ xml.tag! "OAI-PMH",
3
+ :xmlns => "http://www.openarchives.org/OAI/2.0/",
4
+ "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
5
+ "xsi:schemaLocation" => "http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd" do
6
+ xml.responseDate Time.zone.now.utc.iso8601
7
+ xml.request manifestations_url(:format => :oai)
8
+ @oai[:errors].each do |error|
9
+ xml.error :code => error
10
+ end
11
+ end
@@ -0,0 +1,26 @@
1
+ xml.instruct! :xml, :version=>"1.0"
2
+ xml.tag! "OAI-PMH", :xmlns => "http://www.openarchives.org/OAI/2.0/",
3
+ "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
4
+ "xsi:schemaLocation" => "http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd" do
5
+ xml.responseDate Time.zone.now.utc.iso8601
6
+ xml.request manifestations_url(:format => :oai), :verb => "ListIdentifiers", :metadataPrefix => "oai_dc"
7
+ @oai[:errors].each do |error|
8
+ xml.error :code => error
9
+ end
10
+ xml.ListIdentifiers do
11
+ @manifestations.each do |manifestation|
12
+ cache({:controller => :manifestations, :action => :show, :id => manifestation.id, :page => 'oai_pmh_list_identifiers', :role => current_user_role_name, :locale => @locale, :manifestation_id => nil}) do
13
+ xml.header do
14
+ xml.identifier manifestation.oai_identifier
15
+ xml.datestamp manifestation.updated_at.utc.iso8601
16
+ xml.setSpec manifestation.series_statement.id if manifestation.series_statement
17
+ end
18
+ end
19
+ end
20
+ if @resumption.present?
21
+ if @resumption[:cursor].to_i + @manifestations.per_page < @manifestations.total_entries
22
+ xml.resumptionToken @resumption[:token], :completeListSize => @manifestations.total_entries, :cursor => @resumption[:cursor], :expirationDate => @resumption[:expired_at]
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,19 @@
1
+ xml.instruct! :xml, :version=>"1.0"
2
+ xml.tag! "OAI-PMH", :xmlns => "http://www.openarchives.org/OAI/2.0/",
3
+ "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
4
+ "xsi:schemaLocation" => "http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd" do
5
+ xml.responseDate Time.zone.now.utc.iso8601
6
+ xml.request manifestations_url(:format => :oai), :verb => "ListMetadataFormats"
7
+ xml.ListMetadataFormats do
8
+ xml.metadataFormat do
9
+ xml.metadataPrefix "oai_dc"
10
+ xml.schema "http://www.openarchives.org/OAI/2.0/oai_dc.xsd"
11
+ xml.metadataNamespace "http://www.openarchives.org/OAI/2.0/oai_dc.xsd"
12
+ end
13
+ #xml.metadataFormat do
14
+ # xml.metadataPrefix "junii2"
15
+ # xml.schema "http://ju.nii.ac.jp/oai/junii2.xsd"
16
+ # xml.metadataNamespace "http://ju.nii.ac.jp/junii2"
17
+ #end
18
+ end
19
+ end
@@ -0,0 +1,57 @@
1
+ def request_attr(prefix = 'oai_dc')
2
+ from_time = @from_time.utc.iso8601 if @from_time
3
+ until_time = @until_time.utc.iso8601 if @until_time
4
+ attribute = {:metadataPrefix => prefix, :verb => 'ListRecords'}
5
+ attribute.merge(:from => from_time) if from_time
6
+ attribute.merge(:until => until_time) if until_time
7
+ attribute
8
+ end
9
+
10
+ xml.instruct! :xml, :version=>"1.0"
11
+ xml.tag! "OAI-PMH", :xmlns => "http://www.openarchives.org/OAI/2.0/",
12
+ "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
13
+ "xsi:schemaLocation" => "http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd" do
14
+ xml.responseDate Time.zone.now.utc.iso8601
15
+ xml.request manifestations_url(:format => :oai), request_attr('oai_dc')
16
+ @oai[:errors].each do |error|
17
+ xml.error :code => error
18
+ end
19
+ xml.ListRecords do
20
+ @manifestations.each do |manifestation|
21
+ cache({:controller => :manifestations, :action => :show, :id => manifestation.id, :page => 'oai_pmh_list_records', :role => current_user_role_name, :locale => @locale, :manifestation_id => nil}) do
22
+ xml.record do
23
+ xml.header do
24
+ xml.identifier manifestation.oai_identifier
25
+ xml.datestamp manifestation.updated_at.utc.iso8601
26
+ end
27
+ xml.metadata do
28
+ xml.tag! "oai_dc:dc",
29
+ "xsi:schemaLocation" => "http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd",
30
+ "xmlns:oai_dc" => "http://www.openarchives.org/OAI/2.0/oai_dc/",
31
+ "xmlns:dc" => "http://purl.org/dc/elements/1.1/" do
32
+ xml.tag! "dc:title", manifestation.original_title
33
+ manifestation.creators.readable_by(current_user).each do |patron|
34
+ xml.tag! "dc:creator", patron.full_name
35
+ end
36
+ manifestation.contributors.readable_by(current_user).each do |patron|
37
+ xml.tag! "dc:contributor", patron.full_name
38
+ end
39
+ manifestation.publishers.readable_by(current_user).each do |patron|
40
+ xml.tag! "dc:publisher", patron.full_name
41
+ end
42
+ manifestation.subjects.each do |subject|
43
+ xml.tag! "dc:subject", subject.term
44
+ end
45
+ xml.tag! "dc:description", manifestation.description
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ if @resumption.present?
52
+ if @resumption[:cursor].to_i + @manifestations.per_page < @manifestations.total_entries
53
+ xml.resumptionToken @resumption[:token], :completeListSize => @manifestations.total_entries, :cursor => @resumption[:cursor], :expirationDate => @resumption[:expired_at]
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,15 @@
1
+ xml.instruct! :xml, :version=>"1.0"
2
+ xml.tag! "OAI-PMH", :xmlns => "http://www.openarchives.org/OAI/2.0/",
3
+ "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
4
+ "xsi:schemaLocation" => "http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd" do
5
+ xml.responseDate Time.zone.now.utc.iso8601
6
+ xml.request manifestations_url(:format => :oai), :verb => "ListSets"
7
+ xml.ListSets do
8
+ @series_statements.each do |series_statement|
9
+ xml.set do
10
+ xml.setSpec series_statement.id
11
+ xml.setName series_statement.original_title
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,24 @@
1
+ xml.instruct! :xml, :version=>"1.0"
2
+ xml.tag! "OAI-PMH", :xmlns => "http://www.openarchives.org/OAI/2.0/",
3
+ "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
4
+ "xsi:schemaLocation" => "http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd" do
5
+ xml.responseDate Time.zone.now.utc.iso8601
6
+ xml.request manifestations_url(:format => :oai), :verb => "GetRecord"
7
+ xml.GetRecord do
8
+ xml.record do
9
+ xml.header do
10
+ xml.identifier @manifestation.oai_identifier
11
+ xml.datestamp @manifestation.updated_at.utc.iso8601
12
+ xml.setSpec @manifestation.series_statement.id if @manifestation.series_statement
13
+ end
14
+ xml.metadata do
15
+ xml.tag! "oai_dc:dc",
16
+ "xsi:schemaLocation" => "http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd",
17
+ "xmlns:oai_dc" => "http://www.openarchives.org/OAI/2.0/oai_dc/",
18
+ "xmlns:dc" => "http://purl.org/dc/elements/1.1/" do
19
+ xml.tag! "dc:title", @manifestation.original_title
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,2 @@
1
+ Rails.application.routes.draw do
2
+ end
@@ -0,0 +1,14 @@
1
+ require 'devise'
2
+ require 'cancan'
3
+ require 'sunspot_rails'
4
+ require 'acts_as_list'
5
+ require 'attribute_normalizer'
6
+ require 'friendly_id'
7
+ require 'configatron'
8
+ require 'will_paginate'
9
+ require 'mobile-fu'
10
+
11
+ module EnjuOai
12
+ class Engine < ::Rails::Engine
13
+ end
14
+ end
@@ -0,0 +1,109 @@
1
+ module EnjuOai
2
+ module OaiController
3
+ def self.included(base)
4
+ base.send :include, InstanceMethods
5
+ end
6
+
7
+ module InstanceMethods
8
+ private
9
+ def check_oai_params(params)
10
+ oai = {}
11
+ if params[:format] == 'oai'
12
+ oai[:need_not_to_search] = nil
13
+ oai[:errors] = []
14
+ case params[:verb]
15
+ when 'Identify'
16
+ oai[:need_not_to_search] = true
17
+ when 'ListSets'
18
+ oai[:need_not_to_search] = true
19
+ when 'ListMetadataFormats'
20
+ oai[:need_not_to_search] = true
21
+ when 'ListIdentifiers'
22
+ unless valid_metadata_format?(params[:metadataPrefix])
23
+ oai[:errors] << "cannotDisseminateFormat"
24
+ end
25
+ when 'ListRecords'
26
+ unless valid_metadata_format?(params[:metadataPrefix])
27
+ oai[:errors] << "cannotDisseminateFormat"
28
+ end
29
+ when 'GetRecord'
30
+ if params[:identifier].blank?
31
+ oai[:need_not_to_search] = true
32
+ oai[:errors] << "badArgument"
33
+ end
34
+ unless valid_metadata_format?(params[:metadataPrefix])
35
+ oai[:errors] << "cannotDisseminateFormat"
36
+ end
37
+ else
38
+ oai[:errors] << "badVerb"
39
+ end
40
+ end
41
+ return oai
42
+ end
43
+
44
+ def valid_metadata_format?(format)
45
+ if format.present?
46
+ if ['oai_dc'].include?(format)
47
+ true
48
+ else
49
+ false
50
+ end
51
+ else
52
+ true
53
+ end
54
+ end
55
+ end
56
+
57
+ def get_resumption_token(token)
58
+ if token.present?
59
+ resumption = Rails.cache.read(token)
60
+ end
61
+ rescue
62
+ nil
63
+ end
64
+
65
+ def set_resumption_token(token, from_time, until_time, per_page = 10)
66
+ return nil unless Rails.env.to_s == 'production'
67
+ if token.present?
68
+ latest_resumption = Rails.cache.read(token)
69
+ if latest_resumption
70
+ cursor = latest_resumption[:cursor] + per_page
71
+ end
72
+ end
73
+ cursor ||= 0
74
+ ttl = EnjuLeaf::Application.config.cache_store.last[:expires_in].to_i
75
+ resumption = {
76
+ :token => "f(#{from_time.utc.iso8601.to_s}).u(#{until_time.utc.iso8601.to_s}):#{cursor}",
77
+ :cursor => cursor,
78
+ # memcachedの使用が前提
79
+ :expired_at => ttl.seconds.from_now.utc.iso8601
80
+ }
81
+ Rails.cache.fetch(resumption[:token]){resumption}
82
+ end
83
+
84
+ def set_from_and_until(klass, from_t, until_t)
85
+ if klass.first and klass.last
86
+ from_t ||= klass.last.updated_at.to_s
87
+ until_t ||= klass.first.updated_at.to_s
88
+ else
89
+ from_t ||= Time.zone.now.to_s
90
+ until_t ||= Time.zone.now.to_s
91
+ end
92
+
93
+ times = {}
94
+ if /^[12]\d{3}-(0?[1-9]|1[0-2])-(0?[1-9]|[12]\d|3[01])$/ =~ from_t
95
+ times[:from] = Time.zone.parse(from_t).beginning_of_day
96
+ else
97
+ times[:from] = Time.zone.parse(from_t)
98
+ end
99
+ if /^[12]\d{3}-(0?[1-9]|1[0-2])-(0?[1-9]|[12]\d|3[01])$/ =~ until_t
100
+ times[:until] = Time.zone.parse(until_t).beginning_of_day
101
+ else
102
+ times[:until] = Time.zone.parse(until_t)
103
+ end
104
+ times[:from] ||= Time.zone.parse(from_t)
105
+ times[:until] ||= Time.zone.parse(until_t)
106
+ times
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,25 @@
1
+ module EnjuOai
2
+ module ActsAsMethods
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ def enju_oai
9
+ include InstanceMethods
10
+ end
11
+
12
+ def find_by_oai_identifier(identifier)
13
+ self.find(identifier.to_s.split(":").last.split("-").last)
14
+ end
15
+ end
16
+
17
+ module InstanceMethods
18
+ def oai_identifier
19
+ "oai:#{::Addressable::URI.parse(LibraryGroup.site_config.url).host}:#{self.class.to_s.tableize}-#{self.id}"
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ ActiveRecord::Base.send :include, EnjuOai::ActsAsMethods
@@ -0,0 +1,3 @@
1
+ module EnjuOai
2
+ VERSION = "0.0.1"
3
+ end
data/lib/enju_oai.rb ADDED
@@ -0,0 +1,6 @@
1
+ require "enju_oai/engine"
2
+ require 'enju_oai/oai_model'
3
+ require 'enju_oai/oai_controller'
4
+
5
+ module EnjuOai
6
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :enju_oai do
3
+ # # Task goes here
4
+ # end