mack 0.5.0 → 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/CHANGELOG +19 -0
  2. data/bin/mack +3 -2
  3. data/bin/mack_ring_server +19 -1
  4. data/lib/{sea_level/controller_base.rb → controller/base.rb} +87 -128
  5. data/lib/{sea_level → controller}/cookie_jar.rb +3 -3
  6. data/lib/{sea_level → controller}/filter.rb +0 -0
  7. data/lib/{sea_level → controller}/request.rb +0 -0
  8. data/lib/{sea_level → controller}/response.rb +0 -0
  9. data/lib/{sea_level → controller}/session.rb +0 -0
  10. data/lib/{sea_level → controller}/uploaded_file.rb +0 -0
  11. data/lib/distributed/routing/urls.rb +1 -1
  12. data/lib/distributed/utils/rinda.rb +1 -1
  13. data/lib/errors/errors.rb +6 -4
  14. data/lib/generators/mack_application_generator/templates/config/initializers/mime_types.rb.template +3 -0
  15. data/lib/generators/mack_application_generator/templates/public/favicon.ico.template +0 -0
  16. data/lib/initialization/configuration.rb +2 -1
  17. data/lib/initialization/console.rb +2 -2
  18. data/lib/initialization/{initializers/logging.rb → logging.rb} +0 -0
  19. data/lib/initialization/{initializers/orm_support.rb → orm_support.rb} +0 -0
  20. data/lib/initialization/{initializers/plugins.rb → plugins.rb} +0 -0
  21. data/lib/mack.rb +107 -131
  22. data/lib/mack_tasks.rb +1 -1
  23. data/lib/rendering/engine/base.rb +26 -0
  24. data/lib/rendering/engine/builder.rb +30 -0
  25. data/lib/rendering/engine/erubis.rb +67 -0
  26. data/lib/rendering/engine/haml.rb +18 -0
  27. data/lib/rendering/engine/markaby.rb +27 -0
  28. data/lib/rendering/engine/registry.rb +48 -0
  29. data/lib/rendering/type/action.rb +37 -0
  30. data/lib/rendering/type/base.rb +59 -0
  31. data/lib/rendering/type/file_base.rb +32 -0
  32. data/lib/rendering/type/inline.rb +26 -0
  33. data/lib/rendering/type/layout.rb +26 -0
  34. data/lib/rendering/type/partial.rb +40 -0
  35. data/lib/rendering/type/public.rb +29 -0
  36. data/lib/rendering/type/template.rb +22 -0
  37. data/lib/rendering/type/text.rb +17 -0
  38. data/lib/rendering/type/url.rb +120 -0
  39. data/lib/rendering/type/xml.rb +34 -0
  40. data/lib/rendering/view_template.rb +168 -0
  41. data/lib/routing/route_map.rb +20 -11
  42. data/lib/runner.rb +137 -0
  43. data/lib/utils/mime_types.rb +56 -0
  44. data/lib/utils/mime_types.yml +449 -0
  45. data/lib/{sea_level/helpers/view_helpers → view_helpers}/html_helpers.rb +0 -0
  46. data/lib/{sea_level/helpers/view_helpers → view_helpers}/string_helpers.rb +0 -0
  47. metadata +58 -29
  48. data/lib/initialization/initializer.rb +0 -110
  49. data/lib/rendering/base.rb +0 -62
  50. data/lib/rendering/classes/action.rb +0 -26
  51. data/lib/rendering/classes/partial.rb +0 -12
  52. data/lib/rendering/classes/public.rb +0 -13
  53. data/lib/rendering/classes/text.rb +0 -12
  54. data/lib/rendering/classes/url.rb +0 -59
  55. data/lib/rendering/classes/xml.rb +0 -24
  56. data/lib/sea_level/view_binder.rb +0 -88
