djatoka 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 11aaf1e80818a81069ad5935756e293a80b87dbf
4
+ data.tar.gz: 850d1b033f7c80a5ac496e1fcfa3902ad1040bb8
5
+ SHA512:
6
+ metadata.gz: ac8a7b99068dd81346499e49302d00a5bced11ee481744f8a3698e8f4ff66f93adcffbe6e8a2fa741c1a4bc96e012e518088116f576f4232a4b808f39c996288
7
+ data.tar.gz: 3e0231731a8cbe8154d37895994a2e8b0d097eaae00a40866dd3bf15a5e64302bda280e16e7991e05a1de3e258e938c2d1b949a8fbff314589a21cb1e2444373
data/.gitignore CHANGED
@@ -21,5 +21,7 @@ pkg
21
21
  ## PROJECT::SPECIFIC
22
22
  .redcar
23
23
  .rvmrc
24
+ .ruby-gemset
25
+ .ruby-version
24
26
 
25
27
  .rbx
data/Gemfile.lock CHANGED
@@ -1,10 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- djatoka (0.2.0)
4
+ djatoka (0.2.2)
5
5
  addressable
6
6
  hashie
7
7
  json
8
+ mime-types
8
9
  trollop
9
10
 
10
11
  GEM
@@ -13,10 +14,12 @@ GEM
13
14
  activesupport (3.2.13)
14
15
  i18n (= 0.6.1)
15
16
  multi_json (~> 1.0)
16
- addressable (2.3.3)
17
+ addressable (2.3.4)
17
18
  bourne (1.4.0)
18
19
  mocha (~> 0.13.2)
19
20
  coderay (1.0.9)
21
+ equivalent-xml (0.3.0)
22
+ nokogiri (>= 1.4.3)
20
23
  fakeweb (1.3.0)
21
24
  ffi (1.6.0-java)
22
25
  hashie (2.0.3)
@@ -25,9 +28,12 @@ GEM
25
28
  json (1.7.7-java)
26
29
  metaclass (0.0.1)
27
30
  method_source (0.8.1)
31
+ mime-types (1.22)
28
32
  mocha (0.13.3)
29
33
  metaclass (~> 0.0.1)
30
34
  multi_json (1.7.2)
35
+ nokogiri (1.5.9)
36
+ nokogiri (1.5.9-java)
31
37
  pry (0.9.12)
32
38
  coderay (~> 1.0.5)
33
39
  method_source (~> 0.8)
@@ -59,6 +65,7 @@ PLATFORMS
59
65
 
60
66
  DEPENDENCIES
61
67
  djatoka!
68
+ equivalent-xml
62
69
  fakeweb
63
70
  mocha
64
71
  pry
data/README.rdoc CHANGED
@@ -90,6 +90,46 @@ Tested with the following Ruby versions:
90
90
  - 1.8.7-p302
91
91
  - 1.9.2-p0
92
92
 
