iiif_manifest 1.0.1 → 1.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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +10 -22
- data/.github_changelog_generator +2 -0
- data/.rubocop.yml +14 -7
- data/.rubocop_todo.yml +38 -83
- data/CHANGELOG.md +118 -0
- data/README.md +40 -29
- data/iiif_manifest.gemspec +2 -4
- data/lib/iiif_manifest/manifest_builder.rb +6 -6
- data/lib/iiif_manifest/manifest_builder/canvas_builder.rb +12 -12
- data/lib/iiif_manifest/manifest_builder/canvas_builder_factory.rb +3 -3
- data/lib/iiif_manifest/manifest_builder/deep_canvas_builder_factory.rb +9 -9
- data/lib/iiif_manifest/manifest_builder/image_builder.rb +9 -9
- data/lib/iiif_manifest/manifest_builder/image_service_builder.rb +3 -3
- data/lib/iiif_manifest/manifest_builder/record_property_builder.rb +35 -35
- data/lib/iiif_manifest/manifest_builder/resource_builder.rb +9 -9
- data/lib/iiif_manifest/manifest_builder/sequence_builder.rb +19 -19
- data/lib/iiif_manifest/manifest_factory.rb +3 -3
- data/lib/iiif_manifest/manifest_service_locator.rb +2 -2
- data/lib/iiif_manifest/v3/manifest_builder.rb +7 -7
- data/lib/iiif_manifest/v3/manifest_builder/body_builder.rb +37 -37
- data/lib/iiif_manifest/v3/manifest_builder/canvas_builder.rb +24 -24
- data/lib/iiif_manifest/v3/manifest_builder/choice_builder.rb +14 -14
- data/lib/iiif_manifest/v3/manifest_builder/content_builder.rb +9 -9
- data/lib/iiif_manifest/v3/manifest_builder/image_service_builder.rb +10 -10
- data/lib/iiif_manifest/v3/manifest_builder/record_property_builder.rb +40 -40
- data/lib/iiif_manifest/v3/manifest_factory.rb +3 -3
- data/lib/iiif_manifest/version.rb +1 -1
- metadata +14 -40
    
        data/iiif_manifest.gemspec
    CHANGED
    
    | @@ -19,12 +19,10 @@ Gem::Specification.new do |spec| | |
| 19 19 |  | 
| 20 20 | 
             
              spec.add_dependency 'activesupport', '>= 4'
         | 
| 21 21 |  | 
| 22 | 
            -
              spec.add_development_dependency 'bixby', '~>  | 
| 22 | 
            +
              spec.add_development_dependency 'bixby', '~> 3.0'
         | 
| 23 23 | 
             
              spec.add_development_dependency 'coveralls'
         | 
| 24 24 | 
             
              spec.add_development_dependency 'pry-byebug'
         | 
| 25 | 
            -
              spec.add_development_dependency 'rake', ' | 
| 25 | 
            +
              spec.add_development_dependency 'rake', '>= 12.3.3'
         | 
| 26 26 | 
             
              spec.add_development_dependency 'rspec', '~> 3.0'
         | 
| 27 27 | 
             
              spec.add_development_dependency 'rspec_junit_formatter'
         | 
| 28 | 
            -
              spec.add_development_dependency 'rubocop'
         | 
| 29 | 
            -
              spec.add_development_dependency 'rubocop-rspec'
         | 
| 30 28 | 
             
            end
         | 
| @@ -35,12 +35,12 @@ module IIIFManifest | |
| 35 35 |  | 
| 36 36 | 
             
                private
         | 
| 37 37 |  | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 38 | 
            +
                def manifest
         | 
| 39 | 
            +
                  @manifest ||= manifest_builder_class
         | 
| 40 | 
            +
                end
         | 
| 41 41 |  | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 42 | 
            +
                def top_record
         | 
| 43 | 
            +
                  top_record_factory.new
         | 
| 44 | 
            +
                end
         | 
