pakyow-core 0.8.rc4 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/pakyow-core/CHANGES +4 -0
- data/pakyow-core/lib/core/app.rb +51 -50
- data/pakyow-core/lib/core/app_context.rb +10 -0
- data/pakyow-core/lib/core/base.rb +4 -1
- data/pakyow-core/lib/core/errors.rb +13 -0
- data/pakyow-core/lib/core/helpers.rb +6 -3
- data/pakyow-core/lib/core/loader.rb +5 -5
- data/pakyow-core/lib/core/middleware/static.rb +3 -2
- data/pakyow-core/lib/core/request.rb +8 -9
- data/pakyow-core/lib/core/response.rb +12 -0
- data/pakyow-core/lib/core/route_eval.rb +252 -159
- data/pakyow-core/lib/core/route_lookup.rb +4 -5
- data/pakyow-core/lib/core/route_merger.rb +76 -0
- data/pakyow-core/lib/core/route_module.rb +21 -0
- data/pakyow-core/lib/core/route_set.rb +15 -8
- data/pakyow-core/lib/core/route_template_defaults.rb +29 -31
- data/pakyow-core/lib/core/router.rb +15 -10
- data/pakyow-core/lib/utils/dir.rb +6 -3
- data/pakyow-core/lib/utils/hash.rb +32 -29
- data/pakyow-core/lib/utils/string.rb +30 -27
- metadata +15 -12
- data/pakyow-core/lib/core/exceptions.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a272d5c2f6d429275df4e3eac0561c8df6c285e3
|
4
|
+
data.tar.gz: 8b21f4193337cd9c7298ccbe0e004bd9c814beb0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dbb4242d0cbbb4dcce94608b6773026e68c4168c450dd4e7587def70a3db921d5e6d53a7b9cd45b3f718451ec70c8b7cf7878ea998eacf95aed655dc084cea56
|
7
|
+
data.tar.gz: b965ed0dd836899da344beb011cd777eb09080fa3013c381d7a4e1194108147f90c58f9be3dfcb0dedce8d6c06519a66d78ea85188a10c992280cb1506173f07
|
data/pakyow-core/CHANGES
CHANGED
data/pakyow-core/lib/core/app.rb
CHANGED
@@ -4,6 +4,7 @@ module Pakyow
|
|
4
4
|
def reset
|
5
5
|
@@routes = {}
|
6
6
|
@@config = {}
|
7
|
+
@@middleware = []
|
7
8
|
|
8
9
|
@@stacks = {:before => {}, :after => {}}
|
9
10
|
%w(init load process route match error).each {|name|
|
@@ -16,7 +17,7 @@ module Pakyow
|
|
16
17
|
#
|
17
18
|
def define(&block)
|
18
19
|
# sets the path to the app file so it can be reloaded later
|
19
|
-
config.app.path =
|
20
|
+
config.app.path = Utils::String.parse_path_from_caller(caller[0])
|
20
21
|
|
21
22
|
self.instance_eval(&block)
|
22
23
|
end
|
@@ -32,15 +33,10 @@ module Pakyow
|
|
32
33
|
end
|
33
34
|
end
|
34
35
|
|
35
|
-
#
|
36
|
+
# Accepts block to be added to middleware stack.
|
36
37
|
#
|
37
38
|
def middleware(&block)
|
38
|
-
|
39
|
-
# request when auto_reload is enabled
|
40
|
-
return if prepared?
|
41
|
-
|
42
|
-
# tell builder about the middleware
|
43
|
-
builder.instance_eval(&block)
|
39
|
+
@@middleware << block
|
44
40
|
end
|
45
41
|
|
46
42
|
# Creates an environment.
|
@@ -144,7 +140,11 @@ module Pakyow
|
|
144
140
|
envs = envs.empty? || envs.first.nil? ? [config.app.default_environment] : envs
|
145
141
|
load_config(envs)
|
146
142
|
|
147
|
-
# load middleware
|
143
|
+
# load each block from middleware stack
|
144
|
+
@@middleware.each {|mw|
|
145
|
+
self.instance_exec(builder, &mw)
|
146
|
+
}
|
147
|
+
|
148
148
|
builder.use(Rack::MethodOverride)
|
149
149
|
builder.use(Middleware::Static) if config.app.static
|
150
150
|
builder.use(Middleware::Logger) if config.app.log
|
@@ -185,7 +185,7 @@ module Pakyow
|
|
185
185
|
include Helpers
|
186
186
|
include AppHelpers
|
187
187
|
|
188
|
-
|
188
|
+
attr_writer :context
|
189
189
|
|
190
190
|
def initialize
|
191
191
|
Pakyow.app = self
|
@@ -217,42 +217,43 @@ module Pakyow
|
|
217
217
|
def process(env)
|
218
218
|
call_stack(:before, :process)
|
219
219
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
220
|
+
req = Request.new(env)
|
221
|
+
res = Response.new
|
222
|
+
|
223
|
+
# set response format based on request
|
224
|
+
res.format = req.format
|
225
|
+
|
226
|
+
@context = AppContext.new(req, res)
|
224
227
|
|
225
228
|
set_initial_cookies
|
226
229
|
|
227
230
|
@found = false
|
228
231
|
catch(:halt) {
|
229
|
-
|
230
|
-
call_stack(:before, :route)
|
232
|
+
call_stack(:before, :route)
|
231
233
|
|
232
|
-
|
233
|
-
|
234
|
-
|
234
|
+
@found = @router.perform(context, self) {
|
235
|
+
call_stack(:after, :match)
|
236
|
+
}
|
235
237
|
|
236
|
-
|
237
|
-
end
|
238
|
+
call_stack(:after, :route)
|
238
239
|
|
239
240
|
unless found?
|
240
|
-
handle(404, false)
|
241
|
+
handle(404, false)
|
241
242
|
|
242
243
|
if config.app.errors_in_browser
|
243
|
-
|
244
|
+
response["Content-Type"] = 'text/html'
|
244
245
|
|
245
246
|
view_file = File.join(File.expand_path('../../', __FILE__), 'views', 'errors', '404.html')
|
246
247
|
content = File.open(view_file).read
|
247
248
|
|
248
|
-
path =
|
249
|
+
path = Utils::String.normalize_path(request.path)
|
249
250
|
path = '/' if path.empty?
|
250
251
|
|
251
252
|
content.gsub!('{view_path}', path == '/' ? 'index.html' : "#{path}.html")
|
252
253
|
content.gsub!('{route_path}', path)
|
253
254
|
|
254
|
-
|
255
|
-
|
255
|
+
response.body = []
|
256
|
+
response.body << content
|
256
257
|
end
|
257
258
|
end
|
258
259
|
}
|
@@ -261,38 +262,38 @@ module Pakyow
|
|
261
262
|
|
262
263
|
call_stack(:after, :process)
|
263
264
|
|
264
|
-
|
265
|
+
response.finish
|
265
266
|
rescue StandardError => error
|
266
267
|
call_stack(:before, :error)
|
267
268
|
|
268
|
-
|
269
|
+
request.error = error
|
269
270
|
|
270
271
|
handle(500, false) unless found?
|
271
272
|
|
272
273
|
if config.app.errors_in_browser
|
273
|
-
|
274
|
-
|
274
|
+
response["Content-Type"] = 'text/html'
|
275
|
+
|
275
276
|
view_file = File.join(File.expand_path('../../', __FILE__), 'views', 'errors', '500.html')
|
276
277
|
content = File.open(view_file).read
|
277
278
|
|
278
|
-
path =
|
279
|
+
path = Utils::String.normalize_path(request.path)
|
279
280
|
path = '/' if path.empty?
|
280
281
|
|
281
282
|
nice_source = error.backtrace[0].match(/^(.+?):(\d+)(|:in `(.+)')$/)
|
282
283
|
|
283
284
|
content.gsub!('{file}', nice_source[1].gsub(File.expand_path(Config::App.root) + '/', ''))
|
284
285
|
content.gsub!('{line}', nice_source[2])
|
285
|
-
|
286
|
-
content.gsub!('{msg}', error.to_s)
|
287
|
-
content.gsub!('{trace}', error.backtrace.join('<br>'))
|
288
286
|
|
289
|
-
|
290
|
-
|
287
|
+
content.gsub!('{msg}', CGI.escapeHTML(error.to_s))
|
288
|
+
content.gsub!('{trace}', error.backtrace.map { |bt| CGI.escapeHTML(bt) }.join('<br>'))
|
289
|
+
|
290
|
+
response.body = []
|
291
|
+
response.body << content
|
291
292
|
end
|
292
293
|
|
293
294
|
call_stack(:after, :error)
|
294
295
|
|
295
|
-
|
296
|
+
response.finish
|
296
297
|
end
|
297
298
|
|
298
299
|
def found?
|
@@ -319,17 +320,17 @@ module Pakyow
|
|
319
320
|
# Interrupts the application and returns response immediately.
|
320
321
|
#
|
321
322
|
def halt
|
322
|
-
throw :halt,
|
323
|
+
throw :halt, response
|
323
324
|
end
|
324
325
|
|
325
326
|
# Routes the request to different logic.
|
326
327
|
#
|
327
328
|
def reroute(path, method = nil)
|
328
|
-
|
329
|
+
request.setup(path, method)
|
329
330
|
|
330
331
|
call_stack(:before, :route)
|
331
332
|
call_stack(:after, :match)
|
332
|
-
@router.reroute(
|
333
|
+
@router.reroute(request)
|
333
334
|
call_stack(:after, :route)
|
334
335
|
end
|
335
336
|
|
@@ -344,7 +345,7 @@ module Pakyow
|
|
344
345
|
data = file_or_data.read
|
345
346
|
|
346
347
|
# auto set type based on file type
|
347
|
-
type = Rack::Mime.mime_type("." +
|
348
|
+
type = Rack::Mime.mime_type("." + Utils::String.split_at_last_dot(file_or_data.path)[1])
|
348
349
|
else
|
349
350
|
data = file_or_data
|
350
351
|
end
|
@@ -353,7 +354,7 @@ module Pakyow
|
|
353
354
|
headers["Content-Type"] = type if type
|
354
355
|
headers["Content-disposition"] = "attachment; filename=#{send_as}" if send_as
|
355
356
|
|
356
|
-
|
357
|
+
self.context = AppContext.new(request, Response.new(data, response.status, response.header.merge(headers)))
|
357
358
|
halt
|
358
359
|
end
|
359
360
|
|
@@ -361,11 +362,11 @@ module Pakyow
|
|
361
362
|
#
|
362
363
|
def redirect(location, status_code = 302)
|
363
364
|
location = router.path(location) if location.is_a?(Symbol)
|
364
|
-
|
365
|
+
|
365
366
|
headers = response ? response.header : {}
|
366
367
|
headers = headers.merge({'Location' => location})
|
367
368
|
|
368
|
-
|
369
|
+
self.context = AppContext.new(request, Response.new('', status_code, headers))
|
369
370
|
halt
|
370
371
|
end
|
371
372
|
|
@@ -409,18 +410,18 @@ module Pakyow
|
|
409
410
|
@router = Router.instance.reset
|
410
411
|
self.class.routes.each_pair {|set_name, block|
|
411
412
|
@router.set(set_name, &block)
|
412
|
-
}
|
413
|
+
} unless config.app.ignore_routes
|
413
414
|
end
|
414
415
|
|
415
416
|
def set_cookies
|
416
|
-
|
417
|
-
|
417
|
+
request.cookies.each_pair {|k, v|
|
418
|
+
response.unset_cookie(k) if v.nil?
|
418
419
|
|
419
420
|
# cookie is already set with value, ignore
|
420
421
|
next if @initial_cookies.include?(k.to_s) && @initial_cookies[k.to_s] == v
|
421
422
|
|
422
423
|
# set cookie with defaults
|
423
|
-
|
424
|
+
response.set_cookie(k, {
|
424
425
|
:path => config.cookies.path,
|
425
426
|
:expires => config.cookies.expiration,
|
426
427
|
:value => v
|
@@ -429,7 +430,7 @@ module Pakyow
|
|
429
430
|
|
430
431
|
# delete cookies that are no longer present
|
431
432
|
@initial_cookies.each {|k|
|
432
|
-
|
433
|
+
response.delete_cookie(k) unless request.cookies.key?(k.to_s)
|
433
434
|
}
|
434
435
|
end
|
435
436
|
|
@@ -437,7 +438,7 @@ module Pakyow
|
|
437
438
|
# for comparison at the end of the cycle
|
438
439
|
def set_initial_cookies
|
439
440
|
@initial_cookies = {}
|
440
|
-
|
441
|
+
request.cookies.each {|k,v|
|
441
442
|
@initial_cookies[k] = v
|
442
443
|
}
|
443
444
|
end
|
@@ -5,16 +5,19 @@ require 'core/config/cookies'
|
|
5
5
|
require 'core/config/logger'
|
6
6
|
require 'core/helpers'
|
7
7
|
require 'core/multilog'
|
8
|
+
require 'core/app_context'
|
8
9
|
require 'core/request'
|
9
10
|
require 'core/response'
|
10
11
|
require 'core/loader'
|
11
12
|
require 'core/router'
|
13
|
+
require 'core/route_merger'
|
14
|
+
require 'core/route_module'
|
12
15
|
require 'core/route_set'
|
13
16
|
require 'core/route_eval'
|
14
17
|
require 'core/route_template_defaults'
|
15
18
|
require 'core/route_lookup'
|
16
19
|
require 'core/app'
|
17
|
-
require 'core/
|
20
|
+
require 'core/errors'
|
18
21
|
|
19
22
|
# middlewares
|
20
23
|
require 'core/middleware/logger'
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Pakyow
|
2
|
+
# Raised when no app context is available
|
3
|
+
class NoContextError < StandardError; end
|
4
|
+
|
5
|
+
# Raised when route is looked up that doesn't exist
|
6
|
+
class MissingRoute < StandardError; end
|
7
|
+
|
8
|
+
# Raised when template part doesn't exist
|
9
|
+
class UnknownTemplatePart < StandardError; end
|
10
|
+
|
11
|
+
class Error < StandardError; end
|
12
|
+
end
|
13
|
+
|
@@ -1,7 +1,10 @@
|
|
1
1
|
module Pakyow
|
2
|
-
|
3
2
|
# For methods that should be accessible anywhere
|
4
3
|
module Helpers
|
4
|
+
def context
|
5
|
+
@context or raise NoContextError
|
6
|
+
end
|
7
|
+
|
5
8
|
def logger
|
6
9
|
request.logger
|
7
10
|
end
|
@@ -11,12 +14,12 @@ module Pakyow
|
|
11
14
|
end
|
12
15
|
|
13
16
|
def request
|
14
|
-
|
17
|
+
context.request
|
15
18
|
end
|
16
19
|
alias_method :req, :request
|
17
20
|
|
18
21
|
def response
|
19
|
-
|
22
|
+
context.response
|
20
23
|
end
|
21
24
|
alias_method :res, :response
|
22
25
|
|
@@ -7,21 +7,21 @@ module Pakyow
|
|
7
7
|
def load_from_path(path)
|
8
8
|
require_recursively(path)
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
protected
|
12
|
-
|
12
|
+
|
13
13
|
def require_recursively(dir)
|
14
14
|
@times ||= {}
|
15
15
|
if File.exists?(dir)
|
16
|
-
|
16
|
+
Utils::Dir.walk_dir(dir) do |path|
|
17
17
|
next if FileTest.directory?(path)
|
18
18
|
next if path.split('.')[-1] != 'rb'
|
19
|
-
|
19
|
+
|
20
20
|
if Config::Base.app.auto_reload
|
21
21
|
if !@times[path] || (@times[path] && File.mtime(path) - @times[path] > 0)
|
22
22
|
load(path)
|
23
23
|
@times[path] = File.mtime(path)
|
24
|
-
end
|
24
|
+
end
|
25
25
|
else
|
26
26
|
require path
|
27
27
|
end
|
@@ -11,8 +11,9 @@ module Pakyow
|
|
11
11
|
if static
|
12
12
|
catch(:halt) do
|
13
13
|
app = Pakyow.app.dup
|
14
|
-
|
15
|
-
|
14
|
+
res = Response.new
|
15
|
+
req = Request.new(env)
|
16
|
+
app.context = AppContext.new(req, res)
|
16
17
|
app.send(File.open(resource_path))
|
17
18
|
end
|
18
19
|
else
|
@@ -2,8 +2,8 @@ module Pakyow
|
|
2
2
|
|
3
3
|
# The Request object.
|
4
4
|
class Request < Rack::Request
|
5
|
-
attr_accessor :restful, :route_path, :controller, :action, :format,
|
6
|
-
:error, :
|
5
|
+
attr_accessor :restful, :route_path, :controller, :action, :format,
|
6
|
+
:error, :path, :method, :paths, :methods, :formats
|
7
7
|
|
8
8
|
def initialize(*args)
|
9
9
|
super
|
@@ -14,6 +14,8 @@ module Pakyow
|
|
14
14
|
|
15
15
|
@path = path_info
|
16
16
|
@method = request_method.downcase.to_sym
|
17
|
+
|
18
|
+
setup
|
17
19
|
end
|
18
20
|
|
19
21
|
def path=(path)
|
@@ -30,9 +32,6 @@ module Pakyow
|
|
30
32
|
format = format ? format.to_sym : :html
|
31
33
|
@formats << format
|
32
34
|
@format = format
|
33
|
-
|
34
|
-
# Set response type
|
35
|
-
@app.response["Content-Type"] = Rack::Mime.mime_type(".#{@format}")
|
36
35
|
end
|
37
36
|
|
38
37
|
def first_path
|
@@ -52,12 +51,12 @@ module Pakyow
|
|
52
51
|
end
|
53
52
|
|
54
53
|
def cookies
|
55
|
-
@cookies ||=
|
54
|
+
@cookies ||= Utils::Hash.strhash(super)
|
56
55
|
end
|
57
56
|
|
58
57
|
# Returns indifferent params (see {HashUtils.strhash} for more info on indifferent hashes).
|
59
58
|
def params
|
60
|
-
@params ||=
|
59
|
+
@params ||= Utils::Hash.strhash(super)
|
61
60
|
end
|
62
61
|
|
63
62
|
# Returns array of url components.
|
@@ -98,14 +97,14 @@ module Pakyow
|
|
98
97
|
protected
|
99
98
|
|
100
99
|
def set_working_path_from_path(path, method)
|
101
|
-
base_route, ignore_format =
|
100
|
+
base_route, ignore_format = Utils::String.split_at_last_dot(path)
|
102
101
|
|
103
102
|
self.path = base_route
|
104
103
|
self.method = method || self.method
|
105
104
|
end
|
106
105
|
|
107
106
|
def set_request_format_from_path(path)
|
108
|
-
path, format =
|
107
|
+
path, format = Utils::String.split_at_last_dot(path)
|
109
108
|
self.format = ((format && (format[format.length - 1, 1] == '/')) ? format[0, format.length - 1] : format)
|
110
109
|
end
|
111
110
|
end
|