djatoka 0.0.2

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.
@@ -0,0 +1,76 @@
1
+ # A class for retrieving metadata on a particular image.
2
+ # See the Djatoka documentation on the {getMetadata service}[http://sourceforge.net/apps/mediawiki/djatoka/index.php?title=Djatoka_OpenURL_Services#info:lanl-repo.2Fsvc.2FgetMetadata]
3
+ class Djatoka::Metadata
4
+ attr_accessor :rft_id, :identifier, :imagefile, :width, :height, :dwt_levels,
5
+ :levels, :layer_count, :response, :resolver
6
+ include Djatoka::Net
7
+
8
+ def initialize(resolver, rft_id)
9
+ @resolver = resolver
10
+ @rft_id = rft_id
11
+ end
12
+
13
+ # To actually retrieve metadata from the server this method must be called.
14
+ def perform
15
+ @response = get_json(url)
16
+ if @response
17
+ @identifier = response['identifier']
18
+ @imagefile = response['imagefile']
19
+ @width = response['width']
20
+ @height = response['height']
21
+ @dwt_levels = response['dwtLevels']
22
+ @levels = response['levels']
23
+ @layer_count = response['compositingLayerCount']
24
+ end
25
+ self
26
+ end
27
+
28
+ # If #perform has been called then this can tell you whether
29
+ # the status of the request was 'OK' or not (nil).
30
+ def status
31
+ if @response
32
+ 'OK'
33
+ else
34
+ nil
35
+ end
36
+ end
37
+
38
+ # Returns an Addressable::URI which can be used to retrieve metadata from the
39
+ # image server, inspected for query_values, or changed before a request.
40
+ def uri
41
+ uri = Addressable::URI.new(resolver.base_uri_params)
42
+ uri.query_values = {'url_ver'=>'Z39.88-2004','svc_id'=>'info:lanl-repo/svc/getMetadata',
43
+ 'rft_id'=>rft_id }
44
+ uri
45
+ end
46
+
47
+ # Returns a URL as a String for retrieving metdata from the image server.
48
+ def url
49
+ uri.to_s
50
+ end
51
+
52
+ # The Djatoka image server {determines level logic}[http://sourceforge.net/apps/mediawiki/djatoka/index.php?title=Djatoka_Level_Logic]
53
+ # different from the number of dwtLevels. This method determines the height and
54
+ # width of each level. Djatoka only responds with the largest level, so we have
55
+ # to determine these other levels ourself.
56
+ def all_levels
57
+ perform if !response # if we haven't already performed the metadata query do it now
58
+ levels_hash = Mash.new
59
+ dwt_levels_i = dwt_levels.to_i
60
+ (0..dwt_levels_i).each do |level_num|
61
+ level_height = height.to_i
62
+ level_width = width.to_i
63
+
64
+ times_to_halve = dwt_levels_i - level_num
65
+ times_to_halve.times do
66
+ level_height = level_height / 2
67
+ level_width = level_width / 2
68
+ end
69
+
70
+ levels_hash[level_num] = {:height => level_height, :width => level_width}
71
+ end
72
+ levels_hash
73
+ end
74
+
75
+ end
76
+
@@ -0,0 +1,25 @@
1
+ # Module to allow mixing in the ability to retrieve JSON via http.
2
+ # Uses curb if available; otherwise falls back on Net::HTTP
3
+ module Djatoka::Net
4
+ # Used to get the JSON response from Djatoka for Djatoka::Metadata and ping requests.
5
+ # Uses curb if the gem is installed; otherwise it falls back on Net::HTTP.
6
+ def get_json(url)
7
+ if Djatoka.use_curb?
8
+ c = Curl::Easy.new(url)
9
+ data = nil
10
+ c.on_success{|curl| data = JSON.parse(curl.body_str) }
11
+ c.perform
12
+ else
13
+ uri = URI.parse(url)
14
+ response = Net::HTTP.get_response(uri)
15
+ case response
16
+ when Net::HTTPSuccess
17
+ data = JSON.parse(response.body)
18
+ else
19
+ data = nil
20
+ end
21
+ end
22
+ data
23
+ end
24
+ end
25
+
@@ -0,0 +1,134 @@
1
+ # Class to ease the creation of query parameters for retrieval of a region of
2
+ # an image from the Djatoka image server.
3
+ # See the Djatoka documentation on specifics on the {getRegion service}[http://sourceforge.net/apps/mediawiki/djatoka/index.php?title=Djatoka_OpenURL_Services#info:lanl-repo.2Fsvc.2FgetRegion]
4
+ #
5
+ # Many of the methods here can be chained together to set query parameters like so:
6
+ # region = Djatoka::Region.new('http://african.lanl.gov/adore-djatoka/resolver',
7
+ # 'info:lanl-repo/ds/5aa182c2-c092-4596-af6e-e95d2e263de3')
8
+ #
9
+ # region.scale(300).format('image/png').region([1250,550,800,800]).rotate(180).level(5).url
10
+ # # => "http://african.lanl.gov/adore-djatoka/resolver?svc.level=5&url_ver=Z39.88-2004&svc.region=1250%2C550%2C800%2C800&svc.scale=300&rft_id=info%3Alanl-repo%2Fds%2F5aa182c2-c092-4596-af6e-e95d2e263de3&svc_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Ajpeg2000&svc_id=info%3Alanl-repo%2Fsvc%2FgetRegion&svc.format=image%2Fpng&svc.rotate=180"
11
+ #
12
+ # All of these values are added in to the query attribute of the Djatoka::Region.
13
+ # Any of the values which are separated by a comma in the {docs}[http://sourceforge.net/apps/mediawiki/djatoka/index.php?title=Djatoka_OpenURL_Services#info:lanl-repo.2Fsvc.2FgetRegion]
14
+ # can be sent in as a String or an Array.
15
+ class Djatoka::Region
16
+ include Djatoka::Common
17
+ attr_accessor :resolver, :rft_id, :query
18
+
19
+ # Pass in a Djatoka::Resolver (or an http URL as a String) and
20
+ # an rft_id to create a Region. Valid parameters include any of the methods below
21
+ # which add their value to <tt>query</tt> and return self (so they can be
22
+ # chained together).
23
+ def initialize(resolver, rft_id, params={})
24
+ if resolver.is_a? String
25
+ @resolver = Djatoka::Resolver.new(resolver)
26
+ else
27
+ @resolver = resolver
28
+ end
29
+ @rft_id = rft_id
30
+ @query = Mash.new
31
+ unless params.empty?
32
+ map_params(params)
33
+ end
34
+ end
35
+
36
+ # url for a Region as a String
37
+ def url
38
+ uri.to_s
39
+ end
40
+
41
+ # Addressable::URI for the Region
42
+ def uri
43
+ uri = Addressable::URI.new(resolver.base_uri_params)
44
+ uri.query_values = region_params
45
+ uri
46
+ end
47
+
48
+ # Take the query values and prefixes 'svc.' for the OpenURL.
49
+ def svc_query
50
+ prefixed_query = {}
51
+ query.each do |k,v|
52
+ prefixed_query['svc.' + k] = v
53
+ end
54
+ prefixed_query
55
+ end
56
+
57
+ # Set the scale query parameter as a String or Array. Returns self.
58
+ def scale(v)
59
+ if v.is_a? String or v.is_a? Integer or v.is_a? Float
60
+ query[:scale] = v.to_s
61
+ elsif v.is_a? Array
62
+ raise Djatoka::Region::Exception if v.length != 2
63
+ query[:scale] = v.join(',')
64
+ end
65
+ self
66
+ end
67
+
68
+ # Set the level query parameter as a String or Integer. Returns self.
69
+ def level(v)
70
+ if v.is_a? String or v.is_a? Integer
71
+ query[:level] = v.to_s
72
+ end
73
+ self
74
+ end
75
+
76
+ # Sets the rotate query parameter as a String or Integer. Returns self.
77
+ def rotate(v)
78
+ if v.is_a? String or v.is_a? Integer
79
+ query[:rotate] = v.to_s
80
+ end
81
+ self
82
+ end
83
+
84
+ # Sets the region query parameter as a String or Array. Returns self.
85
+ # See the {Djatoka documentation}[http://sourceforge.net/apps/mediawiki/djatoka/index.php?title=Djatoka_OpenURL_Services#info:lanl-repo.2Fsvc.2FgetRegion]
86
+ # on the valid values for the region parameter and what they mean.
87
+ def region(v)
88
+ if v.is_a? String
89
+ svc_region = v.split(',')
90
+ raise Djatoka::Region::Exception if svc_region.length != 4
91
+ query[:region] = v
92
+ elsif v.is_a? Array
93
+ raise Djatoka::Region::Exception if v.length != 4
94
+ query[:region] = v.join(',')
95
+ end
96
+ self
97
+ end
98
+
99
+ # Set the format query parameter for what image format will be returned. Returns self.
100
+ def format(v)
101
+ query[:format] = v
102
+ self
103
+ end
104
+
105
+ def clayer(v)
106
+ query[:clayer] = v
107
+ self
108
+ end
109
+
110
+ def region_params
111
+ region_base_url_params.merge(svc_query)
112
+ end
113
+
114
+ # base parameters for creating a getRegion service OpenURL.
115
+ def region_base_url_params
116
+ {'url_ver'=>'Z39.88-2004', 'svc_id'=>'info:lanl-repo/svc/getRegion',
117
+ 'svc_val_fmt'=>'info:ofi/fmt:kev:mtx:jpeg2000',
118
+ 'rft_id' => rft_id
119
+ }
120
+ end
121
+
122
+ private
123
+
124
+ def map_params(params)
125
+ params.each do |k,v|
126
+ if k.to_s != 'resolver' and self.respond_to?(k) and
127
+ self.class.instance_methods(false).include?(k.to_s)
128
+ self.send(k,v)
129
+ end
130
+ end
131
+ end
132
+
133
+ end
134
+
@@ -0,0 +1,83 @@
1
+ # A resolver holds the URL for a Djatoka resolver and allows for
2
+ # {ping requests}[http://sourceforge.net/apps/mediawiki/djatoka/index.php?title=Djatoka_OpenURL_Services#info:lanl-repo.2Fsvc.2Fping] to the server and shortcuts for the creation of Djatoka::Region
3
+ # and Djatoka::Metadata objects.
4
+ class Djatoka::Resolver
5
+ include Djatoka::Net
6
+ attr_accessor :base_url, :host, :path, :port
7
+
8
+ def initialize(base_url='http://african.lanl.gov/adore-djatoka/resolver')
9
+ #if base_url.to_s =~ /(^$)|(^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$)/ix
10
+ uri = Addressable::URI.parse(base_url)
11
+ @base_url = uri.to_s
12
+ @host = uri.host
13
+ @path = uri.path
14
+ @port = uri.port
15
+ #else #fails this basic validation that it is a URL
16
+ # @base_url = nil
17
+ # @host = nil
18
+ # @path = nil
19
+ #end
20
+ end
21
+
22
+ # same as #base_url
23
+ def url
24
+ base_url
25
+ end
26
+
27
+ # Shortcut to return a Djatoka::Metadata object
28
+ def metadata(rft_id)
29
+ Djatoka::Metadata.new(self, rft_id)
30
+ end
31
+
32
+ # Returns a URL as a String for retrieving metadata from the server as JSON.
33
+ def metadata_url(rft_id)
34
+ metadata(rft_id).url
35
+ end
36
+
37
+ # Returns a URL as a String which can be used to ping the server.
38
+ def ping_url(rft_id)
39
+ ping_url_template.expand(:rft_id => rft_id).to_str
40
+ end
41
+
42
+ # Make a ping request for a particular identifier to the Djatoka server
43
+ # and get a Mash/Hash in return. See the Djatoka docs on
44
+ # {the ping service}[http://sourceforge.net/apps/mediawiki/djatoka/index.php?title=Djatoka_OpenURL_Services#info:lanl-repo.2Fsvc.2Fping]
45
+ def ping(rft_id)
46
+ m_url = ping_url(rft_id)
47
+ response = get_json(m_url)
48
+ if response
49
+ Mash.new(response)
50
+ else
51
+ response
52
+ end
53
+ end
54
+
55
+ # Shortcut for creating a Djatoka::Region from a Djatoka::Resolver.
56
+ def region(rft_id, params={})
57
+ Djatoka::Region.new(self, rft_id, params)
58
+ end
59
+
60
+ # Shortcut for creating an Addressable::URI for a Djatoka::Region.
61
+ def region_uri(rft_id, params={})
62
+ Djatoka::Region.new(self, rft_id, params).uri
63
+ end
64
+
65
+ def base_uri_params
66
+ params = {:host => host, :path => path, :scheme => 'http'}
67
+ params[:port] = port if port
68
+ params
69
+ end
70
+
71
+ # same as #base_url
72
+ def to_s
73
+ base_url
74
+ end
75
+
76
+ private
77
+
78
+ def ping_url_template
79
+ Addressable::Template.new("#{base_url}?url_ver=Z39.88-2004&svc_id=info:lanl-repo/svc/ping&rft_id={rft_id}")
80
+ end
81
+
82
+ end
83
+
@@ -0,0 +1,106 @@
1
+ module Djatoka
2
+
3
+ # = Djatoka view helpers
4
+ #
5
+ # These methods accept an rft_id (identifier) that a Djatoka resolver knows
6
+ # about and params. Params can include both parameters for a Djatoka query
7
+ # and params for image_tag. All parameters will be passed on to image_tag allowing
8
+ # setting of attributes like the <tt>class</tt>.
9
+ # The resolver can either be set in
10
+ # config/initializers/djatoka.rb of a Rails application or by setting a
11
+ # <tt>:resolver</tt> parameter when using one of these helpers.
12
+ module ViewHelpers
13
+
14
+ # Returns an image_tag. Unless params are passed in which constrain the
15
+ # <tt>scale</tt> or <tt>level</tt> of the image, this will be the highest
16
+ # resolution of the given image.
17
+ # djatoka_image_tag('info:lanl-repo/ds/5aa182c2-c092-4596-af6e-e95d2e263de3',
18
+ # {:scale => 150, :class => 'djatoka_image'})
19
+ #
20
+ # djatoka_image_tag('info:lanl-repo/ds/5aa182c2-c092-4596-af6e-e95d2e263de3',
21
+ # {:scale => 150, :region => [1400,500,1400,1500], :class => 'volleyball'})
22
+ def djatoka_image_tag(rft_id, params={})
23
+ resolver, region = setup_djatoka_image_tag(rft_id, params)
24
+ if resolver and region
25
+ image_tag region.url, params
26
+ else
27
+
28
+ end
29
+ end
30
+
31
+ # Returns an image_tag for a square image. The long side is cropped.
32
+ # This can be combined with <tt>scale</tt> to determine the dimensions.
33
+ # The correct level is attempted to be determined by Djatoka::Common#square_params.
34
+ # djatoka_square_image_tag('info:lanl-repo/ds/5aa182c2-c092-4596-af6e-e95d2e263de3',
35
+ # {:scale => 250, :class => 'djatoka_image_larger',
36
+ # :resolver => 'http://african.lanl.gov/adore-djatoka/resolver' })
37
+ def djatoka_square_image_tag(rft_id, params={})
38
+ resolver, region = setup_djatoka_image_tag(rft_id, params)
39
+ if resolver and region
40
+ image_tag(region.square.url, params) #+ debug(region)
41
+ else
42
+
43
+ end
44
+ end
45
+
46
+ # Returns an image tag for an image exactly 75x75
47
+ # djatoka_smallbox_image_tag('info:lanl-repo/ds/5aa182c2-c092-4596-af6e-e95d2e263de3')
48
+ def djatoka_smallbox_image_tag(rft_id, params={})
49
+ resolver, region = setup_djatoka_image_tag(rft_id, params)
50
+ if resolver and region
51
+ image_tag region.smallbox.url, params
52
+ else
53
+
54
+ end
55
+ end
56
+
57
+ # Include djatoka_openlayers_script on any page you need pan and zoom to
58
+ # include the scripts OpenLayers, OpenURL and djatoka. Including those scripts
59
+ # is required for #djatoka_init_openlayers to work.
60
+ def djatoka_openlayers_script
61
+ jquery = '<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>'
62
+ jquery + javascript_include_tag('OpenLayers','OpenURL', 'djatoka')
63
+ end
64
+
65
+ # View helper to include a bit of jQuery on the page which waits for document
66
+ # load and then initializes the Ajax, OpenLayers viewer. Since this works
67
+ # via Ajax, Djatoka will need to be running or proxied at the same domain as
68
+ # the application to avoid cross-domain restrictions.
69
+ def djatoka_init_openlayers(rft_id, div_identifier, params={})
70
+ resolver = determine_resolver(params)
71
+ metadata_url = resolver.metadata_url(rft_id)
72
+ %Q|<script type="text/javascript">
73
+ $(document).ready(function() {openlayersInit('http://#{resolver.host}',
74
+ '#{metadata_url}',
75
+ '#{rft_id}', '#{div_identifier}');
76
+ });
77
+ </script>
78
+ |
79
+ end
80
+
81
+ private
82
+
83
+ def setup_djatoka_image_tag(rft_id, params)
84
+ resolver = determine_resolver(params)
85
+ if resolver
86
+ region = Djatoka::Region.new(resolver, rft_id, params)
87
+ return resolver, region
88
+ else
89
+ end
90
+ end
91
+
92
+ # Uses the <tt>:resolver</tt> parameter first and then the value stored in
93
+ # Djatoka.resolver second.
94
+ def determine_resolver(params)
95
+ if params[:resolver]
96
+ Djatoka::Resolver.new(params[:resolver])
97
+ elsif Djatoka.resolver
98
+ Djatoka.resolver
99
+ else
100
+ nil
101
+ end
102
+ end
103
+
104
+ end
105
+ end
106
+
@@ -0,0 +1,24 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'djatoka'
8
+ require 'ruby-debug'
9
+
10
+ class Test::Unit::TestCase
11
+ def self.with_a_resolver(&block)
12
+ context 'resolver setup' do
13
+ setup do
14
+ @resolver = Djatoka::Resolver.new('http://african.lanl.gov/adore-djatoka/resolver')
15
+ @identifier = 'info:lanl-repo/ds/5aa182c2-c092-4596-af6e-e95d2e263de3'
16
+ @url_encoded_identifier = 'info%3Alanl-repo%2Fds%2F5aa182c2-c092-4596-af6e-e95d2e263de3'
17
+ end
18
+
19
+ merge_block(&block) if block_given?
20
+ end
21
+ end
22
+
23
+ end
24
+