| 45 45 | 
             
              end
         | 
| 46 46 | 
             
            end
         | 
| @@ -28,18 +28,18 @@ module IIIFManifest | |
| 28 28 |  | 
| 29 29 | 
             
                  private
         | 
| 30 30 |  | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 31 | 
            +
                  def display_image
         | 
| 32 | 
            +
                    record.display_image if record.respond_to?(:display_image)
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  def apply_record_properties
         | 
| 36 | 
            +
                    canvas['@id'] = path
         | 
| 37 | 
            +
                    canvas.label = record.to_s
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  def attach_image
         | 
| 41 | 
            +
                    image_builder.new(display_image).apply(canvas)
         | 
| 42 | 
            +
                  end
         | 
| 43 43 | 
             
                end
         | 
| 44 44 | 
             
              end
         | 
| 45 45 | 
             
            end
         | 
| @@ -3,9 +3,9 @@ module IIIFManifest | |
| 3 3 | 
             
                class DeepCanvasBuilderFactory < CanvasBuilderFactory
         | 
| 4 4 | 
             
                  private
         | 
| 5 5 |  | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 6 | 
            +
                  def file_set_presenters(work)
         | 
| 7 | 
            +
                    DeepFileSetEnumerator.new(work).to_a
         | 
| 8 | 
            +
                  end
         | 
| 9 9 | 
             
                end
         | 
| 10 10 |  | 
| 11 11 | 
             
                class DeepFileSetEnumerator
         | 
| @@ -26,13 +26,13 @@ module IIIFManifest | |
| 26 26 |  | 
| 27 27 | 
             
                  private
         | 
| 28 28 |  | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 29 | 
            +
                  def file_set_presenters
         | 
| 30 | 
            +
                    work.try(:file_set_presenters) || []
         | 
| 31 | 
            +
                  end
         | 
| 32 32 |  | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 33 | 
            +
                  def work_presenters
         | 
| 34 | 
            +
                    work.try(:work_presenters) || []
         | 
| 35 | 
            +
                  end
         | 
| 36 36 | 
             
                end
         | 
| 37 37 | 
             
              end
         | 
| 38 38 | 
             
            end
         | 
| @@ -18,17 +18,17 @@ module IIIFManifest | |
| 18 18 |  | 
| 19 19 | 
             
                  private
         | 
| 20 20 |  | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 21 | 
            +
                  def build_resource
         | 
| 22 | 
            +
                    resource_builder.apply(annotation)
         | 
| 23 | 
            +
                  end
         | 
| 24 24 |  | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 25 | 
            +
                  def resource_builder
         | 
| 26 | 
            +
                    resource_builder_factory.new(display_image)
         | 
| 27 | 
            +
                  end
         | 
| 28 28 |  | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 29 | 
            +
                  def annotation
         | 
| 30 | 
            +
                    @annotation ||= iiif_annotation_factory.new
         | 
| 31 | 
            +
                  end
         | 
| 32 32 | 
             
                end
         | 
| 33 33 | 
             
              end
         | 
| 34 34 | 
             
            end
         | 
| @@ -22,65 +22,65 @@ module IIIFManifest | |
| 22 22 |  | 
| 23 23 | 
             
                  private
         | 
| 24 24 |  | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 25 | 
            +
                  def viewing_hint
         | 
| 26 | 
            +
                    (record.respond_to?(:viewing_hint) && record.send(:viewing_hint))
         | 
| 27 | 
            +
                  end
         | 
| 28 28 |  | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 29 | 
            +
                  def viewing_direction
         | 
| 30 | 
            +
                    (record.respond_to?(:viewing_direction) && record.send(:viewing_direction))
         | 
| 31 | 
            +
                  end
         | 
| 32 32 |  | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 33 | 
            +
                  def autocomplete_service
         | 
| 34 | 
            +
                    (record.respond_to?(:autocomplete_service) && record.send(:autocomplete_service))
         | 
