wax_iiif 0.0.2 → 0.1.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/.gitignore +1 -0
  3. data/.rubocop.yml +25 -0
  4. data/.travis.yml +2 -2
  5. data/Gemfile +3 -2
  6. data/README.md +4 -4
  7. data/lib/wax_iiif.rb +34 -44
  8. data/lib/wax_iiif/base_properties.rb +90 -0
  9. data/lib/wax_iiif/builder.rb +252 -0
  10. data/lib/wax_iiif/collection.rb +58 -0
  11. data/lib/{iiif_s3 → wax_iiif}/config.rb +46 -60
  12. data/lib/{iiif_s3 → wax_iiif}/errors.rb +6 -12
  13. data/lib/{iiif_s3 → wax_iiif}/full_image.rb +3 -8
  14. data/lib/wax_iiif/image_info.rb +89 -0
  15. data/lib/{iiif_s3 → wax_iiif}/image_record.rb +48 -63
  16. data/lib/{iiif_s3 → wax_iiif}/image_tile.rb +8 -14
  17. data/lib/{iiif_s3 → wax_iiif}/image_variant.rb +20 -38
  18. data/lib/wax_iiif/manifest.rb +151 -0
  19. data/lib/{iiif_s3 → wax_iiif}/thumbnail.rb +5 -9
  20. data/lib/{iiif_s3 → wax_iiif}/utilities.rb +5 -5
  21. data/lib/{iiif_s3 → wax_iiif}/utilities/helpers.rb +18 -48
  22. data/lib/{iiif_s3 → wax_iiif}/utilities/pdf_splitter.rb +20 -23
  23. data/spec/base_properties_spec.rb +8 -12
  24. data/spec/shared_contexts.rb +28 -92
  25. data/spec/spec_helper.rb +3 -3
  26. data/spec/wax_iiif/builder_spec.rb +143 -0
  27. data/spec/wax_iiif/collection_spec.rb +53 -0
  28. data/spec/wax_iiif/config_spec.rb +15 -0
  29. data/spec/wax_iiif/image_info_spec.rb +57 -0
  30. data/spec/wax_iiif/image_record_spec.rb +82 -0
  31. data/spec/wax_iiif/image_variant_spec.rb +66 -0
  32. data/spec/wax_iiif/manifest_spec.rb +97 -0
  33. data/spec/wax_iiif/utilities/pdf_splitter_spec.rb +14 -0
  34. data/wax_iiif.gemspec +15 -19
  35. metadata +52 -97
  36. data/Guardfile +0 -10
  37. data/Rakefile +0 -24
  38. data/lib/iiif_s3/base_properties.rb +0 -95
  39. data/lib/iiif_s3/builder.rb +0 -241
  40. data/lib/iiif_s3/collection.rb +0 -61
  41. data/lib/iiif_s3/image_info.rb +0 -96
  42. data/lib/iiif_s3/manifest.rb +0 -151
  43. data/lib/iiif_s3/version.rb +0 -5
  44. data/spec/iiif_s3/builder_spec.rb +0 -152
  45. data/spec/iiif_s3/collection_spec.rb +0 -68
  46. data/spec/iiif_s3/config_spec.rb +0 -15
  47. data/spec/iiif_s3/image_info_spec.rb +0 -57
  48. data/spec/iiif_s3/image_record_spec.rb +0 -96
  49. data/spec/iiif_s3/image_variant_spec.rb +0 -68
  50. data/spec/iiif_s3/manifest_spec.rb +0 -97
  51. data/spec/iiif_s3/utilities/pdf_splitter_spec.rb +0 -17
  52. data/test.rb +0 -77
