ddr-models 2.3.2 → 2.4.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|