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
@@ -5,7 +5,7 @@ module Pakyow
5
5
  attr_accessor :dev_mode, :log, :public_dir, :root, :log_dir,
6
6
  :presenter, :default_action, :ignore_routes, :error_level,
7
7
  :default_environment, :application_path, :log_name, :src_dir,
8
- :auto_reload, :errors_in_browser, :static
8
+ :auto_reload, :errors_in_browser, :static, :all_views_visible
9
9
 
10
10
  # Displays development-specific warnings.
11
11
  #
@@ -46,7 +46,7 @@ module Pakyow
46
46
  end
47
47
 
48
48
  def src_dir
49
- @src_dir || "#{root}/app/lib"
49
+ @src_dir || "#{root}/lib"
50
50
  end
51
51
 
52
52
  # Default action
@@ -58,6 +58,10 @@ module Pakyow
58
58
  def ignore_routes
59
59
  @ignore_routes.nil? ? false : @ignore_routes
60
60
  end
61
+
62
+ def all_views_visible
63
+ @all_views_visible.nil? ? true : @all_views_visible
64
+ end
61
65
 
62
66
  def default_environment
63
67
  @default_environment || :development
@@ -2,7 +2,7 @@ module Pakyow
2
2
  module Configuration
3
3
  class Server
4
4
  class << self
5
- attr_accessor :port, :host
5
+ attr_accessor :port, :host, :handler
6
6
 
7
7
  # On what port does the application run?
8
8
  def port
@@ -13,6 +13,11 @@ module Pakyow
13
13
  def host
14
14
  @host || '0.0.0.0'
15
15
  end
16
+
17
+ # If set, adds a handler to try (e.g. puma)
18
+ def handler
19
+ @handler || nil
20
+ end
16
21
  end
17
22
  end
18
23
  end
@@ -0,0 +1,5 @@
1
+ module Pakyow
2
+ class FnContext
3
+ include Helpers
4
+ end
5
+ end
@@ -9,6 +9,22 @@ module Pakyow
9
9
  def response
10
10
  Pakyow.app.response
11
11
  end
12
+
13
+ def router
14
+ RouteLookup.new
15
+ end
16
+
17
+ def params
18
+ request.params
19
+ end
20
+
21
+ def session
22
+ request.session
23
+ end
24
+
25
+ def cookies
26
+ request.cookies
27
+ end
12
28
  end
13
29
 
14
30
  # Helper methods specific to delegates and controllers.
@@ -1,11 +1,10 @@
1
1
  module Pakyow
2
-
3
2
  # Handles the loading and reloading of a Pakyow application. If in development
4
3
  # mode, files are automatically reloaded if modified.
5
4
  class Loader
6
5
 
7
6
  # Loads files in the provided path, decending into child directories.
8
- def load!(path)
7
+ def load_from_path(path)
9
8
  require_recursively(path)
10
9
  end
11
10
 
@@ -2,20 +2,24 @@ module Pakyow
2
2
 
3
3
  # Provides an easy way to log text, warnings, etc.
4
4
  class Log
5
-
5
+ # Opens stdout and the log file for writing.
6
+ def self.reopen
7
+ @@console = $stdout
8
+
9
+ d = Configuration::Base.app.log_dir
10
+ @@file = File.exists?(d) ? File.open("#{d}/#{Configuration::Base.app.log_name}", 'a') : nil
11
+ end
12
+
13
+ def self.close
14
+ @@file.close if @@file
15
+ end
16
+
6
17
  # Adds text to the log.
7
18
  def self.puts(text = "")
8
19
  return if !Configuration::Base.app.log
9
20
 
10
- @@console ||= $stdout
11
21
  @@console << "#{text}\r\n"
12
-
13
- dir = "#{Configuration::Base.app.log_dir}"
14
-
15
- if File.exists?(dir)
16
- @@file ||= File.open("#{dir}/#{Configuration::Base.app.log_name}", 'a')
17
- @@file.write "#{text}\r\n"
18
- end
22
+ @@file.write "#{text}\r\n" if @@file
19
23
  end
20
24
 
21
25
  class << self
