curation_concerns 1.0.0.beta1 → 1.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/app/actors/curation_concerns/actors/abstract_actor.rb +30 -0
  3. data/app/actors/curation_concerns/actors/actor_stack.rb +29 -0
  4. data/app/actors/curation_concerns/actors/add_to_collection_actor.rb +40 -0
  5. data/app/actors/curation_concerns/actors/apply_order_actor.rb +26 -0
  6. data/app/actors/curation_concerns/actors/assign_identifier_actor.rb +9 -0
  7. data/app/actors/curation_concerns/actors/assign_representative_actor.rb +20 -0
  8. data/app/actors/curation_concerns/actors/attach_files_actor.rb +41 -0
  9. data/app/actors/curation_concerns/actors/base_actor.rb +78 -0
  10. data/app/actors/curation_concerns/actors/embargo_actor.rb +21 -0
  11. data/app/actors/curation_concerns/actors/file_actor.rb +81 -0
  12. data/app/actors/curation_concerns/actors/file_set_actor.rb +159 -0
  13. data/app/actors/curation_concerns/actors/interpret_visibility_actor.rb +125 -0
  14. data/app/actors/curation_concerns/actors/lease_actor.rb +21 -0
  15. data/app/actors/curation_concerns/actors/root_actor.rb +19 -0
  16. data/app/actors/curation_concerns/actors/work_actor_behavior.rb +12 -0
  17. data/app/actors/curation_concerns/actors.rb +18 -0
  18. data/app/controllers/concerns/curation_concerns/embargoes_controller_behavior.rb +2 -2
  19. data/app/controllers/concerns/curation_concerns/file_sets_controller_behavior.rb +21 -15
  20. data/app/controllers/concerns/curation_concerns/leases_controller_behavior.rb +2 -2
  21. data/app/forms/curation_concerns/forms/collection_edit_form.rb +1 -1
  22. data/app/forms/curation_concerns/forms/file_set_edit_form.rb +2 -2
  23. data/app/forms/curation_concerns/forms/work_form.rb +1 -1
  24. data/app/forms/curation_concerns/forms.rb +14 -0
  25. data/app/helpers/curation_concerns/collections_helper.rb +10 -8
  26. data/app/jobs/audit_job.rb +0 -2
  27. data/app/jobs/characterize_job.rb +1 -1
  28. data/app/jobs/create_derivatives_job.rb +1 -1
  29. data/app/jobs/import_url_job.rb +2 -2
  30. data/app/jobs/ingest_file_job.rb +1 -1
  31. data/app/jobs/ingest_local_file_job.rb +2 -2
  32. data/app/jobs/resolrize_job.rb +0 -2
  33. data/app/jobs/visibility_copy_job.rb +0 -2
  34. data/app/models/concerns/curation_concerns/basic_metadata.rb +1 -1
  35. data/app/models/concerns/curation_concerns/characterization.rb +41 -0
  36. data/app/models/concerns/curation_concerns/collection.rb +0 -1
  37. data/app/models/concerns/curation_concerns/file_set_behavior.rb +1 -1
  38. data/app/models/concerns/curation_concerns/solr_document_behavior.rb +6 -5
  39. data/app/presenters/curation_concerns/collection_presenter.rb +1 -1
  40. data/app/presenters/curation_concerns/file_set_presenter.rb +1 -1
  41. data/app/presenters/curation_concerns/presents_attributes.rb +1 -1
  42. data/app/renderers/curation_concerns/renderers/attribute_renderer.rb +100 -0
  43. data/app/renderers/curation_concerns/renderers/configured_microdata.rb +42 -0
  44. data/app/renderers/renderers.rb +11 -0
  45. data/app/services/curation_concerns/actors/actor_factory.rb +26 -0
  46. data/app/services/curation_concerns/curation_concern.rb +1 -1
  47. data/app/services/curation_concerns/thumbnail_path_service.rb +1 -1
  48. data/app/views/collections/show.html.erb +7 -3
  49. data/app/views/curation_concerns/base/_representative_media.html.erb +1 -1
  50. data/app/views/curation_concerns/file_sets/show.html.erb +1 -1
  51. data/config/locales/curation_concerns.en.yml +4 -4
  52. data/curation_concerns.gemspec +1 -4
  53. data/lib/curation_concerns/configuration.rb +7 -0
  54. data/lib/curation_concerns/version.rb +1 -1
  55. data/lib/generators/curation_concerns/templates/catalog_controller.rb +4 -4
  56. data/lib/generators/curation_concerns/work/templates/actor.rb.erb +2 -2
  57. data/lib/generators/curation_concerns/work/templates/actor_spec.rb.erb +1 -1
  58. data/lib/generators/curation_concerns/work/work_generator.rb +2 -2
  59. data/spec/actors/curation_concerns/add_to_collections_actor_spec.rb +6 -6
  60. data/spec/actors/curation_concerns/embargo_actor_spec.rb +1 -1
  61. data/spec/actors/curation_concerns/file_actor_spec.rb +1 -1
  62. data/spec/actors/curation_concerns/file_set_actor_spec.rb +11 -10
  63. data/spec/actors/curation_concerns/interpret_visibility_actor_spec.rb +6 -6
  64. data/spec/actors/curation_concerns/lease_actor_spec.rb +1 -1
  65. data/spec/actors/curation_concerns/work_actor_spec.rb +1 -1
  66. data/spec/controllers/curation_concerns/collections_controller_spec.rb +3 -3
  67. data/spec/controllers/curation_concerns/file_sets_controller_spec.rb +4 -4
  68. data/spec/controllers/embargoes_controller_spec.rb +1 -1
  69. data/spec/controllers/leases_controller_spec.rb +1 -1
  70. data/spec/factories/generic_works.rb +1 -1
  71. data/spec/features/add_file_spec.rb +1 -1
  72. data/spec/features/work_generator_spec.rb +1 -1
  73. data/spec/forms/collection_edit_form_spec.rb +2 -2
  74. data/spec/forms/file_set_edit_form_spec.rb +1 -1
  75. data/spec/forms/work_form_spec.rb +2 -2
  76. data/spec/indexers/file_set_indexer_spec.rb +12 -9
  77. data/spec/jobs/import_url_job_spec.rb +2 -2
  78. data/spec/jobs/ingest_local_file_job_spec.rb +1 -1
  79. data/spec/models/curation_concerns/collection_behavior_spec.rb +12 -3
  80. data/spec/models/file_set_spec.rb +25 -19
  81. data/spec/presenters/curation_concerns/collection_presenter_spec.rb +1 -1
  82. data/spec/presenters/curation_concerns/file_set_presenter_spec.rb +1 -1
  83. data/spec/presenters/curation_concerns/work_show_presenter_spec.rb +2 -2
  84. data/spec/renderers/curation_concerns/{attribute_renderer_spec.rb → renderers/attribute_renderer_spec.rb} +2 -2
  85. data/spec/services/curation_concern_spec.rb +1 -1
  86. data/spec/services/thumbnail_path_service_spec.rb +13 -9
  87. data/spec/support/curation_concerns/factory_helpers.rb +18 -0
  88. metadata +28 -50
  89. data/app/actors/curation_concerns/abstract_actor.rb +0 -28
  90. data/app/actors/curation_concerns/actor_stack.rb +0 -27
  91. data/app/actors/curation_concerns/add_to_collection_actor.rb +0 -38
  92. data/app/actors/curation_concerns/apply_order_actor.rb +0 -24
  93. data/app/actors/curation_concerns/assign_identifier_actor.rb +0 -7
  94. data/app/actors/curation_concerns/assign_representative_actor.rb +0 -18
  95. data/app/actors/curation_concerns/attach_files_actor.rb +0 -39
  96. data/app/actors/curation_concerns/base_actor.rb +0 -76
  97. data/app/actors/curation_concerns/embargo_actor.rb +0 -19
  98. data/app/actors/curation_concerns/file_actor.rb +0 -79
  99. data/app/actors/curation_concerns/file_set_actor.rb +0 -157
  100. data/app/actors/curation_concerns/interpret_visibility_actor.rb +0 -123
  101. data/app/actors/curation_concerns/lease_actor.rb +0 -19
  102. data/app/actors/curation_concerns/root_actor.rb +0 -17
  103. data/app/actors/curation_concerns/work_actor_behavior.rb +0 -8
  104. data/app/renderers/curation_concerns/attribute_renderer.rb +0 -98
  105. data/app/renderers/curation_concerns/configured_microdata.rb +0 -40
  106. data/app/services/curation_concerns/actor_factory.rb +0 -24
