Skip to content

Commit

Permalink
Merge pull request #20 from cbeer/classify-resolvers
Browse files Browse the repository at this point in the history
Convert resolvers into proper classes
  • Loading branch information
jcoyne committed Feb 2, 2015
2 parents 42eeccd + fa7fe9c commit 243026c
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 41 deletions.
8 changes: 8 additions & 0 deletions .travis.yml
@@ -0,0 +1,8 @@
notifications:
email: false

rvm:
- 2.2

sudo: false
language: ruby
12 changes: 6 additions & 6 deletions README.md
Expand Up @@ -36,7 +36,7 @@ Or install it yourself as:
By default Riiif is set to load images from the filesystem using the Riiif::FileSystemFileResolver.
You can configure how this resolver finds the files by setting this property:
```
Riiif::FileSystemFileResolver.base_path = '/opt/repository/images/'
Riiif::Image.file_resolver.base_path = '/opt/repository/images/'
```
When the Id passed in is "foo_image", then it will look for an image file using this glob:
```
Expand All @@ -46,18 +46,18 @@ When the Id passed in is "foo_image", then it will look for an image file using
### Images retrieved over HTTP
It's preferable to use files on the filesystem, because this avoids the overhead of downloading the file. If this is unavoidable, Riiif can be configured to fetch files from the network. To enable this behavior, configure Riiif to use an alternative resolver:
```
Riiif::Image.file_resolver = Riiif::HTTPFileResolver
Riiif::Image.file_resolver = Riiif::HTTPFileResolver.new
```
Then we configure the resolver with a mechanism for mapping the provided id to a url:
```
Riiif::HTTPFileResolver.id_to_uri = lambda do |id|
Riiif::Image.file_resolver.id_to_uri = lambda do |id|
"http://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/#{id}.jpg/600px-#{id}.jpg"
end
```

This file resolver caches the network files, so you will want to clear out the old files or the cache will expand until you run out of disk space.
Using a script like this would be a good idea: https://github.com/pulibrary/loris/blob/607567b921404a15a2111fbd7123604f4fdec087/bin/loris-cache_clean.sh
By default the cache is located in `tmp/network_files`. You can set the cache path like this: `Riiif::HTTPFileResolver.cache_path = '/var/cache'`
By default the cache is located in `tmp/network_files`. You can set the cache path like this: `Riiif::Image.file_resolver.cache_path = '/var/cache'`

## Usage

Expand Down Expand Up @@ -103,11 +103,11 @@ Create an initializer like this in `config/initializers/riiif_initializer.rb`

```ruby
# Tell RIIIF to get files via HTTP (not from the local disk)
Riiif::Image.file_resolver = Riiif::HTTPFileResolver
Riiif::Image.file_resolver = Riiif::HTTPFileResolver.new

# This tells RIIIF how to resolve the identifier to a URI in Fedora
DATASTREAM = 'imageContent'
Riiif::HTTPFileResolver.id_to_uri = lambda do |id|
Riiif::Image.file_resolver.id_to_uri = lambda do |id|
connection = ActiveFedora::Base.connection_for_pid(id)
host = connection.config[:url]
path = connection.api.datastream_content_url(id, DATASTREAM, {})
Expand Down
6 changes: 4 additions & 2 deletions Rakefile
Expand Up @@ -4,6 +4,8 @@ require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new(:spec)

require 'engine_cart/rake_task'
task :ci => ['engine_cart:generate'] do
# run the tests
task ci: ['engine_cart:generate'] do
Rake::Task["spec"].invoke
end

task default: :ci
2 changes: 1 addition & 1 deletion app/models/riiif/image.rb
Expand Up @@ -3,7 +3,7 @@ module Riiif
class Image

class_attribute :file_resolver, :info_service
self.file_resolver = FileSystemFileResolver
self.file_resolver = FileSystemFileResolver.new

# this is the default info service
# returns a hash with the original image dimensions.
Expand Down
19 changes: 10 additions & 9 deletions lib/riiif/file_system_file_resolver.rb
@@ -1,23 +1,24 @@
module Riiif
module FileSystemFileResolver
mattr_accessor :root, :base_path, :input_types

self.root = File.expand_path(File.join(File.dirname(__FILE__), '../..'))
self.base_path = File.join(root, 'spec/samples')
self.input_types = %W{png jpg tiff jp jp2}
class FileSystemFileResolver
attr_accessor :root, :base_path, :input_types

def initialize
@root = ::File.expand_path(::File.join(::File.dirname(__FILE__), '../..'))
@base_path = ::File.join(root, 'spec/samples')
@input_types = %W{png jpg tiff jp jp2}
end

def self.find(id)
def find(id)
Riiif::File.new(path(id))
end

def self.path(id)
def path(id)
search = pattern(id)
Dir.glob(search).first || raise(ImageNotFoundError, search)
end


