curation_concerns 1.4.0 → 1.5.0

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 (90) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +2 -0
  4. data/Gemfile +4 -0
  5. data/Rakefile +2 -2
  6. data/app/actors/curation_concerns/actors/file_actor.rb +2 -3
  7. data/app/assets/javascripts/curation_concerns/file_manager.es6 +32 -1
  8. data/app/assets/javascripts/curation_concerns/file_manager/member.es6 +6 -0
  9. data/app/assets/stylesheets/curation_concerns/_positioning.scss +3 -2
  10. data/app/assets/stylesheets/curation_concerns/modules/file_manager.scss +14 -0
  11. data/app/controllers/concerns/curation_concerns/curation_concern_controller.rb +3 -3
  12. data/app/controllers/concerns/curation_concerns/single_use_links_controller_behavior.rb +2 -2
  13. data/app/indexers/curation_concerns/admin_set_indexer.rb +13 -0
  14. data/app/indexers/curation_concerns/file_set_indexer.rb +5 -0
  15. data/app/indexers/curation_concerns/work_indexer.rb +3 -0
  16. data/app/models/admin_set.rb +3 -0
  17. data/app/models/concerns/curation_concerns/admin_set_behavior.rb +29 -0
  18. data/app/models/concerns/curation_concerns/file_set/characterization.rb +2 -1
  19. data/app/models/concerns/curation_concerns/in_admin_set.rb +9 -0
  20. data/app/models/concerns/curation_concerns/publishable.rb +19 -0
  21. data/app/models/concerns/curation_concerns/solr_behavior/characterization.rb +106 -0
  22. data/app/models/concerns/curation_concerns/solr_document_behavior.rb +5 -0
  23. data/app/models/concerns/curation_concerns/work_behavior.rb +2 -0
  24. data/app/models/curation_concerns/state_workflow.rb +13 -0
  25. data/app/models/vocab/fedora_resource_status.rb +6 -0
  26. data/app/presenters/curation_concerns/characterization_behavior.rb +84 -0
  27. data/app/presenters/curation_concerns/file_set_presenter.rb +1 -0
  28. data/app/presenters/curation_concerns/work_show_presenter.rb +1 -1
  29. data/app/search_builders/curation_concerns/admin_set_search_builder.rb +22 -0
  30. data/app/services/curation_concerns/admin_set_service.rb +26 -0
  31. data/app/services/curation_concerns/indexes_thumbnails.rb +1 -0
  32. data/app/services/curation_concerns/license_service.rb +8 -0
  33. data/app/services/curation_concerns/qa_select_service.rb +33 -0
  34. data/app/services/curation_concerns/rights_statements.rb +8 -0
  35. data/app/services/rights_service.rb +9 -2
  36. data/app/views/collections/_button_create_collection.html.erb +1 -1
  37. data/app/views/collections/_button_for_update_collection.html.erb +1 -1
  38. data/app/views/curation_concerns/base/_file_manager_actions.html.erb +1 -0
  39. data/app/views/curation_concerns/base/_file_manager_member.html.erb +24 -23
  40. data/app/views/curation_concerns/base/_file_manager_member_resource_options.html.erb +6 -0
  41. data/app/views/curation_concerns/base/_file_manager_resource_form.html.erb +5 -0
  42. data/app/views/curation_concerns/base/_form_rights.html.erb +1 -1
  43. data/app/views/curation_concerns/file_sets/media_display/_default.html.erb +18 -9
  44. data/app/views/curation_concerns/file_sets/media_display/_image.html.erb +18 -13
  45. data/app/views/curation_concerns/file_sets/media_display/_office_document.html.erb +18 -13
  46. data/app/views/curation_concerns/file_sets/media_display/_pdf.html.erb +18 -13
  47. data/config/locales/curation_concerns.en.yml +6 -0
  48. data/curation_concerns.gemspec +2 -2
  49. data/lib/curation_concerns/version.rb +1 -1
  50. data/lib/generators/curation_concerns/install_generator.rb +6 -9
  51. data/lib/generators/curation_concerns/templates/config/authorities/{rights.yml → licenses.yml} +0 -0
  52. data/lib/generators/curation_concerns/templates/config/authorities/rights_statements.yml +37 -0
  53. data/spec/abilities/admin_set_abilities_spec.rb +15 -0
  54. data/spec/actors/curation_concerns/file_actor_spec.rb +1 -2
  55. data/spec/controllers/catalog_controller_spec.rb +9 -11
  56. data/spec/controllers/curation_concerns/classify_concerns_controller_spec.rb +2 -2
  57. data/spec/controllers/curation_concerns/collections_controller_spec.rb +39 -33
  58. data/spec/controllers/curation_concerns/file_sets_controller_json_spec.rb +10 -10
  59. data/spec/controllers/curation_concerns/file_sets_controller_spec.rb +54 -35
  60. data/spec/controllers/curation_concerns/generic_works_controller_json_spec.rb +6 -6
  61. data/spec/controllers/curation_concerns/generic_works_controller_spec.rb +30 -35
  62. data/spec/controllers/curation_concerns/operations_controller_spec.rb +2 -2
  63. data/spec/controllers/curation_concerns/permissions_controller_spec.rb +2 -2
  64. data/spec/controllers/curation_concerns/single_use_links_controller_spec.rb +10 -10
  65. data/spec/controllers/curation_concerns/single_use_links_viewer_controller_spec.rb +7 -12
  66. data/spec/controllers/downloads_controller_spec.rb +15 -19
  67. data/spec/controllers/embargoes_controller_spec.rb +6 -6
  68. data/spec/controllers/leases_controller_spec.rb +6 -6
  69. data/spec/factories/admin_sets.rb +9 -0
  70. data/spec/indexers/file_set_indexer_spec.rb +11 -2
  71. data/spec/indexers/work_indexer_spec.rb +41 -20
  72. data/spec/models/admin_set_spec.rb +78 -0
  73. data/spec/models/curation_concerns/file_set/characterization_spec.rb +1 -1
  74. data/spec/models/file_set_spec.rb +4 -1
  75. data/spec/models/generic_work_spec.rb +24 -1
  76. data/spec/models/solr_document_spec.rb +30 -0
  77. data/spec/presenters/curation_concerns/file_set_presenter_spec.rb +131 -6
  78. data/spec/renderers/curation_concerns/renderers/attribute_renderer_spec.rb +1 -4
  79. data/spec/search_builders/curation_concerns/admin_set_search_builder_spec.rb +17 -0
  80. data/spec/services/curation_concerns/admin_set_service_spec.rb +37 -0
  81. data/spec/services/curation_concerns/license_service_spec.rb +36 -0
  82. data/spec/services/curation_concerns/rights_statements_spec.rb +11 -0
  83. data/spec/services/rights_service_spec.rb +2 -0
  84. data/spec/spec_helper.rb +44 -0
  85. data/spec/support/backport_test.rb +14 -0
  86. data/spec/support/curation_concerns/factory_helpers.rb +3 -1
  87. data/spec/test_app_templates/Gemfile.extra +0 -2
  88. data/spec/views/curation_concerns/base/file_manager.html.erb_spec.rb +13 -1
  89. data/spec/views/curation_concerns/file_sets/show.html.erb_spec.rb +8 -8
  90. metadata +40 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f7cfdad9a9be43d5356653c2f33b2366241c07b8
