hydra-derivatives 3.5.0 → 3.6.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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +14 -7
  3. data/Gemfile +3 -2
  4. data/README.md +6 -1
  5. data/Rakefile +1 -1
  6. data/VERSION +1 -1
  7. data/hydra-derivatives.gemspec +9 -6
  8. data/lib/hydra/derivatives/config.rb +1 -1
  9. data/lib/hydra/derivatives/processors/document.rb +4 -1
  10. data/lib/hydra/derivatives/processors/full_text.rb +5 -3
  11. data/solr/config/xslt/example.xsl +1 -1
  12. data/solr/config/xslt/luke.xsl +1 -1
  13. metadata +132 -92
  14. data/spec/fixtures/FlashPix.ppt +0 -0
  15. data/spec/fixtures/adobe1998.tif +0 -0
  16. data/spec/fixtures/countdown.avi +0 -0
  17. data/spec/fixtures/jpeg2k_config.yml +0 -20
  18. data/spec/fixtures/piano_note.wav +0 -0
  19. data/spec/fixtures/sample.rtf +0 -68
  20. data/spec/fixtures/test.dng +0 -0
  21. data/spec/fixtures/test.doc +0 -0
  22. data/spec/fixtures/test.docx +0 -0
  23. data/spec/fixtures/test.pdf +0 -0
  24. data/spec/fixtures/test.pptx +0 -0
  25. data/spec/fixtures/test.tif +0 -0
  26. data/spec/fixtures/test.xls +0 -0
  27. data/spec/fixtures/test.xlsx +0 -0
  28. data/spec/fixtures/world.png +0 -0
  29. data/spec/processors/active_encode_spec.rb +0 -132
  30. data/spec/processors/document_spec.rb +0 -41
  31. data/spec/processors/full_text_spec.rb +0 -127
  32. data/spec/processors/image_spec.rb +0 -124
  33. data/spec/processors/jpeg2k_spec.rb +0 -82
  34. data/spec/processors/processor_spec.rb +0 -53
  35. data/spec/processors/shell_based_processor_spec.rb +0 -28
  36. data/spec/processors/video_spec.rb +0 -59
  37. data/spec/runners/active_encode_derivatives_spec.rb +0 -38
  38. data/spec/runners/runner_spec.rb +0 -9
  39. data/spec/services/audio_derivatives_spec.rb +0 -78
  40. data/spec/services/persist_basic_contained_output_file_service_spec.rb +0 -42
  41. data/spec/services/persist_external_file_output_file_service_spec.rb +0 -26
  42. data/spec/services/persist_output_file_service_spec.rb +0 -47
  43. data/spec/services/remote_source_file_spec.rb +0 -33
  44. data/spec/services/retrieve_source_file_service_spec.rb +0 -60
  45. data/spec/services/tempfile_service_spec.rb +0 -54
  46. data/spec/spec_helper.rb +0 -40
  47. data/spec/units/audio_encoder_spec.rb +0 -34
  48. data/spec/units/config_spec.rb +0 -50
  49. data/spec/units/derivatives_spec.rb +0 -70
  50. data/spec/units/io_decorator_spec.rb +0 -45
  51. data/spec/units/logger_spec.rb +0 -27
  52. data/spec/units/transcoding_spec.rb +0 -354