@@ -0,0 +1,37 @@
1
+ module Pakyow
2
+ module Middleware
3
+ class Logger
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ result = nil
10
+ difference = time { |began_at|
11
+ Log.enter "Processing #{env['PATH_INFO']} (#{env['REMOTE_ADDR']} at #{began_at}) [#{env['REQUEST_METHOD']}]"
12
+
13
+ if error = catch(:error) {
14
+ result = @app.call(env)
15
+ nil
16
+ }
17
+ Log.enter "[500] #{error}\n"
18
+ Log.enter error.backtrace.join("\n") + "\n\n"
19
+
20
+ result = Pakyow.app.response.finish
21
+ end
22
+ }
23
+
24
+ Log.enter "Completed in #{difference}ms | #{Pakyow.app.response.status} | [#{Pakyow.app.request.url}]"
25
+ Log.enter
26
+
27
+ result
28
+ end
29
+
30
+ def time
31
+ s = Time.now
32
+ yield(s)
33
+ (Time.now.to_f - s.to_f) * 1000.0
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,40 @@
1
+ module Pakyow
2
+ module Middleware
3
+ class NotFound
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ @app.call(env)
10
+
11
+ # 404 if no route matched and no views were found
12
+ unless found?
13
+ Log.enter "[404] Not Found"
14
+
15
+ Pakyow.app.response.body = []
16
+ Pakyow.app.presenter.reset if Pakyow.app.presenter
17
+
18
+ Pakyow.app.response.status = 404
19
+ Pakyow.app.router.handle!(404)
20
+
21
+ if Pakyow.app.presenter
22
+ # consider moving to presenter middleware
23
+ # Pakyow.app.presenter.prepare_for_request(Pakyow.app.request)
24
+ Pakyow.app.response.body = [Pakyow.app.presenter.content] if Pakyow.app.presenter.presented?
25
+ end
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def found?
32
+ return true if Pakyow.app.router.routed?
33
+ return true if Pakyow.app.presenter && Pakyow.app.presenter.presented? && Configuration::App.all_views_visible
34
+
35
+ false
36
+ end
37
+ end
38
+ end
39
+ end
40
+
@@ -0,0 +1,25 @@
1
+ module Pakyow
2
+ module Middleware
3
+ class Presenter
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ r = Pakyow.app.request
10
+
11
+ while(r) do
12
+ Pakyow.app.presenter.prepare_for_request(Pakyow.app.request)
13
+
14
+ r = catch(:rerouted) {
15
+ @app.call(@env)
16
+ nil
17
+ }
18
+ end
19
+ #TODO the right thing to do?
20
+ Pakyow.app.response.body = [Pakyow.app.presenter.content] if Pakyow.app.presenter.presented?
21
+ Pakyow.app.response.finish
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,14 @@
1
+ module Pakyow
2
+ module Middleware
3
+ class Reloader
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ Pakyow.app.reload
10
+ @app.call(env)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,33 @@
1
+ module Pakyow
2
+ module Middleware
3
+ class Router
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ catch(:halt) {
10
+ Pakyow.app.router.route!(Pakyow.app.request)
11
+ @app.call(env)
12
+ }
13
+ rescue StandardError => error
14
+ Pakyow.app.request.error = error
15
+
16
+ Pakyow.app.response.status = 500
17
+ Pakyow.app.router.handle!(500)
18
+
19
+ if Configuration::Base.app.errors_in_browser
20
+ Pakyow.app.response.body = []
21
+ Pakyow.app.response.body << "<h4>#{CGI.escapeHTML(error.to_s)}</h4>"
22
+ Pakyow.app.response.body << error.backtrace.join("<br />")
23
+ end
24
+
25
+ begin
26
+ # caught by other middleware (e.g. logger)
27
+ throw :error, error
28
+ rescue ArgumentError
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,15 @@
1
+ module Pakyow
2
+ module Middleware
3
+ class Setup
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ #TODO don't track r/r on app; pass through middleware instead (or call in a context that has access to current r/r)
10
+ Pakyow.app.setup_rr(env)
11
+ @app.call(env)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,27 @@
1
+ module Pakyow
2
+ module Middleware
3
+ class Static
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ if is_static?(env)
10
+ response = Rack::Response.new
11
+
12
+ catch(:halt) do
13
+ Pakyow.app.send(File.open(File.join(Configuration::Base.app.public_dir, env['PATH_INFO'])))
14
+ end
15
+ else
16
+ @app.call(env)
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def is_static?(env)
23
+ env['PATH_INFO'] =~ /\.(.*)$/ && File.exists?(File.join(Configuration::Base.app.public_dir, env['PATH_INFO']))
24
+ end
25
+ end
26
+ end
27
+ end
@@ -3,5 +3,9 @@ module Pakyow
3
3
  def self.inherited(subclass)
