sinatra-rabbit 0.0.2 → 0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,247 +0,0 @@
1
- # respond_to (The MIT License)
2
-
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy of this software
4
- # and associated documentation files (the 'Software'), to deal in the Software without restriction,
5
- # including without limitation the rights to use, copy, modify, merge, publish, distribute,
6
- # sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
7
- # furnished to do so, subject to the following conditions:
8
- #
9
- # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
10
- # NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
12
- # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
13
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
14
-
15
- require 'rack/accept'
16
-
17
- module Sinatra
18
-
19
- module RespondTo
20
-
21
- class MissingTemplate < Sinatra::NotFound; end
22
-
23
- # Define all MIME types you want to support here.
24
- # This conversion table will be used for auto-negotiation
25
- # with browser in sinatra when no 'format' parameter is specified.
26
-
27
- SUPPORTED_ACCEPT_HEADERS = {
28
- :xml => [
29
- 'text/xml',
30
- 'application/xml'
31
- ],
32
- :html => [
33
- 'text/html',
34
- 'application/xhtml+xml'
35
- ],
36
- :json => [
37
- 'application/json'
38
- ]
39
- }
40
-
41
- # We need to pass array of available response types to
42
- # best_media_type method
43
- def accept_to_array
44
- SUPPORTED_ACCEPT_HEADERS.keys.collect do |key|
45
- SUPPORTED_ACCEPT_HEADERS[key]
46
- end.flatten
47
- end
48
-
49
- # Then, when we get best media type for response, we need
50
- # to know which format to choose
51
- def lookup_format_from_mime(mime)
52
- SUPPORTED_ACCEPT_HEADERS.keys.each do |format|
53
- return format if SUPPORTED_ACCEPT_HEADERS[format].include?(mime)
54
- end
55
- end
56
-
57
- def self.registered(app)
58
-
59
- app.helpers RespondTo::Helpers
60
- use Rack::Accept
61
-
62
- app.before do
63
-
64
- # Skip development error image and static content
65
- next if self.class.development? && request.path_info =~ %r{/__sinatra__/.*?.png}
66
- next if options.static? && options.public? && (request.get? || request.head?) && static_file?(request.path_info)
67
-
68
- # Remove extension from URI
69
- # Extension will be available as a 'extension' method (extension=='txt')
70
-
71
- extension request.path_info.match(/\.([^\.\/]+)$/).to_a.first
72
-
73
- # If ?format= is present, ignore all Accept negotiations because
74
- # we are not dealing with browser
75
- if request.params.has_key? 'format'
76
- format params['format'].to_sym
77
- end
78
-
79
- # Let's make a little exception here to handle
80
- # /api/instance_states[.gv/.png] calls
81
- if extension.eql?('gv')
82
- format :gv
83
- elsif extension.eql?('png')
84
- format :png
85
- end
86
-
87
- # Get Rack::Accept::Response object and find best possible
88
- # mime type to output.
89
- # This negotiation works fine with latest rest-client gem:
90
- #
91
- # RestClient.get 'http://localhost:3001/api', {:accept => :json } =>
92
- # 'application/json'
93
- # RestClient.get 'http://localhost:3001/api', {:accept => :xml } =>
94
- # 'application/xml'
95
- #
96
- # Also browsers like Firefox (3.6.x) and Chromium reporting
97
- # 'application/xml+xhtml' which is recognized as :html reponse
98
- # In browser you can force output using ?format=[format] parameter.
99
-
100
- rack_accept = env['rack-accept.request']
101
-
102
- if rack_accept.media_type.to_s.strip.eql?('Accept:')
103
- format :xml
104
- elsif is_chrome?
105
- format :html
106
- else
107
- format lookup_format_from_mime(rack_accept.best_media_type(accept_to_array))
108
- end
109
-
110
- end
111
-
112
- app.class_eval do
113
-
114
- # Simple helper to detect Chrome based browsers
115
- # which have screwed up they Accept headers.
116
- # Set HTML as default output format here
117
- def is_chrome?
118
- true if env['HTTP_USER_AGENT'] =~ /Chrome/
119
- end
120
-
121
- # This code was copied from respond_to plugin
122
- # http://github.com/cehoffman/sinatra-respond_to
123
- # MIT License
124
- alias :render_without_format :render
125
- def render(*args, &block)
126
- assumed_layout = args[1] == :layout
127
- args[1] = "#{args[1]}.#{format}".to_sym if args[1].is_a?(::Symbol)
128
- render_without_format *args, &block
129
- rescue Errno::ENOENT => e
130
- raise MissingTemplate, "#{args[1]}.#{args[0]}" unless assumed_layout
131
- raise e
132
- end
133
- private :render
134
- end
135
-
136
- # This code was copied from respond_to plugin
137
- # http://github.com/cehoffman/sinatra-respond_to
138
- app.configure :development do |dev|
139
- dev.error MissingTemplate do
140
- content_type :html, :charset => 'utf-8'
141
- response.status = request.env['sinatra.error'].code
142
-
143
- engine = request.env['sinatra.error'].message.split('.').last
144
- engine = 'haml' unless ['haml', 'builder', 'erb'].include? engine
145
-
146
- path = File.basename(request.path_info)
147
- path = "root" if path.nil? || path.empty?
148
-
149
- format = engine == 'builder' ? 'xml' : 'html'
150
-
151
- layout = case engine
152
- when 'haml' then "!!!\n%html\n %body= yield"
153
- when 'erb' then "<html>\n <body>\n <%= yield %>\n </body>\n</html>"
154
- end
155
-
156
- layout = "<small>app.#{format}.#{engine}</small>\n<pre>#{escape_html(layout)}</pre>"
157
-
158
- (<<-HTML).gsub(/^ {10}/, '')
159
- <!DOCTYPE html>
160
- <html>
161
- <head>
162
- <style type="text/css">
163
- body { text-align:center;font-family:helvetica,arial;font-size:22px;
164
- color:#888;margin:20px}
165
- #c {margin:0 auto;width:500px;text-align:left;}
166
- small {float:right;clear:both;}
167
- pre {clear:both;text-align:left;font-size:70%;width:500px;margin:0 auto;}
168
- </style>
169
- </head>
170
- <body>
171
- <h2>Sinatra can't find #{request.env['sinatra.error'].message}</h2>
172
- <img src='/__sinatra__/500.png'>
173
- <pre>#{request.env['sinatra.error'].backtrace.join("\n")}</pre>
174
- <div id="c">
175
- <small>application.rb</small>
176
- <pre>#{request.request_method.downcase} '#{request.path_info}' do\n respond_to do |wants|\n wants.#{format} { #{engine} :#{path} }\n end\nend</pre>
177
- </div>
178
- </body>
179
- </html>
180
- HTML
181
- end
182
-
183
- end
184
- end
185
-
186
- module Helpers
187
-
188
- # This code was copied from respond_to plugin
189
- # http://github.com/cehoffman/sinatra-respond_to
190
- def self.included(klass)
191
- klass.class_eval do
192
- alias :content_type_without_save :content_type
193
- def content_type(*args)
194
- content_type_without_save *args
195
- @_format = args.first.to_sym
196
- response['Content-Type']
197
- end
198
- end
199
- end
200
-
201
- def static_file?(path)
202
- public_dir = File.expand_path(options.public)
203
- path = File.expand_path(File.join(public_dir, unescape(path)))
204
-
205
- path[0, public_dir.length] == public_dir && File.file?(path)
206
- end
207
-
208
-
209
- # Extension holds trimmed extension. This is extra usefull
210
- # when you want to build original URI (with extension)
211
- # You can simply call "#{request.env['REQUEST_URI']}.#{extension}"
212
- def extension(val=nil)
213
- @_extension ||= val
214
- @_extension
215
- end
216
-
217
- # This helper will holds current format. Helper should be
218
- # accesible from all places in Sinatra
219
- def format(val=nil)
220
- @_format ||= val
221
- @_format
222
- end
223
-
224
- def respond_to(&block)
225
- wants = {}
226
-
227
- def wants.method_missing(type, *args, &handler)
228
- self[type] = handler
229
- end
230
-
231
- # Set proper content-type and encoding for
232
- # text based formats
233
- if [:xml, :gv, :html, :json].include?(format)
234
- content_type format, :charset => 'utf-8'
235
- end
236
- yield wants
237
- # Raise this error if requested format is not defined
238
- # in respond_to { } block.
239
- raise MissingTemplate if wants[format].nil?
240
-
241
- wants[format].call
242
- end
243
-
244
- end
245
-
246
- end
247
- end
@@ -1,53 +0,0 @@
1
- require 'uri'
2
-
3
- module Sinatra
4
- module UrlForHelper
5
- # Construct a link to +url_fragment+, which should be given relative to
6
- # the base of this Sinatra app. The mode should be either
7
- # <code>:path_only</code>, which will generate an absolute path within
8
- # the current domain (the default), or <code>:full</code>, which will
9
- # include the site name and port number. (The latter is typically
10
- # necessary for links in RSS feeds.) Example usage:
11
- #
12
- # url_for "/" # Returns "/myapp/"
13
- # url_for "/foo" # Returns "/myapp/foo"
14
- # url_for "/foo", :full # Returns "http://example.com/myapp/foo"
15
- #--
16
- # See README.rdoc for a list of some of the people who helped me clean
17
- # up earlier versions of this code.
18
- def url_for url_fragment, mode=:path_only
19
- case mode
20
- when :path_only
21
- base = request.script_name
22
- when :full
23
- scheme = request.scheme
24
- if (scheme == 'http' && request.port == 80 ||
25
- scheme == 'https' && request.port == 443)
26
- port = ""
27
- else
28
- port = ":#{request.port}"
29
- end
30
- request_host = HOSTNAME ? HOSTNAME : request.host
31
- base = "#{scheme}://#{request_host}#{port}#{request.script_name}"
32
- else
33
- raise TypeError, "Unknown url_for mode #{mode}"
34
- end
35
- url_escape = URI.escape(url_fragment)
36
- # Don't add the base fragment if url_for gets called more than once
37
- # per url or the url_fragment passed in is an absolute url
38
- if url_escape.match(/^#{base}/) or url_escape.match(/^http/)
39
- url_escape
40
- else
41
- "#{base}#{url_escape}"
42
- end
43
- end
44
-
45
- def root_url
46
- url_for '/'
47
- end
48
- end
49
-
50
-
51
-
52
- helpers UrlForHelper
53
- end
@@ -1,75 +0,0 @@
1
- module Sinatra
2
-
3
- module Rabbit
4
-
5
- module Validation
6
- class Failure < StandardError
7
- attr_reader :param
8
- def initialize(param, msg='')
9
- super(msg)
10
- @param = param
11
- end
12
-
13
- def name
14
- param.name
15
- end
16
- end
17
-
18
- class Param
19
- attr_reader :name, :klass, :type, :options, :description
20
-
21
- def initialize(args)
22
- @name = args[0]
23
- @klass = args[1] || :string
24
- @type = args[2] || :optional
25
- @options = args[3] || []
26
- @description = args[4] || ''
27
- end
28
-
29
- def required?
30
- type.eql?(:required)
31
- end
32
-
33
- def optional?
34
- type.eql?(:optional)
35
- end
36
- end
37
-
38
- def param(*args)
39
- raise RabbitDuplicateParamException if params[args[0]]
40
- p = Param.new(args)
41
- params[p.name] = p
42
- end
43
-
44
- def params
45
- @params ||= {}
46
- @params
47
- end
48
-
49
- # Add the parameters in hash +new+ to already existing parameters. If
50
- # +new+ contains a parameter with an already existing name, the old
51
- # definition is clobbered.
52
- def add_params(new)
53
- # We do not check for duplication on purpose: multiple calls
54
- # to add_params should be cumulative
55
- new.each { |p| @params[p.name] = p }
56
- end
57
-
58
- def each_param(&block)
59
- params.each_value { |p| yield p }
60
- end
61
-
62
- def validate(values)
63
- each_param do |p|
64
- if p.required? and not values[p.name]
65
- raise Failure.new(p, "Required parameter #{p.name} not found")
66
- end
67
- if values[p.name] and not p.options.empty? and
68
- not p.options.include?(values[p.name])
69
- raise Failure.new(p, "Parameter #{p.name} has value #{values[p.name]} which is not in #{p.options.join(", ")}")
70
- end
71
- end
72
- end
73
- end
74
- end
75
- end