@@ -1,151 +0,0 @@
1
- module IiifS3
2
-
3
- FakeManifest = Struct.new(:id, :type, :label)
4
-
5
- #
6
- # Class Manifest is an abstraction over the IIIF Manifest, and by extension over the
7
- # entire Presentation API. It takes the internal representation of data and converts
8
- # it into a collection of JSON-LD documents. Optionally, it also provides the ability
9
- # to save these files to disk and upload them to Amazon S3.
10
- #
11
- # @author David Newbury <david.newbury@gmail.com>
12
- #
13
-
14
- class Manifest
15
-
16
- # @return [String] The IIIF default type for a manifest.
17
- TYPE = "sc:Manifest"
18
-
19
- include BaseProperties
20
-
21
- #--------------------------------------------------------------------------
22
- # CONSTRUCTOR
23
- #--------------------------------------------------------------------------
24
-
25
- # This will initialize a new manifest.
26
- #
27
- # @param [Array<ImageRecord>] image_records An array of ImageRecord types
28
- # @param [<type>] config <description>
29
- # @param [<type>] opts <description>
30
- #
31
- def initialize(image_records,config, opts = {})
32
- @config = config
33
- image_records.each do |record|
34
- raise IiifS3::Error::InvalidImageData, "The data provided to the manifest were not ImageRecords" unless record.is_a? ImageRecord
35
- end
36
-
37
- @primary = image_records.find{|obj| obj.is_primary}
38
- raise IiifS3::Error::InvalidImageData, "No 'is_primary' was found in the image data." unless @primary
39
- raise IiifS3::Error::MultiplePrimaryImages, "Multiple primary images were found in the image data." unless image_records.count{|obj| obj.is_primary} == 1
40
-
41
- self.id = "#{@primary.id}/manifest"
42
- self.label = @primary.label || opts[:label] || ""
43
- self.description = @primary.description || opts[:description]
44
- self.attribution = @primary.attribution || opts.fetch(:attribution, nil)
45
- self.logo = @primary.logo || opts.fetch(:logo, nil)
46
- self.license = @primary.license || opts.fetch(:license, nil)
47
- self.metadata = @primary.metadata || opts.fetch(:metadata, nil)
48
-
49
- @sequences = build_sequence(image_records)
50
- end
51
-
52
- #
53
- # @return [String] the JSON-LD representation of the manifest as a string.
54
- #
55
- def to_json
56
- obj = base_properties
57
-
58
- obj["thumbnail"] = @primary.variants["thumbnail"].uri
59
- obj["viewingDirection"] = @primary.viewing_direction
60
- obj["viewingHint"] = @primary.is_document ? "paged" : "individuals"
61
- obj["sequences"] = [@sequences]
62
-
63
- return JSON.pretty_generate obj
64
- end
65
-
66
- #
67
- # Save the manifest and all sub-resources to disk, using the
68
- # paths contained withing the IiifS3::Config object passed at
69
- # initialization.
70
- #
71
- # Will create the manifest, sequences, canvases, and annotation subobjects.
72
- #
73
- # @return [Void]
74
- #
75
- def save_all_files_to_disk
76
- data = JSON.parse(self.to_json)
77
- save_to_disk(data)
78
- data["sequences"].each do |sequence|
79
- save_to_disk(sequence)
80
- sequence["canvases"].each do |canvas|
81
- save_to_disk(canvas)
82
- canvas["images"].each do |annotation|
83
- save_to_disk(annotation)
84
- end
85
- end
86
- end
87
- return nil
88
- end
89
-
90
- protected
91
-
92
-
93
- #--------------------------------------------------------------------------
94
- def build_sequence(image_records,opts = {name: DEFAULT_SEQUENCE_NAME})
95
- name = opts.delete(:name)
96
- seq_id = generate_id "#{@primary.id}/sequence/#{name}"
97
-
98
- opts.merge({
99
- "@id" => seq_id,
100
- "@type" => SEQUENCE_TYPE,
101
- "canvases" => image_records.collect {|image_record| build_canvas(image_record)}
102
- })
103
- end
104
-
105
- #--------------------------------------------------------------------------
106
- def build_canvas(data)
107
-
108
- canvas_id = generate_id "#{data.id}/canvas/#{data.section}"
109
-
110
- obj = {
111
- "@type" => CANVAS_TYPE,
112
- "@id" => canvas_id,
113
- "label" => data.section_label,
114
- "width" => data.variants["full"].width.floor,
115
- "height" => data.variants["full"].height.floor,
116
- "thumbnail" => data.variants["thumbnail"].uri
117
- }
118
- obj["images"] = [build_image(data, obj)]
119
-
120
- # handle objects that are less than 1200px on a side by doubling canvas size
121
- if obj["width"] < MIN_CANVAS_SIZE || obj["height"] < MIN_CANVAS_SIZE
122
- obj["width"] *= 2
123
- obj["height"] *= 2
124
- end
125
- return obj
126
- end
127
-
128
- #--------------------------------------------------------------------------
129
- def build_image(data, canvas)
130
- annotation_id = generate_id "#{data.id}/annotation/#{data.section}"
131
- {
132
- "@type" => ANNOTATION_TYPE,
133
- "@id" => annotation_id,
134
- "motivation" => MOTIVATION,
135
- "resource" => {
136
- "@id" => data.variants["full"].uri,
137
- "@type" => IMAGE_TYPE,
138
- "format" => data.variants["full"].mime_type || "image/jpeg",
139
- "service" => {
140
- "@context" => IiifS3::IMAGE_CONTEXT,
141
- "@id" => data.variants["full"].id,
142
- "profile" => IiifS3::LEVEL_0,
143
- },
144
- "width" => data.variants["full"].width,
145
- "height" => data.variants["full"].height,
146
- },
147
- "on" => canvas["@id"]
148
- }
149
- end
150
- end
151
- end
@@ -1,5 +0,0 @@
1
- module IiifS3
2
- #
3
- # @return [String] The current library version
4
- VERSION = "0.1.0"
5
- end
@@ -1,152 +0,0 @@
1
- require 'spec_helper'
2
- require 'ostruct'
3
- require 'fileutils'
4
-
5
- describe IiifS3::Builder do
6
- # before(:each) do
7
- # fake_aws_bucket = OpenStruct.new({
8
- # "exists?" => "true"
9
- # })
10
- # unless ENV["TEST_INTERNET_CONNECTIVITY"]
11
- # allow(Aws::S3::Bucket).to receive(:new) {nil}
12
- # allow(Aws::S3::Bucket).to receive(:exists?) {true}
13
- # end
14
- # end
15
-
16
- let (:iiif) { IiifS3::Builder.new() }
17
- let (:test_object_0) {ImageRecord.new({"id" => 1, "page_number" => 1})}
18
- let (:test_object_1) {ImageRecord.new({"id" => 2, "page_number" => 1})}
19
- let (:test_object_2) {ImageRecord.new({"id" => 2, "page_number" => 2})}
20
- let (:data) {[test_object_0, test_object_1,test_object_2]}
21
-
22
- context "When initializing" do
23
- it "generates manifests" do
24
- expect(iiif.manifests).to eq(Array.new)
25
- end
26
- it "uses the default config" do
27
- expect(iiif.config).to eq(IiifS3::Config.new)
28
- end
29
- it "will accept a configuration hash" do
30
- opts = {tile_width: 99}
31
- iiif2 = IiifS3::Builder.new(opts)
32
- expect(iiif2.config.tile_width).to eq(99)
33
- end
34
- end
35
-
36
- context "loading data" do
37
- it "will accept an array of objects" do
38
- iiif.load(data)
39
- expect(iiif.data).to eq(data)
40
- end
41
- it "will accept a single object" do
42
- iiif.load(test_object_1)
43
- expect(iiif.data).to eq([test_object_1])
44
- end
45
-
46
- it "will error if the data is bad" do
47
- expect{iiif.load({random: "hash"})}.to raise_error(IiifS3::Error::InvalidImageData)
48
- expect{iiif.load([{random: "hash"}])}.to raise_error(IiifS3::Error::InvalidImageData)
49
- end
50
- end
51
-
52
- context "when processing data" do
53
- include_context("fake variants")
54
- include_context("fake data")
55
-
56
- before(:example) do
57
- @iiif = IiifS3::Builder.new({base_url: 'http://0.0.0.0', verbose: true, thumbnail_size: 120})
58
- @iiif.load(@fake_data)
59
- allow(@iiif).to receive(:generate_tiles) {nil}
60
- allow(@iiif).to receive(:generate_variants) {@fake_variants}
61
-
62
- end
63
- it "does not fail with no data" do
64
- expect {iiif.process_data}.not_to raise_error
65
- end
66
-
67
- it "does not fail with real data" do
68
- expect {@iiif.process_data}.not_to raise_error
69
- end
70
-
71
- it " passes the Temporary Manifest Check" do
72
- @iiif.process_data
73
- expect(@iiif.manifests.count).to eq 1
74
- expect(@iiif.manifests.first.to_json).to eq @fake_manifest
75
- end
76
- end
77
-
78
-
79
- context "when dealing with already loaded data" do
80
- include_context("fake data")
81
- include_context("fake variants")
82
-
83
- before(:example) do
84
- @dir = Dir.mktmpdir
85
- @iiif = IiifS3::Builder.new({output_dir: @dir, base_url: 'http://0.0.0.0', verbose: true, thumbnail_size: 120})
86
- @iiif.load(@fake_data)
87
- @info_json = "#{@dir}/images/1-1/info.json"
88
- allow(@iiif).to receive(:generate_tiles) {nil}
89
- allow(@iiif).to receive(:generate_variants) {@fake_variants}
90
- @iiif.process_data
91
- end
92
-
93
- after(:example) do
94
- FileUtils.remove_entry @dir
95
- end
96
-
97
- it "has the temporary file" do
98
- expect(File.exist?(@info_json)).to eq true
99
- end
100
-
101
- it "does try to generate images if that file is missing" do
102
- File.delete(@info_json)
103
- @iiif.process_data
104
- expect(@iiif).to have_received(:generate_tiles).twice
105
- expect(@iiif).to have_received(:generate_variants).twice
106
- end
107
-
108
- it "does not try to generate images if that file is present" do
109
- @iiif.process_data
110
- expect(@iiif).to have_received(:generate_tiles).once
111
- expect(@iiif).to have_received(:generate_variants).once
112
- end
113
-
114
- it "generates the correct manifest anyway" do
115
- @iiif.process_data
116
- expect(@iiif.manifests.count).to eq 1
117
- expect(@iiif.manifests.first.to_json).to eq @fake_manifest
118
- end
119
-
120
- end
121
-
122
- context "When load_csving CSV files" do
123
- it "accepts a path" do
124
- expect{iiif.load_csv('./spec/data/test.csv')}.not_to raise_error()
125
- end
126
- it "fails on blank CSV files" do
127
- expect{iiif.load_csv('./spec/data/blank.csv')}.to raise_error(IiifS3::Error::BlankCSV)
128
- end
129
- it "fails on invalid CSV files" do
130
- expect{iiif.load_csv('./spec/data/invalid.csv')}.to raise_error(IiifS3::Error::InvalidCSV)
131
- end
132
- it "fails on missing CSV files" do
133
- expect{iiif.load_csv('./spec/data/i_dont_exist.csv')}.to raise_error(IiifS3::Error::InvalidCSV)
134
- end
135
- end
136
-
137
- context "When loading a CSV file" do
138
- it "saves the data into the @data param" do
139
- expect(iiif.data).to be_nil
140
- iiif.load_csv('./spec/data/test.csv')
141
- expect(iiif.data).not_to be_nil
142
- end
143
- it "removes headers" do
144
- iiif.load_csv('./spec/data/test.csv')
145
- expect(iiif.data[0]['image_path']).to eq('spec/data/test.jpg')
146
- end
147
- it "doesn't remove headers if not present" do
148
- iiif.load_csv('./spec/data/no_header.csv')
149
- expect(iiif.data[0]['image_path']).to eq('spec/data/test.jpg')
150
- end
151
- end
152
- end
@@ -1,68 +0,0 @@
1
- require 'spec_helper'
2
- require "base_properties_spec"
3
-
4
- describe IiifS3::Collection do
5
- let (:config) {IiifS3::Config.new()}
6
- context "base" do
7
- before(:each) do
8
- @object = IiifS3::Collection.new("Test data", config)
9
- end
10
- it_behaves_like "base properties"
11
- end
12
-
13
- context "initialization" do
14
- it "initializes without issues" do
15
- collection = nil
16
- expect{collection = IiifS3::Collection.new("Test data", config)}.not_to raise_error
17
- expect(collection.id).to eq("http://0.0.0.0/collection/top.json")
18
- end
19
- it "initializes without issues when provided a name" do
20
- collection = nil
21
- expect{collection = IiifS3::Collection.new("Test data", config, "name")}.not_to raise_error
22
- expect(collection.id).to eq("http://0.0.0.0/collection/name.json")
23
- end
24
- it "initializes without issues when provided a name with a space in it" do
25
- collection = nil
26
- expect{collection = IiifS3::Collection.new("Test data", config, "name and space")}.not_to raise_error
27
- expect(collection.id).to eq("http://0.0.0.0/collection/name%20and%20space.json")
28
- end
29
- it "fails if there is no label" do
30
- expect{collection = IiifS3::Collection.new(nil, config)}.to raise_error(IiifS3::Error::MissingCollectionName)
31
- end
32
- it "fails if there is a blank label" do
33
- expect{collection = IiifS3::Collection.new("", config)}.to raise_error(IiifS3::Error::MissingCollectionName)
34
- end
35
- it "has the correct default name" do
36
- collection = IiifS3::Collection.new("Test data", config)
37
- expect(collection.id).to include "top.json"
38
- end
39
- end
40
- context "data init" do
41
- include_context("fake data")
42
- let(:collection) {IiifS3::Collection.new("Test Data", config, "name")}
43
- let(:manifest) {IiifS3::Manifest.new([@fake_data],config)}
44
- it "has a label" do
45
- expect(collection.label).to eq "Test Data"
46
- end
47
- it "has an id" do
48
- expect(collection.id).to eq "http://0.0.0.0/collection/name.json"
49
- end
50
-
51
- it "allows you to add a collection" do
52
- newCollection = collection.clone
53
- expect{collection.add_collection(newCollection)}.not_to raise_error
54
- end
55
-
56
- it "fails if you add something else to a collection" do
57
- newCollection = {}
58
- expect{collection.add_collection(newCollection)}.to raise_error(IiifS3::Error::NotACollection)
59
- end
60
-
61
-
62
- it "generates correct JSON" do
63
- collection.add_manifest(manifest)
64
- expect(collection.to_json).to eq @fake_collection
65
- end
66
-
67
- end
68
- end
@@ -1,15 +0,0 @@
1
- require 'spec_helper'
2
-
3
-
4
- describe IiifS3::Config do
5
- context "comparing" do
6
- it "shows equal things to be equal" do
7
- expect(IiifS3::Config.new).to eq(IiifS3::Config.new)
8
- end
9
- it "shows different things to be different" do
10
- opts = {tile_width: 99, upload_to_s3: false}
11
- opts2 = {tile_width: 100, upload_to_s3: false}
12
- expect(IiifS3::Config.new opts).not_to eq(IiifS3::Config.new opts2)
13
- end
14
- end
15
- end
@@ -1,57 +0,0 @@
1
- require 'spec_helper'
2
- require 'ostruct'
3
-
4
- include IiifS3
5
-
6
- describe IiifS3::ImageInfo do
7
-
8
- let(:uri) {"http://www.example.com/test/1"}
9
- include_context("fake variants")
10
-
11
- context "intialization" do
12
-
13
-
14
- it "initializes without errors" do
15
- expect{ImageInfo.new(uri,@fake_variants)}.not_to raise_error
16
- end
17
- it "raises an error without a 'full' variant" do
18
- @fake_variants.delete "full"
19
- expect{ImageInfo.new(uri,@fake_variants)}.to raise_error(Error::InvalidImageData)
20
- end
21
- it "raises an error without a 'thumbnail' variant" do
22
- @fake_variants.delete "thumbnail"
23
- expect{ImageInfo.new(uri,@fake_variants)}.to raise_error(Error::InvalidImageData)
24
- end
25
- end
26
-
27
-
28
- context "valid data" do
29
- before(:example) do
30
- @info = ImageInfo.new(uri,@fake_variants)
31
- end
32
-
33
- it "generates correct sizes" do
34
- expect(@info.sizes).to eq([{"width" => 1000, "height" => 1200},{"width" => 100, "height" => 120}])
35
- end
36
-
37
- it "generates nil when no tile data appears" do
38
- expect(@info.tiles).to be_nil
39
- end
40
-
41
- it "generates tile info when tile data appears" do
42
- info = ImageInfo.new(uri,@fake_variants,500,[1,2,4])
43
- expect(info.tiles).to eq([{"width" => 500, "scaleFactors" => [1,2,4]}])
44
- end
45
-
46
- it "has the correct other methods" do
47
- expect(@info).to respond_to "context"
48
- expect(@info).to respond_to "protocol"
49
- expect(@info).to respond_to "profile"
50
- expect(@info).to respond_to "service"
51
- end
52
-
53
- it "generates correct JSON" do
54
- expect(@info.to_json).to eq(@fake_image_info)
55
- end
56
- end
57
- end