ddr-models 3.0.0.beta.17 → 3.0.0.beta.18

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5ada8e4f7256516690e6fc879f9c7a76ff85d254
4
- data.tar.gz: f6de430ff6b09be6010d34456a1e5a4e5ee59f86
3
+ metadata.gz: 16f19bb0a9c0d7569797de024db2638a3e1b4e2a
4
+ data.tar.gz: 1e83fcc5c343aeed276d1a36de4d99f9b95dc125
5
5
  SHA512:
6
- metadata.gz: 95c1a3beb7903628cfabe5968fa3ac91b1101fbdb3ab0a35ab6a7a67b79bd394e28d91a6758983b4d44fdba83bcf168f6a3a027f3b3a9facc5e299c29b4c99ae
7
- data.tar.gz: cc7cb67e7e46437ad4d1c7f48dfcd673de6673b3d37bd1edbdb3e6459df0c5d14d29d65bdb481b6f4afb0c43445297ebe6298298327fda9f11f86e9c4acd32fd
6
+ metadata.gz: 4abaf0450a6f928fc6c3c52da7c4a570028c82dcd58fedeff07bf24262bdce23d6a4b6c7ee30f49894120c52381d6d93c174515f2ea49ec726ae8ac8de347c34
7
+ data.tar.gz: 6975b9bf6181df4407f480b44f21f4d697fef2c989fc2f878c63c1d524f247210239042e751572530028af6b2deab2bc9c4f8827cc5054d777ef1f38423b0511
@@ -17,6 +17,8 @@ class Component < Ddr::Models::Base
17
17
  predicate: ::RDF::URI("http://www.loc.gov/mix/v20/externalTarget#hasExternalTarget"),
18
18
  class_name: "Target"
19
19
 
20
+ after_save :index_parent, if: :has_extracted_text?, unless: "parent.nil?"
21
+
20
22
  def collection
21
23
  self.parent.parent rescue nil
22
24
  end
@@ -29,4 +31,8 @@ class Component < Ddr::Models::Base
29
31
  parent.present? && parent.published?
30
32
  end
31
33
 
34
+ def index_parent
35
+ Resque.enqueue(Ddr::Jobs::UpdateIndex, parent_id)
36
+ end
37
+
32
38
  end
@@ -21,4 +21,17 @@ class Item < Ddr::Models::Base
21
21
  parent.present? && parent.published?
22
22
  end
23
23
 
24
+ def children_having_extracted_text
25
+ item = self
26
+ Ddr::Index::Query.new do
27
+ is_part_of item
28
+ where attached_files_having_content: "extractedText"
29
+ fields :id, :extracted_text
30
+ end
31
+ end
32
+
33
+ def all_text
34
+ children_having_extracted_text.docs.map(&:extracted_text).flatten
35
+ end
36
+
24
37
  end
@@ -8,8 +8,11 @@ module Ddr::Index
8
8
  ACTIVE_FEDORA_MODEL = Field.new :active_fedora_model, :stored_sortable
9
9
  ADMIN_SET = Field.new :admin_set, :stored_sortable
10
10
  ADMIN_SET_FACET = Field.new :admin_set_facet, :facetable
11
+ ALL_TEXT = Field.new :all_text, solr_name: "all_text_timv"
11
12
  ASPACE_ID = Field.new :aspace_id, :stored_sortable
12
13
  ATTACHED_FILES = Field.new :attached_files, solr_name: "attached_files_ss"
14
+ ATTACHED_FILES_HAVING_CONTENT =
15
+ Field.new :attached_files_having_content, :symbol
13
16
  BOX_NUMBER_FACET = Field.new :box_number_facet, :facetable
14
17
  COLLECTION_FACET = Field.new :collection_facet, :facetable
15
18
  COLLECTION_URI = Field.new :collection_uri, :symbol
@@ -24,7 +27,7 @@ module Ddr::Index
24
27
  DISPLAY_FORMAT = Field.new :display_format, :stored_sortable
25
28
  DOI = Field.new :doi, :symbol
