deltacloud-core 0.0.7 → 0.0.8

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.
data/Rakefile CHANGED
@@ -30,19 +30,18 @@ end
30
30
 
31
31
  desc "Run basic unit tests"
32
32
  Rake::TestTask.new("test") { |t|
33
- t.test_files = FileList[
34
- 'tests/api_test.rb',
35
- 'tests/hardware_profiles_test.rb',
36
- 'tests/realms_test.rb',
37
- 'tests/images_test.rb',
38
- 'tests/instances_test.rb',
39
- 'tests/instance_states_test.rb',
40
- 'tests/url_for_test.rb'
41
- ]
33
+ t.test_files = FileList.new('tests/**/*_test.rb')
42
34
  t.verbose = true
43
35
  t.warning = false
44
36
  }
45
37
 
38
+ begin
39
+ require 'yard'
40
+ YARD::Rake::YardocTask.new do |t|
41
+ t.files = ['lib/**/*.rb', '*.rb'] # optional
42
+ end
43
+ rescue LoadError
44
+ end
46
45
 
47
46
  @specs = ['ruby', 'java'].inject({}) do |hash, spec_platform|
48
47
  $platform = spec_platform
data/config.ru CHANGED
@@ -1,5 +1,7 @@
1
1
  require 'rubygems'
2
2
  require 'sinatra'
3
3
 
4
+ $:.unshift File.join(File.dirname(__FILE__), '.')
5
+
4
6
  require 'server.rb'
5
7
  run Sinatra::Application
@@ -120,7 +120,6 @@ class GogridDriver < Deltacloud::BaseDriver
120
120
  end
121
121
 
122
122
  def instances(credentials, opts=nil)
123
- require 'ap'
124
123
  instances = []
125
124
  if opts and opts[:id]
126
125
  begin
@@ -0,0 +1,5 @@
1
+ :bucket: bucket1
2
+ :content_length: 12627
3
+ :content_type: text/plain
4
+ :last_modified: 2010-09-23 16:44:54 +0100
5
+ :content: "content of blob 1"
@@ -0,0 +1,5 @@
1
+ :bucket: bucket1
2
+ :content_length: 4420
3
+ :content_type: text/html
4
+ :last_modified: 2010-09-23 16:55:05 +0100
5
+ :content: "content of blob 2"
@@ -0,0 +1,5 @@
1
+ :bucket: bucket1
2
+ :content_length: 98732
3
+ :content_type: text/plain
4
+ :last_modified: 2010-08-14 02:14:31 +0100
5
+ :content: "content of blob 3"
@@ -0,0 +1,5 @@
1
+ :bucket: bucket2
2
+ :content_length: 983232
3
+ :content_type: application/octet-stream
4
+ :last_modified: 2010-09-21 06:17:24 +0100
5
+ :content: "content of blob 4"
@@ -0,0 +1,5 @@
1
+ :bucket: bucket2
2
+ :content_length: 651922
3
+ :content_type: application/pdf
4
+ :last_modified: 2009-07-21 11:12:13 +0100
5
+ :content: "content of blob 5"
@@ -0,0 +1,2 @@
1
+ :blob_list: [blob1, blob2, blob3]
2
+ :size: 3
@@ -0,0 +1,2 @@
1
+ :blob_list: [blob4, blob5]
2
+ :size: 2
@@ -25,6 +25,10 @@ module Deltacloud
25
25
  module Mock
26
26
  class MockDriver < Deltacloud::BaseDriver
27
27
 
