Skip to content
Justin Coyne edited this page May 7, 2017 · 2 revisions

2:00 - 3:45 (1hr 45min)

"A new requirement: Deep zoom"

git checkout day2/iiif-start

Undo the inline jobs

In config/application.rb comment out this line:

   config.active_job.queue_adapter = :inline

Start your servers

solr_wrapper
fcrepo_wrapper
bin/rails hyrax:default_admin_set:create
bin/rails server

Sign in

Visit http://localhost:3000/ and create an account

Upload an image file

http://www.brahms-institut.de/web/bihl_digital/jb_erstdrucke/op_049_s_011.jpg

https://photojournal.jpl.nasa.gov/tiff/PIA16869.tif

Customize the show page. Move the image to the top.

mkdir -p app/views/hyrax/base
cp `bundle show hyrax`/app/views/hyrax/base/show.html.erb app/views/hyrax/base

Edit the page app/views/hyrax/base/show.html.erb

Move <%= render 'representative_media', presenter: @presenter %> to it's own row.

(check into git)

Install riiif in Hydra

https://github.com/curationexperts/riiif

add to Gemfile

gem 'riiif'

then bundle install

Mount riiif engine

Add to config/routes.rb

  mount Riiif::Engine => '/images', as: 'riiif'

Install a riiif config

curl https://raw.githubusercontent.com/projecthydra-labs/hyku/master/config/initializers/riiif.rb -o config/initializers/riiif.rb

Comment out the authorization service line (check into git)

then restart rails server

Customize the image media partial.

cp `bundle show hyrax`/app/views/hyrax/base/_representative_media.html.erb app/views/hyrax/base

(check into git)

Edit the partial

app/views/hyrax/base/_representative_media.html.erb

<% if presenter.representative_presenter && presenter.representative_presenter.image? %>
  <% original_file_id = FileSet.find(presenter.representative_id).original_file.id %>
  <%= original_file_id %>
<% elsif presenter.representative_id.present? && presenter.representative_presenter.present? %>
  <%= media_display presenter.representative_presenter %>
<% else %>
  <%= image_tag 'default.png', class: "canonical-image" %>
<% end %>

save and refresh the page. Grab the displayed id (e.g. n583xt96p/files/bb929d64-69e6-416a-b0f8-513416cb1337)

Explore the image api

Encode the slashes:

<%= CGI.escape(FileSet.find(presenter.representative_id).original_file.id) %>

Some URIs to try:

/images/n583xt96p%2Ffiles%2Fbb929d64-69e6-416a-b0f8-513416cb1337
/images/n583xt96p%2Ffiles%2Fbb929d64-69e6-416a-b0f8-513416cb1337/info.json
/images/n583xt96p%2Ffiles%2Fbb929d64-69e6-416a-b0f8-513416cb1337/full/full/0/default.jpg
/images/n583xt96p%2Ffiles%2Fbb929d64-69e6-416a-b0f8-513416cb1337/full/full/90/default.jpg
/images/n583xt96p%2Ffiles%2Fbb929d64-69e6-416a-b0f8-513416cb1337/full/100,/0/default.jpg
/images/n583xt96p%2Ffiles%2Fbb929d64-69e6-416a-b0f8-513416cb1337/200,200,300,300/full/0/default.jpg

Take a look in the logs:

Started GET "/images/n583xt96p%2Ffiles%2Fbb929d64-69e6-416a-b0f8-513416cb1337/200,200,300,300/full/0/default.jpg" for ::1 at 2017-04-29 11:07:56 -0500
Processing by Riiif::ImagesController#show as JPEG
  Parameters: {"rotation"=>"0", "region"=>"200,200,300,300", "quality"=>"default", "model"=>"riiif/image", "id"=>"n583xt96p/files/bb929d64-69e6-416a-b0f8-513416cb1337", "size"=>"full"}
Unpermitted parameters: model, id
Riiif resolved n583xt96p/files/bb929d64-69e6-416a-b0f8-513416cb1337 to http://127.0.0.1:8984/rest/dev/n5/83/xt/96/n583xt96p/files/bb929d64-69e6-416a-b0f8-513416cb1337
Riiif executed convert -crop 300x300+200+200 -quality 85 -sampling-factor 4:2:0 -strip tmp/network_files/75633507f2300270c831146139c9b566 jpg:- (39.1ms)
  Rendering text template
  Rendered text template (0.0ms)
Sent data  (0.7ms)
Completed 200 OK in 45ms (Views: 0.5ms | ActiveRecord: 0.0ms)

Add the openseadragon client