4
- data.tar.gz: fc51ce634c3532c0956d2822f8dcb36f381ab577
3
+ metadata.gz: c3c778b10ded8ecbde18b513c114091bd5db0f03
4
+ data.tar.gz: 7665059aa1ca3e90ac806048ec6e5d05d9336514
5
5
  SHA512:
6
- metadata.gz: 29f30a7c5a4d29c69b1feb098b918b1a5319025a8f38f811a3699745ace59c3fae94f2341e2950b3b4f134c7552e50ff1a85c02bc28e43b213c6cf5d16e80f93
7
- data.tar.gz: df6588bfae1ec8231c6d39853f6bf22e9dfff09705e56d7390049631d5fcd969d2787414257ec35f2ef6c18aed154718408403420ae72a637bc79b03eafaad7d
6
+ metadata.gz: ce3acb4259faa827a4c98563a10f13d492388ae5815f5160a5505a053b8a18ed655928dacbb298a8b2e4cf701ec9280c41efd1d28d05a9a0abc57fb78f65751e
7
+ data.tar.gz: 7d4ccf6d0e886559560ffc178cba90eeb27d6654d6871905f5bdd79128b688d6a3eff8c1414bf8c89d138d8ecc90e1c34a435c3770c39e540a0c31c4d7382696
data/.gitignore CHANGED
@@ -13,3 +13,4 @@ solr_conf/
13
13
  spec/mock_upload_directory