@@ -1,82 +0,0 @@
1
- require 'spec_helper'
2
- require 'yaml'
3
-
4
- describe Hydra::Derivatives::Processors::Jpeg2kImage do
5
- let(:object) { ActiveFedora::Base.new }
6
- let(:filename) { File.expand_path('../../fixtures/test.tif', __FILE__) }
7
- let(:image) { MiniMagick::Image.open(filename) }
8
-
9
- describe "#calculate_recipe" do
10
- it "calculates the number of levels from a size" do
11
- dim = 7200
12
- expect(described_class.level_count_for_size(dim)).to eq(6)
13
- end
14
-
15
- it "calculates the compression rates for each quality layer" do
16
- compression_num = 10
17
- layers = 8
18
- calc = described_class.layer_rates(layers, compression_num)
19
- expect(calc).to eq("2.4,1.48331273,0.91675694,0.56659885,0.3501847,0.21643059,0.13376427,0.0826726")
20
- end
21
- end
22
-
23
- describe ".srgb_profile_path" do
24
- it "exists" do
25
- expect(File.exist?(described_class.srgb_profile_path)).to eq true
26
- end
27
- end
28
-
29
- describe "#kdu_compress_recipe" do
30
- before(:all) do
31
- @sample_cfg = YAML.load_file(File.expand_path('../../fixtures/jpeg2k_config.yml', __FILE__))['test']
32
- Hydra::Derivatives.kdu_compress_recipes = @sample_cfg['jp2_recipes']
33
- end
34
- after(:all) do
35
- Hydra::Derivatives.reset_config!
36
- end
37
-
38
- it "can get the recipe from a config file" do
39
- args = { recipe: :myrecipe }
40
- r = described_class.kdu_compress_recipe(args, 'grey', 7200)
41
- expect(r).to eq(@sample_cfg['jp2_recipes'][:myrecipe_grey])
42
- end
43
-
44
- it "can take a recipe as a string" do
45
- args = { recipe: '-my -excellent -recipe' }
46
- r = described_class.kdu_compress_recipe(args, 'grey', 7200)
47
- expect(r).to eq(args[:recipe])
48
- end
49
-
50
- it "will fall back to a #calculate_recipe if a symbol is passed but no recipe is found" do
51
- args = { recipe: :x }
52
- r = described_class.kdu_compress_recipe(args, 'grey', 7200)
53
- expect(r).to eq(described_class.calculate_recipe(args, 'grey', 7200))
54
- end
55
-
56
- it "will fall back to a #calculate_recipe if there is no attempt to provide one" do
57
- args = {}
58
- r = described_class.kdu_compress_recipe(args, 'grey', 7200)
59
- expect(r).to eq(described_class.calculate_recipe(args, 'grey', 7200))
60
- end
61
- end
62
-
63
- describe "#encode" do
64
- it "executes the external utility" do
65
- expect(described_class).to receive(:execute) { 0 }
66
- described_class.encode('infile', 'recipe', 'outfile')
67
- end
68
- end
69
-
70
- describe "#tmp_file" do
71
- it "returns a temp file with the correct extension" do
72
- f = described_class.tmp_file('.test')
73
- expect(f).to end_with('.test')
74
- end
75
- end
76
-
77
- describe "long_dim" do
78
- it "returns the image's largest dimension" do
79
- expect(described_class.long_dim(image)).to eq(386)
80
- end
81
- end
82
- end
@@ -1,53 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Hydra::Derivatives::Processors::Processor do
4
- subject { described_class.new(file_path, directives) }
5
-
6
- let(:object) { "Fake Object" }
7
- let(:source_name) { 'content' }
8
- let(:directives) { { thumb: "100x100>" } }
9
- let(:file_path) { Pathname.new("test/unicorn.jpg") }
10
-
11
- describe "output_file_service" do
12
- let(:custom_output_file_service) { "fake service" }
13
- let(:another_custom_output_file_service) { "another fake service" }
14
-
15
- context "with a global configuration setting" do
16
- before do
17
- allow(Hydra::Derivatives).to receive(:output_file_service).and_return(custom_output_file_service)
18
- end
19
- it "utilizes the default output file service" do
20
- expect(subject.output_file_service).to eq(custom_output_file_service)
21
- end
22
- end
23
-
24
- context "with an instance level configuration setting" do
25
- subject do
26
- described_class.new('/opt/derivatives/foo.mp4', directives,
27
- output_file_service: another_custom_output_file_service)
28
- end
29
-
30
- it "accepts a custom output file service as an option" do
31
- expect(subject.output_file_service).to eq(another_custom_output_file_service)
32
- end
33
- end
34
- end
35
-
36
- describe "#process" do
37
- it "raises an implementation error" do
38
- expect { subject.process }.to raise_error "Processor is an abstract class. Implement `process' on Hydra::Derivatives::Processors::Processor"
39
- end
40
- end
41
-
42
- describe "#output_file" do
43
- it "raises an implementation error" do
44
- expect { subject.output_file }.to raise_error "Processor is an abstract class. Utilize an implementation of a PersistOutputFileService class in Hydra::Derivatives::Processors::Processor"
45
- end
46
- end
47
-
48
- describe "#output_filename_for" do
49
- it "returns the basename of the source file" do
50
- expect(subject.output_filename_for("ignored")).to eq "unicorn.jpg"
51
- end
52
- end
53
- end
@@ -1,28 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Hydra::Derivatives::Processors::ShellBasedProcessor do
4
- before do
5
- class TestProcessor
6
- include Hydra::Derivatives::Processors::ShellBasedProcessor
7
- end
8
- end
9
-
10
- after { Object.send(:remove_const, :TestProcessor) }
11
-
12
- let(:processor) { TestProcessor.new }
13
- let(:proc_class) { TestProcessor }
14
-
15
- describe "options_for" do
16
- it "returns a hash" do
17
- expect(processor.options_for("a")).to be_a Hash
18
- end
19
- end
20
-
21
- describe ".execute" do
22
- context "when an EOF error occurs" do
23
- it "doesn't crash" do
24
- proc_class.execute("echo foo")
25
- end
26
- end
27
- end
28
- end
@@ -1,59 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Hydra::Derivatives::Processors::Video::Processor do
4
- subject { described_class.new(file_name, directives) }
5
-
6
- let(:file_name) { 'foo/bar.mov' }
7
-
8
- describe ".config" do
9
- before do
10
- @original_config = described_class.config.dup
11
- described_class.config.mpeg4.codec = "-vcodec mpeg4 -acodec aac -strict -2"
12
- end
13
-
14
- after { described_class.config = @original_config }
15
- let(:directives) { { label: :thumb, format: "mp4", url: 'http://localhost:8983/fedora/rest/dev/1234/thumbnail' } }
16
-
17
- it "is configurable" do
18
- expect(subject).to receive(:encode_file).with("mp4", Hydra::Derivatives::Processors::Ffmpeg::OUTPUT_OPTIONS => "-s 320x240 -vcodec mpeg4 -acodec aac -strict -2 -g 30 -b:v 345k -ac 2 -ab 96k -ar 44100", Hydra::Derivatives::Processors::Ffmpeg::INPUT_OPTIONS => "")
19
- subject.process
20
- end
21
- end
22
-
23
- context "when arguments are passed as a hash" do
24
- context "when a video format is requested" do
25
- let(:directives) { { label: :thumb, format: 'webm', url: 'http://localhost:8983/fedora/rest/dev/1234/thumbnail' } }
26
-
27
- it "creates a fedora resource and infers the name" do
28
- expect(subject).to receive(:encode_file).with("webm", Hydra::Derivatives::Processors::Ffmpeg::OUTPUT_OPTIONS => "-s 320x240 -vcodec libvpx -acodec libvorbis -g 30 -b:v 345k -ac 2 -ab 96k -ar 44100", Hydra::Derivatives::Processors::Ffmpeg::INPUT_OPTIONS => "")
29
- subject.process
30
- end
31
- end
32
-
33
- context "when a jpg is requested" do
34
- let(:directives) { { label: :thumb, format: 'jpg', url: 'http://localhost:8983/fedora/rest/dev/1234/thumbnail' } }
35
-
36
- it "creates a fedora resource and infers the name" do
37
- expect(subject).to receive(:encode_file).with("jpg", output_options: "-s 320x240 -vcodec mjpeg -vframes 1 -an -f rawvideo", input_options: " -itsoffset -2")
38
- subject.process
39
- end
40
- end
41
-
42
- context "when an mkv is requested" do
43
- let(:directives) { { label: :thumb, format: 'mkv', url: 'http://localhost:8983/fedora/rest/dev/1234/thumbnail' } }
44
-
45
- it "creates a fedora resource and infers the name" do
46
- expect(subject).to receive(:encode_file).with("mkv", Hydra::Derivatives::Processors::Ffmpeg::OUTPUT_OPTIONS => "-s 320x240 -vcodec ffv1 -g 30 -b:v 345k -ac 2 -ab 96k -ar 44100", Hydra::Derivatives::Processors::Ffmpeg::INPUT_OPTIONS => "")
47
- subject.process
48
- end
49
- end
50
-
51
- context "when an unknown format is requested" do
52
- let(:directives) { { label: :thumb, format: 'nocnv', url: 'http://localhost:8983/fedora/rest/dev/1234/thumbnail' } }
53
-
54
- it "raises an ArgumentError" do
55
- expect { subject.process }.to raise_error ArgumentError, "Unknown format `nocnv'"
56
- end
57
- end
58
- end
59
- end
@@ -1,38 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Hydra::Derivatives::ActiveEncodeDerivatives do
4
- describe '.create' do
5
- before do
6
- class TestVideo < ActiveFedora::Base
7
- attr_accessor :remote_file_name
8
- end
9
- end
10
-
11
- after { Object.send(:remove_const, :TestVideo) }
12
-
13
- let(:file_path) { 'some/path/to/my_video.mp4' }
14
- let(:video_record) { TestVideo.new(remote_file_name: file_path) }
15
- let(:options) { { source: :remote_file_name, outputs: [low_res_video] } }
16
- let(:low_res_video) { { some_key: 'some options to pass to my encoder service' } }
17
- let(:processor) { instance_double('processor') }
18
-
19
- it 'calls the processor with the right arguments' do
20
- expect(Hydra::Derivatives::Processors::ActiveEncode).to receive(:new).with(file_path, low_res_video, output_file_service: Hydra::Derivatives::PersistExternalFileOutputFileService).and_return(processor)
21
- expect(processor).to receive(:process)
22
- described_class.create(video_record, options)
23
- end
24
-
25
- context 'with a custom encode class' do
26
- before { class TestEncode < ::ActiveEncode::Base; end }
27
- after { Object.send(:remove_const, :TestEncode) }
28
-
29
- let(:options) { { encode_class: TestEncode, source: :remote_file_name, outputs: [low_res_video] } }
30
-
31
- it 'calls the processor with the right arguments' do
32
- expect(Hydra::Derivatives::Processors::ActiveEncode).to receive(:new).with(file_path, low_res_video, output_file_service: Hydra::Derivatives::PersistExternalFileOutputFileService, encode_class: TestEncode).and_return(processor)
33
- expect(processor).to receive(:process)
34
- described_class.create(video_record, options)
35
- end
36
- end
37
- end
38
- end
@@ -1,9 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe Hydra::Derivatives::Runner do
4
- describe ".processor_class" do
5
- it "raises an error if it's not overridden" do
6
- expect { described_class.processor_class }.to raise_error "Overide the processor_class method in a sub class"
7
- end
8
- end
9
- end
@@ -1,78 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Hydra::Derivatives::AudioDerivatives do
4
- describe ".create" do
5
- let(:filename) { 'spec/fixtures/piano_note.wav' }
6
- let(:af_path) { ActiveFedora.fedora.host + ActiveFedora.fedora.base_path }
7
-
8
- context "with a filename", requires_ffmpeg: true do
9
- before do
10
- class LocalFileService
11
- def self.call(file_name, _options, &_block)
12
- yield File.open(file_name)
13
- end
14
- end
15
- described_class.source_file_service = LocalFileService
16
- end
17
-
18
- after do
19
- # restore the default
20
- described_class.source_file_service = Hydra::Derivatives::RetrieveSourceFileService
21
- Object.send(:remove_const, :LocalFileService)
22
- end
23
-
24
- it "creates derivatives" do
25
- described_class.create(filename,
26
- outputs: [{ label: 'mp3', format: 'mp3', url: "#{af_path}/1234/mp3" },
27
- { label: 'ogg', format: 'ogg', url: "#{af_path}/1234/ogg" }])
28
- end
29
- end
30
-
31
- context "with an object" do
32
- let(:object) { "Fake Object" }
33
- let(:source_name) { :content }
34
- let(:file) { instance_double("the file") }
35
-
36
- before do
37
- allow(object).to receive(:original_file).and_return(file)
38
- allow(Hydra::Derivatives::TempfileService).to receive(:create).with(file)
39
- end
40
-
41
- it "creates derivatives" do
42
- described_class.create(object,
43
- source: :original_file,
44
- outputs: [{ label: 'mp3', format: 'mp3' },
45
- { label: 'ogg', format: 'ogg' }])
46
- end
47
- end
48
- end
49
-
50
- describe "source_file" do
51
- subject { described_class }
52
-
53
- it "relies on the source_file_service" do
54
- expect(subject.source_file_service).to receive(:call).with('foo/bar.aiff', baz: true)
55
- subject.source_file('foo/bar.aiff', baz: true)
56
- end
57
- end
58
-
59
- describe "output_file_service" do
60
- before do
61
- class FakeOutputService
62
- end
63
- Hydra::Derivatives.output_file_service = FakeOutputService
64
- end
65
-
66
- after do
67
- # restore the default
68
- Hydra::Derivatives.output_file_service = Hydra::Derivatives::PersistBasicContainedOutputFileService
69
- Object.send(:remove_const, :FakeOutputService)
70
- end
71
-
72
- subject { described_class.output_file_service }
73
-
74
- it "defaults to the value set on Hydra::Derivatives" do
75
- expect(subject).to eq FakeOutputService
76
- end
77
- end
78
- end
@@ -1,42 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Hydra::Derivatives::PersistBasicContainedOutputFileService do
4
- before(:all) do
5
- class BasicContainerObject < ActiveFedora::Base
6
- has_subresource "the_derivative_name"
7
- end
8
- end
9
-
10
- let(:object) { BasicContainerObject.new }
11
- let(:file_path) { File.join(fixture_path, 'test.tif') }
12
- let(:file) { File.new(file_path) }
13
- let(:destination_name) { 'the_derivative_name' }
14
-
15
- # alas, we have to support this as the default because all legacy code (and fedora 3 systems) created basic contained files
16
- # The new signature does not have a destination_name option. There is a default string that will get applied, but his might
17
- # not be sufficient.
18
- context "when file is basic contained (default assumption)" do
19
- let(:object) { BasicContainerObject.create }
20
- let(:content) { StringIO.new("fake file content") }
21
- let(:resource) { object.public_send(destination_name.to_sym) }
22
-
23
- context "when the content is a stream" do
24
- it "persists the file to the specified destination on the given object" do
25
- described_class.call(content, format: 'jpg', url: "#{object.uri}/the_derivative_name")
26
- expect(resource.content).to start_with("fake file content")
27
- expect(resource.content_changed?).to eq false
28
- expect(resource.mime_type).to eq 'image/jpeg'
29
- end
30
- end
31
-
32
- context "when the content is a string" do
33
- let(:content) { "fake file content - ÅÄÖ" }
34
-
35
- it "persists the file to the specified destination on the given object" do
36
- described_class.call(content, format: 'txt', url: "#{object.uri}/the_derivative_name")
37
- expect(resource.content).to eq("fake file content - ÅÄÖ")
38
- expect(resource.mime_type).to eq 'text/plain;charset=UTF-8'
39
- end
40
- end
41
- end
42
- end
@@ -1,26 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Hydra::Derivatives::PersistExternalFileOutputFileService do
4
- before do
5
- class ExternalDerivativeContainerObject < ActiveFedora::Base
6
- has_subresource "external_derivative"
7
- end
8
- end
9
- after do
10
- Object.send(:remove_const, :ExternalDerivativeContainerObject)
11
- end
12
-
13
- let(:object) { ExternalDerivativeContainerObject.create }
14
- let(:directives) { { url: "#{object.uri}/external_derivative" } }
15
- let(:external_url) { 'http://www.example.com/external/content' }
16
- let(:output) { { url: external_url } }
17
- let(:destination_name) { 'external_derivative' }
18
-
19
- describe '.call' do
20
- it "persists the external file to the specified destination on the given object" do
21
- described_class.call(output, directives)
22
- expect(object.send(destination_name.to_sym).mime_type).to eq "message/external-body;access-type=URL;url=\"http://www.example.com/external/content\""
23
- expect(object.send(destination_name.to_sym).content).to eq ''
24
- end
25
- end
26
- end
@@ -1,47 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe Hydra::Derivatives::PersistOutputFileService do
4
- let(:original_filename_class) do
5
- Class.new do
6
- def original_filename
7
- "original filename"
8
- end
9
-
10
- def mime_type
11
- "image/tiff"
12
- end
13
- end
14
- end
15
-
16
- describe ".call" do
17
- it "raises an error if not implemented" do
18
- expect { described_class.call(nil, nil) }.to raise_error NotImplementedError, "PersistOutputFileService is an abstract class. Implement `call' on Class"
19
- end
20
- end
21
-
22
- describe ".determine_original_name" do
23
- context "when given something with an original filename" do
24
- it "returns it from that file" do
25
- expect(described_class.determine_original_name(original_filename_class.new)).to eq "original filename"
26
- end
27
- end
28
- context "when given something without an original filename" do
29
- it "returns derivative" do
30
- expect(described_class.determine_original_name("tardis")).to eq "derivative"
31
- end
32
- end
33
- end
34
-
35
- describe ".determine_mime_type" do
36
- context "when given something with #mime_type" do
37
- it "returns it from that file" do
38
- expect(described_class.determine_mime_type(original_filename_class.new)).to eq "image/tiff"
39
- end
40
- end
41
- context "when given something without #mime_type" do
42
- it "returns application/octet-stream" do
43
- expect(described_class.determine_mime_type("tardis")).to eq "application/octet-stream"
44
- end
45
- end
46
- end
47
- end