@@ -0,0 +1,18 @@
1
+ require File.join(File.dirname(__FILE__), "..", "view_template")
2
+ module Mack
3
+ module Rendering
4
+ module Engine
5
+ class Haml < Mack::Rendering::Engine::Base
6
+
7
+ def render(io, binding)
8
+ ::Haml::Engine.new(io).render(binding)
9
+ end
10
+
11
+ def extension
12
+ :haml
13
+ end
14
+
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ require File.join(File.dirname(__FILE__), "..", "view_template")
2
+ module Mack
3
+ module Rendering
4
+ module Engine
5
+ class Markaby < Mack::Rendering::Engine::Base
6
+
7
+ def render(io, binding)
8
+ @_markaby = ::Markaby::Builder.new({}, self.view_template)
9
+ self.view_template.instance_variable_set("@_markaby", @_markaby)
10
+ eval(io, binding)
11
+ end
12
+
13
+ def extension
14
+ :mab
15
+ end
16
+
17
+ module ViewHelpers
18
+ def mab
19
+ @_markaby
20
+ end
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+ end
27
+ Mack::Rendering::ViewTemplate.send(:include, Mack::Rendering::Engine::Markaby::ViewHelpers)
@@ -0,0 +1,48 @@
1
+ module Mack
2
+ module Rendering
3
+ module Engine
4
+ # A registry used to store which Mack::Rendering::Type objects can use which Mack::Rendering::Engine objects.
5
+ #
6
+ # Example:
7
+ # Mack::Rendering::Engine::Registry.register(:bar, :sass)
8
+ # render(:bar, "my_file") will now get run through Mack::Rendering::Type::Bar and Mack::Rendering::Engine::Sass
9
+ class Registry
10
+ include Singleton
11
+
12
+ # Returns all the engines registered with the system.
13
+ attr_reader :engines
14
+
15
+ def initialize
16
+ @engines = {
17
+ :action => [:erubis, :builder, :markaby, :haml],
18
+ :template => [:erubis, :builder, :markaby, :haml],
19
+ :partial => [:erubis, :builder, :markaby, :haml],
20
+ :layout => [:erubis, :markaby, :haml],
21
+ :xml => [:builder, :erubis, :markaby, :haml]
22
+ }
23
+ end
24
+
25
+ # Registers an engine to a type.
26
+ #
27
+ # Example:
28
+ # Mack::Rendering::Engine::Registry.register(:action, :haml)
29
+ def register(type, engine)
30
+ type = type.to_sym
31
+ if self.engines.has_key?(type)
32
+ self.engines[type].insert(0, engine)
33
+ else
34
+ self.engines[type] = [engine]
35
+ end
36
+ end
37
+
38
+ class << self
39
+
40
+ def method_missing(sym, *args)
41
+ Mack::Rendering::Engine::Registry.instance.send(sym, *args)
42
+ end
43
+
44
+ end
45
+ end # Registry
46
+ end # Engines
47
+ end # Rendering
48
+ end # Mack
@@ -0,0 +1,37 @@
1
+ require File.join(File.dirname(__FILE__), 'file_base')
2
+ module Mack
3
+ module Rendering # :nodoc:
4
+ module Type # :nodoc:
5
+ # Used to render a template that's relative to a controller.
6
+ #
7
+ # Example:
8
+ # class UsersController < Mack::Controller::Base
9
+ # # /users/:id
10
+ # def show
11
+ # @user = User.first(params(:id))
12
+ # end
13
+ # # /users
14
+ # def index
15
+ # @users = User.all
16
+ # render(:action, :list)
17
+ # end
18
+ # end
19
+ # When some calls /users/1 the file: app/views/users/show.html.erb will be rendered.
20
+ # When some calls /users the file: app/views/users/list.html.erb will be rendered.
21
+ class Action < Mack::Rendering::Type::FileBase
22
+
23
+ # See Mack::Rendering::Type::FileBase render_file for more information.
24
+ #
25
+ # The path to the file is built like such:
26
+ # app/views/#{controller name}/#{render_value || action name (show, index, etc...)}.#{format (html, xml, js, etc...)}.#{extension defined in the engine}
27
+ # Example:
28
+ # app/views/users/show.html.erb
29
+ def render
30
+ a_file = File.join(self.controller_view_path, "#{self.render_value}.#{self.options[:format]}")
31
+ render_file(a_file)
32
+ end
33
+
34
+ end # Action
35
+ end # Type
36
+ end # Rendering
37
+ end # Mack
@@ -0,0 +1,59 @@
1
+ module Mack
2
+ module Rendering # :nodoc:
3
+ module Type # :nodoc:
4
+ # Mack::Rendering::Type objects need to extend this class.
5
+ #
6
+ # The method 'render' needs to be implemented as in all subclasses.
7
+ class Base
8
+
9
+ # Returns the Mack::Rendering::ViewTemplate object associated with this render.
10
+ attr_reader :view_template
11
+
12
+ def initialize(view_template)
13
+ @view_template = view_template
14
+ end
15
+
16
+ needs_method :render
17
+
18
+ # If a file is found on disk it will be yielded up.
19
+ #
20
+ # Example:
21
+ # find_file("path", "to", "my", "file") do |f|
22
+ # puts File.open(f).read
23
+ # end
24
+ def find_file(*path)
25
+ f = File.join(path)
26
+ if File.exists?(f)
27
+ yield f
28
+ end
29
+ end
30
+
31
+ # Can be overridden by subclasses to prevent layouts being used with the render.
32
+ def allow_layout?
33
+ true
34
+ end
35
+
36
+ def find_engine(e)
37
+ eval("Mack::Rendering::Engine::#{e.to_s.camelcase}")
38
+ end
39
+
40
+ def method_missing(sym, *args)
41
+ self.view_template.send(sym, *args)
42
+ end
43
+
44
+ # See Mack::Rendering::ViewTemplate content_for for more details.
45
+ def capture(*args, &block)
46
+ @engine.capture(*args, &block)
47
+ end
48
+
49
+ # Returns the directory path for the current controller.
50
+ def controller_view_path
51
+ ivar_cache do
52
+ File.join(Mack::Configuration.views_directory, self.controller.controller_name)
53
+ end
54
+ end
55
+
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,32 @@
1
+ require File.join(File.dirname(__FILE__), 'base')
2
+ module Mack
3
+ module Rendering
4
+ module Type
5
+ class FileBase < Mack::Rendering::Type::Base
6
+
7
+ # Returns a string representing the file stored on disk, once it's be run through
8
+ # the first found Mack::Rendering::Engine object associated with this Mack::Rendering::Type.
9
+ #
10
+ # Since engines are stored in an array, the are looped through until a template is found on disk.
11
+ # If no template is found then a Mack::Errors::ResourceNotFound exception is thrown.
12
+ def render_file(file, type = :action)
13
+ Mack::Rendering::Engine::Registry.engines[type].each do |e|
14
+ @engine = find_engine(e).new(self.view_template)
15
+ find_file(file + ".#{@engine.extension}") do |f|
16
+ return @engine.render(File.open(f).read, self.binder)
17
+ end
18
+ end
19
+ raise Mack::Errors::ResourceNotFound.new(file + ".*")
20
+ end
21
+
22
+ # Passes concatenation messages through to the Mack::Rendering::Engine object.
23
+ # This should append the text, using the passed in binding, to the final output
24
+ # of the render.
25
+ def concat(txt, b)
26
+ @engine.concat(txt, b)
27
+ end
28
+
29
+ end # FileBase
30
+ end # Type
31
+ end # Rendering
32
+ end # Mack
@@ -0,0 +1,26 @@
1
+ module Mack
2
+ module Rendering # :nodoc:
3
+ module Type # :nodoc:
4
+ # This class allows for a template to be rendered inline in a controller, and not served from disk.
5
+ #
6
+ # Examples:
7
+ # <%= render(:inline, "<%= 2 + 2 %> should equal 4") %> # => "4 should equal 4"
8
+ # <%= render(:inline, "xml.hello("Mark")", :engine => :builder) %> # => "<hello>Mark</hello>"
9
+ class Inline < Mack::Rendering::Type::Base
10
+
11
+ def render
12
+ @engine = find_engine((self.options[:engine] || :erubis)).new(self.view_template)
13
+ return @engine.render(self.render_value, self.binder)
14
+ end
15
+
16
+ # Passes concatenation messages through to the Mack::Rendering::Engine object.
17
+ # This should append the text, using the passed in binding, to the final output
18
+ # of the render.
19
+ def concat(txt, b)
20
+ @engine.concat(txt, b)
21
+ end
22
+
23
+ end # Inline
24
+ end # Type
25
+ end # Rendering
26
+ end # Mack
@@ -0,0 +1,26 @@
1
+ module Mack
2
+ module Rendering # :nodoc:
3
+ module Type # :nodoc:
4
+ # Used to render layouts around views.
5
+ class Layout < Mack::Rendering::Type::FileBase
6
+
7
+ # See Mack::Rendering::Type::FileBase render_file for more information.
8
+ #
9
+ # The path to the file is built like such:
10
+ # app/views/layouts/#{options[:layout] || "application"}.#{format (html, xml, js, etc...)}.#{extension defined in the engine}
11
+ # Example:
12
+ # app/views/layouts/application.html.erb
13
+ def render
14
+ l_file = File.join(Mack::Configuration.views_directory, 'layouts', "#{self.options[:layout]}.#{self.options[:format]}")
15
+ begin
16
+ render_file(l_file, :layout)
17
+ rescue Mack::Errors::ResourceNotFound => e
18
+ MACK_DEFAULT_LOGGER.warn(e)
19
+ self.view_template.yield_to :view
20
+ end
21
+ end
22
+
23
+ end # Layout
24
+ end # Type
25
+ end # Rendering
26
+ end # Mack
@@ -0,0 +1,40 @@
1
+ module Mack
2
+ module Rendering # :nodoc:
3
+ module Type # :nodoc:
4
+ # Used to render partials. Partials are small reusable templates. They have to start with an _.
5
+ #
6
+ # Example:
7
+ # <%= render(:partial, "users/form") %> # => /users/_form.html.erb
8
+ class Partial < Mack::Rendering::Type::FileBase
9
+
10
+ # See Mack::Rendering::Type::FileBase render_file for more information.
11
+ #
12
+ # The path to the file is built like such:
13
+ # app/views/#{controller name}/#{partial name with prefixed _}.#{format (html, xml, js, etc...)}.#{extension defined in the engine}
14
+ # Example:
15
+ # app/views/users/_form.html.erb
16
+ def render
17
+ partial = self.render_value.to_s
18
+ parts = partial.split("/")
19
+ if parts.size == 1
20
+ # it's local to this controller
21
+ partial = "_" << partial
22
+ partial = File.join(self.controller_view_path, partial)
23
+ else
24
+ # it's elsewhere
25
+ parts[parts.size - 1] = "_" << parts.last
26
+ partial = File.join(Mack::Configuration.views_directory, parts)
27
+ end
28
+ partial = "#{partial}.#{self.options[:format]}"
29
+ render_file(partial, :partial)
30
+ end
31
+
32
+ # No layouts should be used with this Mack::Rendering::Type
33
+ def allow_layout?
34
+ false
35
+ end
36
+
37
+ end # Partial
38
+ end # Type
39
+ end # Rendering
40
+ end # Mack
@@ -0,0 +1,29 @@
1
+ module Mack
2
+ module Rendering # :nodoc:
3
+ module Type # :nodoc:
4
+ # Used to render files stored in the public directory. These files are NOT run through any engines
5
+ # and are returned 'as is'.
6
+ class Public < Mack::Rendering::Type::Base
7
+
8
+ # Attempts to find the file on disk and return it. If no file extension is provided then the 'format'
9
+ # of the request is appended to the file name.
10
+ def render
11
+ p_file = self.render_value
12
+ if File.extname(p_file).blank?
13
+ p_file = "#{p_file}.#{self.options[:format]}"
14
+ end
15
+ find_file(Mack::Configuration.public_directory, p_file) do |f|
16
+ return File.open(f).read
17
+ end
18
+ raise Mack::Errors::ResourceNotFound.new(p_file)
19
+ end
20
+
21
+ # No layouts should be used with this Mack::Rendering::Type
22
+ def allow_layout?
23
+ false
24
+ end
25
+
26
+ end # Public
27
+ end # Type
28
+ end # Rendering
29
+ end # Mack
@@ -0,0 +1,22 @@
1
+ module Mack
2
+ module Rendering # :nodoc:
3
+ module Type # :nodoc:
4
+ # Pretty much the same thing as Mack::Rendering::Type::Action, except the template is relative to the app/views directory,
5
+ # and not the app/views/#{controller name} directory like action.
6
+ class Template < Mack::Rendering::Type::FileBase
7
+
8
+ # See Mack::Rendering::Type::FileBase render_file for more information.
9
+ #
10
+ # The path to the file is built like such:
11
+ # app/views/#{template (show, index, etc...)}.#{format (html, xml, js, etc...)}.#{extension defined in the engine}
12
+ # Example:
13
+ # <%= render(:template, "users/show") %> # => app/views/users/show.html.erb
14
+ def render
15
+ t_file = File.join(Mack::Configuration.views_directory, "#{self.render_value}.#{self.options[:format]}")
16
+ render_file(t_file, :template)
17
+ end
18
+
19
+ end # Template
20
+ end # Type
21
+ end # Rendering
22
+ end # Mack
@@ -0,0 +1,17 @@
1
+ module Mack
2
+ module Rendering # :nodoc:
3
+ module Type # :nodoc:
4
+ # This is pretty damn brain dead, it just returns the text you supplied to it.
5
+ #
6
+ # Example:
7
+ # <%= render(:text, "Hello World") %> # => "Hello World"
8
+ class Text < Mack::Rendering::Type::Base
9
+
10
+ def render
11
+ self.render_value
12
+ end
13
+
14
+ end # Text
15
+ end # Type
16
+ end # Rendering
17
+ end # Mack
@@ -0,0 +1,120 @@
1
+ module Mack
2
+ module Rendering # :nodoc:
3
+ module Type # :nodoc:
4
+ # This class will render the contents of a url.
5
+ #
6
+ # Examples:
7
+ # This is considered a 'remote' request and will be made using GET.
8
+ # <%= render(:url, "http://www.mackframework.com") %>
9
+ # This is considered a 'remote' request and will be made using POST.
10
+ # <%= render(:url, "http://www.mackframework.com", :method => :post) %>
11
+ # This is considered a 'remote' request and will be made using GET, and will have query string parameters.
12
+ # <%= render(:url, "http://www.mackframework.com", :parameters => {:name => "mark"}) %> # http://www.mackframework.com?name=mark
13
+ # This is considered a 'remote' request and will be made using POST, and will have form parameters.
14
+ # <%= render(:url, "http://www.mackframework.com", :method => :post, :parameters => {:name => "mark"}) %>
15
+ #
16
+ # 'Local' requests can also be made:
17
+ # This is considered a 'local' request and will be made using GET.
18
+ # <%= render(:url, "/users") %>
19
+ # This is considered a 'local' request and will be made using POST.
20
+ # <%= render(:url, "/users", :method => :post) %>
21
+ # This is considered a 'local' request and will be made using GET, and will have query string parameters.
22
+ # <%= render(:url, "/users", :parameters => {:name => "mark"}) %> # /users?name=mark
23
+ # This is considered a 'local' request and will be made using POST, and will have form parameters.
24
+ # <%= render(:url, "/users", :method => :post, :parameters => {:name => "mark"}) %>
25
+ class Url < Mack::Rendering::Type::Base
26
+
27
+ # No layouts should be used with this Mack::Rendering::Type
28
+ def allow_layout?
29
+ false
30
+ end
31
+
32
+ # Retrieves the contents of the url using either GET or POST, passing along any specified parameters.
33
+ def render
34
+ options = {:method => :get, :raise_exception => false}.merge(self.options)
35
+ url = self.render_value
36
+ remote = url.match(/^[a-zA-Z]+:\/\//)
37
+ case options[:method]
38
+ when :get
39
+ if remote
40
+ do_render_remote_url(url_with_query(url, options[:parameters]), options) do |uri, options|
41
+ Net::HTTP.get_response(uri)
42
+ end
43
+ else
44
+ do_render_local_url(url, options) do |url, options|
45
+ Rack::MockRequest.new(self.app_for_rendering).get(url, options)
46
+ end
47
+ end
48
+ when :post
49
+ if remote
50
+ do_render_remote_url(url, options) do |uri, options|
51
+ Net::HTTP.post_form(uri, options[:parameters] || {})
52
+ end
53
+ else
54
+ do_render_local_url(url, options) do |url, options|
55
+ Rack::MockRequest.new(self.app_for_rendering).post(url, options)
56
+ end
57
+ end
58
+ else
59
+ raise Mack::Errors::UnsupportRenderUrlMethodType.new(options[:method])
60
+ end
61
+ end
62
+
63
+ private
64
+ def do_render_remote_url(url, options)
65
+ Timeout::timeout(app_config.mack.render_url_timeout || 5) do
66
+ uri = URI.parse(url)
67
+ response = yield uri, options
68
+ if response.code == "200"
69
+ return response.body
70
+ else
71
+ if options[:raise_exception]
72
+ raise Mack::Errors::UnsuccessfulRenderUrl.new(uri, response)
73
+ else
74
+ return ""
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ def do_render_local_url(url, options)
81
+ Timeout::timeout(app_config.mack.render_url_timeout || 5) do
82
+ cooks = {}
83
+ self.cookies.all.each do |c,v|
84
+ cooks[c] = v[:value]
85
+ end
86
+ request = self.view_template.request
87
+ # MACK_DEFAULT_LOGGER.debug "ORIGINAL REQUEST: #{request.env.inspect}"
88
+ env = request.env.dup
89
+ env - ["rack.input", "rack.errors", "PATH_INFO", "REQUEST_PATH", "REQUEST_URI", "REQUEST_METHOD"]
90
+ env["rack.request.query_hash"] = options[:parameters] || {}
91
+ env["HTTP_COOKIE"] = "#{app_config.mack.session_id}=#{request.session.id};" if env["HTTP_COOKIE"].nil?
92
+ options = env.merge(options)
93
+ # MACK_DEFAULT_LOGGER.debug "NEW OPTIONS: #{options.inspect}"
94
+ # MACK_DEFAULT_LOGGER.debug "url: #{url}"
95
+ response = yield url, options
96
+ if response.successful?
97
+ return response.body
98
+ else
99
+ if options[:raise_exception]
100
+ raise Mack::Errors::UnsuccessfulRenderUrl.new(url, response)
101
+ else
102
+ return ""
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ def url_with_query(url, parameters = {})
109
+ unless parameters.empty?
110
+ url = url.to_s.dup
111
+ url << "?"
112
+ url << parameters.to_params(true)
113
+ end
114
+ url
115
+ end
116
+
117
+ end
118
+ end
119
+ end
120
+ end