26
29
  EAD_ID = Field.new :ead_id, :stored_sortable
27
- EXTRACTED_TEXT = Field.new :extracted_text, :searchable, type: :text
30
+ EXTRACTED_TEXT = Field.new :extracted_text, solr_name: "extracted_text_tsm"
28
31
  FCREPO3_PID = Field.new :fcrepo3_pid, :stored_sortable
29
32
  HAS_MODEL = Field.new :has_model, :symbol
30
33
  IDENTIFIER_ALL = Field.new :identifier_all, :symbol
@@ -76,6 +76,10 @@ module Ddr::Index
76
76
  term is_member_of_collection: get_id(object_or_id)
77
77
  end
78
78
 
79
+ def is_part_of(object_or_id)
80
+ term is_part_of: get_id(object_or_id)
81
+ end
82
+
79
83
  def model(*models)
80
84
  where active_fedora_model: models
81
85
  end
@@ -24,7 +24,7 @@ module Ddr::Index
24
24
  def pids
25
25
  Enumerator.new do |e|
26
26
  each do |doc|
27
- e << doc[Fields::PID]
27
+ e << doc[Fields::ID]
28
28
  end
29
29
  end
30
30
  end
@@ -43,10 +43,11 @@ module Ddr::Models
43
43
  permanent_id && permanent_id.sub(/\Aark:\/\d+\//, "")
44
44
  end
45
45
 
46
+ # Cf. https://github.com/duke-libraries/ddr-models/issues/586
46
47
  # @see ActiveModel::Conversion
47
- def to_key
48
- (key = permanent_id_suffix) ? [key] : super
49
- end
48
+ # def to_key
49
+ # (key = permanent_id_suffix) ? [key] : super
50
+ # end
50
51
 
51
52
  def model_and_id
52
53
  "#{self.class} id: #{id.inspect || '[NEW]'}"
@@ -84,7 +85,7 @@ module Ddr::Models
84
85
  when :present
85
86
  desc_metadata_terms.select { |t| desc_metadata.values(t).present? }
86
87
  when :defined_attributes
87
- desc_metadata_terms & desc_metadata_attributes
88
+ desc_metadata_terms & MetadataMapping.dc11.unqualified_names
88
89
  when :required
89
90
  desc_metadata_terms(:defined_attributes).select {|t| required? t}
90
91
  when :dcterms
@@ -103,12 +104,6 @@ module Ddr::Models
103
104
  terms | desc_metadata_terms(*args)
104
105
  end
105
106
  end
106
- deprecation_deprecate :desc_metadata_terms
107
-
108
- def desc_metadata_attributes
109
- MetadataMapping.dc11.unqualified_names
110
- end
111
- deprecation_deprecate :desc_metadata_attributes
112
107
 
113
108
  def desc_metadata_values(term)
114
109
  Deprecation.warn(Base, "`desc_metadata_values` is deprecated; use `desc_metadata.values` instead.")
@@ -147,7 +142,7 @@ module Ddr::Models
147
142
  def attached_files_having_content
148
143
  Hash.new.tap do |h|
149
144
  attached_files.each do |file_id, file|
150
- h[file_id] = file if file.has_content?
145
+ h[file_id] = file if !file.destroyed? && file.has_content?
151
146
  end
152
147
  end
153
148
  end
@@ -25,6 +25,7 @@ module Ddr
25
25
  CONTRIBUTOR_FACET => desc_metadata.values('contributor'),
26
26
  CREATOR_FACET => desc_metadata.creator,
27
27
  DATE_FACET => desc_metadata.date,
28
+ ATTACHED_FILES_HAVING_CONTENT => attached_files_having_content.keys,
28
29
  DATE_SORT => date_sort,
29
30
  DEPOSITOR => depositor,
30
31
  DISPLAY_FORMAT => display_format,
@@ -86,6 +87,7 @@ module Ddr
86
87
  if is_a? Item
87
88
  fields[ADMIN_SET_FACET] = admin_set_facet
88
89
  fields[COLLECTION_FACET] = collection_facet
90
+ fields[ALL_TEXT] = all_text
89
91
  end
90
92
  fields
91
93
  end
@@ -142,6 +142,10 @@ module Ddr::Models
142
142
  has_datastream?(Ddr::Models::File::CONTENT)
143
143
  end
144
144
 
145
+ def has_extracted_text?
146
+ has_datastream?(Ddr::Datastreams::EXTRACTED_TEXT)
147
+ end
148
+
145
149
  def content_ds
146
150
  datastreams[Ddr::Models::File::CONTENT]
147
151
  end
@@ -228,6 +232,10 @@ module Ddr::Models
228
232
  end
229
233
  end
230
234
 
235
+ def published?
236
+ self[Ddr::Index::Fields::WORKFLOW_STATE] == Ddr::Managers::WorkflowManager::PUBLISHED
237
+ end
238
+
231
239
  private
232
240
 
233
241
  def targets_query
@@ -1,5 +1,5 @@
1
1
  module Ddr
2
2
  module Models
3
- VERSION = "3.0.0.beta.17"
3
+ VERSION = "3.0.0.beta.18"
4
4
  end
5
5
  end
@@ -32,7 +32,8 @@ module Ddr::Auth
32
32
  end
33
33
 
34
34
  describe "non-downloadable attached_files" do
35
- (Component.ds_specs.keys.map(&:to_s) - DatastreamAbilityDefinitions::DATASTREAM_DOWNLOAD_ABILITIES.keys).each do |dsid|
35
+ (Component.child_resource_reflections.keys.map(&:to_s) - \
36
+ DatastreamAbilityDefinitions::DATASTREAM_DOWNLOAD_ABILITIES.keys).each do |dsid|
36
37
  describe "\"#{dsid}\"" do
37
38
  let(:ds) { obj.attached_files[dsid] }
38
39
  before { subject.can :download, obj.id }
@@ -0,0 +1 @@
1
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis scelerisque diam in lacus sollicitudin maximus. Duis molestie rutrum hendrerit. Vestibulum lobortis augue a ultrices mollis. Mauris semper eu odio posuere scelerisque. Donec vel condimentum nunc. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi fermentum, sem vel interdum suscipit, lacus risus ultricies sem, in lacinia ligula risus ut est. Integer gravida, orci ac lobortis blandit, eros tortor bibendum turpis, quis semper velit erat in augue.
@@ -0,0 +1 @@
1
+ Proin convallis nibh quis ex iaculis, eget porttitor elit consequat. Duis in tincidunt ipsum. Aenean imperdiet lacinia libero nec egestas. Fusce a metus volutpat, vehicula augue accumsan, mattis lorem. Donec ex tellus, tempus vitae orci sit amet, sollicitudin pharetra velit. Fusce egestas nunc vitae placerat elementum. Nullam pharetra porta eros, quis tempor sem pulvinar a. Ut in neque cursus, hendrerit neque in, congue est. Phasellus neque mauris, eleifend in sem ac, posuere tincidunt odio. Duis lectus nibh, ultricies a elementum a, consectetur vitae turpis.
@@ -0,0 +1,3 @@
1
+ Ut eu consequat turpis. Proin commodo facilisis pretium. Vestibulum tristique volutpat lobortis. Donec efficitur tincidunt porta. Sed dui massa, rutrum iaculis interdum at, scelerisque nec velit. Suspendisse potenti. Aliquam quis mauris sed magna convallis ullamcorper non ut ipsum.
2
+
3
+ Donec dolor urna, malesuada id condimentum ut, feugiat consectetur lectus. Morbi dignissim nibh neque, a bibendum ex semper vel. Nunc pellentesque varius bibendum. Etiam posuere lorem nibh, sit amet iaculis dolor lobortis nec. Nam congue dui non lectus luctus scelerisque. Aliquam turpis orci, porta non dapibus eu, accumsan sed tortor. Phasellus placerat ac mauris sed vehicula. Sed dolor massa, fringilla vitae urna vel, efficitur porta eros. Ut massa nisi, bibendum id mollis quis, aliquet eu purus. Aliquam erat volutpat. Phasellus accumsan felis eget dui vulputate, eget feugiat diam eleifend. Donec facilisis massa odio, ac auctor eros ullamcorper quis. Donec sit amet malesuada lectus. Aenean egestas, leo id lacinia mattis, dui ex tempor tellus, vel mollis velit leo a ante.
@@ -15,4 +15,68 @@ RSpec.describe Component, type: :model, components: true do
15
15
  its(:index_fields) { is_expected.to include(Ddr::Index::Fields::COLLECTION_URI => "test-1") }
16
16
  end
17
17
 
18
+ describe "extracted text" do
19
+ let(:parent) { FactoryGirl.create(:item) }
20
+ describe "when the child is not already associated with the parent" do
21
+ before {
22
+ subject.extractedText.content = fixture_file_upload('extractedText1.txt')
23
+ subject.save
24
+ subject.reload
25
+ }
26
+ it "updates the parent index when associated" do
27
+ expect(subject).to receive(:index_parent)
28
+ subject.parent = parent
29
+ subject.save
30
+ end
31
+ end
32
+ describe "when the child is already associated with the parent" do
33
+ before {
34
+ subject.parent = parent
35
+ subject.save
36
+ }
37
+ describe "when there is no extracted text" do
38
+ describe "and none is added" do
39
+ it "does not trigger an index update on the parent" do
40
+ expect(subject).not_to receive(:index_parent)
41
+ subject.save
42
+ end
43
+ end
44
+ describe "and extracted text is added" do
45
+ it "triggers an index update on the parent" do
46
+ expect(subject).to receive(:index_parent)
47
+ subject.extractedText.content = fixture_file_upload('extractedText1.txt')
48
+ subject.save
49
+ end
50
+ end
51
+ end
52
+ describe "when extracted text exists" do
53
+ before {
54
+ subject.extractedText.content = fixture_file_upload('extractedText1.txt')
55
+ subject.save
56
+ subject.reload
57
+ }
58
+ describe "and is removed" do
59
+ it "triggers an index update on the parent" do
60
+ pending "Deleting a datastream does not mark the content as changed"
61
+ expect(subject).to receive(:index_parent)
62
+ subject.extractedText.delete
63
+ subject.save
64
+ end
65
+ end
66
+ describe "and doesn't change" do
67
+ it "triggers an index update on the parent" do
68
+ expect(subject).to receive(:index_parent)
69
+ subject.save
70
+ end
71
+ end
72
+ describe "and changes" do
73
+ it "triggers an index update on the parent" do
74
+ expect(subject).to receive(:index_parent)
75
+ subject.extractedText.content = fixture_file_upload('extractedText2.txt')
76
+ subject.save
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
18
82
  end
@@ -57,6 +57,9 @@ module Ddr::Models
57
57
  }
