iiif_print 1.1.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/Gemfile.lock +2 -2
- data/README.md +4 -0
- data/app/actors/iiif_print/actors/file_set_actor_decorator.rb +1 -1
- data/app/indexers/concerns/iiif_print/child_work_indexer.rb +27 -0
- data/app/indexers/concerns/iiif_print/file_set_indexer.rb +37 -22
- data/{lib → app/jobs}/iiif_print/jobs/application_job.rb +2 -1
- data/{lib → app/jobs}/iiif_print/jobs/child_works_from_pdf_job.rb +14 -9
- data/{lib → app/jobs}/iiif_print/jobs/create_relationships_job.rb +10 -20
- data/app/listeners/iiif_print/listener.rb +31 -0
- data/app/models/concerns/iiif_print/set_child_flag.rb +1 -1
- data/app/models/concerns/iiif_print/solr/document.rb +5 -3
- data/app/presenters/iiif_print/file_set_presenter_decorator.rb +11 -0
- data/app/presenters/iiif_print/iiif_manifest_presenter_factory_behavior.rb +1 -1
- data/app/presenters/iiif_print/work_show_presenter_decorator.rb +5 -2
- data/app/services/iiif_print/manifest_builder_service_behavior.rb +4 -2
- data/app/services/iiif_print/pluggable_derivative_service.rb +5 -1
- data/app/services/iiif_print/simple_schema_loader_decorator.rb +11 -0
- data/app/transactions/hyrax/transactions/iiif_print_container_decorator.rb +34 -0
- data/app/transactions/hyrax/transactions/steps/conditionally_destroy_children_from_split.rb +32 -0
- data/app/transactions/hyrax/transactions/steps/delete_all_file_sets_decorator.rb +35 -0
- data/app/views/hyrax/file_sets/_show_actions.html.erb +1 -1
- data/config/initializers/simple_schema_loader.rb +1 -0
- data/config/metadata/child_works_from_pdf_splitting.yaml +21 -0
- data/db/migrate/20181214181358_create_iiif_print_derivative_attachments.rb +8 -6
- data/db/migrate/20190107165909_create_iiif_print_ingest_file_relations.rb +7 -5
- data/db/migrate/20230109000000_create_iiif_print_pending_relationships.rb +8 -6
- data/db/migrate/20231110163052_add_model_details_to_iiif_print_pending_relationships.rb +3 -3
- data/iiif_print.gemspec +1 -1
- data/lib/iiif_print/base_derivative_service.rb +13 -2
- data/lib/iiif_print/blacklight_iiif_search/annotation_decorator.rb +2 -2
- data/lib/iiif_print/catalog_search_builder.rb +2 -2
- data/lib/iiif_print/configuration.rb +65 -5
- data/lib/iiif_print/data/fileset_helper.rb +2 -2
- data/lib/iiif_print/data/work_derivatives.rb +1 -1
- data/lib/iiif_print/engine.rb +46 -2
- data/lib/iiif_print/homepage_search_builder.rb +2 -2
- data/lib/iiif_print/jp2_derivative_service.rb +4 -1
- data/lib/iiif_print/lineage_service.rb +19 -6
- data/lib/iiif_print/pdf_derivative_service.rb +3 -1
- data/lib/iiif_print/persistence_layer/active_fedora_adapter.rb +189 -0
- data/lib/iiif_print/persistence_layer/valkyrie_adapter.rb +183 -0
- data/lib/iiif_print/persistence_layer.rb +118 -0
- data/lib/iiif_print/split_pdfs/base_splitter.rb +11 -0
- data/lib/iiif_print/split_pdfs/child_work_creation_from_pdf_service.rb +19 -9
- data/lib/iiif_print/split_pdfs/destroy_pdf_child_works_service.rb +5 -16
- data/lib/iiif_print/text_extraction_derivative_service.rb +4 -2
- data/lib/iiif_print/text_formats_from_alto_service.rb +3 -1
- data/lib/iiif_print/tiff_derivative_service.rb +3 -1
- data/lib/iiif_print/version.rb +1 -1
- data/lib/iiif_print.rb +79 -44
- metadata +18 -191
- data/app/indexers/concerns/iiif_print/child_indexer.rb +0 -40
- data/app/views/hyrax/file_sets/_actions.html.erb +0 -46
- data/bin/rails +0 -13
- data/spec/.keep.txt +0 -1
- data/spec/factories/ability.rb +0 -6
- data/spec/factories/newspaper_issue.rb +0 -7
- data/spec/factories/newspaper_page.rb +0 -7
- data/spec/factories/newspaper_page_solr_document.rb +0 -20
- data/spec/factories/newspaper_title.rb +0 -8
- data/spec/factories/uploaded_pdf_file.rb +0 -9
- data/spec/factories/uploaded_txt_file.rb +0 -9
- data/spec/factories/user.rb +0 -13
- data/spec/fixtures/authorities/licenses.yml +0 -4
- data/spec/fixtures/authorities/rights_statements.yml +0 -4
- data/spec/fixtures/files/4.1.07.jp2 +0 -0
- data/spec/fixtures/files/4.1.07.tiff +0 -0
- data/spec/fixtures/files/README.md +0 -7
- data/spec/fixtures/files/alto-2-0.xsd +0 -714
- data/spec/fixtures/files/broken-truncated.pdf +0 -0
- data/spec/fixtures/files/credits.md +0 -16
- data/spec/fixtures/files/lowres-gray-via-ndnp-sample.tiff +0 -0
- data/spec/fixtures/files/minimal-1-page.pdf +0 -0
- data/spec/fixtures/files/minimal-2-page.pdf +0 -0
- data/spec/fixtures/files/minimal-alto.xml +0 -31
- data/spec/fixtures/files/ndnp-alto-sample.xml +0 -24
- data/spec/fixtures/files/ndnp-sample1-json.json +0 -1
- data/spec/fixtures/files/ndnp-sample1-txt.txt +0 -1
- data/spec/fixtures/files/ndnp-sample1.pdf +0 -0
- data/spec/fixtures/files/ocr_alto.xml +0 -202
- data/spec/fixtures/files/ocr_alto_scaled_4pts_per_px.xml +0 -202
- data/spec/fixtures/files/ocr_color.tiff +0 -0
- data/spec/fixtures/files/ocr_gray.jp2 +0 -0
- data/spec/fixtures/files/ocr_gray.tiff +0 -0
- data/spec/fixtures/files/ocr_mono.tiff +0 -0
- data/spec/fixtures/files/ocr_mono_text_hocr.html +0 -78
- data/spec/fixtures/files/page1.tiff +0 -0
- data/spec/fixtures/files/sample-4page-issue.pdf +0 -0
- data/spec/fixtures/files/sample-color-newsletter.pdf +0 -0
- data/spec/fixtures/files/thumbnail.jpg +0 -0
- data/spec/helpers/hyrax/iiif_helper_spec.rb +0 -65
- data/spec/helpers/iiif_print_helper_spec.rb +0 -43
- data/spec/iiif_print/base_derivative_service_spec.rb +0 -28
- data/spec/iiif_print/blacklight_iiif_search/annotation_decorator_spec.rb +0 -59
- data/spec/iiif_print/catalog_search_builder_spec.rb +0 -60
- data/spec/iiif_print/configuration_spec.rb +0 -193
- data/spec/iiif_print/data/work_derivatives_spec.rb +0 -245
- data/spec/iiif_print/data/work_file_spec.rb +0 -99
- data/spec/iiif_print/data/work_files_spec.rb +0 -237
- data/spec/iiif_print/image_tool_spec.rb +0 -109
- data/spec/iiif_print/jobs/child_works_from_pdf_job_spec.rb +0 -35
- data/spec/iiif_print/jobs/create_relationships_job_spec.rb +0 -118
- data/spec/iiif_print/jp2_image_metadata_spec.rb +0 -37
- data/spec/iiif_print/lineage_service_spec.rb +0 -13
- data/spec/iiif_print/metadata_spec.rb +0 -249
- data/spec/iiif_print/split_pdfs/base_splitter_spec.rb +0 -27
- data/spec/iiif_print/split_pdfs/derivative_rodeo_splitter_spec.rb +0 -80
- data/spec/iiif_print/split_pdfs/destroy_pdf_child_works_service_spec.rb +0 -92
- data/spec/iiif_print/split_pdfs/pages_to_jpgs_splitter_spec.rb +0 -22
- data/spec/iiif_print/split_pdfs/pages_to_pngs_splitter_spec.rb +0 -18
- data/spec/iiif_print/split_pdfs/pages_to_tiffs_splitter_spec.rb +0 -19
- data/spec/iiif_print/text_extraction/alto_reader_spec.rb +0 -49
- data/spec/iiif_print/text_extraction/hocr_reader_spec.rb +0 -45
- data/spec/iiif_print/text_extraction/page_ocr_spec.rb +0 -84
- data/spec/iiif_print/text_extraction/render_alto_spec.rb +0 -54
- data/spec/iiif_print/text_extraction/word_coords_builder_spec.rb +0 -44
- data/spec/iiif_print_spec.rb +0 -171
- data/spec/misc_shared.rb +0 -111
- data/spec/models/iiif_print/derivative_attachment_spec.rb +0 -37
- data/spec/models/iiif_print/iiif_search_decorator_spec.rb +0 -27
- data/spec/models/iiif_print/ingest_file_relation_spec.rb +0 -56
- data/spec/models/solr_document_spec.rb +0 -14
- data/spec/presenters/iiif_print/iiif_manifest_presenter_behavior_spec.rb +0 -70
- data/spec/presenters/iiif_print/iiif_manifest_presenter_factory_behavior_spec.rb +0 -49
- data/spec/samvera/derivatives/configuration_spec.rb +0 -41
- data/spec/samvera/derivatives/hyrax_spec.rb +0 -62
- data/spec/samvera/derivatives_spec.rb +0 -54
- data/spec/services/iiif_print/derivative_rodeo_service_spec.rb +0 -103
- data/spec/services/iiif_print/jp2_derivative_service_spec.rb +0 -59
- data/spec/services/iiif_print/manifest_builder_service_behavior_spec.rb +0 -20
- data/spec/services/iiif_print/pdf_derivative_service_spec.rb +0 -66
- data/spec/services/iiif_print/pluggable_derivative_service_spec.rb +0 -175
- data/spec/services/iiif_print/text_extraction_derivative_service_spec.rb +0 -82
- data/spec/services/iiif_print/text_formats_from_alto_service_spec.rb +0 -127
- data/spec/services/iiif_print/tiff_derivative_service_spec.rb +0 -65
- data/spec/spec_helper.rb +0 -181
- data/spec/support/controller_level_helpers.rb +0 -28
- data/spec/support/iiif_print_models.rb +0 -127
- data/spec/test_app_templates/blacklight.yml +0 -9
- data/spec/test_app_templates/fedora.yml +0 -15
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +0 -40
- data/spec/test_app_templates/redis.yml +0 -9
- data/spec/test_app_templates/solr/conf/schema.xml +0 -362
- data/spec/test_app_templates/solr/conf/solrconfig.xml +0 -322
- data/spec/test_app_templates/solr.yml +0 -7
- /data/{lib → app/jobs}/iiif_print/jobs/request_split_pdf_job.rb +0 -0
@@ -1,99 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'misc_shared'
|
3
|
-
|
4
|
-
RSpec.describe IiifPrint::Data::WorkFile do
|
5
|
-
include_context "shared setup"
|
6
|
-
|
7
|
-
# sample objects:
|
8
|
-
let(:work) { work_with_file }
|
9
|
-
|
10
|
-
describe "adapter composition" do
|
11
|
-
it "adapts work with nil fileset" do
|
12
|
-
adapter = described_class.new(work)
|
13
|
-
expect(adapter.work).to be work
|
14
|
-
expect(adapter.fileset).to be_nil
|
15
|
-
end
|
16
|
-
|
17
|
-
it "adapts work with 'of' alt constructor" do
|
18
|
-
adapter = described_class.of(work)
|
19
|
-
expect(adapter.work).to be work
|
20
|
-
end
|
21
|
-
|
22
|
-
it "adapts work and explicitly provided fileset" do
|
23
|
-
fileset = work.members.detect { |m| m.is_a? FileSet }
|
24
|
-
adapter = described_class.of(work, fileset)
|
25
|
-
expect(adapter.work).to be work
|
26
|
-
expect(adapter.fileset).to be fileset
|
27
|
-
end
|
28
|
-
|
29
|
-
it "constructs with a parent object, if provided" do
|
30
|
-
fileset = work.members.detect { |m| m.is_a? FileSet }
|
31
|
-
parent = double('parent')
|
32
|
-
adapter = described_class.of(work, fileset, parent)
|
33
|
-
expect(adapter.parent).to be parent
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
describe "read file metadata" do
|
38
|
-
it "gets original filename" do
|
39
|
-
fileset = work.members.detect { |m| m.is_a? FileSet }
|
40
|
-
adapter = described_class.of(work, fileset)
|
41
|
-
expect(adapter.name).to eq fileset.original_file.original_name
|
42
|
-
expect(adapter.name).to eq 'credits.md'
|
43
|
-
end
|
44
|
-
|
45
|
-
it "gets miscellaneous metadata field values" do
|
46
|
-
fileset = work.members.detect { |m| m.is_a? FileSet }
|
47
|
-
adapter = described_class.of(work, fileset)
|
48
|
-
# expectations for accessors of size, date_*, mime_type
|
49
|
-
expect(adapter.size).to eq File.size(txt_path)
|
50
|
-
expect(adapter.name).to eq 'credits.md'
|
51
|
-
expect(adapter.mime_type).to eq 'text/plain'
|
52
|
-
# getting actual value for date fields requires digging through
|
53
|
-
# multiple layers of ActiveTuples indirection...
|
54
|
-
expect(adapter.date_created.to_a[0].to_s).to eq static_date.to_s
|
55
|
-
expect(adapter.date_modified.to_a[0].to_s).to eq static_date.to_s
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
describe "read binary via transparent repository checkout" do
|
60
|
-
it "gets path (from checkout)" do
|
61
|
-
fileset = work.members.detect { |m| m.is_a? FileSet }
|
62
|
-
adapter = described_class.of(work, fileset)
|
63
|
-
# Get a path to a working copy
|
64
|
-
path = adapter.path
|
65
|
-
expect(path).to be_a String
|
66
|
-
expect(File.exist?(path)).to be true
|
67
|
-
# size of working copy binary checkout matches size in computed metadata
|
68
|
-
expect(File.size(path)).to eq fileset.original_file.size
|
69
|
-
end
|
70
|
-
|
71
|
-
it "gets data as bytes" do
|
72
|
-
fileset = work.members.detect { |m| m.is_a? FileSet }
|
73
|
-
adapter = described_class.of(work, fileset)
|
74
|
-
# Get a data from the working copy
|
75
|
-
data = adapter.data
|
76
|
-
expect(data).to be_a String
|
77
|
-
# size of working copy binary checkout matches size in computed metadata
|
78
|
-
expect(data.size).to eq fileset.original_file.size
|
79
|
-
end
|
80
|
-
|
81
|
-
it "runs block on data as IO" do
|
82
|
-
fileset = work.members.detect { |m| m.is_a? FileSet }
|
83
|
-
adapter = described_class.of(work, fileset)
|
84
|
-
adapter.with_io { |io| expect(io.read.size).to eq File.size(txt_path) }
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
describe "derivative access" do
|
89
|
-
it "gets derivatives for file" do
|
90
|
-
fileset = work.members.detect { |m| m.is_a? FileSet }
|
91
|
-
adapter = described_class.of(work, fileset)
|
92
|
-
expect(adapter.derivatives.class).to eq \
|
93
|
-
IiifPrint::Data::WorkDerivatives
|
94
|
-
expect(adapter.derivatives.fileset).to be fileset
|
95
|
-
expect(adapter.derivatives.work).to be work
|
96
|
-
expect(adapter.derivatives.parent).to be adapter
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
@@ -1,237 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'misc_shared'
|
3
|
-
|
4
|
-
RSpec.describe IiifPrint::Data::WorkFiles do
|
5
|
-
include_context "shared setup"
|
6
|
-
|
7
|
-
let(:work) { work_with_file }
|
8
|
-
let(:tiff_path) { File.join(fixture_path, 'ocr_gray.tiff') }
|
9
|
-
let(:tiff_uri) { 'file://' + File.expand_path(tiff_path) }
|
10
|
-
|
11
|
-
describe "adapter composition" do
|
12
|
-
it "adapts work" do
|
13
|
-
adapter = described_class.new(work)
|
14
|
-
expect(adapter.work).to be work
|
15
|
-
end
|
16
|
-
|
17
|
-
it "adapts work with 'of' alt constructor" do
|
18
|
-
adapter = described_class.of(work)
|
19
|
-
expect(adapter.work).to be work
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
describe "path assignment queueing" do
|
24
|
-
it "queues assigned file path" do
|
25
|
-
adapter = described_class.of(work)
|
26
|
-
expect(adapter.assigned).to be_empty
|
27
|
-
# assign a valid source path
|
28
|
-
adapter.assign(tiff_path)
|
29
|
-
expect(adapter.assigned).to include tiff_path
|
30
|
-
end
|
31
|
-
|
32
|
-
it "will fail to assign file in non registered dir" do
|
33
|
-
adapter = described_class.new(work)
|
34
|
-
# need a non-registered file that exists:
|
35
|
-
bad_path = File.expand_path("../../spec_helper.rb", fixture_path)
|
36
|
-
expect { adapter.assign(bad_path) }.to raise_error(SecurityError)
|
37
|
-
end
|
38
|
-
|
39
|
-
it "queues a file:/// URI" do
|
40
|
-
adapter = described_class.of(work)
|
41
|
-
expect(adapter.assigned).to be_empty
|
42
|
-
adapter.assign(tiff_uri)
|
43
|
-
expect(adapter.assigned).to include tiff_uri
|
44
|
-
end
|
45
|
-
|
46
|
-
it "queues a Pathname, normalized to string" do
|
47
|
-
adapter = described_class.of(work)
|
48
|
-
expect(adapter.assigned).to be_empty
|
49
|
-
adapter.assign(Pathname.new(tiff_path))
|
50
|
-
expect(adapter.assigned).to include tiff_path
|
51
|
-
end
|
52
|
-
|
53
|
-
it "unqueues a queued path" do
|
54
|
-
adapter = described_class.of(work)
|
55
|
-
adapter.assign(tiff_path)
|
56
|
-
expect(adapter.assigned).to include tiff_path
|
57
|
-
adapter.unassign(tiff_path)
|
58
|
-
expect(adapter.assigned).to be_empty
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
describe "hash/mapping-like file enumeration" do
|
63
|
-
it "has expected WorkFile in values for work" do
|
64
|
-
adapter = described_class.of(work)
|
65
|
-
values = adapter.values
|
66
|
-
expect(values).to be_an Array
|
67
|
-
expect(values.size).to eq 1
|
68
|
-
expect(values[0]).to be_an IiifPrint::Data::WorkFile
|
69
|
-
expect(values[0].parent).to be adapter
|
70
|
-
first_fileset = work.members.detect { |m| m.is_a?(FileSet) }
|
71
|
-
expect(values[0].fileset).to eq first_fileset
|
72
|
-
expect(values[0].unwrapped).to be_a Hydra::PCDM::File
|
73
|
-
end
|
74
|
-
|
75
|
-
it "has expected fileset keys for work" do
|
76
|
-
adapter = described_class.of(work)
|
77
|
-
keys = adapter.keys
|
78
|
-
expect(keys).to be_an Array
|
79
|
-
expect(keys[0]).to be_a String
|
80
|
-
first_fileset = work.members.detect { |m| m.is_a?(FileSet) }
|
81
|
-
expect(keys[0]).to eq first_fileset.id
|
82
|
-
end
|
83
|
-
|
84
|
-
it "has expected entries for work" do
|
85
|
-
adapter = described_class.of(work)
|
86
|
-
entries = adapter.entries
|
87
|
-
expect(entries).to be_an Array
|
88
|
-
expect(entries[0]).to be_an Array
|
89
|
-
expect(entries[0].size).to eq 2
|
90
|
-
expect(entries[0][0]).to eq adapter.keys[0]
|
91
|
-
expect(entries[0][1]).to eq adapter.values[0]
|
92
|
-
end
|
93
|
-
|
94
|
-
it "gets work file by fileset id" do
|
95
|
-
adapter = described_class.of(work)
|
96
|
-
first_fileset = work.members.detect { |m| m.is_a?(FileSet) }
|
97
|
-
fsid = adapter.keys[0]
|
98
|
-
expect(fsid).to eq first_fileset.id
|
99
|
-
work_file = adapter.get(fsid)
|
100
|
-
expect(work_file.unwrapped).to eq first_fileset.original_file
|
101
|
-
work_file = adapter[fsid]
|
102
|
-
expect(work_file.unwrapped).to eq first_fileset.original_file
|
103
|
-
end
|
104
|
-
|
105
|
-
it "gets work file by work-local filename" do
|
106
|
-
adapter = described_class.of(work)
|
107
|
-
first_fileset = work.members.detect { |m| m.is_a?(FileSet) }
|
108
|
-
name = first_fileset.original_file.original_name
|
109
|
-
work_file = adapter.get(name)
|
110
|
-
expect(work_file).to eq adapter.get(first_fileset.id)
|
111
|
-
end
|
112
|
-
|
113
|
-
it "verifies inclusion of fileset id key" do
|
114
|
-
adapter = described_class.of(work)
|
115
|
-
fsid = adapter.keys[0]
|
116
|
-
expect(adapter.include?(fsid)).to be true
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
describe "assignment state" do
|
121
|
-
it "has empty state for work with no files" do
|
122
|
-
bare_work = MyWork.new
|
123
|
-
bare_work.title = ['No files to see here']
|
124
|
-
bare_work.save!
|
125
|
-
adapter = described_class.of(bare_work)
|
126
|
-
expect(adapter.keys.empty?).to be true
|
127
|
-
expect(adapter.state).to eq 'empty'
|
128
|
-
end
|
129
|
-
|
130
|
-
it "has 'dirty' state when files assigned" do
|
131
|
-
adapter = described_class.of(work)
|
132
|
-
expect(adapter.state).to eq 'saved'
|
133
|
-
adapter.assign(tiff_path)
|
134
|
-
# changes to dirty
|
135
|
-
expect(adapter.state).to eq 'dirty'
|
136
|
-
# unassign path again to empty assigned queue:
|
137
|
-
adapter.unassign(tiff_path)
|
138
|
-
# no we are back to 'saved' since no changes are queued now:
|
139
|
-
expect(adapter.state).to eq 'saved'
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
describe "commits changes" do
|
144
|
-
# We need to register these jobs to run now, at minimum:
|
145
|
-
do_now_jobs = [IngestLocalFileJob, IngestJob, InheritPermissionsJob]
|
146
|
-
# These we skip: [CharacterizeJob, CreateDerivativesJob]
|
147
|
-
# -- skipping these saves 10-15 seconds on attachment example
|
148
|
-
|
149
|
-
permission_methods = [
|
150
|
-
:edit_users,
|
151
|
-
:read_users,
|
152
|
-
:discover_users,
|
153
|
-
:edit_groups,
|
154
|
-
:read_groups,
|
155
|
-
:discover_groups
|
156
|
-
]
|
157
|
-
|
158
|
-
let(:bare_work) do
|
159
|
-
bare_work = MyWork.new
|
160
|
-
bare_work.title = ['No files to see here']
|
161
|
-
bare_work.save!
|
162
|
-
bare_work
|
163
|
-
end
|
164
|
-
|
165
|
-
it "commits unassign (file deletions)" do
|
166
|
-
adapter = described_class.of(work)
|
167
|
-
expect(adapter.keys.size).to eq 1
|
168
|
-
adapter.unassign(adapter.keys[0])
|
169
|
-
adapter.commit!
|
170
|
-
expect(adapter.keys.size).to eq 0
|
171
|
-
expect(work.members.to_a.count { |m| m.is_a? FileSet }).to eq 0
|
172
|
-
end
|
173
|
-
|
174
|
-
context "when it is a new work" do
|
175
|
-
it "commit for assignment invokes actor stack" do
|
176
|
-
work = MyWork.new(title: ['Just a new work'])
|
177
|
-
adapter = described_class.of(work)
|
178
|
-
adapter.assign(tiff_path)
|
179
|
-
allow(Hyrax::CurationConcern.actor).to receive(:create).and_return(true)
|
180
|
-
expect(Hyrax::CurationConcern.actor).to receive(:create)
|
181
|
-
expect(adapter.commit!).to be true
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
context "when the work already exists" do
|
186
|
-
it "commit for assignment invokes actor stack" do
|
187
|
-
work = bare_work
|
188
|
-
adapter = described_class.of(work)
|
189
|
-
adapter.assign(tiff_path)
|
190
|
-
allow(Hyrax::CurationConcern.actor).to receive(:update).and_return(true)
|
191
|
-
expect(Hyrax::CurationConcern.actor).to receive(:update)
|
192
|
-
expect(adapter.commit!).to be true
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
xit "commits successful file attachment", perform_enqueued: do_now_jobs do
|
197
|
-
work = bare_work
|
198
|
-
adapter = described_class.of(work)
|
199
|
-
adapter.assign(tiff_path)
|
200
|
-
adapter.commit!
|
201
|
-
# registered jobs (do_now_jobs) performed as effect of commit!
|
202
|
-
# are configured to effectively run inline. Reloading work
|
203
|
-
# should refresh the work.members, and by consequence adapter.keys
|
204
|
-
work.reload
|
205
|
-
expect(adapter.keys.size).to eq 1
|
206
|
-
expect(work.members.to_a.count { |m| m.is_a? FileSet }).to eq 1
|
207
|
-
expect(adapter.names).to include 'ocr_gray.tiff'
|
208
|
-
end
|
209
|
-
|
210
|
-
xit "copies work perimssions to fileset", perform_enqueued: do_now_jobs do
|
211
|
-
adapter = described_class.of(bare_work)
|
212
|
-
adapter.assign(tiff_path)
|
213
|
-
adapter.commit!
|
214
|
-
bare_work.reload
|
215
|
-
fileset = bare_work.members.detect { |m| m.is_a?(FileSet) }
|
216
|
-
permission_methods.each do |m|
|
217
|
-
expect(fileset.send(m)).to match_array bare_work.send(m)
|
218
|
-
end
|
219
|
-
expect(fileset.visibility).to eq bare_work.visibility
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
describe "derivative access" do
|
224
|
-
it "gets derivatives for first fileset" do
|
225
|
-
fileset = work.members.detect { |m| m.is_a?(FileSet) }
|
226
|
-
adapter = described_class.of(work)
|
227
|
-
# adapts same context(s):
|
228
|
-
expect(adapter.derivatives.fileset.id).to eq fileset.id
|
229
|
-
expect(adapter.derivatives.work).to be work
|
230
|
-
expect(adapter.derivatives.class).to eq \
|
231
|
-
IiifPrint::Data::WorkDerivatives
|
232
|
-
# transitive parent/child relationship, can traverse to adapter from
|
233
|
-
# derivatives:
|
234
|
-
expect(adapter.derivatives.parent.parent).to be adapter
|
235
|
-
end
|
236
|
-
end
|
237
|
-
end
|
@@ -1,109 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'tmpdir'
|
3
|
-
|
4
|
-
describe IiifPrint::ImageTool do
|
5
|
-
let(:fixtures) { File.join(IiifPrint::GEM_PATH, 'spec/fixtures/files') }
|
6
|
-
|
7
|
-
# Image fixtures to test identification, metadata extraction for:
|
8
|
-
let(:gray_jp2) { File.join(fixtures, 'ocr_gray.jp2') }
|
9
|
-
let(:color_jp2) { File.join(fixtures, '4.1.07.jp2') }
|
10
|
-
let(:gray_tiff) { File.join(fixtures, 'ocr_gray.tiff') }
|
11
|
-
let(:mono_tiff) { File.join(fixtures, 'ocr_mono.tiff') }
|
12
|
-
let(:color_tiff) { File.join(fixtures, '4.1.07.tiff') }
|
13
|
-
let(:pdf) { File.join(fixtures, 'minimal-1-page.pdf') }
|
14
|
-
|
15
|
-
describe "Extracts metadata with JP2 backend" do
|
16
|
-
it "constructs with a path" do
|
17
|
-
identify = described_class.new(gray_jp2)
|
18
|
-
expect(identify.path).to eq gray_jp2
|
19
|
-
end
|
20
|
-
|
21
|
-
it "gets metadata for grayscale JP2 image" do
|
22
|
-
result = described_class.new(gray_jp2).metadata
|
23
|
-
expect(result[:color]).to eq 'gray'
|
24
|
-
expect(result[:width]).to eq 418
|
25
|
-
expect(result[:height]).to eq 1046
|
26
|
-
expect(result[:bits_per_component]).to eq 8
|
27
|
-
expect(result[:num_components]).to eq 1
|
28
|
-
end
|
29
|
-
|
30
|
-
it "gets metadata for color JP2 image" do
|
31
|
-
result = described_class.new(color_jp2).metadata
|
32
|
-
expect(result[:color]).to eq 'color'
|
33
|
-
expect(result[:width]).to eq 256
|
34
|
-
expect(result[:height]).to eq 256
|
35
|
-
expect(result[:bits_per_component]).to eq 8
|
36
|
-
# e.g. is 3, but would be four if sample image had an alpha channel
|
37
|
-
expect(result[:num_components]).to eq 3
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
describe "Extracts metadata for non-JP2 images with imagemagick" do
|
42
|
-
it "gets metadata for gray TIFF image" do
|
43
|
-
result = described_class.new(gray_tiff).metadata
|
44
|
-
expect(result[:color]).to eq 'gray'
|
45
|
-
expect(result[:width]).to eq 418
|
46
|
-
expect(result[:height]).to eq 1046
|
47
|
-
expect(result[:bits_per_component]).to eq 8
|
48
|
-
expect(result[:num_components]).to eq 1
|
49
|
-
end
|
50
|
-
|
51
|
-
it "gets metadata for monochrome TIFF image" do
|
52
|
-
result = described_class.new(mono_tiff).metadata
|
53
|
-
expect(result[:color]).to eq 'monochrome'
|
54
|
-
expect(result[:width]).to eq 1261
|
55
|
-
expect(result[:height]).to eq 1744
|
56
|
-
expect(result[:bits_per_component]).to eq 1
|
57
|
-
expect(result[:num_components]).to eq 1
|
58
|
-
end
|
59
|
-
|
60
|
-
it "gets metadata for color TIFF image" do
|
61
|
-
result = described_class.new(color_tiff).metadata
|
62
|
-
expect(result[:color]).to eq 'color'
|
63
|
-
expect(result[:width]).to eq 256
|
64
|
-
expect(result[:height]).to eq 256
|
65
|
-
expect(result[:bits_per_component]).to eq 8
|
66
|
-
# e.g. is 3, but would be four if sample image had an alpha channel
|
67
|
-
expect(result[:num_components]).to eq 3
|
68
|
-
end
|
69
|
-
|
70
|
-
it "detects mime type of pdf" do
|
71
|
-
result = described_class.new(pdf).metadata
|
72
|
-
expect(result[:content_type]).to eq 'application/pdf'
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
describe "converts images" do
|
77
|
-
it "makes a monochrome TIFF from JP2" do
|
78
|
-
tool = described_class.new(gray_jp2)
|
79
|
-
dest = File.join(Dir.mktmpdir, 'mono.tif')
|
80
|
-
tool.convert(dest, true)
|
81
|
-
expect(File.exist?(dest)).to be true
|
82
|
-
expect(described_class.new(dest).metadata[:color]).to eq 'monochrome'
|
83
|
-
end
|
84
|
-
|
85
|
-
it "makes a gray TIFF from JP2" do
|
86
|
-
tool = described_class.new(gray_jp2)
|
87
|
-
dest = File.join(Dir.mktmpdir, 'gray.tif')
|
88
|
-
tool.convert(dest, false)
|
89
|
-
expect(File.exist?(dest)).to be true
|
90
|
-
expect(described_class.new(dest).metadata[:color]).to eq 'gray'
|
91
|
-
end
|
92
|
-
|
93
|
-
it "makes a monochrome TIFF from grayscale TIFF" do
|
94
|
-
tool = described_class.new(gray_tiff)
|
95
|
-
dest = File.join(Dir.mktmpdir, 'mono.tif')
|
96
|
-
tool.convert(dest, true)
|
97
|
-
expect(File.exist?(dest)).to be true
|
98
|
-
expect(described_class.new(dest).metadata[:color]).to eq 'monochrome'
|
99
|
-
end
|
100
|
-
|
101
|
-
# Not yet supported to use this tool to make JP2, for now the only
|
102
|
-
# component in IiifPrint doing that is
|
103
|
-
# IiifPrint::JP2DerivativeService
|
104
|
-
it "raises error on JP2 destination" do
|
105
|
-
expect { described_class.new(gray_tiff).convert('out.jp2') }.to \
|
106
|
-
raise_error(RuntimeError)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'misc_shared'
|
3
|
-
|
4
|
-
RSpec.describe IiifPrint::Jobs::ChildWorksFromPdfJob do
|
5
|
-
# TODO: add specs
|
6
|
-
let(:work) { WorkWithIiifPrintConfig.new(title: ['required title'], id: '123') }
|
7
|
-
let(:my_user) { build(:user) }
|
8
|
-
let(:uploaded_pdf_file) { create(:uploaded_pdf_file) }
|
9
|
-
let(:uploaded_file_ids) { [uploaded_pdf_file.id] }
|
10
|
-
let(:pdf_paths) do
|
11
|
-
uploads = Hyrax::UploadedFile.find(uploaded_file_ids)
|
12
|
-
upload_paths = uploads.map { |upload| upload.file.file.file }
|
13
|
-
upload_paths.select { |path| path.end_with?('.pdf', '.PDF') }
|
14
|
-
end
|
15
|
-
let(:admin_set_id) { "admin_set/default" }
|
16
|
-
let(:prior_pdfs) { 0 }
|
17
|
-
|
18
|
-
let(:subject) { described_class.perform_now(work, pdf_paths, my_user, admin_set_id, prior_pdfs) }
|
19
|
-
|
20
|
-
describe '#perform' do
|
21
|
-
xit 'calls pdf splitter service with path' do
|
22
|
-
end
|
23
|
-
|
24
|
-
xit 'submits one BatchCreateJob per PDF' do
|
25
|
-
end
|
26
|
-
|
27
|
-
xit 'submits IiifPrint::Jobs::CreateRelationshipsJob' do
|
28
|
-
end
|
29
|
-
|
30
|
-
context 'with more than 9 pages' do
|
31
|
-
xit 'pads the page number with a zero' do
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,118 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
require 'misc_shared'
|
5
|
-
|
6
|
-
module IiifPrint::Jobs
|
7
|
-
RSpec.describe CreateRelationshipsJob, type: :job do
|
8
|
-
let(:create_relationships_job) { described_class.new }
|
9
|
-
|
10
|
-
let(:parent_model) { WorkWithIiifPrintConfig.to_s }
|
11
|
-
let(:child_model) { WorkWithIiifPrintConfig.to_s }
|
12
|
-
let(:file) { FileSet.new.tap { |fs| fs.save!(validate: false) } }
|
13
|
-
let(:parent_record) { WorkWithIiifPrintConfig.new(title: ['required title']) }
|
14
|
-
let(:child_record1) { WorkWithIiifPrintConfig.new(title: ["Child of #{parent_record.id} page 01"]) }
|
15
|
-
let(:child_record2) { WorkWithIiifPrintConfig.new(title: ["Child of #{parent_record.id} page 02"]) }
|
16
|
-
let(:pending_rel1) do
|
17
|
-
IiifPrint::PendingRelationship.new(
|
18
|
-
parent_id: parent_record.id,
|
19
|
-
child_title: "Child of #{parent_record.id} page 01",
|
20
|
-
child_order: "Child of #{parent_record.id} page 01",
|
21
|
-
parent_model: parent_model,
|
22
|
-
child_model: child_model,
|
23
|
-
file_id: file.id
|
24
|
-
)
|
25
|
-
end
|
26
|
-
let(:pending_rel2) do
|
27
|
-
IiifPrint::PendingRelationship.new(
|
28
|
-
parent_id: parent_record.id,
|
29
|
-
child_title: "Child of #{parent_record.id} page 02",
|
30
|
-
child_order: "Child of #{parent_record.id} page 02",
|
31
|
-
parent_model: parent_model,
|
32
|
-
child_model: child_model,
|
33
|
-
file_id: file.id
|
34
|
-
)
|
35
|
-
end
|
36
|
-
|
37
|
-
describe '#perform' do
|
38
|
-
before do
|
39
|
-
allow(create_relationships_job).to receive(:acquire_lock_for).and_yield
|
40
|
-
allow(create_relationships_job).to receive(:reschedule_job)
|
41
|
-
allow(parent_record).to receive(:save!)
|
42
|
-
|
43
|
-
parent_record.save
|
44
|
-
pending_rel1.save
|
45
|
-
pending_rel2.save
|
46
|
-
end
|
47
|
-
|
48
|
-
subject(:perform) do
|
49
|
-
create_relationships_job.perform(
|
50
|
-
parent_id: parent_record.id,
|
51
|
-
parent_model: parent_model,
|
52
|
-
child_model: child_model,
|
53
|
-
retries: 0
|
54
|
-
)
|
55
|
-
end
|
56
|
-
|
57
|
-
context 'when adding a child work to a parent work' do
|
58
|
-
before do
|
59
|
-
child_record1.save
|
60
|
-
child_record2.save
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'assigns the child to the parent\'s #ordered_members' do
|
64
|
-
perform
|
65
|
-
expect(parent_record.reload.ordered_member_ids).to eq([child_record1.id, child_record2.id])
|
66
|
-
end
|
67
|
-
|
68
|
-
it 'deletes the pending relationships' do
|
69
|
-
expect { perform }.to change(IiifPrint::PendingRelationship, :count).by(-2)
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'does not reschedule the job' do
|
73
|
-
perform
|
74
|
-
expect(create_relationships_job).not_to have_received(:reschedule_job)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
context 'when a relationship fails' do
|
79
|
-
before do
|
80
|
-
child_record1.save
|
81
|
-
child_record2.save
|
82
|
-
end
|
83
|
-
|
84
|
-
before do
|
85
|
-
expect_any_instance_of(CreateRelationshipsJob).to receive(:add_to_work).and_raise('error')
|
86
|
-
end
|
87
|
-
|
88
|
-
it 'does not save the parent' do
|
89
|
-
expect { perform }.to raise_error(RuntimeError)
|
90
|
-
expect(parent_record).not_to have_received(:save!)
|
91
|
-
end
|
92
|
-
|
93
|
-
it 'does not delete the pending relationships' do
|
94
|
-
expect { perform }.to raise_error(RuntimeError)
|
95
|
-
expect(IiifPrint::PendingRelationship.where(parent_id: parent_record.id).count).to eq(2)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
context 'when any child record is not found' do
|
100
|
-
let(:child_record2) { nil }
|
101
|
-
|
102
|
-
before do
|
103
|
-
child_record1.save
|
104
|
-
end
|
105
|
-
|
106
|
-
it 'does not save the parent' do
|
107
|
-
perform
|
108
|
-
expect(parent_record).not_to have_received(:save!)
|
109
|
-
end
|
110
|
-
|
111
|
-
it 'reschedules the job' do
|
112
|
-
perform
|
113
|
-
expect(create_relationships_job).to have_received(:reschedule_job)
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe IiifPrint::JP2ImageMetadata do
|
4
|
-
let(:fixtures) { File.join(IiifPrint::GEM_PATH, 'spec/fixtures/files') }
|
5
|
-
|
6
|
-
let(:gray_jp2) { File.join(fixtures, 'ocr_gray.jp2') }
|
7
|
-
|
8
|
-
let(:color_jp2) { File.join(fixtures, '4.1.07.jp2') }
|
9
|
-
|
10
|
-
describe "Extracts technical metadata from a JP2 file" do
|
11
|
-
it "constructs with a path" do
|
12
|
-
meta = described_class.new(gray_jp2)
|
13
|
-
expect(meta.path).to eq gray_jp2
|
14
|
-
end
|
15
|
-
|
16
|
-
it "gets metadata for grayscale image" do
|
17
|
-
meta = described_class.new(gray_jp2)
|
18
|
-
result = meta.technical_metadata
|
19
|
-
expect(result[:color]).to eq 'gray'
|
20
|
-
expect(result[:width]).to eq 418
|
21
|
-
expect(result[:height]).to eq 1046
|
22
|
-
expect(result[:bits_per_component]).to eq 8
|
23
|
-
expect(result[:num_components]).to eq 1
|
24
|
-
end
|
25
|
-
|
26
|
-
it "gets metadata for color image" do
|
27
|
-
meta = described_class.new(color_jp2)
|
28
|
-
result = meta.technical_metadata
|
29
|
-
expect(result[:color]).to eq 'color'
|
30
|
-
expect(result[:width]).to eq 256
|
31
|
-
expect(result[:height]).to eq 256
|
32
|
-
expect(result[:bits_per_component]).to eq 8
|
33
|
-
# e.g. is 3, but would be four if sample image had an alpha channel
|
34
|
-
expect(result[:num_components]).to eq 3
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|