14
14
  fcrepo4-data
15
15
  fcrepo4-test-data
16
+ /spec/examples.txt
data/.travis.yml CHANGED
@@ -8,7 +8,9 @@ env:
8
8
  - NOKOGIRI_USE_SYSTEM_LIBRARIES=true
9
9
  matrix:
10
10
  - RAILS_VERSION=4.2.7
11
+ RDF_VERSION=1.99.1
11
12
  - RAILS_VERSION=5.0.0
13
+ RDF_VERSION=2.1.0
12
14
  notifications:
13
15
  irc:
14
16
  channels:
data/Gemfile CHANGED
@@ -3,6 +3,10 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in curation_concerns.gemspec
4
4
  gemspec
5
5
 
6
+ if ENV['RDF_VERSION']
7
+ gem 'rdf', ENV['RDF_VERSION']
8
+ end
9
+
6
10
  group :development, :test do
7
11
  gem 'simplecov', '~> 0.9', require: false
8
12
  gem 'coveralls', require: false
data/Rakefile CHANGED
@@ -28,10 +28,10 @@ namespace :curation_concerns do
28
28
  end
29
29
 
30
30
  desc 'Run test suite and style checker'
31
- task spec: ['curation_concerns:rubocop', 'curation_concerns:spec']
31
+ task spec: ['curation_concerns:spec']
32
32
 
33
33
  desc 'Spin up Solr & Fedora and run the test suite'
34
- task ci: ['engine_cart:generate'] do
34
+ task ci: ['curation_concerns:rubocop', 'engine_cart:generate'] do
35
35
  Rake::Task['spec'].invoke
36
36
  end
37
37
 
@@ -34,9 +34,8 @@ module CurationConcerns
34
34
 
35
35
  CurationConcerns::VersioningService.create(repository_file, user)
36
36
 
37
- # Retrieve a copy of the original file from the repository
38
- working_file = WorkingDirectory.copy_repository_resource_to_working_directory(repository_file, file_set.id)
39
- CharacterizeJob.perform_later(file_set, working_file)
37
+ # Characterize the original file from the repository
38
+ CharacterizeJob.perform_later(file_set, repository_file.id)
40
39
  true
41
40
  end
42
41
  end
@@ -1,12 +1,14 @@
1
1
  import SaveManager from 'curation_concerns/file_manager/save_manager'
2
2
  import SortManager from 'curation_concerns/file_manager/sorting'
3
- import {FileManagerMember} from 'curation_concerns/file_manager/member'
3
+ import {InputTracker, FileManagerMember} from 'curation_concerns/file_manager/member'
4
4
  export default class FileManager {
5
5
  constructor() {
6
6
  this.save_manager = this.initialize_save_manager()
7
7
  this.sorting()
8
8
  this.save_affix()
9
9
  this.member_tracking()
10
+ this.sortable_placeholder()
11
+ this.resource_form()
10
12
  }
11
13
 
12
14
  initialize_save_manager() {
@@ -38,4 +40,33 @@ export default class FileManager {
38
40
  $(element).data("file_manager_member", manager_member)
39
41
  })
40
42
  }