58
58
 
59
59
  its([Indexing::CONTENT_CREATE_DATE]) { is_expected.to eq "2016-01-22T21:50:33Z" }
60
+ its([Indexing::ATTACHED_FILES_HAVING_CONTENT]) {
61
+ is_expected.to eq([:content])
62
+ }
60
63
  end
61
64
 
62
65
  end
@@ -6,4 +6,27 @@ RSpec.describe Item, type: :model do
6
6
  it_behaves_like "a non-collection model"
7
7
  it_behaves_like "a potentially publishable object"
8
8
 
9
+ describe "indexing text" do
10
+ let(:children) { FactoryGirl.build_list(:component, 5) }
11
+
12
+ let(:text1) { fixture_file_upload('extractedText1.txt', 'text/plain') }
13
+ let(:text2) { fixture_file_upload('extractedText2.txt', 'text/plain') }
14
+ let(:text3) { fixture_file_upload('extractedText3.txt', 'text/plain') }
15
+
16
+ before {
17
+ children[0].extractedText.content = text1
18
+ children[0].save
19
+ children[1].extractedText.content = text2
20
+ children[1].save
21
+ children[2].extractedText.content = text3
22
+ children[2].save
23
+ subject.children = children
24
+ subject.save
25
+ }
26
+
27
+ it "indexes the combined text of its children" do
28
+ expect(subject.index_fields[Ddr::Index::Fields::ALL_TEXT]).to contain_exactly(text1.read, text2.read, text3.read)
29
+ end
30
+ end
31
+
9
32
  end
