spiderfw 0.6.25 → 0.6.26.pre1
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/CHANGELOG +15 -0
- data/VERSION +1 -1
- data/apps/core/auth/controllers/login_controller.rb +2 -0
- data/apps/core/auth/controllers/mixins/auth_helper.rb +1 -1
- data/apps/core/auth/public/css/login.css +49 -0
- data/apps/core/auth/views/login.layout.shtml +14 -0
- data/apps/core/auth/views/login.shtml +1 -0
- data/apps/core/components/public/js/jquery/plugins/jquery.ui.nestedSortable.js +356 -0
- data/apps/core/forms/public/date_time.js +1 -1
- data/apps/core/forms/public/select.js +1 -1
- data/apps/core/forms/tags/element_row.erb +2 -2
- data/apps/core/forms/widgets/form/form.rb +34 -22
- data/apps/messenger/_init.rb +1 -0
- data/apps/messenger/views/admin/index.shtml +1 -1
- data/apps/messenger/views/index.shtml +1 -1
- data/blueprints/.DS_Store +0 -0
- data/blueprints/home/.DS_Store +0 -0
- data/blueprints/install/.DS_Store +0 -0
- data/data/keys/spider.rsa +27 -0
- data/data/keys/spider.rsa.pub +1 -0
- data/lib/spiderfw/app.rb +64 -4
- data/lib/spiderfw/autoload.rb +0 -1
- data/lib/spiderfw/cmd/commands/app.rb +2 -1
- data/lib/spiderfw/controller/controller.rb +189 -90
- data/lib/spiderfw/controller/dispatcher.rb +13 -3
- data/lib/spiderfw/controller/http_controller.rb +18 -4
- data/lib/spiderfw/controller/mixins/http_mixin.rb +37 -10
- data/lib/spiderfw/controller/mixins/visual.rb +14 -5
- data/lib/spiderfw/http/http.rb +5 -0
- data/lib/spiderfw/model/base_model.rb +1 -11
- data/lib/spiderfw/model/condition.rb +7 -4
- data/lib/spiderfw/model/mappers/mapper.rb +2 -2
- data/lib/spiderfw/requires.rb +1 -0
- data/lib/spiderfw/setup/app_manager.rb +7 -2
- data/lib/spiderfw/setup/setup_task.rb +1 -1
- data/lib/spiderfw/setup/spider_setup_wizard.rb +1 -1
- data/lib/spiderfw/spider.rb +4 -1
- data/lib/spiderfw/templates/layout.rb +8 -3
- data/lib/spiderfw/templates/template.rb +2 -1
- data/lib/spiderfw/test/rack_tester.rb +10 -0
- data/lib/spiderfw/widget/widget_plugin.rb +8 -1
- metadata +254 -157
- data/lib/spiderfw/model/storage/db/connectors/mysql.rb +0 -16
- data/lib/spiderfw/model/storage/db/connectors/mysql2.rb +0 -9
data/lib/spiderfw/app.rb
CHANGED
@@ -228,6 +228,12 @@ module Spider
|
|
228
228
|
end
|
229
229
|
end
|
230
230
|
|
231
|
+
def route_path(action='')
|
232
|
+
path = Spider::ControllerMixins::HTTPMixin.reverse_proxy_mapping('/'+@route_url)
|
233
|
+
action = action[1..-1] if action[0].chr == '/'
|
234
|
+
[path, action].reject{ |p| p.blank? }.join('/')
|
235
|
+
end
|
236
|
+
|
231
237
|
|
232
238
|
# Convenience method: since all classes inside the app have an #app method,
|
233
239
|
# the App itself has it too
|
@@ -237,14 +243,40 @@ module Spider
|
|
237
243
|
end
|
238
244
|
|
239
245
|
# Require files inside the App's path
|
240
|
-
#
|
246
|
+
#
|
247
|
+
# Can accept either a list of files to require, relative to the app's path; or, a Hash
|
248
|
+
# containing arrays for keys corresponding to folders inside app (e.g. :models, :controllers)
|
249
|
+
#
|
250
|
+
# If an Hash is provided, will load files in the order :lib, :models, :widgets, :controllers, followed
|
251
|
+
# by any additional keys, in the order they are defined in the Hash (under Ruby 1.9.x), or in random order (Ruby 1.8.x)
|
252
|
+
# @param [Hash|file1,file2,...] files to require
|
241
253
|
# @return [nil]
|
242
254
|
def req(*list)
|
243
|
-
|
244
|
-
require File.join(@path,
|
255
|
+
do_require = lambda{ |f|
|
256
|
+
Kernel.require File.join(@path, f)
|
257
|
+
}
|
258
|
+
if list.first.is_a?(Hash)
|
259
|
+
hash = list.first
|
260
|
+
load_keys = ([:lib, :models, :widgets, :controllers] + hash.keys).uniq
|
261
|
+
load_keys.each do |k|
|
262
|
+
if hash[k].is_a?(Array)
|
263
|
+
hash[k].each{ |file|
|
264
|
+
if k == :widgets
|
265
|
+
file = File.join(file, file)
|
266
|
+
end
|
267
|
+
file = File.join(k.to_s, file)
|
268
|
+
do_require.call(file)
|
269
|
+
}
|
270
|
+
end
|
271
|
+
end
|
272
|
+
else
|
273
|
+
list.each do |file|
|
274
|
+
do_require.call(file)
|
275
|
+
end
|
245
276
|
end
|
246
277
|
end
|
247
|
-
|
278
|
+
|
279
|
+
alias :app_require :req
|
248
280
|
|
249
281
|
|
250
282
|
# Returns the currently installed version of an app
|
@@ -600,6 +632,34 @@ END_OF_EVAL
|
|
600
632
|
include TSort
|
601
633
|
|
602
634
|
end
|
635
|
+
|
636
|
+
# This module is included Controller and BaseModel, and provides the
|
637
|
+
# app method, returning the class' app.
|
638
|
+
module AppClass
|
639
|
+
|
640
|
+
def self.included(klass)
|
641
|
+
klass.extend(ClassMethods)
|
642
|
+
end
|
643
|
+
|
644
|
+
# @return [App] The app to which the object's class belongs
|
645
|
+
def app
|
646
|
+
return self.class.app
|
647
|
+
end
|
648
|
+
|
649
|
+
module ClassMethods
|
650
|
+
|
651
|
+
# @return [App] The app to which the class belongs
|
652
|
+
def app
|
653
|
+
return @app if @app
|
654
|
+
@app ||= self.parent_module
|
655
|
+
while @app && !@app.include?(Spider::App) && @app != Object
|
656
|
+
@app = @app.parent_module
|
657
|
+
end
|
658
|
+
@app = nil if @app && !@app.include?(Spider::App)
|
659
|
+
return @app
|
660
|
+
end
|
661
|
+
end
|
662
|
+
end
|
603
663
|
|
604
664
|
end
|
605
665
|
|
data/lib/spiderfw/autoload.rb
CHANGED
@@ -190,6 +190,7 @@ module Spider::CommandLine
|
|
190
190
|
opt.on("--no-clear-cache", _("Don't clear cache"), "-C"){ |c| @no_clear_cache = true }
|
191
191
|
opt.on("--no-restart", _("Don't restart the server after the udpate"), "-R"){ |r| @no_restart = true }
|
192
192
|
opt.on("--branch [BRANCH]", _("Install app from specific branch"), "-b"){ |b| @branch = b }
|
193
|
+
opt.on("--no-rollback", _("Don't rollback if update fails")){ |rb| @no_rollback = rb }
|
193
194
|
end
|
194
195
|
update.set_execution_block do |args|
|
195
196
|
$SPIDER_INTERACTIVE = true
|
@@ -201,7 +202,7 @@ module Spider::CommandLine
|
|
201
202
|
options = {
|
202
203
|
:no_git => @no_git, :all => @all, :no_deps => @no_deps, :no_optional => @no_optional,
|
203
204
|
:no_gems => @no_gems, :no_optional_gems => @no_optional_gems, :no_activate => @no_activate,
|
204
|
-
:clear_cache => !@no_clear_cache, :restart => !@no_restart
|
205
|
+
:clear_cache => !@no_clear_cache, :restart => !@no_restart, :no_rollback => @no_rollback
|
205
206
|
}
|
206
207
|
options[:url] = @server_url if @server_url
|
207
208
|
options[:branch] = @branch if @branch
|
@@ -18,6 +18,7 @@ require 'spiderfw/utils/annotations'
|
|
18
18
|
module Spider
|
19
19
|
|
20
20
|
class Controller
|
21
|
+
include App::AppClass
|
21
22
|
include Dispatcher
|
22
23
|
include Logger
|
23
24
|
include ControllerMixins
|
@@ -25,60 +26,47 @@ module Spider
|
|
25
26
|
include Annotations
|
26
27
|
|
27
28
|
class << self
|
28
|
-
|
29
|
-
def options
|
30
|
-
@options ||= {}
|
31
|
-
end
|
32
|
-
|
33
|
-
def option(k, v)
|
34
|
-
self.option[k] = v
|
35
|
-
end
|
36
29
|
|
37
30
|
def default_action
|
38
31
|
'index'
|
39
32
|
end
|
40
33
|
|
41
|
-
|
42
|
-
return @app if @app
|
43
|
-
@app ||= self.parent_module
|
44
|
-
while @app && !@app.include?(Spider::App) && @app != Object
|
45
|
-
@app = @app.parent_module
|
46
|
-
end
|
47
|
-
@app = nil if @app && !@app.include?(Spider::App)
|
48
|
-
return @app
|
49
|
-
end
|
50
|
-
|
34
|
+
# @return [String] Path to this controller's templates
|
51
35
|
def template_path
|
52
36
|
return nil unless self.app
|
53
|
-
return self.app.path
|
37
|
+
return File.join(self.app.path, '/views')
|
54
38
|
end
|
55
39
|
|
40
|
+
# @return [String] Path to this controller's layouts
|
56
41
|
def layout_path
|
57
42
|
return nil unless self.app
|
58
|
-
return self.app.path
|
43
|
+
return File.join(self.app.path, '/views')
|
59
44
|
end
|
60
45
|
|
61
46
|
# Defines a method that will be called before the controller's before,
|
62
47
|
# if the action matches the given conditions.
|
63
|
-
# - The first argument, the condition(s), may be a String, a Regexp, a Proc or a Symbol,
|
64
|
-
# that will be checked against the action, or an Array containing several conditions.
|
65
|
-
# - The second argument, a Symbol, is the method to be called if the conditions match.
|
66
|
-
# - The third optional argument, an Hash, may contain :unless => true: in this case,
|
67
|
-
# the conditions will be inverted, that is, the method will be executed unless the conditions
|
68
|
-
# match.
|
69
48
|
# Example:
|
70
|
-
# before(
|
49
|
+
# before(/^list_/, :before_lists)
|
71
50
|
# will call the method before_lists if the action starts with 'list_'
|
51
|
+
# @param [String|Regexp|Proc|Symbol|Array] conditions what will be checked against the action
|
52
|
+
# @param [Symbol] method The method to be called if the conditions match.
|
53
|
+
# @param [Hash] params may contain :unless => true: in this case,
|
54
|
+
# the conditions will be inverted, that is, the method will
|
55
|
+
# be executed unless the conditions match.
|
56
|
+
# @return [void]
|
72
57
|
def before(conditions, method, params={})
|
73
58
|
@dispatch_methods ||= {}
|
74
59
|
@dispatch_methods[:before] ||= []
|
75
60
|
@dispatch_methods[:before] << [conditions, method, params]
|
76
61
|
end
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
62
|
+
|
63
|
+
# Like {Controller.before}, but calls the method unless the conditions match
|
64
|
+
# @param [String|Regexp|Proc|Symbol|Array] conditions what will be checked against the action
|
65
|
+
# @param [Symbol] method The method to be called if the conditions match.
|
66
|
+
# @param [Hash] params may contain :unless => true: in this case,
|
67
|
+
# the conditions will be inverted, that is, the method will
|
68
|
+
# be executed unless the conditions match.
|
69
|
+
# @return [void]
|
82
70
|
def before_unless(condition, method, params={})
|
83
71
|
@dispatch_methods ||= {}
|
84
72
|
@dispatch_methods[:before] ||= []
|
@@ -86,6 +74,19 @@ module Spider
|
|
86
74
|
@dispatch_methods[:before] << [condition, method, params]
|
87
75
|
end
|
88
76
|
|
77
|
+
# @return [Array] An array of methods defined with {Controller.before}
|
78
|
+
def before_methods
|
79
|
+
@dispatch_methods && @dispatch_methods[:before] ? @dispatch_methods[:before] : []
|
80
|
+
end
|
81
|
+
|
82
|
+
# Registers a list of methods as controller actions, that is, methods that can
|
83
|
+
# be dispatched to.
|
84
|
+
#
|
85
|
+
# This method is not usually called directly; using the __.action annotation,
|
86
|
+
# or one of the format annotations (__.html, __.xml, __.json, __.text), will
|
87
|
+
# make a method a controller action.
|
88
|
+
# @param [*Symbol] A list of methods
|
89
|
+
# @return [Array] All defined controller actions
|
89
90
|
def controller_actions(*methods)
|
90
91
|
if (methods.length > 0)
|
91
92
|
@controller_actions ||= []
|
@@ -93,7 +94,15 @@ module Spider
|
|
93
94
|
end
|
94
95
|
@controller_actions
|
95
96
|
end
|
97
|
+
|
98
|
+
def controller_action(method, params)
|
99
|
+
@controller_actions ||= []
|
100
|
+
@controller_actions << method
|
101
|
+
@controller_action_params ||= {}
|
102
|
+
@controller_action_params[method] = params
|
103
|
+
end
|
96
104
|
|
105
|
+
# @return [bool] true if the method is a controller action
|
97
106
|
def controller_action?(method)
|
98
107
|
return false unless self.method_defined?(method)
|
99
108
|
return true if default_action && method == default_action.to_sym
|
@@ -108,35 +117,75 @@ module Spider
|
|
108
117
|
end
|
109
118
|
end
|
110
119
|
|
120
|
+
# Finds a resource in the context of the controller's app
|
121
|
+
# See {Spider.find_resource}
|
122
|
+
# @param [Symbol] resource_type
|
123
|
+
# @param [String] path
|
124
|
+
# @param [String] cur_path Current path: if set, will be used to resolve relative paths
|
125
|
+
# @return [Resource]
|
111
126
|
def find_resource(type, name, cur_path=nil)
|
112
127
|
Spider.find_resource(type, name, cur_path, self)
|
113
128
|
end
|
114
129
|
|
130
|
+
# Returns the path of a resource, or nil if none is found
|
131
|
+
# See {Controller.find_resource}
|
132
|
+
# @param [Symbol] resource_type
|
133
|
+
# @param [String] path
|
134
|
+
# @param [String] cur_path Current path: if set, will be used to resolve relative paths
|
135
|
+
# @return [Resource]
|
115
136
|
def find_resource_path(type, name, cur_path=nil)
|
116
137
|
res = Spider.find_resource(type, name, cur_path, self)
|
117
138
|
return res ? res.path : nil
|
118
139
|
end
|
119
140
|
|
120
|
-
#
|
121
|
-
|
141
|
+
# @param [String] action Additional action to get path for
|
142
|
+
# @return [String] The canonical URL path for this controller
|
143
|
+
def route_path(action=nil)
|
122
144
|
u = @default_route || ''
|
123
145
|
u += "/#{action}" if action
|
124
146
|
if @default_dispatcher && @default_dispatcher != self
|
125
|
-
u = @default_dispatcher.
|
147
|
+
u = @default_dispatcher.route_path(u)
|
126
148
|
elsif self.app
|
127
|
-
u = self.app.
|
149
|
+
u = self.app.route_path(u)
|
128
150
|
end
|
129
151
|
u
|
130
152
|
end
|
153
|
+
|
154
|
+
# Returns the full URL for the Controller
|
155
|
+
# The Controller's implementation returns the route_path.
|
156
|
+
#
|
157
|
+
# However, the HTTPMixin will override this method to return a full http url;
|
158
|
+
# other mixins can override the method in different ways.
|
159
|
+
# @param [String] action Additional action to get path for
|
160
|
+
# @return [String] The canonical URL for this controller
|
161
|
+
def url(action=nil)
|
162
|
+
route_path(action)
|
163
|
+
end
|
164
|
+
alias :route_url :url
|
131
165
|
|
132
166
|
|
133
167
|
end
|
134
168
|
|
135
|
-
define_annotation(:action) { |k, m| k.
|
169
|
+
define_annotation(:action) { |k, m, params| k.controller_action(m, params) }
|
136
170
|
|
137
|
-
|
138
|
-
|
171
|
+
# @return [Spider::Request]
|
172
|
+
attr_reader :request
|
173
|
+
# @return [Spider::Response]
|
174
|
+
attr_reader :response
|
175
|
+
# @return [Symbol] The method currently set to be executed, if any
|
176
|
+
attr_reader :executed_method
|
177
|
+
# @return [Scene]
|
178
|
+
attr_reader :scene
|
179
|
+
# @return [String] Action used to reach this controller in the dispatch chain
|
180
|
+
attr_accessor :dispatch_action
|
181
|
+
# @return [bool] True if the controller is the target of the current action
|
182
|
+
attr_accessor :is_target
|
139
183
|
|
184
|
+
# Constructor. Note: you can use the {Controller#init} method for custom
|
185
|
+
# initialization, instead of overrideing this method
|
186
|
+
# @param [Spider::Request] request
|
187
|
+
# @param [Spider::Response] response
|
188
|
+
# @param [scene]
|
140
189
|
def initialize(request, response, scene=nil)
|
141
190
|
@request = request
|
142
191
|
@response = response
|
@@ -144,19 +193,20 @@ module Spider
|
|
144
193
|
@dispatch_path = ''
|
145
194
|
@is_target = true
|
146
195
|
init
|
147
|
-
#@parent = parent
|
148
196
|
end
|
149
197
|
|
150
198
|
# Override this for controller initialization
|
199
|
+
# @return [void]
|
151
200
|
def init
|
152
|
-
|
153
201
|
end
|
154
202
|
|
203
|
+
# @return [String]
|
155
204
|
def inspect
|
156
205
|
self.class.to_s
|
157
206
|
end
|
158
207
|
|
159
|
-
|
208
|
+
# @return [String] The actual action path used to reach this Controller
|
209
|
+
def request_path
|
160
210
|
act = @dispatch_action || ''
|
161
211
|
if (@dispatch_previous)
|
162
212
|
prev = @dispatch_previous.call_path
|
@@ -164,16 +214,15 @@ module Spider
|
|
164
214
|
end
|
165
215
|
return ('/'+act).gsub(/\/+/, '/').sub(/\/$/, '')
|
166
216
|
end
|
217
|
+
alias :call_path :request_path
|
167
218
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
219
|
+
# Returns the method to call on the controller given an action, and the arguments
|
220
|
+
# that should be passed to it.
|
221
|
+
# @param [String] action
|
222
|
+
# @return [Array] A two elements array, containing the method, and additional arguments
|
172
223
|
def get_action_method(action)
|
173
224
|
method = nil
|
174
225
|
additional_arguments = nil
|
175
|
-
# method = action.empty? ? self.class.default_action : action
|
176
|
-
# method = method.split('/', 2)[0]
|
177
226
|
if (action =~ /^([^:]+)(:.+)$/)
|
178
227
|
method = $1
|
179
228
|
elsif (action =~ /^([^\/]+)\/(.+)$/) # methods followed by a slash
|
@@ -191,16 +240,26 @@ module Spider
|
|
191
240
|
|
192
241
|
# Returns true if this controller is the final target for the current action, that is, if it does not
|
193
242
|
# dispatch to any route
|
243
|
+
# @return [bool] True if the controller is the final target
|
194
244
|
def action_target?
|
195
|
-
!@dispatch_next[@call_path] || @dispatch_next[@call_path].dest == self
|
245
|
+
!@dispatch_next[@call_path] || @dispatch_next[@call_path].dest == self \
|
246
|
+
|| @dispatch_next[@call_path].dest == self.class
|
196
247
|
end
|
197
248
|
|
198
|
-
#
|
249
|
+
# @return [bool] false if the target of the call is a widget, true otherwise
|
199
250
|
def is_target?
|
200
251
|
@is_target
|
201
252
|
end
|
202
253
|
|
203
254
|
|
255
|
+
# The main controller's execution method. The Controller will dispatch
|
256
|
+
# to another controller if a route is set; otherwise, it will call the
|
257
|
+
# method that should be executed according to action.
|
258
|
+
#
|
259
|
+
# This method can be overridden in subclasses, but remember to call super,
|
260
|
+
# or the dispatch chain will stop!
|
261
|
+
# @param [String] action The current action
|
262
|
+
# @param [*Object] arguments Additional action arguments
|
204
263
|
def execute(action='', *arguments)
|
205
264
|
return if @__done
|
206
265
|
debug("Controller #{self} executing #{action} with arguments #{arguments}")
|
@@ -218,7 +277,7 @@ module Spider
|
|
218
277
|
if @executed_method
|
219
278
|
meth = self.method(@executed_method)
|
220
279
|
args = arguments + @executed_method_arguments
|
221
|
-
@
|
280
|
+
@current_action = action
|
222
281
|
arity = meth.arity
|
223
282
|
unless arity == -1
|
224
283
|
arity = (-arity + 1) if arity < 0
|
@@ -234,6 +293,9 @@ module Spider
|
|
234
293
|
end
|
235
294
|
end
|
236
295
|
|
296
|
+
# Helper method, that calls and propagates #before
|
297
|
+
# @param [String] action The current action
|
298
|
+
# @param [*Object] arguments Additional action arguments
|
237
299
|
def call_before(action='', *arguments)
|
238
300
|
return if respond_to?(:serving_static?) && self.serving_static?
|
239
301
|
@call_path = action
|
@@ -246,11 +308,21 @@ module Spider
|
|
246
308
|
end
|
247
309
|
end
|
248
310
|
end
|
249
|
-
|
311
|
+
|
312
|
+
# This method can be implemented by Controllers, and will be called
|
313
|
+
# on the controller chain before the execute method.
|
314
|
+
#
|
315
|
+
# This method is usually reserved for preprocessing that does not
|
316
|
+
# output to the browser, to allow other controllers in chain to set response
|
317
|
+
# headers.
|
318
|
+
# @param [String] action The current action
|
319
|
+
# @param [*Object] arguments Additional action arguments
|
250
320
|
def before(action='', *arguments)
|
251
321
|
end
|
252
322
|
|
253
|
-
|
323
|
+
# Helper method, that calls and propagates #after
|
324
|
+
# @param [String] action The current action
|
325
|
+
# @param [*Object] arguments Additional action arguments
|
254
326
|
def call_after(action='', *arguments)
|
255
327
|
return if respond_to?(:serving_static?) && self.serving_static?
|
256
328
|
after(action, *arguments)
|
@@ -260,43 +332,63 @@ module Spider
|
|
260
332
|
do_dispatch(:call_after, action, *arguments)
|
261
333
|
end
|
262
334
|
end
|
263
|
-
# begin
|
264
|
-
# run_chain(:after)
|
265
|
-
# #dispatch(:after, action, params)
|
266
|
-
# rescue => exc
|
267
|
-
# try_rescue(exc)
|
268
|
-
# end
|
269
335
|
end
|
270
336
|
|
337
|
+
# This method can be implemented by Controllers, and will be called
|
338
|
+
# on the controller chain after the execute method.
|
339
|
+
#
|
340
|
+
# If the webserver supports it, this method will be called after the response
|
341
|
+
# has been returned to the browser; so, it's suitable for post processing.
|
342
|
+
# If you aren't using a threaded web server, though, keep in mind that the
|
343
|
+
# process won't be available to service other requests.
|
344
|
+
# @param [String] action The current action
|
345
|
+
# @param [*Object] arguments Additional action arguments
|
271
346
|
def after(action='', *arguments)
|
272
347
|
end
|
273
348
|
|
349
|
+
# @return [bool] True if the controller is done, and should not continue dispatching.
|
274
350
|
def done?
|
275
351
|
@__done
|
276
352
|
end
|
277
353
|
|
354
|
+
# Stops the execution of the controller chain
|
355
|
+
# @return [void]
|
278
356
|
def done
|
279
357
|
self.done = true
|
280
358
|
throw :done
|
281
359
|
end
|
282
360
|
|
361
|
+
# Sets the controller chain's "done" state
|
362
|
+
# @param [bool] val
|
363
|
+
# @return [void]
|
283
364
|
def done=(val)
|
284
365
|
@__done = val
|
285
366
|
@dispatch_previous.done = val if @dispatch_previous
|
286
367
|
end
|
287
368
|
|
369
|
+
# Checks if an action responds to given route conditions. Is called by
|
370
|
+
# {Dispatcher#do_dispatch}.
|
371
|
+
# The default implementation calls Controller.check_action, which in turn is mixed in
|
372
|
+
# from {Dispatcher::ClassMethods#check_action}
|
373
|
+
# @param [String] action
|
374
|
+
# @param [Array] c An array of route conditions
|
375
|
+
# @return [bool]
|
288
376
|
def check_action(action, c)
|
289
377
|
self.class.check_action(action, c)
|
290
378
|
end
|
291
379
|
|
380
|
+
# Returns a new Scene instance for use in the controller.
|
381
|
+
# @param [Hash] scene Hash to construct the scene from
|
382
|
+
# @return [Scene]
|
292
383
|
def get_scene(scene=nil)
|
293
384
|
scene = Scene.new(scene) if scene.class == Hash
|
294
385
|
scene ||= Scene.new
|
295
|
-
# debugger
|
296
|
-
# scene.extend(SceneMethods)
|
297
386
|
return scene
|
298
387
|
end
|
299
388
|
|
389
|
+
# Sets controller information on a scene
|
390
|
+
# @param [Scene] scene
|
391
|
+
# @return [Scene]
|
300
392
|
def prepare_scene(scene)
|
301
393
|
req_path = @request.path
|
302
394
|
req_path += 'index' if !req_path.blank? && req_path[-1].chr == '/'
|
@@ -312,19 +404,17 @@ module Spider
|
|
312
404
|
return scene
|
313
405
|
end
|
314
406
|
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
action_method, action_params = get_action_method(action)
|
320
|
-
if route.nil_route && !action.blank? && self.respond_to?(action_method)
|
321
|
-
route.action = action
|
322
|
-
end
|
323
|
-
route
|
407
|
+
# See {Controller.controller_action?}
|
408
|
+
# @return [bool] True if the method is a controller action for the class
|
409
|
+
def controller_action?(method)
|
410
|
+
self.class.controller_action?(method)
|
324
411
|
end
|
325
412
|
|
326
413
|
protected
|
327
414
|
|
415
|
+
# Instantiates an object dispatched by a route
|
416
|
+
# @param [Route]
|
417
|
+
# @return [Controller]
|
328
418
|
def dispatched_object(route)
|
329
419
|
klass = route.dest
|
330
420
|
if klass.class != Class
|
@@ -332,6 +422,9 @@ module Spider
|
|
332
422
|
set_executed_method(route.action)
|
333
423
|
end
|
334
424
|
return klass
|
425
|
+
elsif klass == self.class
|
426
|
+
self.set_action(route.action)
|
427
|
+
return self
|
335
428
|
end
|
336
429
|
obj = klass.new(@request, @response, @scene)
|
337
430
|
obj.dispatch_action = route.matched || ''
|
@@ -341,46 +434,52 @@ module Spider
|
|
341
434
|
return obj
|
342
435
|
end
|
343
436
|
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
437
|
+
# Given an action, sets the executed method unless it can be dispatched
|
438
|
+
# @param [String] action
|
439
|
+
# @return [Symbol|nil] The executed method, if it was set, or nil
|
348
440
|
def set_action(action)
|
349
441
|
@executed_method = nil
|
350
442
|
@executed_method_arguments = nil
|
351
443
|
if !can_dispatch?(:execute, action)
|
352
|
-
set_executed_method(action)
|
444
|
+
return set_executed_method(action)
|
353
445
|
end
|
446
|
+
nil
|
354
447
|
end
|
355
448
|
|
449
|
+
# Given an action, sets executed_method and executed_method_arguments
|
450
|
+
# @param [String] action
|
451
|
+
# @return [Symbol] The executed_method
|
356
452
|
def set_executed_method(action)
|
357
453
|
method, additional_arguments = get_action_method(action)
|
358
|
-
if
|
454
|
+
if method && controller_action?(method)
|
359
455
|
@executed_method = method.to_sym
|
360
456
|
@executed_method_arguments = additional_arguments || []
|
361
457
|
end
|
362
458
|
return @executed_method
|
363
459
|
end
|
364
|
-
|
365
460
|
|
461
|
+
# This method can be overrided by subclasses, to provide custom handling of
|
462
|
+
# exceptions
|
463
|
+
# @param [Exception]
|
464
|
+
# @return [void]
|
366
465
|
def try_rescue(exc)
|
367
466
|
raise exc
|
368
467
|
end
|
369
|
-
|
370
|
-
|
468
|
+
|
371
469
|
private
|
372
|
-
|
373
|
-
def pass
|
374
|
-
action = @call_path
|
375
|
-
return false unless can_dispatch?(:execute, action)
|
376
|
-
#debug("CAN DISPATCH #{action}")
|
377
|
-
do_dispatch(:execute, action)
|
378
|
-
return true
|
379
|
-
end
|
380
|
-
|
381
|
-
module SceneMethods
|
382
|
-
end
|
383
470
|
|
471
|
+
# Overrides {Dispatcher#get_route}, setting the action for nil routes
|
472
|
+
# @param [String] path
|
473
|
+
def get_route(*args)
|
474
|
+
route = super
|
475
|
+
return route unless route
|
476
|
+
action = route.path.split('/').first
|
477
|
+
action_method, action_params = get_action_method(action)
|
478
|
+
if route.nil_route && !action.blank? && self.respond_to?(action_method)
|
479
|
+
route.action = action
|
480
|
+
end
|
481
|
+
route
|
482
|
+
end
|
384
483
|
|
385
484
|
end
|
386
485
|
|
@@ -62,7 +62,8 @@ module Spider
|
|
62
62
|
return nil if obj == self && route_action == action # short circuit
|
63
63
|
meth_action = route_action.length > 0 ? route_action : obj.class.default_action
|
64
64
|
begin
|
65
|
-
|
65
|
+
# Apply dispatch methods (see {Controller.before})
|
66
|
+
if obj.class.dispatch_methods && obj.class.dispatch_methods[method]
|
66
67
|
obj.class.dispatch_methods[method].each do |dm|
|
67
68
|
conditions, d_method, params = dm
|
68
69
|
test = check_action(route_action, conditions)
|
@@ -71,6 +72,7 @@ module Spider
|
|
71
72
|
end
|
72
73
|
end
|
73
74
|
res = obj.send(method, route_action, *(new_arguments))
|
75
|
+
# Call, for example, before_my_method
|
74
76
|
unless meth_action.empty?
|
75
77
|
meth_action = meth_action[0..-2] if meth_action[-1].chr == '/'
|
76
78
|
meth_action = meth_action.split('/', 2)[0]
|
@@ -131,6 +133,7 @@ module Spider
|
|
131
133
|
try, dest, options = route
|
132
134
|
action = nil
|
133
135
|
nil_route = false
|
136
|
+
next if options[:http_method] && @request.http_method != options[:http_method]
|
134
137
|
case try
|
135
138
|
when true, nil
|
136
139
|
action = path
|
@@ -157,8 +160,8 @@ module Spider
|
|
157
160
|
end
|
158
161
|
when Proc
|
159
162
|
res = try.call(path, self)
|
160
|
-
if
|
161
|
-
if
|
163
|
+
if res
|
164
|
+
if res.is_a?(Array)
|
162
165
|
action = res[0]
|
163
166
|
params = res[1]
|
164
167
|
matched = res[1]
|
@@ -166,6 +169,13 @@ module Spider
|
|
166
169
|
action = res
|
167
170
|
end
|
168
171
|
end
|
172
|
+
when Symbol
|
173
|
+
if Spider::HTTP::METHODS.include?(try)
|
174
|
+
if @request.http_method == try
|
175
|
+
action = path
|
176
|
+
matched = nil
|
177
|
+
end
|
178
|
+
end
|
169
179
|
end
|
170
180
|
if action
|
171
181
|
action = action[1..-1] if action[0] && action[0].chr == '/'
|