4
4
  Configuration::Base.app.presenter = subclass
5
5
  end
6
+
7
+ def self.instance
8
+ @@instance ||= self.new
9
+ end
6
10
  end
7
11
  end
@@ -2,7 +2,13 @@ module Pakyow
2
2
 
3
3
  # The Request object.
4
4
  class Request < Rack::Request
5
- attr_accessor :restful, :route_spec, :controller, :action, :format, :error, :working_path, :working_method
5
+ attr_accessor :restful, :route_path, :controller, :action, :format, :error, :working_path, :working_method
6
+
7
+ def initialize(*args)
8
+ super
9
+
10
+ self.setup(self.path)
11
+ end
6
12
 
7
13
  # Easy access to path_info.
8
14
  def path
@@ -20,6 +26,10 @@ module Pakyow
20
26
  # Set response type
21
27
  Pakyow.app.response["Content-Type"] = Rack::Mime.mime_type(".#{@format}")
22
28
  end
29
+
30
+ def session
31
+ self.env['rack.session'] || {}
32
+ end
23
33
 
24
34
  def cookies
25
35
  @cookies ||= HashUtils.strhash(super)
@@ -31,25 +41,25 @@ module Pakyow
31
41
  end
32
42
 
33
43
  # Returns array of url components.
34
- def url_parts
35
- unless @url
36
- @url = self.class.split_url(self.env['PATH_INFO'])
37
- end
38
-
39
- return @url
44
+ def path_parts
45
+ @url ||= self.path ? self.class.split_url(self.path) : []
46
+ end
47
+
48
+ def referer
49
+ @referer ||= self.env['HTTP_REFERER']
40
50
  end
41
51
 
42
52
  # Returns array of referer components.
43
53
  def referer_parts
44
- unless @referer
45
- @referer = self.class.split_url(self.env['HTTP_REFERER'])
46
- end
47
-
48
- return @referer
54
+ @referer_parts ||= self.referer ? self.class.split_url(self.referer) : []
49
55
  end
50
-
51
- private
52
-
56
+
57
+ def setup(path, method = nil)
58
+ self.set_request_format_from_path(path)
59
+ self.set_working_path_from_path(path, method)
60
+ end
61
+
62
+ #TODO move to util class
53
63
  def self.split_url(url)
54
64
  arr = []
55
65
  url.split('/').each { |r|
@@ -58,5 +68,23 @@ module Pakyow
58
68
 
59
69
  return arr
60
70
  end
71
+
72
+ protected
73
+
74
+ def set_working_path_from_path(path, method)
75
+ base_route, ignore_format = StringUtils.split_at_last_dot(path)
76
+
77
+ self.working_path = base_route
78
+ self.working_method = method || self.method
79
+ end
80
+
81
+ def set_request_format_from_path(path)
82
+ path, format = StringUtils.split_at_last_dot(path)
83
+
84
+ #TODO why it no work without this? was working fine in application
85
+ return unless format
86
+
87
+ self.format = ((format && (format[format.length - 1, 1] == '/')) ? format[0, format.length - 1] : format)
88
+ end
61
89
  end
62
90
  end
@@ -0,0 +1,6 @@
1
+ module Pakyow
2
+
3
+ # The Response object.
4
+ class Response < Rack::Response
5
+ end
6
+ end
@@ -0,0 +1,37 @@
1
+ module Pakyow
2
+
3
+ # Handles looking up paths for named routes and populating
4
+ # the path with data.
5
+ #
6
+ class RouteLookup
7
+ include Helpers
8
+
9
+ def path(name, data = nil)
10
+ route = self.get_named_route(name)
11
+ data ? self.populate(route, data) : File.join('/', route[4])
12
+ end
13
+
14
+ def group(name)
15
+ @group = name
16
+ self
17
+ end
18
+
19
+ protected
20
+
21
+ def get_named_route(name)
22
+ Pakyow.app.router.route(name, @group) || []
23
+ end
24
+
25
+ def populate(route, data = {})
26
+ vars = route[1]
27
+
28
+ split_path = Request.split_url(route[4])
29
+
30
+ vars.each {|v|
31
+ split_path[v[:position]] = data[v[:var]]
32
+ }
33
+
34
+ File.join('/', split_path.join('/'))
35
+ end
36
+ end
37
+ end