@@ -0,0 +1,21 @@
1
+ module CurationConcerns
2
+ module Actors
3
+ class LeaseActor
4
+ attr_reader :work
5
+
6
+ # @param [Hydra::Works::Work] work
7
+ def initialize(work)
8
+ @work = work
9
+ end
10
+
11
+ # Update the visibility of the work to match the correct state of the lease, then clear the lease date, etc.
12
+ # Saves the lease and the work
13
+ def destroy
14
+ work.lease_visibility! # If the lease has lapsed, update the current visibility.
15
+ work.deactivate_lease!
16
+ work.lease.save!
17
+ work.save!
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ module CurationConcerns
2
+ module Actors
3
+ class RootActor
4
+ attr_reader :curation_concern, :user, :cloud_resources
5
+ def initialize(curation_concern, user, _more_actors)
6
+ @curation_concern = curation_concern
7
+ @user = user
8
+ end
9
+
10
+ def create(_)
11
+ true
12
+ end
13
+
14
+ def update(_)
15
+ true
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,12 @@
1
+ module CurationConcerns
2
+ module Actors
3
+ module WorkActorBehavior
4
+ extend ActiveSupport::Concern
5
+ extend Deprecation
6
+
7
+ included do
8
+ Deprecation.warn(CurationConcerns::WorkActorBehavior, "CurationConcerns::WorkActorBehavior is deprecated and will be removed in CurationConcerns 1.0")
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ module CurationConcerns
2
+ # Module for containing Actors
3
+ # @since 0.14.0
4
+ # An Actor coordinates the response to a user command
5
+ # (often via user http request to a controller). It
6
+ # performs one or more steps in the business process of a
7
+ # create, update, or destroy command issued by a user.
8
+ # You may a have a stack of multiple actors that each
9
+ # perform one action. Actors should have a specific task
10
+ # and be chained together to execute more complex business
11
+ # purposes.
12
+ # @example A series of actors responsible for creating an object:
13
+ # Metadata Writing Actor, Rights Assignment Actor,
14
+ # Indexing Actor
15
+ # @see CurationConcerns::AbstractActor for primitive interface definition
16
+ module Actors
17
+ end
18
+ end
@@ -14,7 +14,7 @@ module CurationConcerns
14
14
 