@@ -212,4 +212,14 @@ RSpec.describe SolrDocument, type: :model, contacts: true do
212
212
  end
213
213
  end
214
214
 
215
+ describe "#published?" do
216
+ context "when the object is published" do
217
+ before { subject[Ddr::Index::Fields::WORKFLOW_STATE] = Ddr::Managers::WorkflowManager::PUBLISHED }
218
+ its(:published?) { is_expected.to eq(true) }
219
+ end
220
+ context "when the object is published" do
221
+ its(:published?) { is_expected.to eq(false) }
222
+ end
223
+ end
224
+
215
225
  end
@@ -14,7 +14,10 @@ RSpec.shared_examples "a DDR model" do
14
14
  before {
15
15
  subject.permanent_id = "ark:/99999/fk4rx95k8w"
16
16
  }
17
- its(:to_param) { is_expected.to eq("fk4rx95k8w") }
17
+ its(:to_param) do
18
+ pending "Resolution of https://github.com/duke-libraries/ddr-models/issues/586"
19
+ is_expected.to eq("fk4rx95k8w")
20
+ end
18
21
  end
19
22
  describe "when it does not have a permanent id" do
20
23
  its(:to_param) { is_expected.to_not be_nil }
@@ -23,14 +23,12 @@ RSpec.shared_examples "an object that can have content" do
23
23
  describe "extracted text" do
