ddr-models 2.3.2 → 2.4.0.rc1
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.
- checksums.yaml +4 -4
- data/.travis.yml +2 -3
- data/ddr-models.gemspec +1 -1
- data/lib/ddr/auth.rb +10 -6
- data/lib/ddr/auth/group.rb +2 -1
- data/lib/ddr/auth/grouper_gateway.rb +7 -6
- data/lib/ddr/auth/permissions.rb +2 -1
- data/lib/ddr/auth/roles.rb +3 -2
- data/lib/ddr/auth/roles/role_set.rb +3 -2
- data/lib/ddr/datastreams/administrative_metadata_datastream.rb +3 -0
- data/lib/ddr/derivatives/png_generator.rb +1 -1
- data/lib/ddr/index/fields.rb +11 -1
- data/lib/ddr/index/filter.rb +4 -3
- data/lib/ddr/index/legacy_license_fields.rb +0 -2
- data/lib/ddr/index/query_clause.rb +2 -2
- data/lib/ddr/index/query_value.rb +6 -3
- data/lib/ddr/jobs.rb +5 -1
- data/lib/ddr/jobs/fits_file_characterization.rb +2 -40
- data/lib/ddr/jobs/fixity_check.rb +13 -0
- data/lib/ddr/jobs/job.rb +36 -0
- data/lib/ddr/jobs/queue.rb +27 -0
- data/lib/ddr/jobs/update_index.rb +13 -0
- data/lib/ddr/managers/derivatives_manager.rb +21 -17
- data/lib/ddr/models.rb +14 -2
- data/lib/ddr/models/access_controllable.rb +3 -6
- data/lib/ddr/models/admin_set.rb +5 -3
- data/lib/ddr/models/base.rb +2 -3
- data/lib/ddr/models/contact.rb +17 -0
- data/lib/ddr/models/file_characterization.rb +37 -0
- data/lib/ddr/models/has_admin_metadata.rb +2 -1
- data/lib/ddr/models/has_content.rb +4 -2
- data/lib/ddr/models/indexing.rb +5 -0
- data/lib/ddr/models/licenses/license.rb +5 -3
- data/lib/ddr/models/solr_document.rb +1 -1
- data/lib/ddr/models/version.rb +1 -1
- data/lib/ddr/models/with_content_file.rb +37 -0
- data/lib/ddr/vocab/asset.rb +3 -0
- data/spec/derivatives/png_generator_spec.rb +7 -0
- data/spec/factories/test_model_factories.rb +1 -1
- data/spec/fixtures/arrow1rightred_e0.gif +0 -0
- data/spec/fixtures/bird.jpg +0 -0
- data/spec/index/query_value_spec.rb +33 -0
- data/spec/jobs/fits_file_characterization_spec.rb +8 -44
- data/spec/jobs/fixity_check_spec.rb +22 -0
- data/spec/jobs/job_spec.rb +40 -0
- data/spec/jobs/update_index_spec.rb +22 -0
- data/spec/managers/derivatives_manager_spec.rb +16 -12
- data/spec/models/admin_set_spec.rb +3 -3
- data/spec/models/contact_spec.rb +22 -0
- data/spec/models/effective_license_spec.rb +17 -7
- data/spec/models/file_characterization_spec.rb +39 -0
- data/spec/models/has_admin_metadata_spec.rb +8 -5
- data/spec/models/indexing_spec.rb +2 -0
- data/spec/models/license_spec.rb +3 -1
- data/spec/models/solr_document_spec.rb +6 -3
- data/spec/models/with_content_file_spec.rb +37 -0
- data/spec/spec_helper.rb +2 -0
- metadata +43 -30
- data/lib/ddr/contacts.rb +0 -25
- data/lib/ddr/index_fields.rb +0 -14
- data/spec/auth/ldap_gateway_spec.rb +0 -9
- data/spec/contacts/contacts_spec.rb +0 -26
@@ -51,23 +51,27 @@ module Ddr
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def generate_derivative!(derivative)
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
54
|
+
tempdir_path = File.join(Dir.tmpdir, Dir::Tmpname.make_tmpname('',nil))
|
55
|
+
begin
|
56
|
+
tempdir = FileUtils.mkdir(tempdir_path).first
|
57
|
+
generator_source = create_source_file(tempdir)
|
58
|
+
generator_output = File.new(File.join(tempdir, "output.out"), 'wb')
|
59
|
+
results = derivative.generator.new(generator_source.path, generator_output.path, derivative.options).generate
|
60
|
+
generator_source.close unless generator_source.closed?
|
61
|
+
if results.status.success?
|
62
|
+
generator_output = File.open(generator_output, 'rb')
|
63
|
+
object.reload if object.persisted?
|
64
|
+
object.add_file generator_output, derivative.datastream, mime_type: derivative.generator.output_mime_type
|
65
|
+
object.save!
|
66
|
+
else
|
67
|
+
Rails.logger.error results.stderr
|
68
|
+
raise Ddr::Models::DerivativeGenerationFailure,
|
69
|
+
"Failure generating #{derivative.name} for #{object.pid}: #{results.stderr}"
|
70
|
+
end
|
71
|
+
generator_output.close unless generator_output.closed?
|
72
|
+
ensure
|
73
|
+
FileUtils.remove_dir(tempdir_path) if File.exist?(tempdir_path)
|
68
74
|
end
|
69
|
-
generator_output.close unless generator_output.closed?
|
70
|
-
FileUtils.remove_dir(tempdir)
|
71
75
|
end
|
72
76
|
|
73
77
|
def delete_derivative(derivative)
|
@@ -110,7 +114,7 @@ module Ddr
|
|
110
114
|
when :multires_image
|
111
115
|
object.content_type == "image/tiff"
|
112
116
|
when :thumbnail
|
113
|
-
object.image?
|
117
|
+
object.image?
|
114
118
|
else
|
115
119
|
false
|
116
120
|
end
|
data/lib/ddr/models.rb
CHANGED
@@ -11,15 +11,14 @@ require 'hydra/validations'
|
|
11
11
|
|
12
12
|
module Ddr
|
13
13
|
extend ActiveSupport::Autoload
|
14
|
+
extend Deprecation
|
14
15
|
|
15
16
|
autoload :Actions
|
16
17
|
autoload :Auth
|
17
|
-
autoload :Contacts
|
18
18
|
autoload :Datastreams
|
19
19
|
autoload :Derivatives
|
20
20
|
autoload :Events
|
21
21
|
autoload :Index
|
22
|
-
autoload :IndexFields
|
23
22
|
autoload :Jobs
|
24
23
|
autoload :Managers
|
25
24
|
autoload :Metadata
|
@@ -27,6 +26,16 @@ module Ddr
|
|
27
26
|
autoload :Utils
|
28
27
|
autoload :Vocab
|
29
28
|
|
29
|
+
def self.const_missing(name)
|
30
|
+
if name == :IndexFields
|
31
|
+
Deprecation.warn(Ddr::Models, "`Ddr::IndexFields` is deprecated and will be removed in ddr-models 3.0." \
|
32
|
+
" Use `Ddr::Index::Fields` instead.")
|
33
|
+
Index::Fields
|
34
|
+
else
|
35
|
+
super
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
30
39
|
module Models
|
31
40
|
extend ActiveSupport::Autoload
|
32
41
|
|
@@ -34,11 +43,13 @@ module Ddr
|
|
34
43
|
autoload :AdminSet
|
35
44
|
autoload :Base
|
36
45
|
autoload :ChecksumInvalid, 'ddr/models/error'
|
46
|
+
autoload :Contact
|
37
47
|
autoload :ContentModelError, 'ddr/models/error'
|
38
48
|
autoload :DerivativeGenerationFailure, 'ddr/models/error'
|
39
49
|
autoload :Describable
|
40
50
|
autoload :Error
|
41
51
|
autoload :EventLoggable
|
52
|
+
autoload :FileCharacterization
|
42
53
|
autoload :FileManagement
|
43
54
|
autoload :FindingAid
|
44
55
|
autoload :FixityCheckable
|
@@ -54,6 +65,7 @@ module Ddr
|
|
54
65
|
autoload :SolrDocument
|
55
66
|
autoload :StructDiv
|
56
67
|
autoload :Structure
|
68
|
+
autoload :WithContentFile
|
57
69
|
autoload :YearFacet
|
58
70
|
|
59
71
|
autoload_under "licenses" do
|
@@ -2,26 +2,23 @@ module Ddr
|
|
2
2
|
module Models
|
3
3
|
module AccessControllable
|
4
4
|
extend ActiveSupport::Concern
|
5
|
+
extend Deprecation
|
5
6
|
|
6
7
|
included do
|
7
8
|
include Hydra::AccessControls::Permissions
|
8
9
|
end
|
9
10
|
|
10
11
|
def set_initial_permissions(user_creator = nil)
|
11
|
-
warn "[DEPRECATION] `set_initial_permissions` is deprecated" \
|
12
|
-
" and should not be used with role-based access control" \
|
13
|
-
" (#{caller.first})."
|
14
12
|
if user_creator
|
15
13
|
self.permissions_attributes = [{type: "user", access: "edit", name: user_creator.to_s}]
|
16
14
|
end
|
17
15
|
end
|
16
|
+
deprecation_deprecate :set_initial_permissions
|
18
17
|
|
19
18
|
def copy_permissions_from(other)
|
20
|
-
warn "[DEPRECATION] `copy_permissions_from` is deprecated" \
|
21
|
-
" and should not be used with role-based access control" \
|
22
|
-
" (#{caller.first})."
|
23
19
|
self.permissions_attributes = other.permissions.collect { |p| p.to_hash }
|
24
20
|
end
|
21
|
+
deprecation_deprecate :copy_permissions_from
|
25
22
|
end
|
26
23
|
end
|
27
24
|
end
|
data/lib/ddr/models/admin_set.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
-
require "
|
1
|
+
require "active_resource"
|
2
2
|
|
3
3
|
module Ddr::Models
|
4
|
-
class AdminSet <
|
4
|
+
class AdminSet < ActiveResource::Base
|
5
|
+
|
6
|
+
self.site = ENV["DDR_AUX_API_URL"]
|
5
7
|
|
6
8
|
def self.call(obj)
|
7
9
|
if obj.admin_set
|
8
|
-
find
|
10
|
+
get(:find, code: obj.admin_set)
|
9
11
|
end
|
10
12
|
end
|
11
13
|
|
data/lib/ddr/models/base.rb
CHANGED
@@ -22,9 +22,8 @@ module Ddr
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def copy_admin_policy_or_permissions_from(other)
|
25
|
-
warn "
|
26
|
-
|
27
|
-
" (#{caller.first})."
|
25
|
+
Deprecation.warn(self.class, "`copy_admin_policy_or_permissions_from` is deprecated." \
|
26
|
+
" Use `copy_admin_policy_or_roles_from` instead.")
|
28
27
|
copy_admin_policy_or_roles_from(other)
|
29
28
|
end
|
30
29
|
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "delegate"
|
2
|
+
require "shellwords"
|
3
|
+
|
4
|
+
module Ddr::Models
|
5
|
+
class FileCharacterization < SimpleDelegator
|
6
|
+
|
7
|
+
class FITSError < Error; end
|
8
|
+
|
9
|
+
def self.call(obj)
|
10
|
+
new(obj).call
|
11
|
+
end
|
12
|
+
|
13
|
+
def call
|
14
|
+
with_content_file do |path|
|
15
|
+
fits_output = run_fits(path)
|
16
|
+
reload
|
17
|
+
fits.content = fits_output
|
18
|
+
save!
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def run_fits(path)
|
25
|
+
output = `#{fits_command} -i #{Shellwords.escape(path)}`
|
26
|
+
unless $?.success?
|
27
|
+
raise FITSError, output
|
28
|
+
end
|
29
|
+
output
|
30
|
+
end
|
31
|
+
|
32
|
+
def fits_command
|
33
|
+
File.join(Ddr::Models.fits_home, 'fits.sh')
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -20,6 +20,7 @@ module Ddr::Models
|
|
20
20
|
:research_help_contact,
|
21
21
|
:workflow_state,
|
22
22
|
:ead_id,
|
23
|
+
:aspace_id,
|
23
24
|
datastream: "adminMetadata",
|
24
25
|
multiple: false
|
25
26
|
|
@@ -64,7 +65,7 @@ module Ddr::Models
|
|
64
65
|
end
|
65
66
|
|
66
67
|
def research_help
|
67
|
-
Ddr::
|
68
|
+
Ddr::Models::Contact.call(research_help_contact) if research_help_contact
|
68
69
|
end
|
69
70
|
|
70
71
|
def effective_license
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'openssl'
|
2
|
-
|
3
1
|
module Ddr
|
4
2
|
module Models
|
5
3
|
module HasContent
|
@@ -128,6 +126,10 @@ module Ddr
|
|
128
126
|
extractedText.has_content?
|
129
127
|
end
|
130
128
|
|
129
|
+
def with_content_file(&block)
|
130
|
+
WithContentFile.new(self, &block)
|
131
|
+
end
|
132
|
+
|
131
133
|
protected
|
132
134
|
|
133
135
|
def update_derivatives
|
data/lib/ddr/models/indexing.rb
CHANGED
@@ -4,6 +4,10 @@ module Ddr
|
|
4
4
|
|
5
5
|
include Ddr::Index::Fields
|
6
6
|
|
7
|
+
def self.const_missing(name)
|
8
|
+
Ddr::Index::Fields.const_missing(name)
|
9
|
+
end
|
10
|
+
|
7
11
|
def to_solr(solr_doc=Hash.new, opts={})
|
8
12
|
solr_doc = super(solr_doc, opts)
|
9
13
|
solr_doc.merge index_fields
|
@@ -13,6 +17,7 @@ module Ddr
|
|
13
17
|
fields = {
|
14
18
|
ACCESS_ROLE => roles.to_json,
|
15
19
|
ADMIN_SET => admin_set,
|
20
|
+
ASPACE_ID => aspace_id,
|
16
21
|
BOX_NUMBER_FACET => desc_metadata_values('box_number'),
|
17
22
|
CREATOR_FACET => creator,
|
18
23
|
DATE_FACET => date,
|
@@ -1,13 +1,15 @@
|
|
1
|
-
require "
|
1
|
+
require "active_resource"
|
2
2
|
|
3
3
|
module Ddr::Models
|
4
|
-
class License <
|
4
|
+
class License < ActiveResource::Base
|
5
|
+
|
6
|
+
self.site = ENV["DDR_AUX_API_URL"]
|
5
7
|
|
6
8
|
attr_accessor :pid
|
7
9
|
|
8
10
|
def self.call(obj)
|
9
11
|
if obj.license
|
10
|
-
license = find
|
12
|
+
license = get(:find, url: obj.license)
|
11
13
|
license.pid = obj.pid
|
12
14
|
license
|
13
15
|
end
|
@@ -189,7 +189,7 @@ module Ddr::Models
|
|
189
189
|
|
190
190
|
def research_help
|
191
191
|
research_help_contact = self[Ddr::Index::Fields::RESEARCH_HELP_CONTACT] || inherited_research_help_contact
|
192
|
-
Ddr::
|
192
|
+
Ddr::Models::Contact.call(research_help_contact) if research_help_contact
|
193
193
|
end
|
194
194
|
|
195
195
|
def parent_uri
|
data/lib/ddr/models/version.rb
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
require "tempfile"
|
2
|
+
require "delegate"
|
3
|
+
|
4
|
+
module Ddr::Models
|
5
|
+
class WithContentFile < SimpleDelegator
|
6
|
+
|
7
|
+
def initialize(obj, &block)
|
8
|
+
super(obj)
|
9
|
+
with_temp_file &block
|
10
|
+
end
|
11
|
+
|
12
|
+
# Yields path of tempfile containing content to block
|
13
|
+
# @yield [String] the path to the tempfile containing content
|
14
|
+
def with_temp_file
|
15
|
+
filename = original_filename || content.default_file_name
|
16
|
+
basename = [ File.basename(filename, ".*"), File.extname(filename) ]
|
17
|
+
infile = Tempfile.open(basename, Ddr::Models.tempdir, encoding: 'ascii-8bit')
|
18
|
+
begin
|
19
|
+
infile.write(content.content)
|
20
|
+
infile.close
|
21
|
+
verify_checksum!(infile)
|
22
|
+
yield infile.path
|
23
|
+
ensure
|
24
|
+
infile.close unless infile.closed?
|
25
|
+
File.unlink(infile)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def verify_checksum!(file)
|
30
|
+
digest = Ddr::Utils.digest(File.read(file), content.checksumType)
|
31
|
+
if digest != content.checksum
|
32
|
+
raise ChecksumInvalid, "The checksum of the downloaded file does not match the stored checksum of the content."
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
data/lib/ddr/vocab/asset.rb
CHANGED
@@ -17,6 +17,13 @@ module Ddr
|
|
17
17
|
expect(File.size(output_file.path)).to be > 0
|
18
18
|
end
|
19
19
|
end
|
20
|
+
context "animated gif source" do
|
21
|
+
let(:source) { File.join(Ddr::Models::Engine.root, "spec", "fixtures", "arrow1rightred_e0.gif") }
|
22
|
+
it "should generate a non-empty file" do
|
23
|
+
generator.generate
|
24
|
+
expect(File.size(output_file.path)).to be > 0
|
25
|
+
end
|
26
|
+
end
|
20
27
|
end
|
21
28
|
|
22
29
|
end
|
Binary file
|
Binary file
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Ddr::Index
|
2
|
+
RSpec.describe QueryValue do
|
3
|
+
|
4
|
+
describe ".or_values" do
|
5
|
+
describe "when argument is nil" do
|
6
|
+
it "raises an exception" do
|
7
|
+
expect { described_class.or_values(nil) }.to raise_error(ArgumentError)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
describe "when argument is empty" do
|
11
|
+
it "raises an exception" do
|
12
|
+
expect { described_class.or_values([]) }.to raise_error(ArgumentError)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
describe "when argument is not enumerable" do
|
16
|
+
it "raises an exception" do
|
17
|
+
expect { described_class.or_values("foo") }.to raise_error(ArgumentError)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
describe "when argument size == 1" do
|
21
|
+
it "returns the first value, escaped" do
|
22
|
+
expect(described_class.or_values(["foo:bar"])).to eq("(foo\\:bar)")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
describe "when argument size > 1" do
|
26
|
+
it "return the escaped values OR'd together in parentheses" do
|
27
|
+
expect(described_class.or_values(["foo:bar", "spam:eggs"])).to eq("(foo\\:bar OR spam\\:eggs)")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -3,50 +3,14 @@ require 'spec_helper'
|
|
3
3
|
module Ddr::Jobs
|
4
4
|
RSpec.describe FitsFileCharacterization, jobs: true, file_characterization: true do
|
5
5
|
|
6
|
-
|
7
|
-
let(:event) { object.update_events.last }
|
8
|
-
it "should have the correct event attributes" do
|
9
|
-
expect(event.outcome).to eq(expected_outcome)
|
10
|
-
expect(event.detail).to eq(expected_detail)
|
11
|
-
expect(event.software).to eq("fits #{fits_version}")
|
12
|
-
end
|
13
|
-
end
|
6
|
+
let(:obj) { double }
|
14
7
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
context "fits command is successful" do
|
22
|
-
let(:expected_outcome) { Ddr::Events::Event::SUCCESS }
|
23
|
-
let(:expected_detail) { nil }
|
24
|
-
before do
|
25
|
-
allow(Open3).to receive(:capture3) { [ stdout_msg, stderr_msg, $? ] }
|
26
|
-
allow_any_instance_of(Process::Status).to receive(:success?) { true }
|
27
|
-
Ddr::Jobs::FitsFileCharacterization.perform(object.pid)
|
28
|
-
object.reload
|
29
|
-
end
|
30
|
-
it "should populate the fits datastream" do
|
31
|
-
expect(object.fits.content).to be_present
|
32
|
-
end
|
33
|
-
it_behaves_like "has a fits update event"
|
34
|
-
end
|
35
|
-
context "fits command is not successful" do
|
36
|
-
let(:expected_outcome) { Ddr::Events::Event::FAILURE }
|
37
|
-
let(:expected_detail) { stderr_msg }
|
38
|
-
before do
|
39
|
-
allow(Open3).to receive(:capture3) { [ stdout_msg, stderr_msg, $? ] }
|
40
|
-
allow_any_instance_of(Process::Status).to receive(:success?) { false }
|
41
|
-
Ddr::Jobs::FitsFileCharacterization.perform(object.pid)
|
42
|
-
object.reload
|
43
|
-
end
|
44
|
-
it "should not populate the fits datastream" do
|
45
|
-
expect(object.fits.content).to_not be_present
|
46
|
-
end
|
47
|
-
it_behaves_like "has a fits update event"
|
48
|
-
end
|
49
|
-
end
|
8
|
+
before { allow(ActiveFedora::Base).to receive(:find).with("test:1") { obj } }
|
9
|
+
|
10
|
+
specify {
|
11
|
+
expect(Ddr::Models::FileCharacterization).to receive(:call).with(obj) { nil }
|
12
|
+
described_class.perform("test:1")
|
13
|
+
}
|
50
14
|
|
51
15
|
end
|
52
|
-
end
|
16
|
+
end
|