enju_oai 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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