| 35 | 
            +
                  end
         | 
| 36 36 |  | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 37 | 
            +
                  def search_service
         | 
| 38 | 
            +
                    (record.respond_to?(:search_service) && record.send(:search_service))
         | 
| 39 | 
            +
                  end
         | 
| 40 40 |  | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 41 | 
            +
                  def iiif_search_service
         | 
| 42 | 
            +
                    @iiif_search_service ||= iiif_search_service_factory.new
         | 
| 43 | 
            +
                  end
         | 
| 44 44 |  | 
| 45 | 
            -
             | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 45 | 
            +
                  def iiif_autocomplete_service
         | 
| 46 | 
            +
                    @iiif_autocomplete_service ||= iiif_autocomplete_service_factory.new
         | 
| 47 | 
            +
                  end
         | 
| 48 48 |  | 
| 49 49 | 
             
                    # Build services. Currently supported:
         | 
| 50 50 | 
             
                    #   search_service, with (optional) embedded autocomplete service
         | 
| 51 51 | 
             
                    #
         | 
| 52 52 | 
             
                    # @return [Array] array of services
         | 
| 53 | 
            -
             | 
| 54 | 
            -
             | 
| 55 | 
            -
             | 
| 56 | 
            -
             | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 53 | 
            +
                  def services
         | 
| 54 | 
            +
                    iiif_search_service.search_service = search_service
         | 
| 55 | 
            +
                    iiif_autocomplete_service.autocomplete_service = autocomplete_service
         | 
| 56 | 
            +
                    iiif_search_service.service = iiif_autocomplete_service if autocomplete_service.present?
         | 
| 57 | 
            +
                    [iiif_search_service]
         | 
| 58 | 
            +
                  end
         | 
| 59 59 |  | 
| 60 60 | 
             
                    # Validate manifest_metadata against the IIIF spec format for metadata
         | 
| 61 61 | 
             
                    #
         | 
| 62 62 | 
             
                    # @return [Boolean]
         | 
| 63 | 
            -
             | 
| 64 | 
            -
             | 
| 65 | 
            -
             | 
| 66 | 
            -
             | 
| 67 | 
            -
             | 
| 63 | 
            +
                  def valid_metadata?
         | 
| 64 | 
            +
                    return false unless record.respond_to?(:manifest_metadata)
         | 
| 65 | 
            +
                    metadata = record.manifest_metadata
         | 
| 66 | 
            +
                    valid_metadata_structure?(metadata) && valid_metadata_content?(metadata)
         | 
| 67 | 
            +
                  end
         | 
| 68 68 |  | 
| 69 69 | 
             
                    # Manifest metadata must be an array containing hashes
         | 
| 70 70 | 
             
                    #
         | 
| 71 71 | 
             
                    # @param metadata [Array<Hash>] a list of metadata with label and value as required keys for each entry
         | 
| 72 72 | 
             
                    # @return [Boolean]
         | 
| 73 | 
            -
             | 
| 74 | 
            -
             | 
| 75 | 
            -
             | 
| 73 | 
            +
                  def valid_metadata_structure?(metadata)
         | 
| 74 | 
            +
                    metadata.is_a?(Array) && metadata.all? { |v| v.is_a?(Hash) }
         | 
| 75 | 
            +
                  end
         | 
| 76 76 |  | 
| 77 77 | 
             
                    # Manifest Metadata Hashes must contain 'label' and 'value' keys
         | 
| 78 78 | 
             
                    #
         | 
| 79 79 | 
             
                    # @param metadata [Array<Hash>] a list of metadata with label and value as required keys for each entry
         | 
| 80 80 | 
             
                    # @return [Boolean]
         | 
| 81 | 
            -
             | 
| 82 | 
            -
             | 
| 83 | 
            -
             | 
| 81 | 
            +
                  def valid_metadata_content?(metadata)
         | 