Edit the partial app/views/hyrax/base/_representative_media.html.erb

  <% if presenter.representative_presenter.image? %>
    <% original_file_id = FileSet.find(presenter.representative_id).original_file.id %>
    <%= openseadragon_picture_tag riiif.info_path(original_file_id, locale: nil) %>
  <% elsif presenter.representative_id.present? && presenter.representative_presenter.present? %>
    <%= media_display presenter.representative_presenter %>
  <% else %>
    <%= image_tag 'default.png', class: "canonical-image" %>
  <% end %>

(commit to git)

Adding authorization

mkdir -p app/services
curl https://raw.githubusercontent.com/projecthydra-labs/hyku/master/app/services/iiif_authorization_service.rb -o app/services/iiif_authorization_service.rb

Edit config/initializers/iiif.rb and uncomment this line

Riiif::Image.authorization_service = IIIFAuthorizationService

Then restart the server

Try changing the authorization service to return false (restart the server after changes)

(git commit)

What do we need to know about RIIIF

Clean the caches! https://github.com/loris-imageserver/loris/blob/607567b921404a15a2111fbd7123604f4fdec087/bin/loris-cache_clean.sh

This is a good time to take a break.

4:00 - 5:00

New requirement, present a book.

Add an image to our existing work.

Now, we want both images to display in the viewer.

Let's build a manifest.

First let's get the image paths:

rails console
Image.find('zg64tk92g').ordered_members.to_a.map do |fs|
  Riiif::Engine.routes.url_helpers.info_url(fs.original_file.id, host: 'localhost:3000')
end

Open the manifest editor

http://morning-journey-27147.herokuapp.com

See here for directions https://iiif.github.io/training/intro-to-iiif/IIIF_MANIFESTS.html

Add both images json links.

Host the manifest

Save the manifest.

Then open the manifest file, select all, copy.

Open up a new gist and paste it. Save the gist.

Click the "Raw" link. Copy that URL.

View the manifest.

http://universalviewer.io/uv.html?manifest=*YOUR GIST URL*

Such interop! Wow!

Can we do this automatically?

Install gems

# Gemfile
gem 'iiif_manifest'
bundle install

(restart rails server)

(commit to git)

Add a route

  # config/routes.rb
  
  curation_concerns_basic_routes do
    member do
      get :manifest
    end
  end

Add a controller method

    skip_load_and_authorize_resource only: :manifest

    def manifest
      headers['Access-Control-Allow-Origin'] = '*'
      respond_to do |format|
        format.json { render json: manifest_builder.to_h }
      end
    end

    private

      def manifest_builder
        IIIFManifest::ManifestFactory.new(presenter)
      end

Add Presenter methods

  # app/presenter/musical_work_presenter.rb
  
  Hyrax::MemberPresenterFactory.file_presenter_class = FileSetPresenter

  def manifest_url
    manifest_helper.polymorphic_url([:manifest, self])
  end

  private

    def manifest_helper
      @manifest_helper ||= ManifestHelper.new(request.base_url)
    end

Add FileSetPresenter

class FileSetPresenter < Hyrax::FileSetPresenter
  def display_image
    return nil unless FileSet.exists?(id)
    # TODO: this is slow, find a better way (perhaps index iiif url):
    original_file = FileSet.find(id).original_file

    # TODO: We want url to be like https://libimages1.princeton.edu/loris/plum/0c%2F48%2F3j%2F48%2F8-intermediate_file.jp2/full/!200,200/0/default.jpg
    url = display_image_url(original_file)
    IIIFManifest::DisplayImage.new(url, width: 640, height: 480, iiif_endpoint: iiif_endpoint(original_file))
  end

  private

    def display_image_url(original_file, size = '600,')
      Riiif::Engine.routes.url_helpers.image_url(original_file.id,
                                                 host: request.base_url,
                                                 size: size)
    end

    def base_image_url(original_file)
      uri = Riiif::Engine.routes.url_helpers.info_url(original_file.id, host: request.base_url)
      # TODO: There should be a riiif route for this:
      uri.sub(%r{/info\.json\Z}, '')
    end

    def iiif_endpoint(original_file)
      IIIFManifest::IIIFEndpoint.new(base_image_url(original_file), profile: "http://iiif.io/api/image/2/level2.json")
    end
end

Add ManifestHelper

# app/builders/manifest_helper.rb
class ManifestHelper
  include Rails.application.routes.url_helpers
  include ActionDispatch::Routing::PolymorphicRoutes

  def initialize(hostname)
    @hostname = hostname
  end

  def polymorphic_url(record, opts = {})
    opts[:host] ||= @hostname
    super(record, opts)
  end
end

(restart server)

Why was that needed?

presenters don't have a pointer to the request/controller object. This has come up before. Somebody should fix it.

Does it work?

universalviewer.io/uv.html?manifest=http://localhost:3000/concern/musical_works/jd472w44j/manifest.json