15
15
  # Removes a single embargo
16
16
  def destroy
17
- EmbargoActor.new(curation_concern).destroy
17
+ CurationConcerns::Actors::EmbargoActor.new(curation_concern).destroy
18
18
  flash[:notice] = curation_concern.embargo_history.last
19
19
  if curation_concern.work? && curation_concern.file_sets.present?
20
20
  redirect_to confirm_curation_concerns_permission_path(curation_concern)
@@ -28,7 +28,7 @@ module CurationConcerns
28
28
  filter_docs_with_edit_access!
29
29
  copy_visibility = params[:embargoes].values.map { |h| h[:copy_visibility] }
30
30
  ActiveFedora::Base.find(batch).each do |curation_concern|
31
- EmbargoActor.new(curation_concern).destroy
31
+ CurationConcerns::Actors::EmbargoActor.new(curation_concern).destroy
32
32
  curation_concern.copy_visibility_to_files if copy_visibility.include?(curation_concern.id)
33
33
  end
34
34
  redirect_to embargoes_path
@@ -15,10 +15,16 @@ module CurationConcerns
15
15
  class_attribute :show_presenter, :form_class
16
16
  self.show_presenter = CurationConcerns::FileSetPresenter
17
17
  self.form_class = CurationConcerns::Forms::FileSetEditForm
18
- end
19
18
 
20
- def curation_concern
21
- @file_set
19
+ # A little bit of explanation, CanCan(Can) sets the @file_set via the .load_and_authorize_resource
20
+ # method. However the interface for various CurationConcern modules leverages the #curation_concern method
21
+ # Thus we have file_set and curation_concern that are aliases for each other.
22
+ attr_accessor :file_set
23
+ alias_method :curation_concern, :file_set
24
+ private :file_set=
25
+ alias_method :curation_concern=, :file_set=
26
+ private :curation_concern=
27
+ helper_method :file_set
22
28
  end
23
29
 
24
30
  # routed to /files/new
@@ -61,8 +67,8 @@ module CurationConcerns
61
67
  wants.html { presenter }
62
68
  wants.json do
63
69
  # load and authorize @curation_concern manually because it's skipped for html
64
- @file_set = curation_concern_type.load_instance_from_solr(params[:id]) unless curation_concern
65
- authorize! :show, @file_set
70
+ self.curation_concern ||= curation_concern_type.load_instance_from_solr(params[:id])
71
+ authorize! :show, curation_concern
66
72
  render :show, status: :ok