43
+
44
+ // Initialize a form that represents the parent resource as a whole.
45
+ // For the purpose of CC, this only comes with a thumbnail_id hidden field
46
+ // which is synchronized with the radio buttons on each member and then
47
+ // submitted with the SaveManager.
48
+ resource_form() {
49
+ let manager = new FileManagerMember($("#resource-form").parent(), this.save_manager)
50
+ $("#resource-form").parent().data("file_manager_member", manager)
51
+ // Track thumbnail ID hidden field
52
+ new InputTracker($("*[data-member-link=thumbnail_id]"), manager)
53
+ $("#sortable *[name=thumbnail_id]").change(function() {
54
+ let val = $("#sortable *[name=thumbnail_id]:checked").val()
55
+ $("*[data-member-link=thumbnail_id]").val(val)
56
+ $("*[data-member-link=thumbnail_id]").change()
57
+ })
58
+ }
59
+
60
+ // Keep the ui/sortable placeholder the right size.
61
+ // This keeps the grid a consistent height so when the
62
+ // last row contains 1 object,
63
+ // - an element can be moved into the last spot, and
64
+ // - the footer doesn't jump up.
65
+ sortable_placeholder() {
66
+ $( "#sortable" ).on( "sortstart", function( event, ui ) {
67
+ let found_element = $("#sortable").children("li[data-reorder-id]").first()
68
+ ui.placeholder.width(found_element.width())
69
+ ui.placeholder.height(found_element.height())
70
+ })
71
+ }
41
72
  }
@@ -75,6 +75,12 @@ export class FileManagerMember {
75
75
  this.element.removeClass("success")
76
76
  this.element.removeClass("pending")
77
77
  })
78
+ // unset the callbacks after they've run so they don't build up
79
+ // and consume memory
80
+ deferred.always(function() {
81
+ form.off('ajax:success')
82
+ form.off('ajax:error')
83
+ })
78
84
  form.submit()
79
85
  return deferred
80
86
  } else {
@@ -134,6 +134,7 @@ legend + .form-group {
134
134
  }
135
135
  }
136
136
 
