pakyow-core 0.7.2 → 0.8rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/pakyow-core/bin/pakyow +7 -6
  2. data/pakyow-core/lib/commands/USAGE +2 -1
  3. data/pakyow-core/lib/commands/console.rb +1 -1
  4. data/pakyow-core/lib/commands/server.rb +1 -1
  5. data/pakyow-core/lib/core/application.rb +129 -404
  6. data/pakyow-core/lib/core/base.rb +16 -4
  7. data/pakyow-core/lib/core/configuration/app.rb +6 -2
  8. data/pakyow-core/lib/core/configuration/server.rb +6 -1
  9. data/pakyow-core/lib/core/fn_context.rb +5 -0
  10. data/pakyow-core/lib/core/helpers.rb +16 -0
  11. data/pakyow-core/lib/core/loader.rb +1 -2
  12. data/pakyow-core/lib/core/log.rb +13 -9
  13. data/pakyow-core/lib/core/middleware/logger.rb +37 -0
  14. data/pakyow-core/lib/core/middleware/not_found.rb +40 -0
  15. data/pakyow-core/lib/core/middleware/presenter.rb +25 -0
  16. data/pakyow-core/lib/core/middleware/reloader.rb +14 -0
  17. data/pakyow-core/lib/core/middleware/router.rb +33 -0
  18. data/pakyow-core/lib/core/middleware/setup.rb +15 -0
  19. data/pakyow-core/lib/core/middleware/static.rb +27 -0
  20. data/pakyow-core/lib/core/presenter_base.rb +4 -0
  21. data/pakyow-core/lib/core/request.rb +43 -15
  22. data/pakyow-core/lib/core/response.rb +6 -0
  23. data/pakyow-core/lib/core/route_lookup.rb +37 -0
  24. data/pakyow-core/lib/core/route_set.rb +260 -0
  25. data/pakyow-core/lib/core/route_template.rb +77 -0
  26. data/pakyow-core/lib/core/route_template_defaults.rb +29 -0
  27. data/pakyow-core/lib/core/router.rb +156 -0
  28. data/pakyow-core/lib/generators/pakyow/app/app_generator.rb +12 -2
  29. data/pakyow-core/lib/generators/pakyow/app/templates/app.rb +12 -0
  30. data/pakyow-core/lib/generators/pakyow/app/templates/config.ru +1 -1
  31. data/pakyow-core/lib/generators/pakyow/app/templates/rakefile +1 -1
  32. data/pakyow-core/lib/generators/pakyow/app/templates/{app/views → views}/main.html +0 -0
  33. data/pakyow-core/lib/generators/pakyow/app/templates/{app/views → views}/pakyow.html +1 -1
  34. data/pakyow-core/lib/utils/string.rb +11 -10
  35. metadata +61 -71
  36. data/pakyow-core/lib/core/logger.rb +0 -33
  37. data/pakyow-core/lib/core/reloader.rb +0 -12
  38. data/pakyow-core/lib/core/route_store.rb +0 -220
  39. data/pakyow-core/lib/core/static.rb +0 -25
  40. data/pakyow-core/lib/generators/pakyow/app/templates/app/lib/application_controller.rb +0 -6
  41. data/pakyow-core/lib/generators/pakyow/app/templates/config/application.rb +0 -18
  42. data/pakyow-core/lib/generators/pakyow/app/templates/logs/requests.log +0 -0
@@ -1,16 +1,12 @@
1
1
  module Pakyow
2
2
  class Application
3
3
  class << self
4
- attr_accessor :routes_proc, :handlers_proc, :middleware_proc, :configurations
4
+ attr_accessor :core_proc, :middleware_proc, :middlewares, :configurations
5
5
 
6
6
  # Sets the path to the application file so it can be reloaded later.
7
7
  #
8
8
  def inherited(subclass)