93
+ == IIIF Support
94
+ This gem can translate parameters from {International Image Interoperability Framework (IIIF)}[http://www-sul.stanford.edu/iiif/image-api/] requests into Djatoka requests. It follows the same pattern as creating a Djatoka::Region
95
+
96
+ === IIIF Example
97
+ # Create a resolver object with a URL.
98
+ resolver = Djatoka::Resolver.new('http://african.lanl.gov/adore-djatoka/resolver')
99
+
100
+ # A known good identifier
101
+ identifier = 'info:lanl-repo/ds/5aa182c2-c092-4596-af6e-e95d2e263de3'
102
+
103
+ # IIIF Image Request
104
+ # Create a IiifRequest with the resolver and id
105
+ iiif_request = Djatoka::IiifRequest.new(resolver, identifier)
106
+
107
+ # Set IIIF parameters and create a Djatoka::Region
108
+ # Note: All IIIF parameters are required before creating a Djatoka::Region
109
+ djatoka_region = iiif_request.region('full').size('full').rotation('0').quality('native').format('jpg').djatoka_region
110
+
111
+ # Use the Djatoka::Region as normal
112
+ djatoka_region.url
113
+
114
+ # IIIF Info Request (Metadata)
115
+ # First, create a Djatoka::Metadata object and perform the request to the server for metadata.
116
+ metadata = resolver.metadata(identifier).perform
117
+
118
+ # Create a IIIF Info json response string
119
+ # Set values to optional fields by passing in a block and calling setters on the yielded Mash
120
+ json = metadata.to_iiif_json do |info|
121
+ info.tile_width = 512
122
+ info.tile_height = 512
123
+ info.formats = ['jpg', 'png']
124
+ info.qualities = ['native', 'grey']
125
+ info.profile = 'http://library.stanford.edu/iiif/image-api/compliance.html#level1'
126
+ info.image_host = 'http://myserver.com/image'
127
+ end
128
+
129
+ # If you want the xml flavor of a IIIF Info response, use
130
+ xml = metadata.to_iiif_xml
131
+ # It can be called with the same type of block as #to_iiif_json
132
+
93
133
  == Commandline
94
134
 
95
135
  There is also a little commandline utility for outputting the OpenURL.
@@ -102,14 +142,13 @@ There is also a little commandline utility for outputting the OpenURL.
102
142
 
103
143
  $ djatoka_url --help
104
144
 
105
-
106
145
  == TODO
107
146
  - Testing the view helpers.
108
147
  - View more examples of images where the dwtLevels differ from the Djatoka levels.
109
148
 
110
- == Author
149
+ == Authors
111
150
 
112
- Jason Ronallo
151
+ Jason Ronallo, Willy Mene
113
152
 
114
153
  == Copyright
115
154
 
data/djatoka.gemspec CHANGED
@@ -5,9 +5,9 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{djatoka}
8
- s.version = "0.2.2"
9
- s.authors = ["Jason Ronallo"]
10
- s.email = %q{jronallo@gmail.com}
8
+ s.version = "0.2.3"
9
+ s.authors = ["Jason Ronallo", "Willy Mene"]
10
+ s.email = %q{jronallo@gmail.com wmene@stanford.edu}
11
11
  s.homepage = %q{http://github.com/jronallo/djatoka}
12
12
  s.summary = %q{Djatoka image server helpers for Ruby and Rails.}
13
13
  s.description = %q{The djatoka library provides some simple methods for creation of the OpenURLs needed to communicate with the Djatoka image server.}
@@ -16,15 +16,17 @@ Gem::Specification.new do |s|
16
16
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
17
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
18
  s.require_paths = ["lib"]
19
-
19
+
20
20
  s.add_dependency "addressable"
21
21
  s.add_dependency "hashie"
22
22
  s.add_dependency "json"
23
-
23
+ s.add_dependency "mime-types"
24
+
24
25
  s.add_dependency "trollop"
25
26
 
26
27
  s.add_development_dependency "mocha"
27
28
  s.add_development_dependency "fakeweb"
28
29
  s.add_development_dependency "shoulda"
30
+ s.add_development_dependency "equivalent-xml"
29
31
  end
30
32
 
@@ -0,0 +1,163 @@
1
+
2
+ # For rotation param testing. Allows you to do the following with String:
3
+ # '123.456'.numeric? => true
4
+ class String
5
+ def numeric?
6
+ return true if self =~ /^\d+$/
7
+ true if Float(self) rescue false
8
+ end
9
+ end
10
+
11
+ module Djatoka
12
+
13
+ class IiifException < Exception; end
14
+
15
+ class IiifInvalidParam < IiifException
16
+
17
+ def initialize (param_name, value=nil)
18
+ @param_name = param_name
19
+ @value = value
20
+ end
21
+
22
+ def to_s
23
+ "#{@param_name.capitalize} is invalid: " << @value.to_s
24
+ end
25
+
26
+ end
27
+
28
+ # A class for translating IIIF parameters into a Djatoka::Region object.
29
+ #
30
+ # * See the {documentation for the IIIF API}[http://www-sul.stanford.edu/iiif/image-api/#size]
31
+ #
32
+ # It behaves like the Djatoka::Region object, in that you can chain methods together when setting params.
33
+ # Once you've set all the params, call #djatoka_region to translate the parameters. Validation of
34
+ # values occurs in this method, and a Djatoka::IiifInvalidParam exception is raised if any of the values
35
+ # are invalid.
36
+ #
37
+ # * Usage example
38
+ # resolver = Djatoka::Resolver.new('http://server.edu/adore-djatoka/resolver')
39
+ # id = 'someImageId1234'
40
+ #
41
+ # request = Djatoka::IiifRequest.new(resolver, id)
42
+ # djatoka_region = request.region('full').size('full').rotation('0').quality('native').format('jpg').djatoka_region
43
+ class IiifRequest
44
+
45
+ ALL_PARAMS = Set.new(['region', 'size', 'rotation', 'quality', 'format'])
46
+
47
+ attr_accessor :iiif_params
48
+
49
+ # You can set the params for the request in 2 ways:
50
+ # 1. Pass in params as a hash with the IIIF parameters {:id => 'some/id', :region => 'full'...}
51
+ # 2. Do not pass in params, and use the chain methods to set each value
52
+ def initialize(resolver, id, params = nil)
53
+ @id = id
54
+ @resolver = resolver
55
+ @iiif_params = Hashie::Mash.new
56
+
57
+ if(!params.nil? && params.is_a?(Hash))
58
+ params.keys.each do |k|
59
+ self.send("#{k}", params[k])
60
+ end
61
+ end
62
+ # else, params is nil, the caller will set each value
63
+ end
64
+
65
+ def id(v)
66
+ @iiif_params[:id] = v
67
+ self
68
+ end
69
+
70
+ def region(v)
71
+ @iiif_params[:region] = v
72
+ self
73
+ end
74
+
75
+ def size(v)
76
+ @iiif_params[:size] = v
77
+ self
78
+ end
79
+
80
+ def rotation(v)
81
+ @iiif_params[:rotation] = v
82
+ self
83
+ end
84
+
85
+ def quality(v)
86
+ @iiif_params[:quality] = v
87
+ self
88
+ end
89
+
90
+ def format(v)
91
+ @iiif_params[:format] = v
92
+ self
93
+ end
94
+
95
+ def all_params_present?
96
+ names = Set.new(@iiif_params.keys)
97
+ names == ALL_PARAMS
98
+ end
99
+
100
+ def djatoka_region
101
+ unless(all_params_present?)
102
+ current = Set.new(@iiif_params.keys)
103
+ missing = (ALL_PARAMS - current).to_a
104
+ msg = "Invalid IIIF request. The following params are missing: " << missing.join(',')
105
+ raise IiifException.new(msg)
106
+ end
107
+
108
+ region = @resolver.region(@iiif_params[:id])
109
+
110
+ if(@iiif_params[:region] =~ /^(\d+),(\d+),(\d+),(\d+)$/)
111
+ region.region("#{$2},#{$1},#{$4},#{$3}")
112
+ elsif(!(@iiif_params[:region] =~ /^full$/i))
113
+ raise IiifInvalidParam.new "region", @iiif_params[:region]
114
+ end
115
+
116
+ s = @iiif_params[:size]
117
+ case s
118
+ when /^full$/i
119
+ s #noop
120
+ when /^(\d+),$/
121
+ region.scale( ["#{$1}", "0"] ) #w => w,0
122
+ when /^,(\d+)$/
123
+ region.scale( ["0", "#{$1}"] ) #h => 0,h
124
+ when /^pct:(\d+)$/i
125
+ dj_scale = $1.to_f / 100.0
126
+ region.scale(dj_scale.to_s)
127
+ when /^(\d+),(\d+)$/
128
+ region.scale("#{$1},#{$2}")
129
+ # TODO Best Fit: when /^!(\d+),(\d+)$/
130
+ else
131
+ raise IiifInvalidParam.new "size", s
132
+ end
133
+
134
+ unless(@iiif_params[:rotation].numeric?)
135
+ raise IiifInvalidParam.new "rotation", @iiif_params[:rotation]
136
+ end
137
+ region.rotate(@iiif_params[:rotation])
138
+
139
+ f = @iiif_params[:format]
140
+ if(f)
141
+ if(f =~ /\//)
142
+ type = MIME::Types[f].first
143
+ else
144
+ type = MIME::Types.type_for(@iiif_params[:format]).first
145
+ end
146
+ raise IiifInvalidParam.new("format", f) if(type.nil?)
147
+ else
148
+ #default to jpg or let djatoka determine default
149
+ type = MIME::Types.type_for('jpg').first
150
+ end
151
+ region.format(type.to_s)
152
+
153
+ unless(@iiif_params[:quality] =~ /^(native|color|grey|bitonal)$/i)
154
+ raise IiifInvalidParam.new 'quality', @iiif_params[:quality]
155
+ end
156
+
157
+ region
158
+
159
+ end
160
+
161
+ end
162
+
163
+ end
@@ -56,7 +56,7 @@ class Djatoka::Metadata
56
56
  def all_levels
57
57
  perform if !response # if we haven't already performed the metadata query do it now
58
58
  levels_hash = Hashie::Mash.new
59
- levels_i = levels.to_i
59
+ levels_i = levels.to_i
60
60
  (0..levels_i).each do |level_num|
61
61
  level_height = height.to_i
62
62
  level_width = width.to_i
@@ -71,9 +71,94 @@ class Djatoka::Metadata
71
71
  end
72
72
  levels_hash
73
73
  end
74
-
74
+
75
75
  def max_level
76
- all_levels.keys.sort.last
76
+ all_levels.keys.sort.last
77
+ end
78
+
79
+ # Builds a String containing the JSON response to a IIIF Image Information Request
80
+ #
81
+ # * {Documentation about the Image Info Request}[http://www-sul.stanford.edu/iiif/image-api/#info]
82
+ #
83
+ # It will fill in the required fields of identifier, width, and height. It will also fill in
84
+ # the scale_factors as determined from Djatoka::Metadata#levels
85
+ # The method yields a Mash where you can set the value of the optional fields. Here's an example:
86
+ #
87
+ # metadata.to_iiif_xml do |info|
88
+ # info.tile_width = 512
89
+ # info.tile_height = 512
90
+ # info.formats = ['jpg', 'png']
91
+ # info.qualities = ['native', 'grey']
92
+ # info.profile = 'http://library.stanford.edu/iiif/image-api/compliance.html#level1'
93
+ # info.image_host = 'http://myserver.com/image'
94
+ # end
95
+ def to_iiif_json(&block)
96
+ info = Hashie::Mash.new
97
+ info.identifier = @rft_id
98
+ info.width = @width.to_i
99
+ info.height = @height.to_i
100
+ info.scale_factors = levels_as_i
101
+ # optional fields map directly to json from the Mash
102
+ yield(info)
103
+
104
+ # convert strings to ints for tile width and height
105
+ info.tile_width = info.tile_width.to_i if(info.tile_width?)
106
+ info.tile_height = info.tile_height.to_i if(info.tile_height?)
107
+ JSON.pretty_generate(info)
108
+ end
109
+
110
+ # Builds a String containing the xml response to a IIIF Image Information Request
111
+ #
112
+ # * {Documentation about the Image Info Request}[http://www-sul.stanford.edu/iiif/image-api/#info]
113
+ #
114
+ # It will fill in the required fields of identifier, width, and height. It will also fill in
115
+ # the scale_factors as determined from Djatoka::Metadata#levels
116
+ # The method yields a Mash where you can set the values of the optional fields. Here's an example:
117
+ #
118
+ # metadata.to_iiif_json do |info|
119
+ # info.tile_width = 512
120
+ # info.tile_height = 512
121
+ # info.formats = ['jpg', 'png']
122
+ # info.qualities = ['native', 'grey']
123
+ # info.profile = 'http://library.stanford.edu/iiif/image-api/compliance.html#level1'
124
+ # info.image_host = 'http://myserver.com/image'
125
+ # end
126
+ def to_iiif_xml(&block)
127
+ builder = Nokogiri::XML::Builder.new do |xml|
128
+ info = Hashie::Mash.new
129
+ yield(info)
130
+ xml.info('xmlns' => 'http://library.stanford.edu/iiif/image-api/ns/') {
131
+ xml.identifier @rft_id
132
+ xml.width @width
133
+ xml.height @height
134
+ xml.scale_factors {
135
+ levels_as_i.each {|lvl| xml.scale_factor lvl}
136
+ }
137
+
138
+ #optional fields
139
+ xml.tile_width info.tile_width if(info.tile_width?)
140
+ xml.tile_height info.tile_height if(info.tile_height?)
141
+ if(info.formats?)
142
+ xml.formats {
143
+ info.formats.each {|mt| xml.format mt}
144
+ }
145
+ end
146
+ if(info.qualities?)
147
+ xml.qualities {
148
+ info.qualities.each {|q| xml.quality q}
149
+ }
150
+ end
151
+ xml.profile info.profile if(info.profile?)
152
+ xml.image_host info.image_host if(info.image_host?)
153
+ }
154
+ end
155
+ builder.to_xml
156
+ end
157
+
158
+ private
159
+ # Just the levels themselves, as a sorted array of integers
160
+ def levels_as_i
161
+ all_levels.keys.map{ |l| l.to_i}.sort
77
162
  end
78
163
 
79
164
  end
@@ -63,6 +63,16 @@ class Djatoka::Resolver
63
63
  Djatoka::Region.new(self, rft_id, params).uri
64
64
  end
65
65
 
66
+ # Shortcut for creating a Djatoka::Region from a Hash of Iiif parameters.
67
+ def iiif_region(rft_id, params={})
68
+ Djatoka::IiifRequest.new(self, rft_id, params).djatoka_region
69
+ end
70
+
71
+ # Shortcut for creating an Addressable::URI from a Hash of Iiif parameters.
72
+ def iiif_uri(rft_id, params={})
73
+ Djatoka::IiifRequest.new(self, rft_id, params).djatoka_region.uri
74
+ end
75
+
66
76
  def base_uri_params
67
77
  params = {:host => host, :path => path, :scheme => scheme}
68
78
  params[:port] = port if port
data/lib/djatoka.rb CHANGED
@@ -52,17 +52,21 @@ end
52
52
  require 'net/http'
53
53
  require 'net/https'
54
54
  require 'uri'
55
+ require 'set'
55
56
 
56
57
  require 'djatoka/net'
57
58
  require 'djatoka/resolver'
58
59
  require 'djatoka/metadata'
59
60
  require 'djatoka/common'
60
61
  require 'djatoka/region'
62
+ require 'djatoka/iiif_request'
61
63
 
62
64
  require 'addressable/uri'
63
65
  require 'addressable/template'
64
66
  require 'json'
67
+ require 'nokogiri'
65
68
  require 'hashie'
69
+ require 'mime/types'
66
70
 
67
71
 
68
72
  if defined? Rails
data/test/helper.rb CHANGED
@@ -3,6 +3,7 @@ require 'test/unit'
3
3
  require 'shoulda'
4
4
  require 'fakeweb'
5
5
  require 'pry'
6
+ require 'equivalent-xml'
6
7
 
7
8
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
8
9
  $LOAD_PATH.unshift(File.dirname(__FILE__))
@@ -39,7 +40,7 @@ end
39
40
 
40
41
  FakeWeb.register_uri(:get, "http://african.lanl.gov/adore-djatoka/resolver?rft_id=ua023_015-006-bx0003-014-075&svc_id=info%3Alanl-repo%2Fsvc%2FgetMetadata&url_ver=Z39.88-2004",
41
42
  :response => File.read('test/fixtures/ua023_015-006-bx0003-014-075-metadata.json'))
42
-
43
+
43
44
  FakeWeb.register_uri(:get, "http://african.lanl.gov/adore-djatoka/resolver?rft_id=asdf&svc_id=info%3Alanl-repo%2Fsvc%2FgetMetadata&url_ver=Z39.88-2004",
44
45
  :response => File.read('test/fixtures/empty-metadata.json'))
45
46
  FakeWeb.register_uri(:get, "http://african.lanl.gov/adore-djatoka/resolver?url_ver=Z39.88-2004&svc_id=info%3Alanl-repo%2Fsvc%2Fping&rft_id=asdf",
@@ -0,0 +1,173 @@
1
+ require 'helper'
2
+
3
+ class TestDjatokaIiifRequest < Test::Unit::TestCase
4
+ with_a_resolver do
5
+ context 'creates Djatoka::Region objects' do
6
+ setup do
7
+ @req = Djatoka::IiifRequest.new(@resolver, @identifier)
8
+ end
9
+
10
+ context 'from a IIIF request with all defaults' do
11
+ setup do
12
+ @region = @req.region('full').size('full').rotation('0').quality('native').format('jpg').djatoka_region
13
+ end
14
+
15
+ should 'set region to nil from full' do
16
+ assert_nil @region.query.region
17
+ end
18
+
19
+ should 'set size to nil from full' do
20
+ assert_nil @region.query.scale
21
+ end
22
+
23
+ should 'set rotation to 0' do
24
+ assert_equal '0', @region.query.rotate
25
+ end
26
+
27
+ should 'set format to image/jpg' do
28
+ assert_equal 'image/jpeg', @region.query.format
29
+ end
30
+
31
+ end
32
+
33
+ context 'translates region parameters' do
34
+ setup do
35
+ @req.size('full').rotation('0').quality('native').format('jpg')
36
+ end
37
+
38
+ should 'set x,y,w,h requests' do
39
+ reg = @req.region('10,20,50,100').djatoka_region
40
+ assert_equal '20,10,100,50', reg.query.region
41
+ end
42
+
43
+ should 'raise an exception if the region does not fit the x,y,w,h format, or is not "full"' do
44
+ assert_raise Djatoka::IiifInvalidParam do
45
+ @req.region('blah').djatoka_region
46
+ end
47
+ end
48
+ end
49
+
50
+ context 'translates size parameters' do
51
+ setup do
52
+ @req.region('10,20,50,100').rotation('0').quality('native').format('jpg')
53
+ end
54
+
55
+ should 'set "w," requests to the correct scale value' do
56
+ reg = @req.size('800,').djatoka_region
57
+ assert_equal '800,0', reg.query.scale
58
+ end
59
+
60
+ should 'set ",h" requests to the correct scale value' do
61
+ reg = @req.size(',900').djatoka_region
62
+ assert_equal '0,900', reg.query.scale
63
+ end
64
+
65
+ should 'set "pct:n" requests to the correct scale value' do
66
+ reg = @req.size('pct:75').djatoka_region
67
+ assert_equal '0.75', reg.query.scale
68
+
69
+ reg = @req.size('pct:125').djatoka_region
70
+ assert_equal '1.25', reg.query.scale
71
+ end
72
+
73
+ should 'set "w,h" requests to the correct scale value' do
74
+ reg = @req.size('1024,768').djatoka_region
75
+ assert_equal '1024,768', reg.query.scale
76
+ end
77
+
78
+ should 'raise an exception if the value cannot be parsed into a Float' do
79
+ assert_raise Djatoka::IiifInvalidParam do
80
+ @req.size('pct:0.75').djatoka_region
81
+ end
82
+ end
83
+
84
+ end
85
+
86
+ context 'translates rotation parameters' do
87
+ setup do
88
+ @req.region('10,20,50,100').size('800,').quality('native').format('jpg')
89
+ end
90
+
91
+ should 'set values that are numeric' do
92
+ reg = @req.rotation('90').djatoka_region
93
+ assert_equal '90', reg.query.rotate
94
+
95
+ reg = @req.rotation('270').djatoka_region
96
+ assert_equal '270', reg.query.rotate
97
+ end
98
+
99
+ should 'raise an exception if the value is not numeric' do
100
+ assert_raise Djatoka::IiifInvalidParam do
101
+ @req.rotation('blah').djatoka_region
102
+ end
103
+ end
104
+ end
105
+
106
+ context 'translates format parameters' do
107
+ setup do
108
+ @req.region('full').size('full').rotation('0').quality('native')
109
+ end
110
+
111
+ should 'set the format from a valid extension as from the end of a URL' do
112
+ reg = @req.format('image.png').djatoka_region
113
+ assert_equal 'image/png', reg.query.format
114
+ end
115
+
116
+ should 'set the format from a valid mime-type as from the "Accept:" HTTP header' do
117
+ reg = @req.format('image/tiff').djatoka_region
118
+ assert_equal 'image/tiff', reg.query.format
119
+ end
120
+
121
+ should 'raise an exception if the value is not a valid mime type extension' do
122
+ assert_raise Djatoka::IiifInvalidParam do
123
+ @req.format('nobody').djatoka_region
124
+ end
125
+ end
126
+
127
+ should 'raise an exception if the value is not a valid mime type value' do
128
+ assert_raise Djatoka::IiifInvalidParam do
129
+ @req.format('image/blahtype').djatoka_region
130
+ end
131
+ end
132
+ end
133
+
134
+ context 'validates quaility parameters' do
135
+ setup do
136
+ @req.region('full').size('full').rotation('0').format('jpg')
137
+ end
138
+
139
+ should 'not raise when the quality is valid' do
140
+ assert_nothing_raised do
141
+ @req.quality('color').djatoka_region
142
+ end
143
+ end
144
+
145
+ should 'raise an exception when the quality is invalid' do
146
+ assert_raise Djatoka::IiifInvalidParam do
147
+ @req.quality('3d').djatoka_region
148
+ end
149
+ end
150
+ end
151
+
152
+ context '#all_params_present?' do
153
+ should 'return true when all the valid params have been set' do
154
+ @req.region('full').size('full').rotation('0').quality('native').format('jpg')
155
+ assert @req.all_params_present?
156
+ end
157
+
158
+ should 'return false when params are missing' do
159
+ @req.region('full').size('full').quality('native').format('jpg')
160
+ assert_equal false, @req.all_params_present?
161
+ end
162
+ end
163
+
164
+ context '#djatoka_region' do
165
+ should 'raise a IiifException if a required param is missing from the request' do
166
+ assert_raise Djatoka::IiifException do
167
+ @req.size('800,').djatoka_region
168
+ end
169
+ end
170
+ end
171
+ end #context
172
+ end #with_a_resolver
173
+ end
@@ -60,14 +60,14 @@ class TestDjatokaMetadata < Test::Unit::TestCase
60
60
  end
61
61
  end
62
62
 
63
- context 'using net::https' do
64
- should 'get metadata when using an https URI' do
63
+ context 'using net::https' do
64
+ should 'get metadata when using an https URI' do
65
65
  Djatoka.use_curb=false
66
66
  resolver = Djatoka::Resolver.new('https://scrc.lib.ncsu.edu/adore-djatoka/resolver')
67
67
  metadata_obj = resolver.metadata('0004817')
68
68
  metadata = metadata_obj.perform
69
69
  assert_equal('10669', metadata.height)
70
- end
70
+ end
71
71
  end
72
72
 
73
73
  context 'determining all the levels for a particular metadata response' do
@@ -92,7 +92,7 @@ class TestDjatokaMetadata < Test::Unit::TestCase
92
92
  should 'know which is the max level' do
93
93
  assert_equal "6", @metadata.max_level
94
94
  end
95
-
95
+
96
96
  should 'return appropriate height and width for all levels when levels and dwt_levels do not match' do
97
97
  levels = {"0"=>{"height"=>58, "width"=>37},
98
98
  "1"=>{"height"=>115, "width"=>74},
@@ -104,10 +104,85 @@ class TestDjatokaMetadata < Test::Unit::TestCase
104
104
  assert_equal levels, returned_levels
105
105
 
106
106
  end
107
-
107
+
108
108
  end # levels
109
109
 
110
+ context 'IIIF Image Information Requests' do
111
+ setup do
112
+ @metadata_obj = @resolver.metadata(@identifier)
113
+ @metadata = @metadata_obj.perform
114
+ end
115
+
116
+ should 'create json responses' do
117
+ iiif_json = <<-EOF
118
+ {
119
+ "identifier": "info:lanl-repo/ds/5aa182c2-c092-4596-af6e-e95d2e263de3",
120
+ "width": 5120,
121
+ "height": 3372,
122
+ "scale_factors": [ 0,1,2,3,4,5,6 ],
123
+ "tile_width": 512,
124
+ "tile_height": 512,
125
+ "formats": [ "jpg", "png" ],
126
+ "qualities": [ "native", "grey" ],
127
+ "profile": "http://library.stanford.edu/iiif/image-api/compliance.html#level1",
128
+ "image_host": "http://myserver.com/image"
129
+ }
130
+ EOF
131
+ expected = JSON.parse(iiif_json)
132
+
133
+ str = @metadata.to_iiif_json do |info|
134
+ info.tile_width = '512'
135
+ info.tile_height = 512 # tile_* can be string or int
136
+ info.formats = ['jpg', 'png']
137
+ info.qualities = ['native', 'grey']
138
+ info.profile = 'http://library.stanford.edu/iiif/image-api/compliance.html#level1'
139
+ info.image_host = 'http://myserver.com/image'
140
+ end
141
+ assert_equal expected, JSON.parse(str)
142
+ end
143
+
144
+ should 'create xml responses' do
145
+ iiif_xml =<<-EOXML
146
+ <info xmlns="http://library.stanford.edu/iiif/image-api/ns/">
147
+ <identifier>info:lanl-repo/ds/5aa182c2-c092-4596-af6e-e95d2e263de3</identifier>
148
+ <width>5120</width>
149
+ <height>3372</height>
150
+ <scale_factors>
151
+ <scale_factor>0</scale_factor>
152
+ <scale_factor>1</scale_factor>
153
+ <scale_factor>2</scale_factor>
154
+ <scale_factor>3</scale_factor>
155
+ <scale_factor>4</scale_factor>
156
+ <scale_factor>5</scale_factor>
157
+ <scale_factor>6</scale_factor>
158
+ </scale_factors>
159
+ <tile_width>512</tile_width>
160
+ <tile_height>512</tile_height>
161
+ <formats>
162
+ <format>jpg</format>
163
+ <format>png</format>
164
+ </formats>
165
+ <qualities>
166
+ <quality>native</quality>
167
+ <quality>grey</quality>
168
+ </qualities>
169
+ <profile>http://library.stanford.edu/iiif/image-api/compliance.html#level1</profile>
170
+ <image_host>http://myserver.com/image</image_host>
171
+ </info>
172
+ EOXML
173
+
174
+ str = @metadata.to_iiif_xml do |info|
175
+ info.tile_width = '512'
176
+ info.tile_height = 512 # tile_* can be string or int
177
+ info.formats = ['jpg', 'png']
178
+ info.qualities = ['native', 'grey']
179
+ info.profile = 'http://library.stanford.edu/iiif/image-api/compliance.html#level1'
180
+ info.image_host = 'http://myserver.com/image'
181
+ end
182
+ assert EquivalentXml.equivalent?(str, iiif_xml)
183
+ end
184
+ end #IIIF Info Responses
185
+
110
186
  end #with_a_resolver
111
187
 
112
188
  end
113
-
@@ -58,6 +58,26 @@ class TestDjatokaResolver < Test::Unit::TestCase
58
58
  assert @resolver.region_uri(@identifier).is_a? Addressable::URI
59
59
  end
60
60
 
61
+ context 'Iiif Requests' do
62
+ setup do
63
+ @iiif = {
64
+ :region => 'full',
65
+ :size => 'full',
66
+ :rotation => '0',
67
+ :quality => 'native',
68
+ :format => 'jpg'
69
+ }
70
+ end
71
+
72
+ should 'create a region from a hash of IIIF parameters' do
73
+ assert @resolver.iiif_region(@identifier, @iiif).is_a? Djatoka::Region
74
+ end
75
+
76
+ should 'create a region uri from a hash of IIIF parameters' do
77
+ assert @resolver.iiif_uri(@identifier, @iiif).is_a? Addressable::URI
78
+ end
79
+ end
80
+
61
81
  end #context a Djatoka::Resolver
62
82
 
63
83
  context 'a resolver with a port number' do
metadata CHANGED
@@ -1,131 +1,145 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: djatoka
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
5
- prerelease:
4
+ version: 0.2.3
6
5
  platform: ruby
7
6
  authors:
8
7
  - Jason Ronallo
8
+ - Willy Mene
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-08 00:00:00.000000000 Z
12
+ date: 2013-04-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: addressable
16
16
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
17
  requirements:
19
- - - ! '>='
18
+ - - '>='
20
19
  - !ruby/object:Gem::Version
21
20
  version: '0'
22
21
  type: :runtime
23
22
  prerelease: false
24
23
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
24
  requirements:
27
- - - ! '>='
25
+ - - '>='
28
26
  - !ruby/object:Gem::Version
29
27
  version: '0'
30
28
  - !ruby/object:Gem::Dependency
31
29
  name: hashie
32
30
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
31
  requirements:
35
- - - ! '>='
32
+ - - '>='
36
33
  - !ruby/object:Gem::Version
37
34
  version: '0'
38
35
  type: :runtime
39
36
  prerelease: false
40
37
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
38
  requirements:
43
- - - ! '>='
39
+ - - '>='
44
40
  - !ruby/object:Gem::Version
45
41
  version: '0'
46
42
  - !ruby/object:Gem::Dependency
47
43
  name: json
48
44
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
45
  requirements:
51
- - - ! '>='
46
+ - - '>='
52
47
  - !ruby/object:Gem::Version
53
48
  version: '0'
54
49
  type: :runtime
55
50
  prerelease: false
56
51
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
52
  requirements:
59
- - - ! '>='
53
+ - - '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: mime-types
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '>='
60
68
  - !ruby/object:Gem::Version
61
69
  version: '0'
62
70
  - !ruby/object:Gem::Dependency
63
71
  name: trollop
64
72
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
73
  requirements:
67
- - - ! '>='
74
+ - - '>='
68
75
  - !ruby/object:Gem::Version
69
76
  version: '0'
70
77
  type: :runtime
71
78
  prerelease: false
72
79
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
80
  requirements:
75
- - - ! '>='
81
+ - - '>='
76
82
  - !ruby/object:Gem::Version
77
83
  version: '0'
78
84
  - !ruby/object:Gem::Dependency
79
85
  name: mocha
80
86
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
87
  requirements:
83
- - - ! '>='
88
+ - - '>='
84
89
  - !ruby/object:Gem::Version
85
90
  version: '0'
86
91
  type: :development
87
92
  prerelease: false
88
93
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
94
  requirements:
91
- - - ! '>='
95
+ - - '>='
92
96
  - !ruby/object:Gem::Version
93
97
  version: '0'
94
98
  - !ruby/object:Gem::Dependency
95
99
  name: fakeweb
96
100
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
101
  requirements:
99
- - - ! '>='
102
+ - - '>='
100
103
  - !ruby/object:Gem::Version
101
104
  version: '0'
102
105
  type: :development
103
106
  prerelease: false
104
107
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
108
  requirements:
107
- - - ! '>='
109
+ - - '>='
108
110
  - !ruby/object:Gem::Version
109
111
  version: '0'
110
112
  - !ruby/object:Gem::Dependency
111
113
  name: shoulda
112
114
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
115
  requirements:
115
- - - ! '>='
116
+ - - '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: equivalent-xml
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - '>='
116
131
  - !ruby/object:Gem::Version
117
132
  version: '0'
118
133
  type: :development
119
134
  prerelease: false
120
135
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
136
  requirements:
123
- - - ! '>='
137
+ - - '>='
124
138
  - !ruby/object:Gem::Version
125
139
  version: '0'
126
140
  description: The djatoka library provides some simple methods for creation of the
127
141
  OpenURLs needed to communicate with the Djatoka image server.
128
- email: jronallo@gmail.com
142
+ email: jronallo@gmail.com wmene@stanford.edu
129
143
  executables:
130
144
  - djatoka_url
131
145
  extensions: []
@@ -158,6 +172,7 @@ files:
158
172
  - init.rb
159
173
  - lib/djatoka.rb
160
174
  - lib/djatoka/common.rb
175
+ - lib/djatoka/iiif_request.rb
161
176
  - lib/djatoka/metadata.rb
162
177
  - lib/djatoka/net.rb
163
178
  - lib/djatoka/region.rb
@@ -173,6 +188,7 @@ files:
173
188
  - test/helper.rb
174
189
  - test/test_common.rb
175
190
  - test/test_djatoka.rb
191
+ - test/test_iiif_request.rb
176
192
  - test/test_metadata.rb
177
193
  - test/test_region.rb
178
194
  - test/test_resolver.rb
@@ -180,27 +196,25 @@ files:
180
196
  - watchr.rb
181
197
  homepage: http://github.com/jronallo/djatoka
182
198
  licenses: []
199
+ metadata: {}
183
200
  post_install_message:
184
201
  rdoc_options: []
185
202
  require_paths:
186
203
  - lib
187
204
  required_ruby_version: !ruby/object:Gem::Requirement
188
- none: false
189
205
  requirements:
190
- - - ! '>='
206
+ - - '>='
191
207
  - !ruby/object:Gem::Version
192
208
  version: '0'
193
209
  required_rubygems_version: !ruby/object:Gem::Requirement
194
- none: false
195
210
  requirements:
196
- - - ! '>='
211
+ - - '>='
197
212
  - !ruby/object:Gem::Version
198
213
  version: '0'
199
214
  requirements: []
200
215
  rubyforge_project: djatoka
201
- rubygems_version: 1.8.24
216
+ rubygems_version: 2.0.0.rc.2
202
217
  signing_key:
203
- specification_version: 3
218
+ specification_version: 4
204
219
  summary: Djatoka image server helpers for Ruby and Rails.
205
220
  test_files: []
206
- has_rdoc: