Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
elohanlon committed Feb 20, 2024
1 parent 776bd9b commit b03ab20
Show file tree
Hide file tree
Showing 14 changed files with 191 additions and 90 deletions.
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ gem 'imogen', git: 'https://github.com/cul/imogen.git', branch: 'iiif_tile_gener
gem 'io-wait', '0.2.0'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.7'
# JWT Tokens
gem 'jwt', '~> 2.7.1'
# Use mysql as a database option for Active Record
gem 'mysql2', '~> 0.5.5'
# Use Puma as the app server
Expand Down
122 changes: 62 additions & 60 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9,71 +9,71 @@ GIT
GEM
remote: https://rubygems.org/
specs:
actioncable (7.1.2)
actionpack (= 7.1.2)
activesupport (= 7.1.2)
actioncable (7.1.3)
actionpack (= 7.1.3)
activesupport (= 7.1.3)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
zeitwerk (~> 2.6)
actionmailbox (7.1.2)
actionpack (= 7.1.2)
activejob (= 7.1.2)
activerecord (= 7.1.2)
activestorage (= 7.1.2)
activesupport (= 7.1.2)
actionmailbox (7.1.3)
actionpack (= 7.1.3)
activejob (= 7.1.3)
activerecord (= 7.1.3)
activestorage (= 7.1.3)
activesupport (= 7.1.3)
mail (>= 2.7.1)
net-imap
net-pop
net-smtp
actionmailer (7.1.2)
actionpack (= 7.1.2)
actionview (= 7.1.2)
activejob (= 7.1.2)
activesupport (= 7.1.2)
actionmailer (7.1.3)
actionpack (= 7.1.3)
actionview (= 7.1.3)
activejob (= 7.1.3)
activesupport (= 7.1.3)
mail (~> 2.5, >= 2.5.4)
net-imap
net-pop
net-smtp
rails-dom-testing (~> 2.2)
actionpack (7.1.2)
actionview (= 7.1.2)
activesupport (= 7.1.2)
actionpack (7.1.3)
actionview (= 7.1.3)
activesupport (= 7.1.3)
nokogiri (>= 1.8.5)
racc
rack (>= 2.2.4)
rack-session (>= 1.0.1)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
actiontext (7.1.2)
actionpack (= 7.1.2)
activerecord (= 7.1.2)
activestorage (= 7.1.2)
activesupport (= 7.1.2)
actiontext (7.1.3)
actionpack (= 7.1.3)
activerecord (= 7.1.3)
activestorage (= 7.1.3)
activesupport (= 7.1.3)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (7.1.2)
activesupport (= 7.1.2)
actionview (7.1.3)
activesupport (= 7.1.3)
builder (~> 3.1)
erubi (~> 1.11)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
activejob (7.1.2)
activesupport (= 7.1.2)
activejob (7.1.3)
activesupport (= 7.1.3)
globalid (>= 0.3.6)
activemodel (7.1.2)
activesupport (= 7.1.2)
activerecord (7.1.2)
activemodel (= 7.1.2)
activesupport (= 7.1.2)
activemodel (7.1.3)
activesupport (= 7.1.3)
activerecord (7.1.3)
activemodel (= 7.1.3)
activesupport (= 7.1.3)
timeout (>= 0.4.0)
activestorage (7.1.2)
actionpack (= 7.1.2)
activejob (= 7.1.2)
activerecord (= 7.1.2)
activesupport (= 7.1.2)
activestorage (7.1.3)
actionpack (= 7.1.3)
activejob (= 7.1.3)
activerecord (= 7.1.3)
activesupport (= 7.1.3)
marcel (~> 1.0)
activesupport (7.1.2)
activesupport (7.1.3)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2)
Expand All @@ -91,7 +91,7 @@ GEM
bcrypt_pbkdf (1.1.0)
best_type (0.0.10)
mime-types (~> 3.0)
bigdecimal (3.1.5)
bigdecimal (3.1.6)
bindex (0.8.1)
bootsnap (1.17.0)
msgpack (~> 1.2)
Expand Down Expand Up @@ -178,9 +178,9 @@ GEM
hashie (5.0.0)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
io-console (0.7.1)
io-console (0.7.2)
io-wait (0.2.0)
irb (1.11.1)
irb (1.11.2)
rdoc
reline (>= 0.4.2)
jbuilder (2.11.5)
Expand All @@ -190,6 +190,7 @@ GEM
json_spec (1.1.5)
multi_json (~> 1.0)
rspec (>= 2.0, < 4.0)
jwt (2.7.1)
language_server-protocol (3.17.0.3)
listen (3.8.0)
rb-fsevent (~> 0.10, >= 0.10.3)
Expand All @@ -208,15 +209,15 @@ GEM
mime-types-data (3.2023.1205)
mini_mime (1.1.5)
mini_portile2 (2.8.5)
minitest (5.21.1)
minitest (5.22.2)
mono_logger (1.1.2)
msgpack (1.7.2)
multi_json (1.15.0)
mustermann (3.0.0)
ruby2_keywords (~> 0.0.1)
mutex_m (0.2.0)
mysql2 (0.5.5)
net-imap (0.4.9.1)
net-imap (0.4.10)
date
net-protocol
net-pop (0.1.2)
Expand All @@ -229,7 +230,7 @@ GEM
net-protocol
net-ssh (7.2.1)
nio4r (2.7.0)
nokogiri (1.16.0)
nokogiri (1.16.2)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
omniauth (2.1.2)
Expand Down Expand Up @@ -262,30 +263,30 @@ GEM
rackup (1.0.0)
rack (< 3)
webrick
rails (7.1.2)
actioncable (= 7.1.2)
actionmailbox (= 7.1.2)
actionmailer (= 7.1.2)
actionpack (= 7.1.2)
actiontext (= 7.1.2)
actionview (= 7.1.2)
activejob (= 7.1.2)
activemodel (= 7.1.2)
activerecord (= 7.1.2)
activestorage (= 7.1.2)
activesupport (= 7.1.2)
rails (7.1.3)
actioncable (= 7.1.3)
actionmailbox (= 7.1.3)
actionmailer (= 7.1.3)
actionpack (= 7.1.3)
actiontext (= 7.1.3)
actionview (= 7.1.3)
activejob (= 7.1.3)
activemodel (= 7.1.3)
activerecord (= 7.1.3)
activestorage (= 7.1.3)
activesupport (= 7.1.3)
bundler (>= 1.15.0)
railties (= 7.1.2)
railties (= 7.1.3)
rails-dom-testing (2.2.0)
activesupport (>= 5.0.0)
minitest
nokogiri (>= 1.6)
rails-html-sanitizer (1.6.0)
loofah (~> 2.21)
nokogiri (~> 1.14)
railties (7.1.2)
actionpack (= 7.1.2)
activesupport (= 7.1.2)
railties (7.1.3)
actionpack (= 7.1.3)
activesupport (= 7.1.3)
irb
rackup (>= 1.0.0)
rake (>= 12.2)
Expand Down Expand Up @@ -439,7 +440,7 @@ GEM
websocket-driver (0.7.6)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
zeitwerk (2.6.12)
zeitwerk (2.6.13)

PLATFORMS
ruby
Expand All @@ -460,6 +461,7 @@ DEPENDENCIES
io-wait (= 0.2.0)
jbuilder (~> 2.7)
json_spec
jwt (~> 2.7.1)
listen (~> 3.3)
mysql2 (~> 0.5.5)
omniauth
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/api/v1/resources_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def set_resource
end

def create_params
params.require(:resource).permit(:source_uri, :featured_region, :pcdm_type)
params.require(:resource).permit(:source_uri, :featured_region, :pcdm_type, :has_view_limitation)
end
end
end
Expand Down
1 change: 1 addition & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ class ApplicationController < ActionController::Base

def add_cors_header!
headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Headers'] = 'Authorization'
end
end
77 changes: 53 additions & 24 deletions app/controllers/iiif/images_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@ class Iiif::ImagesController < ApplicationController
include Triclops::Iiif::ImagesController::Schemas
include Triclops::Iiif::ImagesController::Sizing

before_action :add_cors_header!, only: [:info, :raster]
skip_before_action :verify_authenticity_token, only: [:raster_preflight_check]
before_action :add_cors_header!, only: [:info, :raster, :raster_preflight_check]
before_action :set_resource_or_handle_not_found, only: [:info, :raster, :test_viewer]
before_action :set_base_type, only: [:info, :raster]
before_action :require_token_if_resource_has_view_limitation!, only: [:raster] # For now, not limiting info endpoint

def raster_preflight_check
render plain: 'Success', status: :ok
end

def info
unless @resource.ready?
Expand All @@ -14,11 +21,11 @@ def info

assign_compliance_level_header!(response)

render json: info_json_for_resource(@resource)
render json: info_json_for_resource(@resource, @base_type)
end

