padrino-response 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.travis.yml +12 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +84 -0
- data/Rakefile +5 -0
- data/lib/padrino-response.rb +34 -0
- data/lib/padrino-response/helpers/controller.rb +92 -0
- data/lib/padrino-response/helpers/simple.rb +34 -0
- data/lib/padrino-response/locale/en.yml +7 -0
- data/lib/padrino-response/locale/pl.yml +7 -0
- data/lib/padrino-response/notifiers/flash_notifier.rb +20 -0
- data/lib/padrino-response/respond.rb +25 -0
- data/lib/padrino-response/responders/default.rb +165 -0
- data/lib/padrino-response/responders/jsend.rb +92 -0
- data/lib/padrino-response/status_codes.rb +88 -0
- data/lib/padrino-response/version.rb +5 -0
- data/padrino-response.gemspec +29 -0
- data/spec/all_spec.rb +49 -0
- data/spec/fixtures/app.rb +62 -0
- data/spec/spec.rake +17 -0
- data/spec/spec_helper.rb +12 -0
- metadata +163 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 340112ce19798bc835b91a04a1d96fab55b38419
|
4
|
+
data.tar.gz: 6cd6de2f37d5ff9c56f0a5fc3a3362010c685d5d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c128575feb849a70d38cc1920e220946ca0d78d35d8a727f021aa45095232909a030a0818fe2bf3ed67d40fa1f1559c6d2bba99f75b0f00824751efd29c9a039
|
7
|
+
data.tar.gz: 70cae9051a7be7e27f7da5a3fa83bca631fa839a198d518df7101b4149d4272b18a98b1b88c93231a8601576e30e6bf8dd5d8415c67d517036b3dcc42f81699b
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013 K-2052
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
# padrino-response
|
2
|
+
|
3
|
+
Eliminates the repetitive response code in your [Padrino](http://www.padrinorb.com/) controllers
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Via rubygems:
|
8
|
+
|
9
|
+
$ gem install padrino-responders
|
10
|
+
|
11
|
+
Or add add the following to your Gemfile:
|
12
|
+
|
13
|
+
gem 'padrino-response'
|
14
|
+
|
15
|
+
Now register it in your application:
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
class App < Padrino::Application
|
19
|
+
register Padrino::Response
|
20
|
+
end
|
21
|
+
```
|
22
|
+
|
23
|
+
## Usage Examples
|
24
|
+
|
25
|
+
Basic:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
get :user, map: '/user' do
|
29
|
+
respond @user
|
30
|
+
end
|
31
|
+
```
|
32
|
+
|
33
|
+
With a status code:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
post :unauthorized_user, map: => '/unauthurized-user' do
|
37
|
+
respond :unauthorized
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
Skip the object:
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
get :not_found, map: '/not-found' do
|
45
|
+
respond :not_found
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
### Customizing the responder:
|
50
|
+
|
51
|
+
Via options:
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
class CustomResponder < Padrino::Responders::Default
|
55
|
+
end
|
56
|
+
|
57
|
+
get :custom_responder, map: '/custom-responder' do
|
58
|
+
respond responder: "CustomResponder"
|
59
|
+
end
|
60
|
+
```
|
61
|
+
|
62
|
+
Specify a responder for the controller:
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
class Padrino::Responders::Main < Padrino::Responders::Default
|
66
|
+
end
|
67
|
+
```
|
68
|
+
|
69
|
+
# Five Second Contributions Guide
|
70
|
+
|
71
|
+
- Fork
|
72
|
+
- Make changes in a branch
|
73
|
+
- Write tests
|
74
|
+
- Commit
|
75
|
+
- Pull Request
|
76
|
+
|
77
|
+
# Copyright
|
78
|
+
|
79
|
+
This started out as a fork of nu7hatch's [padrino-responders](https://github.com/k2052/padrino-responders); my fork
|
80
|
+
diverged enough that I felt it was best to make an entirely new gem. I cant thank nu7hatch enough for the original code
|
81
|
+
.
|
82
|
+
|
83
|
+
Licensed under MIT
|
84
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'padrino-core'
|
2
|
+
require 'padrino-gen'
|
3
|
+
|
4
|
+
FileSet.glob_require('padrino-response/*.rb', __FILE__)
|
5
|
+
FileSet.glob_require('padrino-response/{helpers,notifiers,responders}/*.rb', __FILE__)
|
6
|
+
|
7
|
+
module Padrino
|
8
|
+
##
|
9
|
+
# This component is used to create slim controllers without unnecessery
|
10
|
+
# and repetitive code.
|
11
|
+
#
|
12
|
+
module Response
|
13
|
+
##
|
14
|
+
# Method used by Padrino::Application when we register the extension
|
15
|
+
#
|
16
|
+
class << self
|
17
|
+
def registered(app)
|
18
|
+
app.enable :sessions
|
19
|
+
app.enable :flash
|
20
|
+
app.helpers Padrino::Response::Helpers::Controller
|
21
|
+
app.helpers Padrino::Response::Helpers::Simple
|
22
|
+
app.set :notifier, Padrino::Response::Notifiers::FlashNotifier
|
23
|
+
app.send :include, Padrino::Response::Respond
|
24
|
+
end
|
25
|
+
alias :included :registered
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Load our Padrino::Response locales
|
32
|
+
#
|
33
|
+
I18n.load_path += Dir["#{File.dirname(__FILE__)}/padrino-response/locale/**/*.yml"]
|
34
|
+
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module Padrino
|
2
|
+
module Response
|
3
|
+
module Helpers
|
4
|
+
module Controller
|
5
|
+
##
|
6
|
+
# A request from a non-browser user. Could be ajax, via curl etc.
|
7
|
+
#
|
8
|
+
def api_request
|
9
|
+
(request.xhr? or content_type == :json or mime_type(:json) == request.preferred_type.to_s)
|
10
|
+
end
|
11
|
+
|
12
|
+
##
|
13
|
+
# Shortcut for <code>notifier.say</code> method.
|
14
|
+
#
|
15
|
+
def notify(kind, message, *args, &block)
|
16
|
+
settings.notifier.say(self, kind, message, *args, &block) if settings.notifier
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# Trys to render and then falls back to to_format
|
21
|
+
#
|
22
|
+
def try_render(object, detour_name=nil, responder)
|
23
|
+
begin
|
24
|
+
if responder.layout
|
25
|
+
render "#{controller_name}/#{detour_name || action_name}", :layout => responder.layout, :strict_format => true
|
26
|
+
else
|
27
|
+
render "#{controller_name}/#{detour_name || action_name}", :strict_format => true
|
28
|
+
end
|
29
|
+
rescue Exception => e
|
30
|
+
if api_request
|
31
|
+
if responder.jsend? && object.respond_to?(:attributes)
|
32
|
+
{:status => (responder.options.include?(:status) ? responder.options[:status] : 200),
|
33
|
+
:data => {responder.human_model_name.to_sym => object.attributes}}.to_json
|
34
|
+
else
|
35
|
+
return object.to_json if object.respond_to?(:to_json)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
if content_type == :xml or mime_type(:xml) == request.preferred_type
|
40
|
+
return object.to_xml if object.respond_to?(:to_xml)
|
41
|
+
end
|
42
|
+
|
43
|
+
# raise ::Padrino::Responder::ResponderError, e.message
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
##
|
48
|
+
# Returns name of current action
|
49
|
+
#
|
50
|
+
def action_name
|
51
|
+
if request.respond_to? :action
|
52
|
+
action = request.action
|
53
|
+
else
|
54
|
+
action, parameters = Padrino.mounted_apps[0].app_obj.recognize_path request.path_info
|
55
|
+
action = action.to_s
|
56
|
+
action.gsub!(/^#{controller_name}_?/, '')
|
57
|
+
end
|
58
|
+
action = 'index' if action == ''
|
59
|
+
action
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# Returns name of current controller
|
64
|
+
#
|
65
|
+
def controller_name
|
66
|
+
request.controller
|
67
|
+
end
|
68
|
+
|
69
|
+
##
|
70
|
+
# Returns translated, human readable name for specified model.
|
71
|
+
#
|
72
|
+
def human_model_name(object)
|
73
|
+
if object.class.respond_to?(:human)
|
74
|
+
object.class.human
|
75
|
+
elsif object.class.respond_to?(:human_name)
|
76
|
+
object.class.human_name
|
77
|
+
else
|
78
|
+
I18n.translate("models.#{object.class.to_s.underscore}", :default => object.class.to_s.humanize)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
##
|
83
|
+
# Returns url
|
84
|
+
#
|
85
|
+
def back_or_default(default)
|
86
|
+
return_to = session.delete(:return_to)
|
87
|
+
return_to || default
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Padrino
|
2
|
+
module Response
|
3
|
+
module Helpers
|
4
|
+
module Simple
|
5
|
+
def error_resp(obj, message=nil)
|
6
|
+
status 400
|
7
|
+
if api_request
|
8
|
+
content_type 'application/json'
|
9
|
+
@resp ||= {}
|
10
|
+
@resp[:success] = false
|
11
|
+
@resp[:errors] = obj.errors if message == nil
|
12
|
+
@resp[:message] = message if message
|
13
|
+
halt 400, @resp.to_json
|
14
|
+
else
|
15
|
+
flash[:warning] = obj.errors.full_messages if message == nil
|
16
|
+
flash[:warning] = message if message
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def success_resp(obj, message=nil)
|
21
|
+
if api_request
|
22
|
+
content_type 'application/json'
|
23
|
+
@resp ||= {}
|
24
|
+
@resp[:success] = true
|
25
|
+
@resp[:message] = message if message
|
26
|
+
halt 200, @resp.to_json
|
27
|
+
else
|
28
|
+
flash[:notice] = message
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Padrino
|
2
|
+
module Response
|
3
|
+
module Notifiers
|
4
|
+
module FlashNotifier
|
5
|
+
##
|
6
|
+
# Saves specified message as flash notification with specified type.
|
7
|
+
#
|
8
|
+
# ==== Examples
|
9
|
+
#
|
10
|
+
# notifier.say(self, :error, "Something went wrong")
|
11
|
+
#
|
12
|
+
# ... will save message to <code>flash[:notice]</code>
|
13
|
+
#
|
14
|
+
def self.say(app, kind, message, *args, &block)
|
15
|
+
app.flash[kind.to_sym] = message
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Padrino
|
2
|
+
module Response
|
3
|
+
module Respond
|
4
|
+
def respond(*options)
|
5
|
+
if ::Padrino::Responders.constants.include?("#{controller_name.capitalize}")
|
6
|
+
responder = ::Padrino::Responders.const_get("#{controller_name.capitalize}").new
|
7
|
+
elsif options.include?(:responder)
|
8
|
+
responder = ::Padrino::Responders.const_get("#{options[:responder]}").new
|
9
|
+
else
|
10
|
+
responder = Padrino::Responders::Default.new
|
11
|
+
end
|
12
|
+
|
13
|
+
responder.object = options.shift if !options.first.is_a?(Hash)
|
14
|
+
options = options.extract_options!
|
15
|
+
responder.object = options.delete(:object) if options.include?(:object)
|
16
|
+
responder.object ||= {}
|
17
|
+
responder.options[:location] = options.shift if options.first.is_a?(String)
|
18
|
+
responder.options.merge!(options)
|
19
|
+
responder.class = self
|
20
|
+
return responder.respond
|
21
|
+
end
|
22
|
+
alias :resp :respond
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
module Padrino
|
2
|
+
module Responders
|
3
|
+
class ResponderError < RuntimeError
|
4
|
+
end
|
5
|
+
class Default
|
6
|
+
include Padrino::Response::StatusCodes
|
7
|
+
attr_accessor :options, :object, :class
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@options = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
# Jsend format?
|
14
|
+
def jsend?
|
15
|
+
return false
|
16
|
+
end
|
17
|
+
|
18
|
+
def respond
|
19
|
+
set_status
|
20
|
+
|
21
|
+
if self.class.request.put?
|
22
|
+
put
|
23
|
+
elsif self.class.request.post?
|
24
|
+
post
|
25
|
+
elsif self.class.request.delete?
|
26
|
+
delete
|
27
|
+
else
|
28
|
+
default
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def put_or_post(message_type, error_detour)
|
33
|
+
message = message(message_type)
|
34
|
+
|
35
|
+
if valid?
|
36
|
+
if location
|
37
|
+
if api_request
|
38
|
+
content = try_render
|
39
|
+
redirect location, content
|
40
|
+
else
|
41
|
+
notify(:notice, message)
|
42
|
+
redirect location
|
43
|
+
end
|
44
|
+
end
|
45
|
+
else
|
46
|
+
set_status 400
|
47
|
+
if api_request
|
48
|
+
return object.errors.to_json
|
49
|
+
else
|
50
|
+
notify(:error, message)
|
51
|
+
try_render error_detour
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def put
|
57
|
+
put_or_post :update, 'edit'
|
58
|
+
end
|
59
|
+
|
60
|
+
def post
|
61
|
+
put_or_post :create, 'new'
|
62
|
+
end
|
63
|
+
|
64
|
+
def delete
|
65
|
+
message = message(:destroy)
|
66
|
+
|
67
|
+
if location
|
68
|
+
if api_request
|
69
|
+
redirect location, {:message => message}.to_json
|
70
|
+
else
|
71
|
+
notify(:notice, message)
|
72
|
+
redirect location
|
73
|
+
end
|
74
|
+
else
|
75
|
+
try_render
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def default
|
80
|
+
if location
|
81
|
+
redirect location
|
82
|
+
else
|
83
|
+
try_render
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def message(type)
|
88
|
+
return @options[:message] if @options[:message]
|
89
|
+
return @options[:error_message] if @options[:error_message] and !valid
|
90
|
+
return @options[:success_message] if @options[:success_message] and valid
|
91
|
+
|
92
|
+
return object.errors.full_messages if !valid?
|
93
|
+
|
94
|
+
object_notice = "responder.messages.#{controller_name}.#{type}"
|
95
|
+
alternative_notice = "responder.messages.default.#{type}"
|
96
|
+
|
97
|
+
object_notice = I18n.translate(object_notice, :model => human_model_name)
|
98
|
+
alternative_notice = I18n.translate(alternative_notice, :model => human_model_name)
|
99
|
+
|
100
|
+
return object_notice unless object_notice.blank?
|
101
|
+
return alternative_notice unless alternative_notice.blank?
|
102
|
+
|
103
|
+
return 'No message found in locale'
|
104
|
+
end
|
105
|
+
|
106
|
+
def valid?
|
107
|
+
valid = true
|
108
|
+
# `valid?` method may override existing errors, so check for those first
|
109
|
+
valid &&= object.valid? if object.respond_to?(:valid?)
|
110
|
+
valid &&= (object.errors.count == 0) if object.respond_to?(:errors)
|
111
|
+
return valid
|
112
|
+
end
|
113
|
+
|
114
|
+
def request
|
115
|
+
self.class.request
|
116
|
+
end
|
117
|
+
|
118
|
+
def notify(kind, message, *args, &block)
|
119
|
+
self.class.notify(kind, message, *args, &block)
|
120
|
+
end
|
121
|
+
|
122
|
+
def try_render(detour_name=nil)
|
123
|
+
self.class.try_render(object, detour_name, self)
|
124
|
+
end
|
125
|
+
|
126
|
+
def redirect(*args)
|
127
|
+
self.class.redirect(*args)
|
128
|
+
end
|
129
|
+
|
130
|
+
def api_request
|
131
|
+
self.class.api_request
|
132
|
+
end
|
133
|
+
|
134
|
+
def human_model_name
|
135
|
+
self.class.human_model_name(object)
|
136
|
+
end
|
137
|
+
|
138
|
+
def controller_name
|
139
|
+
self.class.controller_name
|
140
|
+
end
|
141
|
+
|
142
|
+
def action_name
|
143
|
+
self.class.action_name
|
144
|
+
end
|
145
|
+
|
146
|
+
def location
|
147
|
+
@options[:location]
|
148
|
+
end
|
149
|
+
|
150
|
+
def layout
|
151
|
+
return @options[:layout] if @options.include?(:layout)
|
152
|
+
end
|
153
|
+
|
154
|
+
def set_status(status=nil)
|
155
|
+
if status.is_a?(Integer)
|
156
|
+
self.class.status status
|
157
|
+
elsif status.is_a?(String)
|
158
|
+
self.class.status SYMBOL_TO_STATUS_CODE[status]
|
159
|
+
else
|
160
|
+
self.class.status SYMBOL_TO_STATUS_CODE[@options[:status]] if @options[:status]
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module Padrino
|
2
|
+
module Responders
|
3
|
+
class Jsend < Default
|
4
|
+
include Padrino::Response::StatusCodes
|
5
|
+
attr_accessor :options, :object, :class
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@options = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def jsend?
|
12
|
+
return true
|
13
|
+
end
|
14
|
+
|
15
|
+
def put_or_post(message_type, error_detour)
|
16
|
+
message = message( message_type )
|
17
|
+
if valid?
|
18
|
+
if request.xhr?
|
19
|
+
ajax_obj = {
|
20
|
+
:status => :success,
|
21
|
+
:data => {
|
22
|
+
object.class.to_s.singularize.downcase => object
|
23
|
+
}
|
24
|
+
}
|
25
|
+
end
|
26
|
+
if location
|
27
|
+
if request.xhr?
|
28
|
+
ajax_obj[:data][:redirect] = location
|
29
|
+
return ajax_obj.to_json
|
30
|
+
else
|
31
|
+
notify(:notice, message)
|
32
|
+
redirect location
|
33
|
+
end
|
34
|
+
else
|
35
|
+
try_render
|
36
|
+
end
|
37
|
+
else
|
38
|
+
if request.xhr?
|
39
|
+
ajax_obj = {
|
40
|
+
:status => :fail,
|
41
|
+
:data => {
|
42
|
+
:errors => object.errors
|
43
|
+
}
|
44
|
+
}
|
45
|
+
ajax_obj[:data][:redirect] = location if location
|
46
|
+
return ajax_obj.to_json
|
47
|
+
else
|
48
|
+
notify(:error, message)
|
49
|
+
try_render error_detour
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def delete
|
55
|
+
message = message(:destroy)
|
56
|
+
|
57
|
+
if request.xhr?
|
58
|
+
ajax_obj = {
|
59
|
+
:status => :success,
|
60
|
+
:data => {
|
61
|
+
:message => message
|
62
|
+
}
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
if location
|
67
|
+
if request.xhr?
|
68
|
+
ajax_obj[:data][:redirect] = location
|
69
|
+
return ajax_obj.to_json
|
70
|
+
else
|
71
|
+
notify(:notice, message)
|
72
|
+
redirect location
|
73
|
+
end
|
74
|
+
else
|
75
|
+
try_render
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def default
|
80
|
+
if location
|
81
|
+
if request.xhr?
|
82
|
+
{:status => :success, :data => { :redirect => location } }.to_json
|
83
|
+
else
|
84
|
+
redirect location
|
85
|
+
end
|
86
|
+
else
|
87
|
+
try_render
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Padrino
|
2
|
+
module Response
|
3
|
+
module StatusCodes
|
4
|
+
# Defines the standard HTTP status codes, by integer, with their
|
5
|
+
# corresponding default message texts.
|
6
|
+
# Source: http://www.iana.org/assignments/http-status-codes
|
7
|
+
STATUS_CODES = {
|
8
|
+
100 => "Continue",
|
9
|
+
101 => "Switching Protocols",
|
10
|
+
102 => "Processing",
|
11
|
+
|
12
|
+
200 => "OK",
|
13
|
+
201 => "Created",
|
14
|
+
202 => "Accepted",
|
15
|
+
203 => "Non-Authoritative Information",
|
16
|
+
204 => "No Content",
|
17
|
+
205 => "Reset Content",
|
18
|
+
206 => "Partial Content",
|
19
|
+
207 => "Multi-Status",
|
20
|
+
226 => "IM Used",
|
21
|
+
|
22
|
+
300 => "Multiple Choices",
|
23
|
+
301 => "Moved Permanently",
|
24
|
+
302 => "Found",
|
25
|
+
303 => "See Other",
|
26
|
+
304 => "Not Modified",
|
27
|
+
305 => "Use Proxy",
|
28
|
+
307 => "Temporary Redirect",
|
29
|
+
|
30
|
+
400 => "Bad Request",
|
31
|
+
401 => "Unauthorized",
|
32
|
+
402 => "Payment Required",
|
33
|
+
403 => "Forbidden",
|
34
|
+
404 => "Not Found",
|
35
|
+
405 => "Method Not Allowed",
|
36
|
+
406 => "Not Acceptable",
|
37
|
+
407 => "Proxy Authentication Required",
|
38
|
+
408 => "Request Timeout",
|
39
|
+
409 => "Conflict",
|
40
|
+
410 => "Gone",
|
41
|
+
411 => "Length Required",
|
42
|
+
412 => "Precondition Failed",
|
43
|
+
413 => "Request Entity Too Large",
|
44
|
+
414 => "Request-URI Too Long",
|
45
|
+
415 => "Unsupported Media Type",
|
46
|
+
416 => "Requested Range Not Satisfiable",
|
47
|
+
417 => "Expectation Failed",
|
48
|
+
422 => "Unprocessable Entity",
|
49
|
+
423 => "Locked",
|
50
|
+
424 => "Failed Dependency",
|
51
|
+
426 => "Upgrade Required",
|
52
|
+
|
53
|
+
500 => "Internal Server Error",
|
54
|
+
501 => "Not Implemented",
|
55
|
+
502 => "Bad Gateway",
|
56
|
+
503 => "Service Unavailable",
|
57
|
+
504 => "Gateway Timeout",
|
58
|
+
505 => "HTTP Version Not Supported",
|
59
|
+
507 => "Insufficient Storage",
|
60
|
+
510 => "Not Extended"
|
61
|
+
}
|
62
|
+
|
63
|
+
# Provides a symbol-to-fixnum lookup for converting a symbol (like
|
64
|
+
# :created or :not_implemented) into its corresponding HTTP status
|
65
|
+
# code (like 200 or 501).
|
66
|
+
SYMBOL_TO_STATUS_CODE = STATUS_CODES.inject({}) do |hash, (code, message)|
|
67
|
+
hash[message.gsub(/ /, "").underscore.to_sym] = code
|
68
|
+
hash
|
69
|
+
end
|
70
|
+
|
71
|
+
# Given a status parameter, determine whether it needs to be converted
|
72
|
+
# to a string. If it is a fixnum, use the STATUS_CODES hash to lookup
|
73
|
+
# the default message. If it is a symbol, use the SYMBOL_TO_STATUS_CODE
|
74
|
+
# hash to convert it.
|
75
|
+
def interpret_status(status)
|
76
|
+
case status
|
77
|
+
when Fixnum then
|
78
|
+
STATUS_CODES[status]
|
79
|
+
when Symbol then
|
80
|
+
interpret_status(SYMBOL_TO_STATUS_CODE[status] ||
|
81
|
+
"500 Unknown Status #{status.inspect}")
|
82
|
+
else
|
83
|
+
status.to_s
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "padrino-response/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "padrino-response"
|
7
|
+
s.version = Padrino::Response::VERSION
|
8
|
+
s.authors = ["K-2052"]
|
9
|
+
s.email = ["k@2052.me"]
|
10
|
+
s.homepage = "https://github.com/k2052/padrino-response"
|
11
|
+
s.summary = %q{Eliminates the repetitive response code in your Padrino controllers}
|
12
|
+
s.description = %q{Eliminates the repetitive response code in your Padrino controllers}
|
13
|
+
|
14
|
+
s.rubyforge_project = "padrino-response"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
s.add_development_dependency "rspec"
|
23
|
+
s.add_development_dependency "adapter"
|
24
|
+
s.add_development_dependency "toystore"
|
25
|
+
s.add_development_dependency "rack-test"
|
26
|
+
s.add_dependency "padrino", ">= 0.10.7"
|
27
|
+
s.add_dependency "rake"
|
28
|
+
s.add_dependency "sinatra-flash", ">= 0.3.0"
|
29
|
+
end
|
data/spec/all_spec.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper.rb')
|
2
|
+
|
3
|
+
describe 'Main Controller' do
|
4
|
+
before do
|
5
|
+
header 'Accept', 'application/json'
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should return an error resp' do
|
9
|
+
get '/error'
|
10
|
+
last_response.status.should eq 400
|
11
|
+
resp = MultiJson.load last_response.body
|
12
|
+
resp['success'].should eq false
|
13
|
+
resp['message'].should eq 'Error'
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should return a success resp' do
|
17
|
+
get '/success'
|
18
|
+
last_response.status.should eq 200
|
19
|
+
resp = MultiJson.load last_response.body
|
20
|
+
resp['success'].should eq true
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should return a 404' do
|
24
|
+
get '/not-found'
|
25
|
+
last_response.status.should eq 404
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should return no-content' do
|
29
|
+
get '/no-content'
|
30
|
+
last_response.status.should eq 204
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should create a new human' do
|
34
|
+
post '/new', human: {name: 'Bob'}
|
35
|
+
last_response.status.should eq 302
|
36
|
+
resp = MultiJson.load last_response.body
|
37
|
+
resp['human']['name'].should eq 'Bob'
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should fail to update a human' do
|
41
|
+
put '/fail-update', human: {name: 'Bob'}
|
42
|
+
last_response.status.should eq 400
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should fail to create a human' do
|
46
|
+
post '/fail-create', human: {name: 'Bob'}
|
47
|
+
last_response.status.should eq 400
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'i18n'
|
2
|
+
require 'padrino'
|
3
|
+
require 'padrino-response'
|
4
|
+
require 'adapter/memory'
|
5
|
+
require 'toystore'
|
6
|
+
|
7
|
+
class Human
|
8
|
+
include Toy::Store
|
9
|
+
adapter :memory, {}
|
10
|
+
|
11
|
+
attribute :name, String
|
12
|
+
attribute :dont_set, String
|
13
|
+
validate :dont_set_should_be_blank
|
14
|
+
|
15
|
+
def dont_set_should_be_blank
|
16
|
+
unless self[:dont_set].blank?
|
17
|
+
errors.add :base, "Don't set that!"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class App < Padrino::Application
|
23
|
+
register Padrino::Response
|
24
|
+
register Padrino::Helpers::TranslationHelpers
|
25
|
+
|
26
|
+
controllers :main do
|
27
|
+
get :error, map: '/error' do
|
28
|
+
error_resp Human.new, 'Error'
|
29
|
+
end
|
30
|
+
|
31
|
+
get :success, map: '/success' do
|
32
|
+
success_resp Human.new name: 'Bob'
|
33
|
+
end
|
34
|
+
|
35
|
+
get :not_found, map: '/not-found' do
|
36
|
+
resp status: :not_found
|
37
|
+
end
|
38
|
+
|
39
|
+
get :no_content, map: '/no-content' do
|
40
|
+
resp status: :no_content
|
41
|
+
end
|
42
|
+
|
43
|
+
post :create, map: '/new' do
|
44
|
+
@human = Human.create name: 'Bob'
|
45
|
+
resp @human, location: '/success'
|
46
|
+
end
|
47
|
+
|
48
|
+
put :fail_update, map: '/fail-update' do
|
49
|
+
@human = Human.create name: 'Bob'
|
50
|
+
@human.update_attributes dont_set: 'Cats'
|
51
|
+
resp @human
|
52
|
+
end
|
53
|
+
|
54
|
+
post :fail_create, map: '/fail-create' do
|
55
|
+
@human = Human.create name: 'Bob', dont_set: 'Cats'
|
56
|
+
resp @human
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
Padrino.load!
|
62
|
+
Padrino.mount(App).to('/')
|
data/spec/spec.rake
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
begin
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
|
4
|
+
spec_tasks = Dir['spec/*/'].map { |d| File.basename(d) }
|
5
|
+
|
6
|
+
spec_tasks.each do |folder|
|
7
|
+
RSpec::Core::RakeTask.new("spec:#{folder}") do |t|
|
8
|
+
t.pattern = "./spec/#{folder}/**/*_spec.rb"
|
9
|
+
t.rspec_opts = %w(-fs --color)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "Run complete application spec suite"
|
14
|
+
task 'spec' => spec_tasks.map { |f| "spec:#{f}" }
|
15
|
+
rescue LoadError
|
16
|
+
puts "RSpec is not part of this bundle, skip specs."
|
17
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
PADRINO_ENV = 'test' unless defined?(PADRINO_ENV)
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + "/fixtures/app.rb")
|
3
|
+
require 'rack/test'
|
4
|
+
|
5
|
+
RSpec.configure do |conf|
|
6
|
+
conf.include Rack::Test::Methods
|
7
|
+
end
|
8
|
+
|
9
|
+
def app(app = nil, &blk)
|
10
|
+
@app ||= block_given? ? app.instance_eval(&blk) : app
|
11
|
+
@app ||= Padrino.application
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: padrino-response
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- K-2052
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-11-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: adapter
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: toystore
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rack-test
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: padrino
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.10.7
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.10.7
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: sinatra-flash
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.3.0
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.3.0
|
111
|
+
description: Eliminates the repetitive response code in your Padrino controllers
|
112
|
+
email:
|
113
|
+
- k@2052.me
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- .gitignore
|
119
|
+
- .travis.yml
|
120
|
+
- Gemfile
|
121
|
+
- LICENSE
|
122
|
+
- README.md
|
123
|
+
- Rakefile
|
124
|
+
- lib/padrino-response.rb
|
125
|
+
- lib/padrino-response/helpers/controller.rb
|
126
|
+
- lib/padrino-response/helpers/simple.rb
|
127
|
+
- lib/padrino-response/locale/en.yml
|
128
|
+
- lib/padrino-response/locale/pl.yml
|
129
|
+
- lib/padrino-response/notifiers/flash_notifier.rb
|
130
|
+
- lib/padrino-response/respond.rb
|
131
|
+
- lib/padrino-response/responders/default.rb
|
132
|
+
- lib/padrino-response/responders/jsend.rb
|
133
|
+
- lib/padrino-response/status_codes.rb
|
134
|
+
- lib/padrino-response/version.rb
|
135
|
+
- padrino-response.gemspec
|
136
|
+
- spec/all_spec.rb
|
137
|
+
- spec/fixtures/app.rb
|
138
|
+
- spec/spec.rake
|
139
|
+
- spec/spec_helper.rb
|
140
|
+
homepage: https://github.com/k2052/padrino-response
|
141
|
+
licenses: []
|
142
|
+
metadata: {}
|
143
|
+
post_install_message:
|
144
|
+
rdoc_options: []
|
145
|
+
require_paths:
|
146
|
+
- lib
|
147
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - '>='
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
153
|
+
requirements:
|
154
|
+
- - '>='
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: '0'
|
157
|
+
requirements: []
|
158
|
+
rubyforge_project: padrino-response
|
159
|
+
rubygems_version: 2.0.3
|
160
|
+
signing_key:
|
161
|
+
specification_version: 4
|
162
|
+
summary: Eliminates the repetitive response code in your Padrino controllers
|
163
|
+
test_files: []
|