| 82 | 
            +
                    metadata.all? { |v| v['label'].present? && v['value'].present? }
         | 
| 83 | 
            +
                  end
         | 
| 84 84 | 
             
                end
         | 
| 85 85 | 
             
              end
         | 
| 86 86 | 
             
            end
         | 
| @@ -20,17 +20,17 @@ module IIIFManifest | |
| 20 20 |  | 
| 21 21 | 
             
                  private
         | 
| 22 22 |  | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 23 | 
            +
                  def resource
         | 
| 24 | 
            +
                    @resource ||= iiif_resource_factory.new
         | 
| 25 | 
            +
                  end
         | 
| 26 26 |  | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 27 | 
            +
                  def iiif_endpoint
         | 
| 28 | 
            +
                    display_image.try(:iiif_endpoint)
         | 
| 29 | 
            +
                  end
         | 
| 30 30 |  | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 31 | 
            +
                  def image_service_builder
         | 
| 32 | 
            +
                    image_service_builder_factory.new(iiif_endpoint)
         | 
| 33 | 
            +
                  end
         | 
| 34 34 | 
             
                end
         | 
| 35 35 | 
             
              end
         | 
| 36 36 | 
             
            end
         | 
| @@ -20,28 +20,28 @@ module IIIFManifest | |
| 20 20 |  | 
| 21 21 | 
             
                  private
         | 
| 22 22 |  | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
                    def sequence
         | 
| 28 | 
            -
                      @sequence ||=
         | 
| 29 | 
            -
                        begin
         | 
| 30 | 
            -
                          sequence = sequence_factory.new
         | 
| 31 | 
            -
                          sequence['@id'] ||= work.manifest_url + '/sequence/normal'
         | 
| 32 | 
            -
                          sequence['rendering'] ||= populate_sequence_rendering
         | 
| 33 | 
            -
                          canvas_builder.apply(sequence)
         | 
| 34 | 
            -
                          sequence
         | 
| 35 | 
            -
                        end
         | 
| 36 | 
            -
                    end
         | 
| 23 | 
            +
                  def canvas_builder
         | 
| 24 | 
            +
                    canvas_builder_factory.from(work)
         | 
| 25 | 
            +
                  end
         | 
| 37 26 |  | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
                        []
         | 
| 27 | 
            +
                  def sequence
         | 
| 28 | 
            +
                    @sequence ||=
         | 
| 29 | 
            +
                      begin
         | 
| 30 | 
            +
                        sequence = sequence_factory.new
         | 
| 31 | 
            +
                        sequence['@id'] ||= work.manifest_url + '/sequence/normal'
         | 
| 32 | 
            +
                        sequence['rendering'] ||= populate_sequence_rendering
         | 
| 33 | 
            +
                        canvas_builder.apply(sequence)
         | 
| 34 | 
            +
                        sequence
         | 
| 43 35 | 
             
                      end
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  def populate_sequence_rendering
         | 
| 39 | 
            +
                    if work.respond_to?(:sequence_rendering)
         | 
| 40 | 
            +
                      work.sequence_rendering.each(&:to_h)
         | 
| 41 | 
            +
                    else
         | 
| 42 | 
            +
                      []
         | 
| 44 43 | 
             
                    end
         | 
| 44 | 
            +
                  end
         | 
| 45 45 | 
             
                end
         | 
| 46 46 | 
             
              end
         | 
| 47 47 | 
             
            end
         | 
| @@ -195,13 +195,13 @@ module IIIFManifest | |
| 195 195 |  | 
| 196 196 | 
             
                class InjectedFactory
         | 
| 197 197 | 
             
                  attr_reader :factory, :hash_args
         | 
| 198 | 
            -
                  def initialize(factory, hash_args)
         | 
| 198 | 
            +
                  def initialize(factory, **hash_args)
         | 
| 199 199 | 
             
                    @hash_args = hash_args
         | 
| 200 200 | 
             
                    @factory = factory
         | 