24
24
  describe "when it is not present" do
25
25
  its(:has_extracted_text?) { should be false }
26
- its(:to_solr) { should_not include(Ddr::Index::Fields::EXTRACTED_TEXT) }
26
+ its(:to_solr) { is_expected.not_to include(Ddr::Index::Fields::EXTRACTED_TEXT) }
27
27
  end
28
28
  describe "when it is present" do
29
29
  before { subject.extractedText.content = "This is my text. See Spot run." }
30
30
  its(:has_extracted_text?) { should be true }
31
- it "should be indexed" do
32
- expect(subject.to_solr[Ddr::Index::Fields::EXTRACTED_TEXT]).to eq("This is my text. See Spot run.")
33
- end
31
+ its(:to_solr) { is_expected.to include(Ddr::Index::Fields::EXTRACTED_TEXT) }
34
32
  end
35
33
  end
36
34
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ddr-models
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.beta.17
4
+ version: 3.0.0.beta.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Coble
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-03-09 00:00:00.000000000 Z
12
+ date: 2016-03-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -662,6 +662,9 @@ files:
662
662
  - spec/fixtures/8bit.tif
663
663
  - spec/fixtures/arrow1rightred_e0.gif
664
664
  - spec/fixtures/bird.jpg
665
+ - spec/fixtures/extractedText1.txt
666
+ - spec/fixtures/extractedText2.txt
667
+ - spec/fixtures/extractedText3.txt
665
668
  - spec/fixtures/fits/document.xml
666
669
  - spec/fixtures/fits/image.xml
667
670
  - spec/fixtures/imageA.tif
@@ -837,6 +840,9 @@ test_files:
837
840
  - spec/fixtures/8bit.tif
838
841
  - spec/fixtures/arrow1rightred_e0.gif
839
842
  - spec/fixtures/bird.jpg
843
+ - spec/fixtures/extractedText1.txt
844
+ - spec/fixtures/extractedText2.txt
845
+ - spec/fixtures/extractedText3.txt
840
846
  - spec/fixtures/fits/document.xml
841
847
  - spec/fixtures/fits/image.xml
842
848
  - spec/fixtures/imageA.tif