sinatra-rabbit 0.0.2 → 0.9

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.
@@ -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