def self.pattern(id)
def pattern(id)
raise ArgumentError, "Invalid characters in id `#{id}`" unless /^[\w\-:]+$/.match(id)
::File.join(base_path, "#{id}.{#{input_types.join(',')}}")
end
Expand Down
28 changes: 16 additions & 12 deletions lib/riiif/http_file_resolver.rb
Expand Up @@ -2,32 +2,36 @@
require 'active_support/core_ext/file/atomic'

module Riiif
module HTTPFileResolver
class HTTPFileResolver

# Set a lambda that maps the first parameter (id) to a URL
# Example:
#
# Riiif::HTTPFileResolver.id_to_uri = lambda do |id|
# resolver = Riiif::HTTPFileResolver.new
# resolver.id_to_uri = lambda do |id|
# "http://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/#{id}.jpg/600px-#{id}.jpg"
# end
#
mattr_accessor :id_to_uri
attr_accessor :id_to_uri

mattr_accessor :cache_path
self.cache_path = 'tmp/network_files'
attr_accessor :cache_path

def initialize
@cache_path = 'tmp/network_files'
end

def self.find(id)
remote = RemoteFile.new(uri(id))
def find(id)
remote = RemoteFile.new(uri(id), cache_path: cache_path)
Riiif::File.new(remote.fetch)
end

class RemoteFile
include ActiveSupport::Benchmarkable
delegate :logger, to: :Rails
attr_reader :url
def initialize(url)
attr_reader :url, :cache_path
def initialize(url, options = {})
@url = url
@cache_path = options[:cache_path]
end

def fetch
Expand All @@ -42,13 +46,13 @@ def ext
end

def file_name
@cache_file_name ||= ::File.join(HTTPFileResolver.cache_path, Digest::MD5.hexdigest(url)+"#{ext}")
@cache_file_name ||= ::File.join(cache_path, Digest::MD5.hexdigest(url)+"#{ext}")
end

def download_file
ensure_cache_path(::File.dirname(file_name))
benchmark ("Riiif downloaded #{url}") do
::File.atomic_write(file_name, HTTPFileResolver.cache_path) do |local|
::File.atomic_write(file_name, cache_path) do |local|
begin
Kernel::open(url) do |remote|
while chunk = remote.read(8192)
Expand All @@ -71,7 +75,7 @@ def ensure_cache_path(path)

protected

def self.uri(id)
def uri(id)
raise "Must set the id_to_uri lambda" if id_to_uri.nil?
id_to_uri.call(id)
end
Expand Down
4 changes: 2 additions & 2 deletions spec/models/file_system_file_resolver_spec.rb
@@ -1,13 +1,13 @@
require 'spec_helper'

describe Riiif::FileSystemFileResolver do
subject { Riiif::FileSystemFileResolver }
subject { Riiif::FileSystemFileResolver.new }
it "should raise an error when the file isn't found" do
expect{subject.find('1234')}.to raise_error Riiif::ImageNotFoundError
end

it "should get the jpeg2000 file" do
expect(subject.find('world').path).to eq Riiif::FileSystemFileResolver.root + '/spec/samples/world.jp2'
expect(subject.find('world').path).to eq subject.root + '/spec/samples/world.jp2'
end

it "should accept ids with dashes" do
Expand Down
10 changes: 4 additions & 6 deletions spec/models/http_file_resolver_spec.rb
@@ -1,12 +1,10 @@
require 'spec_helper'

describe Riiif::HTTPFileResolver do
subject { Riiif::HTTPFileResolver }
around do |example|
old_value = Riiif::HTTPFileResolver.id_to_uri
Riiif::HTTPFileResolver.id_to_uri = lambda {|id| id}
example.run
Riiif::HTTPFileResolver.id_to_uri = old_value
subject { Riiif::HTTPFileResolver.new }

before do
subject.id_to_uri = lambda {|id| id}
end

it "should raise an error when the file isn't found" do
Expand Down
6 changes: 3 additions & 3 deletions spec/models/image_spec.rb
Expand Up @@ -33,13 +33,13 @@

context "using HTTPFileResolver" do
before do
Riiif::Image.file_resolver = Riiif::HTTPFileResolver
Riiif::HTTPFileResolver.id_to_uri = lambda do |id|
Riiif::Image.file_resolver = Riiif::HTTPFileResolver.new
Riiif::Image.file_resolver.id_to_uri = lambda do |id|
"http://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/#{id}.jpg/600px-#{id}.jpg"
end
end
after do
Riiif::Image.file_resolver = Riiif::FileSystemFileResolver
Riiif::Image.file_resolver = Riiif::FileSystemFileResolver.new
end

describe "get info" do
Expand Down

0 comments on commit 243026c

Please sign in to comment.