# GET /iiif/2/:identifier/:region/:size/:rotation/:quality.(:format)
# e.g. /iiif/2/sample/full/full/0/default.png
# GET /iiif/2/:base_type/:identifier/:region/:size/:rotation/:quality.(:format)
# e.g. /iiif/2/standard/cul:123/full/full/0/default.png
def raster
params_as_regular_hash = params.to_unsafe_h
params_validation_result = Triclops::Contracts::Iiif2ImageParamsContract.new.call(params_as_regular_hash)
Expand All @@ -30,9 +37,10 @@ def raster

original_raster_opts = params_validation_result.to_h
original_raster_opts.delete(:identifier) # :identifier isn't part of our "raster opts"
base_type = original_raster_opts.delete(:base_type) # :base_type isn't part of our "raster opts"
normalized_raster_opts = Triclops::Iiif::RasterOptNormalizer.normalize_raster_opts(@resource, original_raster_opts)

handle_ready_resource_or_redirect(@resource, original_raster_opts, normalized_raster_opts)
handle_ready_resource_or_redirect(@resource, base_type, original_raster_opts, normalized_raster_opts)
end

def test_viewer
Expand All @@ -41,7 +49,24 @@ def test_viewer

private

def handle_ready_resource_or_redirect(resource, original_raster_opts, normalized_raster_opts)
def require_token_if_resource_has_view_limitation!
# Featured images don't ever require a token
return if @base_type == Triclops::Iiif::Constants::BASE_TYPE_FEATURED

# If this resource does not have a view limitation, no token is required
return unless @resource.has_view_limitation
# This will immediately render a 401 if no token was provided
authenticate_or_request_with_http_token do |token, _options|
puts "got token #{token}"
validate_image_request_token(token, @base_type, @resource.identifier, request.remote_ip)
end
end

def validate_image_request_token(token, base_type, resource_identifier, client_ip)
Triclops::Utils::TokenUtils.token_is_valid?(token, base_type, resource_identifier, client_ip)
end

def handle_ready_resource_or_redirect(resource, base_type, original_raster_opts, normalized_raster_opts)
# Whenever a valid resource is requested, cache the Resource identifier in
# our ResourceAccessStatCache. This cache will be periodically flushed to the
# Resource database (by a separate process) so that many access time updates
Expand Down Expand Up @@ -97,6 +122,10 @@ def contract_validation_error_response(contract_validation_result)
error_response(error_messages)
end

def set_base_type
@base_type = params[:base_type]
end

def set_resource_or_handle_not_found
identifier = params[:identifier]

Expand Down Expand Up @@ -157,30 +186,30 @@ def assign_compliance_level_header!(resp)
resp.set_header('Link', compliance_level_url)
end

def info_json_for_resource(resource)
def info_json_for_resource(resource, base_type)
width, height = dimensions_for_base_type(resource, base_type)
resource.iiif_info(
iiif_info_url(resource.identifier)[0...-10], # chop off last 10 characters to remove "/info.json"
resource.width,
resource.height,
Triclops::Iiif::Constants::RECOMMENDED_SIZES.map { |size| closest_size(size, resource.width, resource.height) },
iiif_info_url(base_type, resource.identifier)[0...-10], # chop off last 10 characters to remove "/info.json"
width,
height,
Triclops::Iiif::Constants::RECOMMENDED_SIZES.map { |size| closest_size(size, width, height) },
Triclops::Iiif::Constants::ALLOWED_FORMATS.keys,
Triclops::Iiif::Constants::ALLOWED_QUALITIES,
Triclops::Iiif::Constants::TILE_SIZE,
resource.scale_factors_for_tile_size(Triclops::Iiif::Constants::TILE_SIZE)
resource.scale_factors_for_tile_size(width, height, Triclops::Iiif::Constants::TILE_SIZE)
)
end

# def cacheable_raster?(resource, raster_opts)
# # Do not use cache if the cache is disabled globally
# return false unless TRICLOPS[:raster_cache][:enabled]

# # Serve cached images for placeholder resources
# return true if resource.source_uri_is_placeholder?
def dimensions_for_base_type(resource, base_type)
raise Triclops::Exceptions::UnknownBaseType, "Unknown base type: #{base_type}" unless Triclops::Iiif::Constants::ALLOWED_BASE_TYPES.include?(base_type)

# # Serve a cached raster if the raster already exists in the cache
# return true if resource.raster_exists?(raster_opts)

# # Otherwise do not serve from the cache
# false
# end
case base_type
when 'standard'
[resource.width, resource.height]
when 'limited'
[resource.limited_width, resource.limited_height]
when 'featured'
[resource.featured_width, resource.featured_height]
end
end
end
Loading

0 comments on commit b03ab20

Please sign in to comment.