9
- Pakyow::Configuration::App.application_path = parse_path_from_caller(caller[0])
10
- end
11
-
12
- def parse_path_from_caller(caller)
13
- caller.match(/^(.+)(:?:\d+(:?:in `.+')?$)/)[1]
9
+ Pakyow::Configuration::App.application_path = StringUtils.parse_path_from_caller(caller[0])
14
10
  end
15
11
 
16
12
  # Runs the application. Accepts the environment(s) to run, for example:
@@ -19,10 +15,11 @@ module Pakyow
19
15
  #
20
16
  def run(*args)
21
17
  return if running?
18
+
22
19
  @running = true
23
20
  self.builder.run(self.prepare(args))
24
21
  detect_handler.run(builder, :Host => Pakyow::Configuration::Base.server.host, :Port => Pakyow::Configuration::Base.server.port) do |server|
25
- trap(:INT) { stop(server) }
22
+ trap(:INT) { stop(server) }
26
23
  trap(:TERM) { stop(server) }
27
24
  end
28
25
  end
@@ -70,32 +67,50 @@ module Pakyow
70
67
  self.configurations[environment] = block
71
68
  end
72
69
 
73
- # Creates routes. Example:
74
- # routes { get '/' { # do something } }
70
+ # The block that stores routes, handlers, and hooks.
75
71
  #
76
- def routes(&block)
77
- self.routes_proc = block
72
+ def core(&block)
73
+ self.core_proc = block
78
74
  end
79
75
 
80
- # Creates handlers for later execution.
81
- # The handler can be created one of two ways:
82
- #
83
- # Define a controller/action handler with an associate response status:
84
- # handler(name, 404, :ApplicationController, :handle_404)
85
- #
86
- # Specify a block as a handler:
87
- # handler(name, 404) { # handle error }
76
+ # The block that stores presenter related things.
88
77
  #
89
- # If a controller calls #invoke_handler!(name) then the
90
- # handler defined for that code will be invoked.
91
- #
92
- def handlers(&block)
93
- self.handlers_proc = block
78
+ def presenter(&block)
79
+ Configuration::Base.app.presenter.proc = block
94
80
  end
95
81
 
96
82
  def middleware(&block)
97
83
  self.middleware_proc = block
98
84
  end
85
+
86
+ def before(step, middlewares)
87
+ middlewares = [middlewares] unless middlewares.is_a?(Array)
88
+ step = step.to_sym
89
+
90
+ self.middlewares ||= {}
91
+ self.middlewares[step] ||= {}
92
+ (self.middlewares[step][:before] ||= []).concat(middlewares)
93
+ end
94
+
95
+ def after(step, middlewares)
96
+ middlewares = [middlewares] unless middlewares.is_a?(Array)
97
+ step = step.to_sym
98
+
99
+ self.middlewares ||= {}
100
+ self.middlewares[step] ||= {}
101
+ (self.middlewares[step][:after] ||= []).concat(middlewares)
102
+ end
103
+
104
+ def use(step, type, builder)
105
+ return unless self.middlewares
106
+ return unless self.middlewares[step]
107
+ return unless self.middlewares[step][type]
108
+
109
+ self.middlewares[step][type].each { |m|
110
+ builder.use(m)
111
+ }
112
+ end
113
+
99
114
 
100
115
  protected
101
116
 
@@ -106,10 +121,29 @@ module Pakyow
106
121
  return if prepared?
107
122
 
108
123
  self.builder.use(Rack::MethodOverride)
124
+
125
+ self.builder.use(Pakyow::Middleware::Setup)
126
+
127
+ #TODO possibly deprecate
109
128
  self.builder.instance_eval(&self.middleware_proc) if self.middleware_proc
110
- self.builder.use(Pakyow::Static) if Configuration::Base.app.static
111
- self.builder.use(Pakyow::Logger) if Configuration::Base.app.log
112
- self.builder.use(Pakyow::Reloader) if Configuration::Base.app.auto_reload
129
+
130
+ self.builder.use(Pakyow::Middleware::Static) if Configuration::Base.app.static
131
+ self.builder.use(Pakyow::Middleware::Logger) if Configuration::Base.app.log
132
+ self.builder.use(Pakyow::Middleware::Reloader) if Configuration::Base.app.auto_reload
133
+
134
+ if Configuration::Base.app.presenter
135
+ self.use(:presentation, :before, self.builder)
136
+ self.builder.use(Pakyow::Middleware::Presenter)
137
+ self.use(:presentation, :after, self.builder)
138
+ end
139
+
140
+ unless Configuration::Base.app.ignore_routes
141
+ self.use(:routing, :before, self.builder)
142
+ self.builder.use(Pakyow::Middleware::Router)
143
+ self.use(:routing, :after, self.builder)
144
+ end
145
+
146
+ self.builder.use(Pakyow::Middleware::NotFound) # always
113
147
 
114
148
  @prepared = true
115
149
 
@@ -128,9 +162,12 @@ module Pakyow
128
162
  end
129
163
 
130
164
  def detect_handler
131
- ['thin', 'mongrel', 'webrick'].each do |server|
165
+ handlers = ['thin', 'mongrel', 'webrick']
166
+ handlers.unshift(Configuration::Base.server.handler) if Configuration::Base.server.handler
167
+
168
+ handlers.each do |handler|
132
169
  begin
133
- return Rack::Handler.get(server)
170
+ return Rack::Handler.get(handler)
134
171
  rescue LoadError
135
172
  rescue NameError
136
173
  end
@@ -151,408 +188,102 @@ module Pakyow
151
188
 
152
189
  include Helpers
153
190
 
154
- attr_accessor :request, :response, :presenter, :route_store, :restful_routes, :handler_store
191
+ attr_accessor :request, :response, :presenter, :router
155
192
 
156
193
  def initialize
157
194
  Pakyow.app = self
158
- @handler_name_to_code = {}
159
- @handler_code_to_name = {}
160
-
161
- # This configuration option will be set if a presenter is to be used
162
- if Configuration::Base.app.presenter
163
- # Create a new instance of the presenter
164
- self.presenter = Configuration::Base.app.presenter.new
165
- end
166
195
 
196
+ Pakyow.app.presenter = Configuration::Base.app.presenter.instance if Configuration::Base.app.presenter
197
+
167
198
  # Load application files
168
199
  load_app(false)
169
- end
170
-
171
- # Interrupts the application and returns response immediately.
172
- #
173
- def halt!
174
- throw :halt, self.response
175
- end
176
200
 
177
- def invoke_route!(route, method=nil)
178
- base_route, ignore_format = StringUtils.split_at_last_dot(route)
179
- self.request.working_path = base_route
180
- self.request.working_method = method if method
181
- block = prepare_route_block(route, self.request.working_method)
182
- throw :new_block, block
201
+ # Prepare for logging
202
+ Log.reopen
183
203
  end
184
204
 
185
- def invoke_handler!(name_or_code)
186
- if block = @handler_store[name_or_code]
187
- # we are given a name
188
- code = @handler_name_to_code[name_or_code]
189
- self.response.status = code if code
190
- throw :new_block, block
191
- elsif name = @handler_code_to_name[name_or_code]
192
- # we are given a code
193
- block = @handler_store[name]
194
- self.response.status = name_or_code
195
- throw :new_block, block
196
- else
197
- # no block to be found
198
- # do we assume code if a number and set status?
199
- self.response.status = name_or_code if name_or_code.is_a?(Fixnum)
200
- # still need to stop execution, I think? But do nothing.
201
- throw :new_block, nil
202
- end
205
+ def setup_rr(env)
206
+ self.request = Request.new(env)
207
+ self.response = Response.new
203
208
  end
204
209
 
205
210
  # Called on every request.
206
211
  #
207
212
  def call(env)
208
- self.request = Request.new(env)
209
- self.response = Rack::Response.new
210
- base_route, ignore_format = StringUtils.split_at_last_dot(self.request.path)
211
- self.request.working_path = base_route
212
- self.request.working_method = self.request.method
213
-
214
- has_route = false
215
- catch(:halt) {
216
- route_block = prepare_route_block(self.request.path, self.request.method)
217
- has_route = true if route_block
218
-
219
- if self.presenter
220
- self.presenter.prepare_for_request(self.request)
221
- end
222
-
223
- has_route = trampoline(route_block)
224
-
225
- if self.presenter
226
- self.response.body = [self.presenter.content]
227
- end
228
-
229
- # 404 if no route matched and no views were found
230
- if !has_route && (!self.presenter || !self.presenter.presented?)
231
- Log.enter "[404] Not Found"
232
- handler404 = @handler_store[@handler_code_to_name[404]] if @handler_code_to_name[404]
233
- if handler404
234
- catch(:halt) {
235
- if self.presenter
236
- self.presenter.prepare_for_request(self.request)
237
- end
238
- trampoline(handler404)
239
- if self.presenter then
240
- self.response.body = [self.presenter.content]
241
- end
242
- }
243
- end
244
- self.response.status = 404
245
- end
246
- } #end :halt catch block
247
-
248
- # This needs to be in the 'return' position (last statement)
249
- finish!
250
-
251
- rescue StandardError => error
252
- self.request.error = error
253
- handler500 = @handler_store[@handler_code_to_name[500]] if @handler_code_to_name[500]
254
- if handler500
255
- catch(:halt) {
256
- if self.presenter
257
- self.presenter.prepare_for_request(self.request)
258
- end
259
- trampoline(handler500)
260
- if self.presenter then
261
- self.response.body = [self.presenter.content]
262
- end
263
- } #end :halt catch block
264
- end
265
- self.response.status = 500
266
-
267
- if Configuration::Base.app.errors_in_browser
268
- self.response.body = []
269
- self.response.body << "<h4>#{CGI.escapeHTML(error.to_s)}</h4>"
270
- self.response.body << error.backtrace.join("<br />")
271
- end
272
-
273
- begin
274
- # caught by other middleware (e.g. logger)
275
- throw :error, error
276
- rescue ArgumentError
277
- end
278
-
279
- finish!
280
- end
281
-
282
- # Sends a file in the response (immediately). Accepts a File object. Mime
283
- # type is automatically detected.
284
- #
285
- def send_file!(source_file, send_as = nil, type = nil)
286
- path = source_file.is_a?(File) ? source_file.path : source_file
287
- send_as ||= path
288
- type ||= Rack::Mime.mime_type(".#{send_as.split('.')[-1]}")
289
-
290
- data = ""
291
- File.open(path, "r").each_line { |line| data << line }
292
-
293
- self.response = Rack::Response.new(data, self.response.status, self.response.header.merge({ "Content-Type" => type }))
294
- halt!
213
+ finish
295
214
  end
296
215
 
297
- # Sends data in the response (immediately). Accepts the data, mime type,
298
- # and optional file name.
299
- #
300
- def send_data!(data, type, file_name = nil)
301
- status = self.response ? self.response.status : 200
302
-
303
- headers = self.response ? self.response.header : {}
304
- headers = headers.merge({ "Content-Type" => type })
305
- headers = headers.merge({ "Content-disposition" => "attachment; filename=#{file_name}"}) if file_name
306
-
307
- self.response = Rack::Response.new(data, status, headers)
308
- halt!
216
+ # This is NOT a useless method, it's a part of the external api
217
+ def reload
218
+ load_app
309
219
  end
310
220
 
311
- # Redirects to location (immediately).
312
- #
313
- def redirect_to!(location, status_code = 302)
314
- headers = self.response ? self.response.header : {}
315
- headers = headers.merge({'Location' => location})
316
-
317
- self.response = Rack::Response.new('', status_code, headers)
318
- halt!
319
- end
320
221
 
321
- # Registers a route for GET requests. Route can be defined one of two ways:
322
- # get('/', :ControllerClass, :action_method)
323
- # get('/') { # do something }
324
- #
325
- # Routes for namespaced controllers (e.g. Admin::ControllerClass) can be defined like this:
326
- # get('/', :Admin_ControllerClass, :action_method)
327
- #
328
- def get(route, *args, &block)
329
- register_route(:user, route, block, :get, *args)
330
- end
222
+ # APP ACTIONS
331
223
 
332
- # Registers a route for POST requests (see #get).
224
+ # Interrupts the application and returns response immediately.
333
225
  #
334
- def post(route, *args, &block)
335
- register_route(:user, route, block, :post, *args)
226
+ def halt
227
+ throw :halt, response
336
228
  end
337
229
 
338
- # Registers a route for PUT requests (see #get).
230
+ # Routes the request to different logic.
339
231
  #
340
- def put(route, *args, &block)
341
- register_route(:user, route, block, :put, *args)
342
- end
232
+ def reroute(path, method = nil)
233
+ self.request.setup(path, method)
343
234
 
344
- # Registers a route for DELETE requests (see #get).
345
- #
346
- def delete(route, *args, &block)
347
- register_route(:user, route, block, :delete, *args)
235
+ begin
236
+ # caught by other middleware (e.g. presenter) that does something with the
237
+ # new request then hands it back down to the router
238
+ throw :rerouted, request
239
+ rescue ArgumentError
240
+ # nobody caught it, so tell the router to reroute
241
+ app.router.reroute!(request)
242
+ end
348
243
  end
349
244
 
350
- # Registers the default route (see #get).
245
+ # Sends data in the response (immediately). Accepts a string of data or a File,
246
+ # mime-type (auto-detected; defaults to octet-stream), and optional file name.
351
247
  #
352
- def default(*args, &block)
353
- register_route(:user, '/', block, :get, *args)
354
- end
355
-
356
- # Creates REST routes for a resource. Arguments: url, controller, model, hooks
248
+ # If a File, mime type will be guessed. Otherwise mime type and file name will
249
+ # default to whatever is set in the response.
357
250
  #
358
- def restful(url, controller, *args, &block)
359
- model, hooks = parse_restful_args(args)
360
-
361
- with_scope(:url => url.gsub(/^[\/]+|[\/]+$/,""), :model => model) do
362
- nest_scope(&block) if block_given?
363
-
364
- @restful_routes ||= {}
365
- @restful_routes[model] ||= {} if model
366
-
367
- @@restful_actions.each do |opts|
368
- action_url = current_path
369
- if suffix = opts[:url_suffix]
370
- action_url = File.join(action_url, suffix)
371
- end
372
-
373
- # Create the route
374
- register_route(:restful, action_url, nil, opts[:method], controller, opts[:action], hooks)
375
-
376
- # Store url for later use (currently used by Binder#action)
377
- @restful_routes[model][opts[:action]] = action_url if model
378
- end
379
-
380
- remove_scope
381
- end
382
- end
383
-
384
- @@restful_actions = [
385
- { :action => :edit, :method => :get, :url_suffix => 'edit/:id' },
386
- { :action => :show, :method => :get, :url_suffix => ':id' },
387
- { :action => :new, :method => :get, :url_suffix => 'new' },
388
- { :action => :update, :method => :put, :url_suffix => ':id' },
389
- { :action => :delete, :method => :delete, :url_suffix => ':id' },
390
- { :action => :index, :method => :get },
391
- { :action => :create, :method => :post }
392
- ]
393
-
394
- def hook(name, controller = nil, action = nil, &block)
395
- block = build_controller_block(controller, action) if controller
396
- @route_store.add_hook(name, block)
397
- end
398
-
399
- def handler(name, *args, &block)
400
- code, controller, action = parse_handler_args(args)
251
+ def send(file_or_data, type = nil, send_as = nil)
252
+ case file_or_data.class
253
+ when File
254
+ data = File.open(path, "r").each_line { |line| data << line }
401
255
 
402
- if block_given?
403
- @handler_store[name] = block
256
+ # auto set type based on file type
257
+ type = Rack::Mime.mime_type("." + StringUtils.split_at_last_dot(File.path))[1]
404
258
  else
405
- @handler_store[name] = build_controller_block(controller, action)
259
+ data = file_or_data
406
260
  end
407
261
 
408
- if code
409
- @handler_name_to_code[name] = code
410
- @handler_code_to_name[code] = name
411
- end
412
- end
413
-
414
- #TODO: don't like this...
415
- def reload
416
- load_app
417
- end
418
-
419
- def session
420
- self.request.env['rack.session'] || {}
421
- end
422
-
423
- protected
424
-
425
- def prepare_route_block(route, method)
426
- set_request_format_from_route(route)
427
- base_route, ignore_format = StringUtils.split_at_last_dot(route)
428
-
429
- if Pakyow::Configuration::App.ignore_routes
430
- controller_block, packet = nil, {:vars=>{}, :data=>nil}
431
- else
432
- controller_block, packet = @route_store.get_block(base_route, method)
433
- end
262
+ headers = {}
263
+ headers["Content-Type"] = type if type
264
+ headers["Content-disposition"] = "attachment; filename=#{send_as}" if send_as
434
265
 
435
- self.request.params.merge!(HashUtils.strhash(packet[:vars]))
436
- self.request.route_spec = packet[:data][:route_spec] if packet[:data]
437
- self.request.restful = packet[:data][:restful] if packet[:data]
438
-
439
- controller_block
266
+ app.response = Rack::Response.new(data, response.status, response.header.merge(headers))
267
+ halt
440
268
  end
441
269
 
442
- def trampoline(block)
443
- last_call_has_block = (block == nil) ? false : true
444
- while block do
445
- block = catch(:new_block) {
446
- block.call()
447
- # Getting here means that call() returned normally (not via a throw)
448
- :fall_through
449
- } # end :invoke_route catch block
450
- # If invoke_route! or invoke_handler! was called in the block, block will have a new value (nil or block).
451
- # If neither was called, block will be :fall_through
452
-
453
- if block == nil
454
- last_call_has_block = false
455
- elsif block == :fall_through
456
- last_call_has_block = true
457
- block = nil
458
- end
459
-
460
- if block && self.presenter
461
- self.presenter.prepare_for_request(self.request)
462
- end
463
- end
464
- last_call_has_block
465
- end
466
-
467
- def parse_route_args(args)
468
- controller = args[0] if args[0] && (args[0].is_a?(Symbol) || args[0].is_a?(String))
469
- action = args[1] if controller
470
- hooks = args[2] if controller
471
- unless controller
472
- hooks = args[0] if args[0] && args[0].is_a?(Hash)
473
- end
474
- return controller, action, hooks
475
- end
476
-
477
- def parse_restful_args(args)
478
- model = args[0] if args[0] && (args[0].is_a?(Symbol) || args[0].is_a?(String))
479
- hooks = args[1] if model
480
- unless model
481
- hooks = args[0] if args[0] && args[0].is_a?(Hash)
482
- end
483
- return model, hooks
484
- end
485
-
486
- def parse_handler_args(args)
487
- code = args[0] if args[0] && args[0].is_a?(Fixnum)
488
- controller = args[1] if code && args[1]
489
- action = args[2] if controller && args[2]
490
- unless code
491
- controller = args[0] if args[0]
492
- action = args[1] if controller && args[1]
493
- end
494
- return code, controller, action
495
- end
496
-
497
- # Handles route registration.
270
+ # Redirects to location (immediately).
498
271
  #
499
- def register_route(type, route, block, method, *args)
500
- controller, action, hooks = parse_route_args(args)
501
- if controller
502
- block = build_controller_block(controller, action)
503
- end
504
-
505
- data = {:route_type=>type, :route_spec=>route}
506
- if type == :restful
507
- data[:restful] = {:restful_action=>action}
508
- end
509
- @route_store.add_route(route, block, method, data, hooks)
510
- end
511
-
512
- def build_controller_block(controller, action)
513
- controller = eval(controller.to_s)
514
- action ||= Configuration::Base.app.default_action
515
-
516
- block = lambda {
517
- instance = controller.new
518
- request.controller = instance
519
- request.action = action
520
-
521
- instance.send(action)
522
- }
523
-
524
- block
525
- end
526
-
527
- def set_request_format_from_route(route)
528
- route, format = StringUtils.split_at_last_dot(route)
529
- self.request.format = ((format && (format[format.length - 1, 1] == '/')) ? format[0, format.length - 1] : format)
530
- end
531
-
532
- def with_scope(opts)
533
- @scope ||= {}
534
- @scope[:path] ||= []
535
- @scope[:model] = opts[:model]
536
-
537
- @scope[:path] << opts[:url]
538
-
539
- yield
540
- end
272
+ def redirect(location, status_code = 302)
273
+ headers = response ? response.header : {}
274
+ headers = headers.merge({'Location' => location})
541
275
 
542
- def remove_scope
543
- @scope[:path].pop
276
+ app.response = Rack::Response.new('', status_code, headers)
277
+ halt
544
278
  end
545
279
 
546
- def nest_scope(&block)
547
- @scope[:path].insert(-1, ":#{StringUtils.underscore(@scope[:model].to_s)}_id")
548
- yield
549
- @scope[:path].pop
280
+ def handle(name_or_code)
281
+ app.router.handle!(name_or_code, true)
550
282
  end
551
283
 
552
- def current_path
553
- @scope[:path].join('/')
554
- end
284
+ protected
555
285
 
286
+ #TODO need configuration options for cookies (plus ability to override for each?)
556
287
  def set_cookies
557
288
  if self.request.cookies && self.request.cookies != {}
558
289
  self.request.cookies.each do |key, value|
@@ -573,30 +304,24 @@ module Pakyow
573
304
  load(Configuration::App.application_path) if reload_app
574
305
 
575
306
  @loader = Loader.new unless @loader
576
- @loader.load!(Configuration::Base.app.src_dir)
307
+ @loader.load_from_path(Configuration::Base.app.src_dir)
577
308
 
578
- load_handlers
579
- load_routes
580
-
581
- # Reload views
582
- if self.presenter
583
- self.presenter.load
584
- end
309
+ self.load_core
310
+ self.presenter.load if self.presenter
585
311
  end
586
312
 
587
- def load_handlers
588
- @handler_store = {}
589
- self.instance_eval(&self.class.handlers_proc) if self.class.handlers_proc
590
- end
313
+ # Evaluates core_proc
314
+ #
315
+ def load_core
316
+ @router = Router.instance.reset
591
317
 
592
- def load_routes
593
- @route_store = RouteStore.new
594
- self.instance_eval(&self.class.routes_proc) if self.class.routes_proc
318
+ @router.set(:default, &self.class.core_proc) if self.class.core_proc
595
319
  end
596
320
 
597
321
  # Send the response and cleanup.
598
322
  #
599
- def finish!
323
+ #TODO remove exclamation
324
+ def finish
600
325
  set_cookies
601
326
  self.response.finish
602
327
  end
@@ -2,14 +2,26 @@ require 'core/configuration/base'
2
2
  require 'core/helpers'
3
3
  require 'core/log'
4
4
  require 'core/request'
5
+ require 'core/response'
5
6
  require 'core/loader'
7
+ require 'core/router'
8
+ require 'core/route_set'
9
+ require 'core/route_template'
10
+ require 'core/route_template_defaults'
11
+ require 'core/route_lookup'
6
12
  require 'core/application'
7
- require 'core/route_store'
8
- require 'core/logger'
9
- require 'core/static'
10
- require 'core/reloader'
11
13
  require 'core/cache'
12
14
  require 'core/presenter_base'
15
+ require 'core/fn_context'
16
+
17
+ # middlewares
18
+ require 'core/middleware/logger'
19
+ require 'core/middleware/static'
20
+ require 'core/middleware/reloader'
21
+ require 'core/middleware/presenter'
22
+ require 'core/middleware/not_found'
23
+ require 'core/middleware/router'
24
+ require 'core/middleware/setup'
13
25
 
14
26
  # utils
15
27
  require 'utils/string'