137
- .img-responsive, figure {
138
- display: inline-block;
137
+ .representative-media {
138
+ display: block;
139
+ padding: 0.5em 0;
139
140
  }
@@ -35,6 +35,13 @@
35
35
  .attributes {
36
36
  @extend .col-xs-12;
37
37
  }
38
+ .member_resource_options {
39
+ @extend .col-xs-12;
40
+ float: none;
41
+ input[type=radio] {
42
+ margin-left: 1px;
43
+ }
44
+ }
38
45
  .order-title {
39
46
  width: 85%;
40
47
  }
@@ -59,6 +66,13 @@
59
66
  .attributes {
60
67
  @extend .col-xs-6;
61
68
  }
69
+ .member_resource_options {
70
+ @extend .col-xs-12;
71
+ float: none;
72
+ input[type=radio] {
73
+ margin-left: 1px;
74
+ }
75
+ }
62
76
  .order-title {
63
77
  width: 49%;
64
78
  display: inline-block;
@@ -62,13 +62,13 @@ module CurationConcerns::CurationConcernController
62
62
  end
63
63
  additional_response_formats(wants)
64
64
  wants.ttl do
65
- render text: presenter.export_as_ttl
65
+ render body: presenter.export_as_ttl, content_type: 'text/turtle'
66
66
  end
67
67
  wants.jsonld do
68
- render text: presenter.export_as_jsonld
68
+ render body: presenter.export_as_jsonld, content_type: 'application/ld+json'
69
69
  end
70
70
  wants.nt do
71
- render text: presenter.export_as_nt
71
+ render body: presenter.export_as_nt, content_type: 'application/n-triples'
72
72
  end
73
73
  end
74
74
  end
@@ -20,12 +20,12 @@ module CurationConcerns
20
20
 
21
21
  def create_download
22
22
  @su = SingleUseLink.create itemId: params[:id], path: main_app.download_path(id: params[:id])
23
- render text: curation_concerns.download_single_use_link_url(@su.downloadKey)
23
+ render plain: curation_concerns.download_single_use_link_url(@su.downloadKey)
24
24
  end
25
25
 
26
26
  def create_show
27
27
  @su = SingleUseLink.create(itemId: params[:id], path: asset_show_path)
28
- render text: curation_concerns.show_single_use_link_url(@su.downloadKey)
28
+ render plain: curation_concerns.show_single_use_link_url(@su.downloadKey)
29
29
  end
30
30
 
31
31
  def index
@@ -0,0 +1,13 @@
1
+ module CurationConcerns
2
+ class AdminSetIndexer < ActiveFedora::IndexingService
3
+ include IndexesThumbnails
4
+
5
+ def generate_solr_document
6
+ super.tap do |solr_doc|
7
+ # Makes Admin Sets show under the "Admin Sets" tab
8
+ Solrizer.set_field(solr_doc, 'generic_type', 'Admin Set', :facetable)
9
+ solr_doc['thumbnail_path_ss'] = thumbnail_path
10
+ end
11
+ end
12
+ end
13
+ end
@@ -22,6 +22,11 @@ module CurationConcerns
22
22
  # between files on disk (in fcrepo.binary-store-path) and objects
23
23
  # in the repository.
24
24
  solr_doc[Solrizer.solr_name('digest', :symbol)] = digest_from_content
25
+ solr_doc[Solrizer.solr_name('page_count')] = object.page_count
26
+ solr_doc[Solrizer.solr_name('file_title')] = object.file_title
27
+ solr_doc[Solrizer.solr_name('duration')] = object.duration
28
+ solr_doc[Solrizer.solr_name('sample_rate')] = object.sample_rate
29
+ solr_doc[Solrizer.solr_name('original_checksum')] = object.original_checksum
25
30
  end
26
31
  end
27
32
 
@@ -1,10 +1,13 @@
1
1
  module CurationConcerns
2
2
  class WorkIndexer < ActiveFedora::IndexingService
3
3
  include IndexesThumbnails
4
+ STORED_BOOL = Solrizer::Descriptor.new(:boolean, :stored, :indexed)
5
+
4
6
  def generate_solr_document
5
7
  super.tap do |solr_doc|
6
8
  solr_doc[Solrizer.solr_name('member_ids', :symbol)] = object.member_ids
7
9
  Solrizer.set_field(solr_doc, 'generic_type', 'Work', :facetable)
10
+ solr_doc[Solrizer.solr_name('suppressed', STORED_BOOL)] = object.suppressed?
8
11
  end
9
12
  end
10
13
  end
@@ -0,0 +1,3 @@
1
+ class AdminSet < ActiveFedora::Base
2
+ include CurationConcerns::AdminSetBehavior
3
+ end
@@ -0,0 +1,29 @@
1
+ module CurationConcerns
2
+ module AdminSetBehavior
3
+ extend ActiveSupport::Concern
4
+
5
+ include Hydra::AccessControls::WithAccessRight
6
+ include CurationConcerns::Noid
7
+ include CurationConcerns::HumanReadableType
8
+ include CurationConcerns::HasRepresentative
9
+
10
+ included do
11
+ validates_with HasOneTitleValidator
12
+ class_attribute :human_readable_short_description, :indexer
13
+ self.indexer = CurationConcerns::AdminSetIndexer
14
+ property :title, predicate: ::RDF::Vocab::DC.title do |index|
15
+ index.as :stored_searchable, :facetable
16
+ end
17
+ property :description, predicate: ::RDF::Vocab::DC.description do |index|
18
+ index.as :stored_searchable
19
+ end
20
+ has_many :members,
21
+ predicate: ::RDF::Vocab::DC.isPartOf,
22
+ class_name: 'ActiveFedora::Base'
23
+ end
24
+
25
+ def to_s
26
+ title.present? ? title : 'No Title'
27
+ end
28
+ end
29
+ end
@@ -19,7 +19,8 @@ module CurationConcerns
19
19
  class_attribute :characterization_terms, :characterization_proxy
20
20
  self.characterization_terms = [
21
21
  :format_label, :file_size, :height, :width, :filename, :well_formed,
22
- :page_count, :file_title, :last_modified, :original_checksum, :mime_type
22
+ :page_count, :file_title, :last_modified, :original_checksum, :mime_type,
23
+ :duration, :sample_rate
23
24
  ]
24
25
  self.characterization_proxy = :original_file
25
26
 
@@ -0,0 +1,9 @@
1
+ module CurationConcerns
2
+ module InAdminSet
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ belongs_to :admin_set, predicate: ::RDF::Vocab::DC.isPartOf
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,19 @@
1
+ module CurationConcerns
2
+ module Publishable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ # This holds the workflow state
7
+ property :state, predicate: Vocab::FedoraResourceStatus.objState, multiple: false
8
+
9
+ class_attribute :state_workflow, instance_writer: false
10
+ self.state_workflow = StateWorkflow
11
+ end
12
+
13
+ # Override this method if you have some critera by which records should not
14
+ # display in the search results.
15
+ def suppressed?
16
+ state_workflow.new(state).pending?
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,106 @@
1
+ module CurationConcerns
2
+ module SolrBehavior
3
+ # TODO: aside from height and width, I don't think any of these other terms are indexed by default. - Justin 3/2016
4
+ module Characterization
5
+ def format_label
6
+ self[Solrizer.solr_name("format_label")]
7
+ end
8
+
9
+ def file_size
10
+ self[Solrizer.solr_name("file_size")]
11
+ end
12
+
13
+ def filename
14
+ self[Solrizer.solr_name("filename")]
15
+ end
16
+
17
+ def well_formed
18
+ self[Solrizer.solr_name("well_formed")]
19
+ end
20
+
21
+ def byte_order
22
+ self[Solrizer.solr_name("byte_order")]
23
+ end
24
+
25
+ def capture_device
26
+ self[Solrizer.solr_name("capture_device")]
27
+ end
28
+
29
+ def color_map
30
+ self[Solrizer.solr_name("color_map")]
31
+ end
32
+
33
+ def color_space
34
+ self[Solrizer.solr_name("color_space")]
35
+ end
36
+
37
+ def compression
38
+ self[Solrizer.solr_name("compression")]
39
+ end
40
+
41
+ def gps_timestamp
42
+ self[Solrizer.solr_name("gps_timestamp")]
43
+ end
44
+
45
+ def height
46
+ self['height_is']
47
+ end
48
+
49
+ def image_producer
50
+ self[Solrizer.solr_name("image_producer")]
51
+ end
52
+
53
+ def latitude
54
+ self[Solrizer.solr_name("latitude")]
55
+ end
56
+
57
+ def longitude
58
+ self[Solrizer.solr_name("longitude")]
59
+ end
60
+
61
+ def orientation
62
+ self[Solrizer.solr_name("orientation")]
63
+ end
64
+
65
+ def profile_name
66
+ self[Solrizer.solr_name("profile_name")]
67
+ end
68
+
69
+ def profile_version
70
+ self[Solrizer.solr_name("profile_version")]
71
+ end
72
+
73
+ def scanning_software
74
+ self[Solrizer.solr_name("scanning_software")]
75
+ end
76
+
77
+ def width
78
+ self['width_is']
79
+ end
80
+
81
+ def page_count
82
+ self[Solrizer.solr_name("page_count")]
83
+ end
84
+
85
+ def file_title
86
+ self[Solrizer.solr_name("file_title")]
87
+ end
88
+
89
+ def duration
90
+ self[Solrizer.solr_name("duration")]
91
+ end
92
+
93
+ def sample_rate
94
+ self[Solrizer.solr_name("sample_rate")]
95
+ end
96
+
97
+ def last_modified
98
+ self[Solrizer.solr_name("last_modified")]
99
+ end
100
+
101
+ def original_checksum
102
+ self[Solrizer.solr_name("original_checksum")]
103
+ end
104
+ end
105
+ end
106
+ end
@@ -2,6 +2,7 @@ module CurationConcerns
2
2
  module SolrDocumentBehavior
3
3
  extend ActiveSupport::Concern
4
4
  include Hydra::Works::MimeTypes
5
+ include CurationConcerns::SolrBehavior::Characterization
5
6
 
6
7
  def title_or_label
7
8
  return label if title.blank?
@@ -64,6 +65,10 @@ module CurationConcerns
64
65
  first(Solrizer.solr_name('hasRelatedMediaFragment', :symbol))
65
66
  end
66
67
 
68
+ def thumbnail_id
69
+ first(Solrizer.solr_name('thumbnail_id', :symbol))
70
+ end
71
+
67
72
  # Date created is indexed as a string. This allows users to enter values like: 'Circa 1840-1844'
68
73
  def date_created
69
74
  first(Solrizer.solr_name("date_created"))