28
+ def supported_collections
29
+ DEFAULT_COLLECTIONS + [ :buckets ]
30
+ end
31
+
28
32
  ( REALMS = [
29
33
  Realm.new({
30
34
  :id=>'us',
@@ -104,7 +108,6 @@ class MockDriver < Deltacloud::BaseDriver
104
108
  #
105
109
  # Images
106
110
  #
107
-
108
111
  def images(credentials, opts=nil )
109
112
  check_credentials( credentials )
110
113
  images = []
@@ -251,6 +254,79 @@ class MockDriver < Deltacloud::BaseDriver
251
254
  snapshots
252
255
  end
253
256
 
257
+ #--
258
+ # Buckets
259
+ #--
260
+ def buckets(credentials, opts=nil)
261
+ check_credentials(credentials)
262
+ buckets=[]
263
+ Dir[ "#{@storage_root}/buckets/*.yml" ].each do |bucket_file|
264
+ bucket = YAML.load( File.read( bucket_file ) )
265
+ bucket[:id] = File.basename( bucket_file, ".yml" )
266
+ bucket[:name] = bucket[:id]
267
+ buckets << Bucket.new( bucket )
268
+ end
269
+ buckets = filter_on( buckets, :id, opts )
270
+ buckets
271
+ end
272
+
273
+ #--
274
+ # Create bucket
275
+ #--
276
+ def create_bucket(credentials, name, opts=nil)
277
+ check_credentials(credentials)
278
+ bucket = {
279
+ :name=>name,
280
+ :size=>'0',
281
+ :blob_list=>[]
282
+ }
283
+ File.open( "#{@storage_root}/buckets/#{name}.yml", 'w' ) {|b| YAML.dump( bucket, b )}
284
+ Bucket.new(bucket)
285
+ end
286
+
287
+ #--
288
+ # Delete bucket
289
+ #--
290
+ def delete_bucket(credentials, name, opts=nil)
291
+ bucket = bucket(credentials, {:id => name})
292
+ unless (bucket.size == "0")
293
+ raise Deltacloud::BackendError.new(403, self.class.to_s, "bucket-not-empty", "delete operation not valid for non-empty bucket")
294
+ end
295
+ safely do
296
+ File.delete("#{@storage_root}/buckets/#{name}.yml")
297
+ end
298
+ end
299
+
300
+ #--
301
+ # Blobs
302
+ #--
303
+ def blobs(credentials, opts = nil)
304
+ check_credentials(credentials)
305
+ blobs=[]
306
+ Dir[ "#{@storage_root}/buckets/blobs/*.yml" ].each do |blob_file|
307
+ blob = YAML.load( File.read( blob_file ) )
308
+ blob[:id] = File.basename( blob_file, ".yml" )
309
+ blob[:name] = blob[:id]
310
+ blobs << Blob.new( blob )
311
+ end
312
+ blobs = filter_on( blobs, :id, opts )
313
+ blobs
314
+ end
315
+
316
+ #--
317
+ # Blob content
318
+ #--
319
+ def blob_data(credentials, bucket_id, blob_id, opts = nil)
320
+ check_credentials(credentials)
321
+ blob=nil
322
+ Dir[ "#{@storage_root}/buckets/blobs/*.yml" ].each do |blob_file|
323
+ if File.basename(blob_file, ".yml") == blob_id
324
+ blob = YAML.load(File.read(blob_file))
325
+ blob[:content].each {|part| yield part}
326
+ end
327
+ end
328
+ end
329
+
254
330
  def valid_credentials?(credentials)
255
331
  begin
256
332
  check_credentials(credentials)
@@ -115,8 +115,11 @@ module ApplicationHelper
115
115
 
116
116
  def cdata(&block)
117
117
  text = capture_haml(&block)
118
- text.gsub!("\n", "\n ")
119
- "<![CDATA[\n #{text}\n]]>"
118
+ "<![CDATA[#{text.strip}]]>"
119
+ end
120
+
121
+ def render_cdata(text)
122
+ "<pem><![CDATA[#{text.strip}]]></pem>"
120
123
  end
121
124
 
122
125
  end
@@ -0,0 +1,43 @@
1
+ #
2
+ # Copyright (C) 2009 Red Hat, Inc.
3
+ #
4
+ # Licensed to the Apache Software Foundation (ASF) under one or more
5
+ # contributor license agreements. See the NOTICE file distributed with
6
+ # this work for additional information regarding copyright ownership. The
7
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance with the
9
+ # License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16
+ # License for the specific language governing permissions and limitations
17
+ # under the License.
18
+
19
+ class Tag < BaseModel
20
+
21
+ attr_accessor :resource_id
22
+ attr_accessor :resource_type
23
+ attr_accessor :values
24
+
25
+ def add_value(name)
26
+ self.values << Value.new(name, self)
27
+ end
28
+
29
+ class Value
30
+ attr_accessor :name
31
+ attr_accessor :tag_id
32
+
33
+ def initialize(name, tag_id)
34
+ self.name, self.tag_id = name, tag_id
35
+ end
36
+
37
+ def to_s
38
+ self.name
39
+ end
40
+
41
+ end
42
+
43
+ end
data/server.rb CHANGED
@@ -14,6 +14,8 @@ require 'lib/deltacloud/helpers/blob_stream'
14
14
  configure do
15
15
  set :raise_errors => false
16
16
  set :show_exceptions, false
17
+ set :views, File.dirname(__FILE__) + '/views'
18
+ set :public, File.dirname(__FILE__) + '/public'
17
19
  end
18
20
 
19
21
  configure :development do
@@ -344,7 +346,7 @@ collection :keys do
344
346
  @key = driver.create_key(credentials, { :key_name => params[:name] })
345
347
  respond_to do |format|
346
348
  format.html { haml :"keys/show" }
347
- format.xml { haml :"keys/show" }
349
+ format.xml { haml :"keys/show", :ugly => true }
348
350
  end
349
351
  end
350
352
  end
@@ -9,7 +9,7 @@
9
9
  = @image.name
10
10
  %dt Owner
11
11
  %dd
12
- = link_to @image.owner_id, images_url( :owner_id => @image.owner_id )
12
+ = link_to @image.owner_id, image_url( :owner_id => @image.owner_id )
13
13
  %dt Architecture
14
14
  %dd
15
15
  = @image.architecture
@@ -8,9 +8,8 @@
8
8
  %fingerprint<
9
9
  =@key.fingerprint
10
10
  - unless @key.pem_rsa_key.nil?
11
- %pem<
12
- =cdata do
13
- =@key.pem_rsa_key
11
+ %pem
12
+ ~render_cdata(@key.pem_rsa_key)
14
13
  - if @key.is_password?
15
14
  %username<
16
15
  =cdata do
@@ -0,0 +1 @@
1
+ =@tags.inspect
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deltacloud-core
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 15
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 7
10
- version: 0.0.7
9
+ - 8
10
+ version: 0.0.8
11
11
  platform: ruby
12
12
  authors:
13
13
  - Red Hat, Inc.
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-09-30 00:00:00 +02:00
18
+ date: 2010-10-19 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -253,7 +253,6 @@ extra_rdoc_files:
253
253
  files:
254
254
  - Rakefile
255
255
  - config.ru
256
- - test.rb
257
256
  - deltacloud.rb
258
257
  - server.rb
259
258
  - support/fedora/rubygem-deltacloud-core.spec
@@ -263,7 +262,6 @@ files:
263
262
  - lib/sinatra/static_assets.rb
264
263
  - lib/sinatra/url_for.rb
265
264
  - lib/sinatra/rabbit.rb
266
- - lib/sinatra/respond_to_old.rb
267
265
  - lib/sinatra/respond_to.rb
268
266
  - lib/deltacloud/models/base_model.rb
269
267
  - lib/deltacloud/models/realm.rb
@@ -274,6 +272,7 @@ files:
274
272
  - lib/deltacloud/models/storage_snapshot.rb
275
273
  - lib/deltacloud/models/image.rb
276
274
  - lib/deltacloud/models/blob.rb
275
+ - lib/deltacloud/models/tag.rb
277
276
  - lib/deltacloud/models/bucket.rb
278
277
  - lib/deltacloud/method_serializer.rb
279
278
  - lib/deltacloud/helpers.rb
@@ -317,6 +316,13 @@ files:
317
316
  - lib/deltacloud/drivers/mock/data/instances/inst1.yml
318
317
  - lib/deltacloud/drivers/mock/data/instances/inst2.yml
319
318
  - lib/deltacloud/drivers/mock/data/instances/inst0.yml
319
+ - lib/deltacloud/drivers/mock/data/buckets/blobs/blob1.yml
320
+ - lib/deltacloud/drivers/mock/data/buckets/blobs/blob2.yml
321
+ - lib/deltacloud/drivers/mock/data/buckets/blobs/blob3.yml
322
+ - lib/deltacloud/drivers/mock/data/buckets/blobs/blob4.yml
323
+ - lib/deltacloud/drivers/mock/data/buckets/blobs/blob5.yml
324
+ - lib/deltacloud/drivers/mock/data/buckets/bucket1.yml
325
+ - lib/deltacloud/drivers/mock/data/buckets/bucket2.yml
320
326
  - views/instance_states/show.xml.haml
321
327
  - views/instance_states/show.html.haml
322
328
  - views/root/index.html.haml
@@ -343,13 +349,13 @@ files:
343
349
  - views/images/index.xml.haml
344
350
  - views/images/index.html.haml
345
351
  - views/images/show.html.haml
346
- - views/api/show.xml.haml
347
352
  - views/api/show.html.haml
348
- - views/keys/show.xml.haml
353
+ - views/api/show.xml.haml
349
354
  - views/keys/new.html.haml
350
355
  - views/keys/index.xml.haml
351
356
  - views/keys/index.html.haml
352
357
  - views/keys/show.html.haml
358
+ - views/keys/show.xml.haml
353
359
  - views/instances/show.xml.haml
354
360
  - views/instances/index.xml.haml
355
361
  - views/instances/index.html.haml
@@ -376,6 +382,7 @@ files:
376
382
  - views/buckets/new.html.haml
377
383
  - views/buckets/show.html.haml
378
384
  - views/buckets/show.xml.haml
385
+ - views/tags/index.html.haml
379
386
  - views/instance_states/show.png.erb
380
387
  - public/favicon.ico
381
388
  - public/images/topbar-bg.png
@@ -390,13 +397,6 @@ files:
390
397
  - public/stylesheets/compiled/screen.css
391
398
  - bin/deltacloudd
392
399
  - COPYING
393
- - tests/api_test.rb
394
- - tests/hardware_profiles_test.rb
395
- - tests/realms_test.rb
396
- - tests/images_test.rb
397
- - tests/instance_states_test.rb
398
- - tests/instances_test.rb
399
- - tests/url_for_test.rb
400
400
  has_rdoc: true
401
401
  homepage: http://www.deltacloud.org
402
402
  licenses: []
@@ -433,11 +433,5 @@ rubygems_version: 1.3.7
433
433
  signing_key:
434
434
  specification_version: 3
435
435
  summary: Deltacloud REST API
436
- test_files:
437
- - tests/api_test.rb
438
- - tests/hardware_profiles_test.rb
439
- - tests/realms_test.rb
440
- - tests/images_test.rb
441
- - tests/instance_states_test.rb
442
- - tests/instances_test.rb
443
- - tests/url_for_test.rb
436
+ test_files: []
437
+
@@ -1,253 +0,0 @@
1
- require 'sinatra/base'
2
- require 'sinatra/accept_media_types'
3
-
4
- # Accept header parsing was looked at but deemed
5
- # too much of an irregularity to deal with. Problems with the header
6
- # differences from IE, Firefox, Safari, and every other UA causes
7
- # problems with the expected output. The general expected behavior
8
- # would be serve html when no extension provided, but most UAs say
9
- # they will accept application/xml with out a quality indicator, meaning
10
- # you'd get the xml block served insead. Just plain retarded, use the
11
- # extension and you'll never be suprised.
12
-
13
- module Sinatra
14
- module RespondTo
15
- class UnhandledFormat < Sinatra::NotFound; end
16
- class MissingTemplate < Sinatra::NotFound
17
- def code; 500 end
18
- end
19
-
20
- TEXT_MIME_TYPES = [:txt, :html, :js, :json, :xml, :rss, :atom, :css, :asm, :c, :cc, :conf,
21
- :csv, :cxx, :diff, :dtd, :f, :f77, :f90, :for, :gemspec, :h, :hh, :htm,
22
- :log, :mathml, :mml, :p, :pas, :pl, :pm, :py, :rake, :rb, :rdf, :rtf, :ru,
23
- :s, :sgm, :sgml, :sh, :svg, :svgz, :text, :wsdl, :xhtml, :xsl, :xslt, :yaml,
24
- :yml, :ics, :png]
25
-
26
- def self.registered(app)
27
- app.helpers RespondTo::Helpers
28
-
29
- app.set :default_charset, 'utf-8'
30
- app.set :default_content, :html
31
- app.set :assume_xhr_is_js, true
32
-
33
- #deltacloud: removed the code that tried to 'guess' content based on extension
34
- #as this broke blobstore api (stripping blob names). Use ?format if present, otherwise
35
- #use http accept, otherwise set to default
36
- app.before do
37
- if (params[:format])
38
- @mime_types = [Helpers::mime_type(params[:format])]
39
- format params[:format]
40
- elsif env['HTTP_ACCEPT'].nil? || env['HTTP_ACCEPT'].empty?
41
- ext = options.default_content
42
- end
43
- end
44
-
45
- app.configure :development do |dev|
46
- dev.error UnhandledFormat do
47
- content_type :html, :charset => 'utf-8'
48
-
49
- (<<-HTML).gsub(/^ {10}/, '')
50
- <!DOCTYPE html>
51
- <html>
52
- <head>
53
- <style type="text/css">
54
- body { text-align:center;font-family:helvetica,arial;font-size:22px;
55
- color:#888;margin:20px}
56
- #c {margin:0 auto;width:500px;text-align:left}
57
- </style>
58
- </head>
59
- <body>
60
- <h2>Sinatra doesn't know this ditty.</h2>
61
- <img src='/__sinatra__/404.png'>
62
- <div id="c">
63
- Try this:
64
- <pre>#{request.request_method.downcase} '#{request.path_info}' do\n respond_to do |wants|\n wants.#{format} { "Hello World" }\n end\nend</pre>
65
- </div>
66
- </body>
67
- </html>
68
- HTML
69
- end
70
-
71
- dev.error MissingTemplate do
72
- content_type :html, :charset => 'utf-8'
73
- response.status = request.env['sinatra.error'].code
74
-
75
- engine = request.env['sinatra.error'].message.split('.').last
76
- engine = 'haml' unless ['haml', 'builder', 'erb'].include? engine
77
-
78
- path = File.basename(request.path_info)
79
- path = "root" if path.nil? || path.empty?
80
-
81
- format = engine == 'builder' ? 'xml' : 'html'
82
-
83
- layout = case engine
84
- when 'haml' then "!!!\n%html\n %body= yield"
85
- when 'erb' then "<html>\n <body>\n <%= yield %>\n </body>\n</html>"
86
- when 'builder' then ::Sinatra::VERSION =~ /^1.0/ ? "xml << yield" : "builder do |xml|\n xml << yield\nend"
87
- end
88
-
89
- layout = "<small>app.#{format}.#{engine}</small>\n<pre>#{escape_html(layout)}</pre>"
90
-
91
- (<<-HTML).gsub(/^ {10}/, '')
92
- <!DOCTYPE html>
93
- <html>
94
- <head>
95
- <style type="text/css">
96
- body { text-align:center;font-family:helvetica,arial;font-size:22px;
97
- color:#888;margin:20px}
98
- #c {margin:0 auto;width:500px;text-align:left;}
99
- small {float:right;clear:both;}
100
- pre {clear:both;}
101
- </style>
102
- </head>
103
- <body>
104
- <h2>Sinatra can't find #{request.env['sinatra.error'].message}</h2>
105
- <img src='/__sinatra__/500.png'>
106
- <div id="c">
107
- Try this:<br />
108
- #{layout}
109
- <small>#{path}.#{format}.#{engine}</small>
110
- <pre>Hello World!</pre>
111
- <small>application.rb</small>
112
- <pre>#{request.request_method.downcase} '#{request.path_info}' do\n respond_to do |wants|\n wants.#{engine == 'builder' ? 'xml' : 'html'} { #{engine} :#{path}#{",\n#{' '*32}layout => :app" if layout} }\n end\nend</pre>
113
- </div>
114
- </body>
115
- </html>
116
- HTML
117
- end
118
-
119
- end
120
-
121
- app.class_eval do
122
- private
123
- def accept_list
124
- @mime_types || Rack::AcceptMediaTypes.new(env['HTTP_ACCEPT'] || '')
125
- end
126
-
127
- # Changes in 1.0 Sinatra reuse render for layout so we store
128
- # the original value to tell us if this is an automatic attempt
129
- # to do a layout call. If it is, it might fail with Errno::ENOENT
130
- # and we want to pass that back to sinatra since it isn't a MissingTemplate
131
- # error
132
- def render_with_format(*args, &block)
133
- assumed_layout = args[1] == :layout
134
- args[1] = "#{args[1]}.#{format}".to_sym if args[1].is_a?(::Symbol)
135
- render_without_format *args, &block
136
- rescue Errno::ENOENT => e
137
- raise MissingTemplate, "#{args[1]}.#{args[0]}" unless assumed_layout
138
- raise e
139
- end
140
- alias_method :render_without_format, :render
141
- alias_method :render, :render_with_format
142
-
143
- if ::Sinatra::VERSION =~ /^0\.9/
144
- def lookup_layout_with_format(*args)
145
- args[1] = "#{args[1]}.#{format}".to_sym if args[1].is_a?(::Symbol)
146
- lookup_layout_without_format *args
147
- end
148
- alias_method :lookup_layout_without_format, :lookup_layout
149
- alias_method :lookup_layout, :lookup_layout_with_format
150
- end
151
- end
152
- end
153
-
154
- module Helpers
155
- # Patch the content_type function to remember the set type
156
- # This helps cut down on time in the format helper so it
157
- # doesn't have to do a reverse lookup on the header
158
- def self.included(klass)
159
- klass.class_eval do
160
- def content_type_with_save(*args)
161
- content_type_without_save *args
162
- @_format = args.first.to_sym
163
- response['Content-Type']
164
- end
165
- alias_method :content_type_without_save, :content_type
166
- alias_method :content_type, :content_type_with_save
167
- end if ::Sinatra::VERSION =~ /^1.0/
168
- end
169
-
170
- def self.mime_type(sym)
171
- ::Sinatra::Base.respond_to?(:mime_type) && ::Sinatra::Base.mime_type(sym) || ::Sinatra::Base.media_type(sym)
172
- end
173
-
174
- def format(val=nil)
175
- unless val.nil?
176
- mime_type = ::Sinatra::RespondTo::Helpers.mime_type(val)
177
- fail "Unknown media type #{val}\nTry registering the extension with a mime type" if mime_type.nil?
178
-
179
- @_format = val.to_sym
180
- response['Content-Type'].sub!(/^[^;]+/, mime_type)
181
- charset options.default_charset if Sinatra::RespondTo::TEXT_MIME_TYPES.include?(format) and format!=:png
182
- end
183
-
184
- @_format
185
- end
186
-
187
- # This is mostly just a helper so request.path_info isn't changed when
188
- # serving files from the public directory
189
- def static_file?(path)
190
- public_dir = File.expand_path(options.public)
191
- path = File.expand_path(File.join(public_dir, unescape(path)))
192
-
193
- path[0, public_dir.length] == public_dir && File.file?(path)
194
- end
195
-
196
- def charset(val=nil)
197
- fail "Content-Type must be set in order to specify a charset" if response['Content-Type'].nil?
198
-
199
- if response['Content-Type'] =~ /charset=[^;]+/
200
- response['Content-Type'].sub!(/charset=[^;]+/, (val == '' && '') || "charset=#{val}")
201
- else
202
- response['Content-Type'] += ";charset=#{val}"
203
- end unless val.nil?
204
-
205
- response['Content-Type'][/charset=([^;]+)/, 1]
206
- end
207
-
208
- def respond_to(&block)
209
- wants = Format.new
210
- yield wants
211
- fmt, type, handler = match_accept_type(accept_list, wants)
212
- raise UnhandledFormat if fmt.nil?
213
- format fmt
214
- handler.nil? ? nil : handler.call
215
- end
216
-
217
- def match_accept_type(mime_types, format)
218
- selected = []
219
-
220
- accepted_types = mime_types.map {|type| Regexp.escape(type).gsub(/\\\*/,'.*') }
221
- # Fix for Chrome based browsers which returns XML when 'xhtml' is requested.
222
- if env['HTTP_USER_AGENT'] =~ /Chrome/ and accepted_types.size>1
223
- accepted_types[0], accepted_types[1] = accepted_types[1], accepted_types[0]
224
- if accepted_types[0].eql?('application/xhtml\\+xml')
225
- accepted_types[0] = 'text/html'
226
- end
227
- end
228
- accepted_types.each do |at|
229
- format.each do |fmt, ht, handler|
230
- (selected = [fmt, ht, handler]) and break if ht.match(at)
231
- end
232
- break unless selected.empty?
233
- end
234
- selected
235
- end
236
-
237
- # NOTE Array instead of hash because order matters (wildcard type
238
- # matches first handler)
239
- class Format < Array #:nodoc:
240
- def method_missing(format, *args, &handler)
241
- mt = Sinatra::RespondTo::Helpers.mime_type(format)
242
- if mt.nil?
243
- Sinatra::Base.send(:fail, "Unknown media type for respond_to: #{format}\nTry registering the extension with a mime type")
244
- end
245
- self << [format.to_s, mt, handler]
246
- end
247
- end
248
- end
249
- end
250
- end
251
-
252
- Rack::Mime::MIME_TYPES.merge!({ ".gv" => "text/plain" })
253
- Sinatra::Application.register Sinatra::RespondTo