67
73
  end
68
74
  additional_response_formats(wants)
@@ -70,7 +76,7 @@ module CurationConcerns
70
76
  end
71
77
 
72
78
  def destroy
73
- parent = @file_set.parent
79
+ parent = curation_concern.parent
74
80
  actor.destroy
75
81
  redirect_to [main_app, parent], notice: 'The file has been deleted.'
76
82
  end
@@ -95,7 +101,7 @@ module CurationConcerns
95
101
  flash[:error] = "There was a problem processing your request."
96
102
  render 'edit', status: :unprocessable_entity
97
103
  end
98
- wants.json { render_json_response(response_type: :unprocessable_entity, options: { errors: @file_set.errors }) }
104
+ wants.json { render_json_response(response_type: :unprocessable_entity, options: { errors: curation_concern.errors }) }
99
105
  end
100
106
  end
101
107
  rescue RSolr::Error::Http => error
@@ -107,9 +113,9 @@ module CurationConcerns
107
113
  def after_update_response
108
114
  respond_to do |wants|
109
115
  wants.html do
110
- redirect_to [main_app, @file_set], notice: "The file #{view_context.link_to(@file_set, [main_app, @file_set])} has been updated."
116
+ redirect_to [main_app, curation_concern], notice: "The file #{view_context.link_to(curation_concern, [main_app, curation_concern])} has been updated."
111
117
  end
112
- wants.json { render :show, status: :ok, location: polymorphic_path([main_app, @file_set]) }
118
+ wants.json { render :show, status: :ok, location: polymorphic_path([main_app, curation_concern]) }
113
119
  end
114
120
  end
115
121
 
@@ -154,15 +160,15 @@ module CurationConcerns
154
160
  end
155
161
 
156
162
  def version_list
157
- CurationConcerns::VersionListPresenter.new(@file_set.original_file.versions.all)
163
+ CurationConcerns::VersionListPresenter.new(curation_concern.original_file.versions.all)
158
164
  end
159
165
 
160
166
  def wants_to_revert?
161
- params.key?(:revision) && params[:revision] != @file_set.latest_content_version.label
167
+ params.key?(:revision) && params[:revision] != curation_concern.latest_content_version.label
162
168
  end
163
169
 
164
170
  def actor
165
- @actor ||= ::CurationConcerns::FileSetActor.new(@file_set, current_user)
171
+ @actor ||= ::CurationConcerns::Actors::FileSetActor.new(curation_concern, current_user)
166
172
  end
167
173
 
168
174
  def attributes
@@ -194,7 +200,7 @@ module CurationConcerns
194
200
  if request.xhr?
195
201
  render 'jq_upload', formats: 'json', content_type: 'text/html'
196
202
  else
197
- redirect_to [main_app, @file_set.parent]
203
+ redirect_to [main_app, curation_concern.parent]
198
204
  end
199
205
  end
200
206
  format.json do
@@ -202,7 +208,7 @@ module CurationConcerns
202
208
  end
203
209
  end
204
210
  else
205
- msg = @file_set.errors.full_messages.join(', ')
211
+ msg = curation_concern.errors.full_messages.join(', ')
206
212
  flash[:error] = msg
207
213
  json_error "Error creating file #{file.original_filename}: #{msg}"
208
214
  end
@@ -211,7 +217,7 @@ module CurationConcerns
211
217
  # this is provided so that implementing application can override this behavior and map params to different attributes
212
218
  def update_metadata_from_upload_screen
213
219
  # Relative path is set by the jquery uploader when uploading a directory
214
- @file_set.relative_path = params[:relative_path] if params[:relative_path]
220
+ curation_concer.relative_path = params[:relative_path] if params[:relative_path]
215
221
  end
216
222
 
217
223
  def curation_concern_type
@@ -14,7 +14,7 @@ module CurationConcerns
14
14
 
15
15
  # Removes a single lease
16
16
  def destroy
17
- LeaseActor.new(curation_concern).destroy
17
+ CurationConcerns::Actors::LeaseActor.new(curation_concern).destroy
18
18
  flash[:notice] = curation_concern.lease_history.last
19
19
  if curation_concern.work? && curation_concern.file_sets.present?
20
20
  redirect_to confirm_curation_concerns_permission_path(curation_concern)
@@ -27,7 +27,7 @@ module CurationConcerns
27
27
  filter_docs_with_edit_access!
28
28
  copy_visibility = params[:leases].values.map { |h| h[:copy_visibility] }
29
29
  ActiveFedora::Base.find(batch).each do |curation_concern|
30
- LeaseActor.new(curation_concern).destroy
30
+ CurationConcerns::Actors::LeaseActor.new(curation_concern).destroy
31
31
  curation_concern.copy_visibility_to_files if copy_visibility.include?(curation_concern.id)
32
32
  end
33
33
  redirect_to leases_path
@@ -7,7 +7,7 @@ module CurationConcerns
7
7
  delegate :human_readable_type, :member_ids, to: :model
8
8
 
9
9
  self.terms = [:resource_type, :title, :creator, :contributor, :description,
10
- :tag, :rights, :publisher, :date_created, :subject, :language,
10
+ :keyword, :rights, :publisher, :date_created, :subject, :language,
11
11
  :representative_id, :thumbnail_id, :identifier, :based_near,
12
12
  :related_url, :visibility]
13
13
 
@@ -1,12 +1,12 @@
1
1
  module CurationConcerns::Forms
2
2
  class FileSetEditForm
3
3
  include HydraEditor::Form
4
- self.required_fields = [:title, :creator, :tag, :rights]
4
+ self.required_fields = [:title, :creator, :keyword, :rights]
5
5
 
6
6
  self.model_class = ::FileSet
7
7
 
8
8
  self.terms = [:resource_type, :title, :creator, :contributor, :description,
9
- :tag, :rights, :publisher, :date_created, :subject, :language,
9
+ :keyword, :rights, :publisher, :date_created, :subject, :language,
10
10
  :identifier, :based_near, :related_url,
11
11
  :visibility_during_embargo, :visibility_after_embargo, :embargo_release_date,
12
12
  :visibility_during_lease, :visibility_after_lease, :lease_expiration_date,
@@ -10,7 +10,7 @@ module CurationConcerns
10
10
  :visibility, to: :model
11
11
 
12
12
  self.terms = [:title, :creator, :contributor, :description,
13
- :tag, :rights, :publisher, :date_created, :subject, :language,
13
+ :keyword, :rights, :publisher, :date_created, :subject, :language,
14
14
  :identifier, :based_near, :related_url,
15
15
  :representative_id, :thumbnail_id, :files,
16
16
  :visibility_during_embargo, :embargo_release_date, :visibility_after_embargo,
@@ -0,0 +1,14 @@
1
+ module CurationConcerns
2
+ # This will be the module for containing forms
3
+ # @since 0.14.0
4
+ # Forms are a type of data structures that include validation that leverage hydra editor
5
+ # capabilities. Their purpose is to allow users to edit and save objects based on models.
6
+ # The impetus for their creation was to remove validation from models, and perhaps
7
+ # demultiplex fields from one form to multiple objects. A form must define the model
8
+ # it uses and attributes it manipulates. It may include default values and define required
9
+ # required fields. They are ruby objects that are typically instantiated by the controller
10
+ # to facilitate user creation, editing, or deleting of an object. They can also be used to
11
+ # sanitize attributes passed along to actors, as they are in curation concerns.
12
+ module Forms
13
+ end
14
+ end
@@ -60,14 +60,16 @@ module CurationConcerns::CollectionsHelper
60
60
  end
61
61
 
62
62
  def convert_solr_docs_to_select_options(results)
63
- results
64
- .map { |r| [SolrDocument.new(r).title, r['id']] }
65
- .sort do |a, b|
66
- if a.first && b.first
67
- a.first <=> b.first
68
- else
69
- a.first ? -1 : 1
70
- end
63
+ option_values = results.map do |r|
64
+ title = SolrDocument.new(r).title
65
+ [title.present? ? title.join(', ') : nil, r['id']]
66
+ end
67
+ option_values.sort do |a, b|
68
+ if a.first && b.first
69
+ a.first <=> b.first
70
+ else
71
+ a.first ? -1 : 1
71
72
  end
73
+ end
72
74
  end
73
75
  end
@@ -1,6 +1,4 @@
1
1
  class AuditJob < ActiveJob::Base
2
- queue_as :audit
3
-
4
2
  # URI of the resource to audit.
5
3
  # This URI could include the actual resource (e.g. content) and the version to audit:
6
4
  # http://localhost:8983/fedora/rest/test/a/b/c/abcxyz/content/fcr:versions/version1
@@ -1,5 +1,5 @@
1
1
  class CharacterizeJob < ActiveJob::Base
2
- queue_as :characterize
2
+ queue_as CurationConcerns.config.ingest_queue_name
3
3
 
4
4
  # @param [FileSet] file_set
5
5
  # @param [String] filename a local path for the file to characterize. By using this, we don't have to pull a copy out of fedora.
@@ -1,5 +1,5 @@
1
1
  class CreateDerivativesJob < ActiveJob::Base
2
- queue_as :derivatives
2
+ queue_as CurationConcerns.config.ingest_queue_name
3
3
 
4
4
  # @param [FileSet] file_set
5
5
  # @param [String] file_name
@@ -3,7 +3,7 @@ require 'uri'
3
3
  require 'tempfile'
4
4
 
5
5
  class ImportUrlJob < ActiveJob::Base
6
- queue_as :import_url
6
+ queue_as CurationConcerns.config.ingest_queue_name
7
7
 
8
8
  before_enqueue do |job|
9
9
  log = job.arguments.last
@@ -21,7 +21,7 @@ class ImportUrlJob < ActiveJob::Base
21
21
  file_set.reload
22
22
 
23
23
  # attach downloaded file to FileSet stubbed out
24
- if CurationConcerns::FileSetActor.new(file_set, user).create_content(f)
24
+ if CurationConcerns::Actors::FileSetActor.new(file_set, user).create_content(f)
25
25
  # send message to user on download success
26
26
  CurationConcerns.config.callback.run(:after_import_url_success, file_set, user)
27
27
  log.success!
@@ -1,5 +1,5 @@
1
1
  class IngestFileJob < ActiveJob::Base
2
- queue_as :ingest
2
+ queue_as CurationConcerns.config.ingest_queue_name
3
3
 
4
4
  # @param [FileSet] file_set
5
5
  # @param [String] filename
@@ -1,5 +1,5 @@
1
1
  class IngestLocalFileJob < ActiveJob::Base
2
- queue_as :ingest_local
2
+ queue_as CurationConcerns.config.ingest_queue_name
3
3
 
4
4
  # @param [FileSet] file_set
5
5
  # @param [String] path
@@ -7,7 +7,7 @@ class IngestLocalFileJob < ActiveJob::Base
7
7
  def perform(file_set, path, user)
8
8
  file_set.label ||= File.basename(path)
9
9
 
10
- actor = CurationConcerns::FileSetActor.new(file_set, user)
10
+ actor = CurationConcerns::Actors::FileSetActor.new(file_set, user)
11
11
 
12
12
  if actor.create_content(File.open(path))
13
13
  FileUtils.rm(path)
@@ -1,6 +1,4 @@
1
1
  class ResolrizeJob < ActiveJob::Base
2
- queue_as :resolrize
3
-
4
2
  def perform
5
3
  ActiveFedora::Base.reindex_everything
6
4
  end
@@ -1,6 +1,4 @@
1
1
  class VisibilityCopyJob < ActiveJob::Base
2
- queue_as :permissions
3
-
4
2
  def perform(work)
5
3
  work.file_sets.each do |file|
6
4
  file.visibility = work.visibility # visibility must come first, because it can clear an embargo/lease
@@ -25,7 +25,7 @@ module CurationConcerns
25
25
  index.type :text
26
26
  index.as :stored_searchable
27
27
  end
28
- property :tag, predicate: ::RDF::Vocab::DC11.relation do |index|
28
+ property :keyword, predicate: ::RDF::Vocab::DC11.relation do |index|
29
29
  index.as :stored_searchable, :facetable
30
30
  end
31
31
  property :rights, predicate: ::RDF::Vocab::DC.rights do |index|
@@ -0,0 +1,41 @@
1
+ # This module points the FileSet to the location of the technical metdata.
2
+ # By default, the file holding the metadata is :original_file and the terms
3
+ # are listed under ::characterization_terms.
4
+ # Implementations may define their own terms or use a different source file, but
5
+ # any terms must be set on the ::characterization_proxy by the Hydra::Works::CharacterizationService
6
+ #
7
+ # class MyFileSet
8
+ # include CurationConcerns::FileSetBehavior
9
+ # end
10
+ #
11
+ # MyFileSet.characterization_proxy = :master_file
12
+ # MyFileSet.characterization_terms = [:term1, :term2, :term3]
13
+ module CurationConcerns
14
+ module Characterization
15
+ extend ActiveSupport::Concern
16
+
17
+ included do
18
+ class_attribute :characterization_terms, :characterization_proxy
19
+ self.characterization_terms = [
20
+ :format_label, :file_size, :height, :width, :filename, :well_formed,
21
+ :page_count, :file_title, :last_modified, :original_checksum, :mime_type
22
+ ]
23
+ self.characterization_proxy = :original_file
24
+
25
+ delegate(*characterization_terms, to: :characterization_proxy)
26
+
27
+ def characterization_proxy
28
+ send(self.class.characterization_proxy) || NullCharacterizationProxy.new
29
+ end
30
+ end
31
+
32
+ class NullCharacterizationProxy
33
+ def method_missing(*_args)
34
+ []
35
+ end
36
+
37
+ def mime_type
38
+ end
39
+ end
40
+ end
41
+ end
@@ -2,7 +2,6 @@ module CurationConcerns
2
2
  module Collection
3
3
  extend ActiveSupport::Concern
4
4
  extend Deprecation
5
- include Hydra::Works::CollectionBehavior
6
5
  include Hydra::WithDepositor # for access to apply_depositor_metadata
7
6
  include Hydra::AccessControls::Permissions
8
7
  include CurationConcerns::RequiredMetadata
@@ -9,7 +9,7 @@ module CurationConcerns
9
9
  include CurationConcerns::BasicMetadata
10
10
  include Hydra::Works::FileSetBehavior
11
11
  include Hydra::Works::VirusCheck
12
- include Hydra::Works::Characterization
12
+ include CurationConcerns::Characterization
13
13
  include Hydra::WithDepositor
14
14
  include CurationConcerns::Serializers
15
15
  include CurationConcerns::Noid
@@ -4,7 +4,8 @@ module CurationConcerns
4
4
  include Hydra::Works::MimeTypes
5
5
 
6
6
  def title_or_label
7
- title || label
7
+ return label if title.blank?
8
+ title.join(', ')
8
9
  end
9
10
 
10
11
  def to_param
@@ -63,11 +64,11 @@ module CurationConcerns
63
64
  end
64
65
 
65
66
  def title
66
- Array.wrap(self[Solrizer.solr_name('title')]).first
67
+ Array.wrap(self[Solrizer.solr_name('title')])
67
68
  end
68
69
 
69
70
  def description
70
- Array.wrap(self[Solrizer.solr_name('description')]).first
71
+ Array.wrap(self[Solrizer.solr_name('description')])
71
72
  end
72
73
 
73
74
  def label
@@ -98,8 +99,8 @@ module CurationConcerns
98
99
  fetch(Solrizer.solr_name('language'), [])
99
100
  end
100
101
 
101
- def tags
102
- fetch(Solrizer.solr_name('tag'), [])
102
+ def keyword
103
+ fetch(Solrizer.solr_name('keyword'), [])
103
104
  end
104
105
 
105
106
  def embargo_release_date
@@ -14,7 +14,7 @@ module CurationConcerns
14
14
 
15
15
  # CurationConcern methods
16
16
  delegate :stringify_keys, :human_readable_type, :collection?, :representative_id,
17
- to: :solr_document
17
+ :to_s, to: :solr_document
18
18
 
19
19
  # Metadata Methods
20
20
  delegate :title, :description, :creator, :contributor, :subject, :publisher, :language,
@@ -22,7 +22,7 @@ module CurationConcerns
22
22
  delegate :title, :description, :creator, :contributor, :subject, :publisher,
23
23
  :language, :date_uploaded, :rights,
24
24
  :embargo_release_date, :lease_expiration_date,
25
- :depositor, :tags, :title_or_label, to: :solr_document
25
+ :depositor, :keyword, :title_or_label, to: :solr_document
26
26
 
27
27
  def page_title
28
28
  Array.wrap(solr_document['label_tesim']).first
@@ -14,7 +14,7 @@ module CurationConcerns
14
14
  Rails.logger.warn("#{self.class} attempted to render #{field}, but no method exists with that name.")
15
15
  return
16
16
  end
17
- AttributeRenderer.new(field, send(field), options).render
17
+ CurationConcerns::Renderers::AttributeRenderer.new(field, send(field), options).render
18
18
  end
19
19
 
20
20
  def permission_badge
@@ -0,0 +1,100 @@
1
+ require "rails_autolink/helpers"
2
+
3
+ module CurationConcerns
4
+ module Renderers
5
+ class AttributeRenderer
6
+ include ActionView::Helpers::UrlHelper
7
+ include ActionView::Helpers::TranslationHelper
8
+ include ActionView::Helpers::TextHelper
9
+ include ConfiguredMicrodata
10
+
11
+ attr_reader :field, :values, :options
12
+
13
+ # @param [Symbol] field
14
+ # @param [Array] values
15
+ # @param [Hash] options
16
+ def initialize(field, values, options = {})
17
+ @field = field
18
+ @values = values
19
+ @options = options
20
+ end
21
+
22
+ # Draw the table row for the attribute
23
+ def render
24
+ markup = ''
25
+
26
+ return markup if !values.present? && !options[:include_empty]
27
+ markup << %(<tr><th>#{label}</th>\n<td><ul class='tabular'>)
28
+ attributes = microdata_object_attributes(field).merge(class: "attribute #{field}")
29
+ Array(values).each do |value|
30
+ markup << "<li#{html_attributes(attributes)}>#{attribute_value_to_html(value.to_s)}</li>"
31
+ end
32
+ markup << %(</ul></td></tr>)
33
+ markup.html_safe
34
+ end
35
+
36
+ # @return The human-readable label for this field.
37
+ # @note This is a central location for determining the label of a field
38
+ # name. Can be overridden if more complicated logic is needed.
39
+ def label
40
+ translate(
41
+ :"blacklight.search.fields.show.#{field}",
42
+ default: [:"blacklight.search.fields.#{field}", options.fetch(:label, field.to_s.humanize)])
43
+ end
44
+
45
+ private
46
+
47
+ def attribute_value_to_html(value)
48
+ if field == :rights
49
+ rights_attribute_to_html(value)
50
+ elsif microdata_value_attributes(field).present?
51
+ "<span#{html_attributes(microdata_value_attributes(field))}>#{li_value(value)}</span>"
52
+ else
53
+ li_value(value)
54
+ end
55
+ end
56
+
57
+ def html_attributes(attributes)
58
+ buffer = ""
59
+ attributes.each do |k, v|
60
+ buffer << " #{k}"
61
+ buffer << %(="#{v}") unless v.blank?
62
+ end
63
+ buffer
64
+ end
65
+
66
+ def search_field
67
+ options.fetch(:search_field, field)
68
+ end
69
+
70
+ def li_value(value)
71
+ if options[:catalog_search_link]
72
+ link_to(ERB::Util.h(value), search_path(value))
73
+ else
74
+ auto_link(ERB::Util.h(value))
75
+ end
76
+ end
77
+
78
+ def search_path(value)
79
+ Rails.application.routes.url_helpers.search_catalog_path(
80
+ search_field: search_field, q: ERB::Util.h(value))
81
+ end
82
+
83
+ ##
84
+ # Special treatment for license/rights. A URL from the Sufia gem's config/sufia.rb is stored in the descMetadata of the
85
+ # curation_concern. If that URL is valid in form, then it is used as a link. If it is not valid, it is used as plain text.
86
+ def rights_attribute_to_html(value)
87
+ begin
88
+ parsed_uri = URI.parse(value)
89
+ rescue
90
+ nil
91
+ end
92
+ if parsed_uri.nil?
93
+ ERB::Util.h(value)
94
+ else
95
+ %(<a href=#{ERB::Util.h(value)} target="_blank">#{RightsService.label(value)}</a>)
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,42 @@
1
+ module CurationConcerns
2
+ module Renderers
3
+ module ConfiguredMicrodata
4
+ def microdata?(field)
5
+ return false unless CurationConcerns.config.display_microdata
6
+ key = "curation_concerns.schema_org.#{field}.property"
7
+ t(key, default: false)
8
+ end
9
+
10
+ def microdata_object?(field)
11
+ return false unless CurationConcerns.config.display_microdata
12
+ key = "curation_concerns.schema_org.#{field}.type"
13
+ t(key, default: false)
14
+ end
15
+
16
+ def microdata_object_attributes(field)
17
+ if microdata_object?(field)
18
+ { itemprop: microdata_property(field), itemscope: '', itemtype: microdata_type(field) }
19
+ else
20
+ {}
21
+ end
22
+ end
23
+
24
+ def microdata_property(field)
25
+ t("curation_concerns.schema_org.#{field}.property")
26
+ end
27
+
28
+ def microdata_type(field)
29
+ t("curation_concerns.schema_org.#{field}.type")
30
+ end
31
+
32
+ def microdata_value_attributes(field)
33
+ if microdata?(field)
34
+ key = microdata_object?(field) ? :value : :property
35
+ { itemprop: t("curation_concerns.schema_org.#{field}.#{key}") }
36
+ else
37
+ {}
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end