deltacloud-core 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
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