| 201 201 | 
             
                  end
         | 
| 202 202 |  | 
| 203 203 | 
             
                  def new(*args)
         | 
| 204 | 
            -
                    factory.new(*args, hash_args)
         | 
| 204 | 
            +
                    factory.new(*args, **hash_args)
         | 
| 205 205 | 
             
                  end
         | 
| 206 206 | 
             
                end
         | 
| 207 207 | 
             
              end
         | 
| @@ -26,10 +26,10 @@ module IIIFManifest | |
| 26 26 |  | 
| 27 27 | 
             
                    private
         | 
| 28 28 |  | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 29 | 
            +
                    def obj_to_language_map(obj)
         | 
| 30 | 
            +
                      return nil unless obj.is_a?(String) || (obj.is_a?(Array) && obj.all? { |o| o.is_a?(String) })
         | 
| 31 | 
            +
                      { '@none' => Array(obj) }
         | 
| 32 | 
            +
                    end
         | 
| 33 33 | 
             
                  end
         | 
| 34 34 |  | 
| 35 35 | 
             
                  attr_reader :work,
         | 
| @@ -53,9 +53,9 @@ module IIIFManifest | |
| 53 53 |  | 
| 54 54 | 
             
                 private
         | 
| 55 55 |  | 
| 56 | 
            -
             | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 56 | 
            +
                  def top_record
         | 
| 57 | 
            +
                    top_record_factory.new
         | 
| 58 | 
            +
                  end
         | 
| 59 59 | 
             
                end
         | 
| 60 60 | 
             
              end
         | 
| 61 61 | 
             
            end
         | 
| @@ -18,43 +18,43 @@ module IIIFManifest | |
| 18 18 |  | 
| 19 19 | 
             
                    private
         | 
| 20 20 |  | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 45 | 
            -
             | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 53 | 
            -
             | 
| 54 | 
            -
             | 
| 55 | 
            -
             | 
| 56 | 
            -
             | 
| 57 | 
            -
             | 
| 21 | 
            +
                    def build_body
         | 
| 22 | 
            +
                      body['id'] = display_content.url
         | 
| 23 | 
            +
                      body['type'] = body_type
         | 
| 24 | 
            +
                      body['height'] = display_content.height if display_content.try(:height).present?
         | 
| 25 | 
            +
                      body['width'] = display_content.width if display_content.try(:width).present?
         | 
| 26 | 
            +
                      body['duration'] = display_content.duration if display_content.try(:duration).present?
         | 
| 27 | 
            +
                      body['format'] = display_content.format if display_content.try(:format).present?
         | 
| 28 | 
            +
                      body['label'] = ManifestBuilder.language_map(display_content.label) if display_content.try(:label).present?
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    def body
         | 
| 32 | 
            +
                      @body ||= iiif_body_factory.new
         | 
| 33 | 
            +
                    end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                    def body_type
         | 
| 36 | 
            +
                      display_content.try(:type) || 'Image'
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    def iiif_endpoint
         | 
| 40 | 
            +
                      display_content.try(:iiif_endpoint)
         | 
| 41 | 
            +
                    end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                    def image_service_builder
         | 
| 44 | 
            +
                      image_service_builder_factory.new(iiif_endpoint)
         | 
| 45 | 
            +
                    end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                    def auth_service
         | 
| 48 | 
            +
                      display_content.try(:auth_service)
         | 
| 49 | 
            +
                    end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                    def apply_auth_service
         | 
| 52 | 
            +
                      body.service = if body['service'].blank?
         | 
| 53 | 
            +
                                       [auth_service]
         | 
| 54 | 
            +
                                     else
         | 
| 55 | 
            +
                                       body['service'] + [auth_service]
         | 
| 56 | 
            +
                                     end
         | 
| 57 | 
            +
                    end
         | 
| 58 58 | 
             
                  end
         | 
| 59 59 | 
             
                end
         | 
| 60 60 | 
             
              end
         |