mack 0.0.3

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.
Files changed (55) hide show
  1. data/README +43 -0
  2. data/bin/mack +60 -0
  3. data/bin/templates/Rakefile.template +6 -0
  4. data/bin/templates/app/controllers/default_controller.rb.template +7 -0
  5. data/bin/templates/app/helpers/application_helper.rb.template +2 -0
  6. data/bin/templates/app/views/default/index.html.erb.template +3 -0
  7. data/bin/templates/app/views/layouts/application.html.erb.template +15 -0
  8. data/bin/templates/config/app_config/default.yml.template +7 -0
  9. data/bin/templates/config/app_config/development.yml.template +0 -0
  10. data/bin/templates/config/app_config/production.yml.template +0 -0
  11. data/bin/templates/config/app_config/test.yml.template +0 -0
  12. data/bin/templates/config/boot.rb.template +6 -0
  13. data/bin/templates/config/database.yml.template +20 -0
  14. data/bin/templates/config/routes.rb.template +7 -0
  15. data/bin/templates/config/thin.ru.template +1 -0
  16. data/bin/templates/config/thin.yml.template +8 -0
  17. data/bin/templates/public/favicon.ico +0 -0
  18. data/bin/templates/public/stylesheets/scaffold.css.template +74 -0
  19. data/core_extensions/hash.rb +9 -0
  20. data/core_extensions/module.rb +29 -0
  21. data/core_extensions/nil.rb +8 -0
  22. data/core_extensions/object.rb +9 -0
  23. data/core_extensions/string.rb +28 -0
  24. data/errors/errors.rb +79 -0
  25. data/initialize/configuration.rb +99 -0
  26. data/initialize/configure_logging.rb +24 -0
  27. data/initialize/configure_orm_support.rb +23 -0
  28. data/initialize/console.rb +13 -0
  29. data/initialize/initializer.rb +88 -0
  30. data/initialize/server/simple_server.rb +21 -0
  31. data/lib/utils/html.rb +88 -0
  32. data/lib/utils/server.rb +27 -0
  33. data/mack.rb +124 -0
  34. data/mack_tasks.rb +16 -0
  35. data/routing/route_map.rb +268 -0
  36. data/routing/urls.rb +54 -0
  37. data/sea_level/controller_base.rb +293 -0
  38. data/sea_level/cookie_jar.rb +67 -0
  39. data/sea_level/filter.rb +63 -0
  40. data/sea_level/helpers/view_helpers/html_helpers.rb +33 -0
  41. data/sea_level/helpers/view_helpers/orm_helpers.rb +72 -0
  42. data/sea_level/request.rb +83 -0
  43. data/sea_level/response.rb +6 -0
  44. data/sea_level/session.rb +33 -0
  45. data/sea_level/view_binder.rb +101 -0
  46. data/tasks/cachetastic_tasks.rake +69 -0
  47. data/tasks/log_tasks.rake +9 -0
  48. data/tasks/mack_tasks.rake +15 -0
  49. data/tasks/rake_helpers.rb +24 -0
  50. data/tasks/rake_rules.rake +19 -0
  51. data/tasks/script_tasks.rake +44 -0
  52. data/tasks/test_tasks.rake +7 -0
  53. data/test_extensions/test_assertions.rb +47 -0
  54. data/test_extensions/test_helpers.rb +84 -0
  55. metadata +173 -0
@@ -0,0 +1,99 @@
1
+ module Mack
2
+ # All configuration for the Mack subsystem happens here. Each of the default environments,
3
+ # production, development, and test have their own default configuration options. These
4
+ # get merged with overall default options.
5
+ module Configuration # :nodoc:
6
+
7
+ # use local memory and store stuff for 24 hours:
8
+ # use file for sessions and store them for 4 hours:
9
+ DEFAULTS_PRODUCTION = {
10
+ "mack::use_lint" => false,
11
+ "mack::show_exceptions" => false,
12
+ "log::level" => "info",
13
+ "log::detailed_requests" => false,
14
+ "cachetastic_default_options" => {
15
+ "debug" => false,
16
+ "adapter" => "local_memory",
17
+ "expiry_time" => 86400,
18
+ "logging" => {
19
+ "logger_1" => {
20
+ "type" => "file",
21
+ "file" => File.join(MACK_ROOT, "log", "cachetastic.log")
22
+ }
23
+ }
24
+ },
25
+ "cachetastic_caches_mack_session_cache_options" => {
26
+ "debug" => false,
27
+ "adapter" => "file",
28
+ "store_options" =>
29
+ {"dir" => File.join(MACK_ROOT, "tmp")},
30
+ "expiry_time" => 14400,
31
+ "logging" => {
32
+ "logger_1" => {
33
+ "type" => "file",
34
+ "file" => File.join(MACK_ROOT, "log", "cachetastic.log")
35
+ }
36
+ }
37
+ }
38
+ } unless self.const_defined?("DEFAULTS_PRODUCTION")
39
+
40
+ # use local memory and store stuff for 5 minutes:
41
+ DEFAULTS_DEVELOPMENT = {
42
+ "mack::cache_classes" => false,
43
+ "log::level" => "debug",
44
+ "log::console" => true,
45
+ "cachetastic_default_options" => {
46
+ "debug" => false,
47
+ "adapter" => "local_memory",
48
+ "expiry_time" => 300,
49
+ "logging" => {
50
+ "logger_1" => {
51
+ "type" => "file",
52
+ "file" => File.join(MACK_ROOT, "log", "cachetastic.log")
53
+ }
54
+ }
55
+ }
56
+ } unless self.const_defined?("DEFAULTS_DEVELOPMENT")
57
+
58
+ # use local memory and store stuff for 1 hour:
59
+ DEFAULTS_TEST = {
60
+ "log::level" => "error",
61
+ "cachetastic_default_options" => {
62
+ "debug" => false,
63
+ "adapter" => "local_memory",
64
+ "expiry_time" => 3600,
65
+ "logging" => {
66
+ "logger_1" => {
67
+ "type" => "file",
68
+ "file" => File.join(MACK_ROOT, "log", "cachetastic.log")
69
+ }
70
+ }
71
+ }
72
+ } unless self.const_defined?("DEFAULTS_TEST")
73
+
74
+ unless self.const_defined?("DEFAULTS")
75
+ DEFAULTS = {
76
+ "mack::cache_classes" => true,
77
+ "mack::use_lint" => true,
78
+ "mack::show_exceptions" => true,
79
+ "mack::session_id" => "_mack_session_id",
80
+ "mack::cookie_values" => {
81
+ "path" => "/"
82
+ },
83
+ # "mack::orm" => "activerecord",
84
+ "log::detailed_requests" => true,
85
+ "log::level" => "info",
86
+ "log::console" => false,
87
+ "log::file" => true,
88
+ "log::console_format" => "%l:\t[%d]\t%M",
89
+ "log::file_format" => "%l:\t[%d]\t%M"
90
+ }.merge(eval("DEFAULTS_#{MACK_ENV.upcase}"))
91
+ end
92
+
93
+ app_config.load_hash(DEFAULTS, "mack_defaults")
94
+ app_config.load_file(File.join(MACK_CONFIG, "app_config", "default.yml"))
95
+ app_config.load_file(File.join(MACK_CONFIG, "app_config", "#{MACK_ENV}.yml"))
96
+ # app_config.reload
97
+
98
+ end
99
+ end
@@ -0,0 +1,24 @@
1
+ #--
2
+ # Configure logging
3
+ #++
4
+ include Log4r
5
+
6
+ log_dir_loc = File.join(MACK_ROOT, "log")
7
+ FileUtils.mkdir_p(log_dir_loc)
8
+
9
+ unless Object.const_defined?("MACK_DEFAULT_LOGGER")
10
+ log = Log4r::Logger.new('')
11
+ log.level = Module.instance_eval("Log4r::#{app_config.log.level.to_s.upcase}")
12
+ # console:
13
+ if app_config.log.console
14
+ console_format = PatternFormatter.new(:pattern => app_config.log.console_format)
15
+ log.add(Log4r::StdoutOutputter.new('console', :formatter => console_format))
16
+ end
17
+ # file:
18
+ if app_config.log.file
19
+ file_format = PatternFormatter.new(:pattern => app_config.log.file_format)
20
+ log.add(FileOutputter.new('fileOutputter', :filename => File.join(log_dir_loc, "#{MACK_ENV}.log"), :trunc => false, :formatter => file_format))
21
+ end
22
+
23
+ Object::MACK_DEFAULT_LOGGER = log
24
+ end
@@ -0,0 +1,23 @@
1
+ # setup ORM:
2
+
3
+ [:activerecord, :data_mapper].each do |orm|
4
+ eval("def using_#{orm}?; false; end")
5
+ end
6
+
7
+ unless app_config.mack.orm.nil?
8
+ dbs = YAML::load(ERB.new(IO.read(File.join(MACK_CONFIG, "database.yml"))).result)
9
+ case app_config.mack.orm
10
+ when 'activerecord'
11
+ require 'activerecord'
12
+ ActiveRecord::Base.establish_connection(dbs[MACK_ENV])
13
+ eval("def using_activerecord?; true; end")
14
+ when 'data_mapper'
15
+ require 'data_mapper'
16
+ DataMapper::Database.setup(dbs[MACK_ENV])
17
+ eval("def using_data_mapper?; true; end")
18
+ else
19
+ MACK_DEFAULT_LOGGER.warn("Attempted to configure an unknown ORM: #{app_config.mack.orm}")
20
+ end
21
+ else
22
+ MACK_DEFAULT_LOGGER.warn("No ORM has been configured!")
23
+ end
@@ -0,0 +1,13 @@
1
+ # This file gets loaded when you run:
2
+ # rake console
3
+ # It loads the following classes to make using the application via the console easier:
4
+ #
5
+ # * Mack::TestHelpers
6
+ # * Mack::Routes::Urls
7
+
8
+ fl = File.join(File.dirname(__FILE__), "..")
9
+
10
+ require File.join(fl, "test_extensions", "test_helpers")
11
+
12
+ self.send(:include, Mack::TestHelpers)
13
+ self.send(:include, Mack::Routes::Urls)
@@ -0,0 +1,88 @@
1
+ require 'rubygems'
2
+ require 'rack'
3
+ require 'digest'
4
+ require 'ruby_extensions'
5
+ require 'application_configuration'
6
+ require 'cachetastic'
7
+ require 'fileutils'
8
+ require 'log4r'
9
+
10
+ # Set up Mack constants, if they haven't already been set up.
11
+ unless Object.const_defined?("MACK_ENV")
12
+ (Object::MACK_ENV = (ENV["MACK_ENV"] ||= "development")).to_sym
13
+ end
14
+ (Object::MACK_ROOT = (ENV["MACK_ROOT"] ||= FileUtils.pwd)) unless Object.const_defined?("MACK_ROOT")
15
+
16
+ Object::MACK_PUBLIC = File.join(MACK_ROOT, "public") unless Object.const_defined?("MACK_PUBLIC")
17
+ Object::MACK_APP = File.join(MACK_ROOT, "app") unless Object.const_defined?("MACK_APP")
18
+ Object::MACK_LIB = File.join(MACK_ROOT, "lib") unless Object.const_defined?("MACK_LIB")
19
+ Object::MACK_CONFIG = File.join(MACK_ROOT, "config") unless Object.const_defined?("MACK_CONFIG")
20
+ Object::MACK_VIEWS = File.join(MACK_APP, "views") unless Object.const_defined?("MACK_VIEWS")
21
+ Object::MACK_LAYOUTS = File.join(MACK_VIEWS, "layouts") unless Object.const_defined?("MACK_LAYOUTS")
22
+
23
+ unless Object.const_defined?("MACK_INITIALIZED")
24
+ puts "Starting application in #{MACK_ENV} mode."
25
+
26
+ Object::MACK_INITIALIZED = true
27
+
28
+ # Set up 'Rails' constants to allow for easier use of existing gems/plugins like application_configuration.
29
+ # I would like to take these out eventually, but for right now, it's not doing too much harm.
30
+ # Object::RAILS_ENV = MACK_ENV unless Object.const_defined?("RAILS_ENV")
31
+ # Object::RAILS_ROOT = MACK_ROOT unless Object.const_defined?("RAILS_ROOT")
32
+
33
+ require File.join(File.dirname(__FILE__), "configuration.rb")
34
+
35
+ require File.join(File.dirname(__FILE__), "configure_logging.rb")
36
+
37
+ require File.join(File.dirname(__FILE__), "configure_orm_support.rb")
38
+
39
+ fl = File.join(File.dirname(__FILE__), "..")
40
+
41
+ # Require all the necessary files to make Mack actually work!
42
+ ["errors", "core_extensions", "lib", "test_extensions", "routing", "sea_level", "tasks", "initialize/server"].each do |dir|
43
+ dir_globs = Dir.glob(File.join(fl, dir, "**/*.rb"))
44
+ dir_globs.each do |d|
45
+ require d
46
+ end
47
+ end
48
+
49
+
50
+
51
+ # ------------------------------------------------------------------------
52
+
53
+ # set up application stuff:
54
+
55
+ # set up routes:
56
+ require File.join(MACK_ROOT, "config", "routes")
57
+
58
+ # require 'app' files:
59
+ Dir.glob(File.join(MACK_APP, "**/*.rb")).each do |d|
60
+ require d
61
+ end
62
+
63
+ # require 'lib' files:
64
+ Dir.glob(File.join(MACK_LIB, "**/*.rb")).each do |d|
65
+ require d
66
+ end
67
+
68
+
69
+ # ------------------------------------------------------------------------
70
+
71
+ # Include ApplicationHelper into all controllers:
72
+ if Object.const_defined?("ApplicationHelper")
73
+ ApplicationHelper.include_safely_into(Mack::Controller::Base, Mack::ViewBinder)
74
+ end
75
+ # Find other Helpers and include them into their respective controllers.
76
+ Object.constants.collect {|c| c if c.match(/Controller$/)}.compact.each do |cont|
77
+ if Object.const_defined?("#{cont}Helper")
78
+ h = "#{cont}Helper".constantize
79
+ h.include_safely_into(cont, Mack::ViewBinder)
80
+ end
81
+ end
82
+
83
+ # Find view level Helpers and include them into the Mack::ViewBinder
84
+ Mack::ViewHelpers.constants.each do |cont|
85
+ h = "Mack::ViewHelpers::#{cont}".constantize
86
+ h.include_safely_into(Mack::ViewBinder)
87
+ end
88
+ end
@@ -0,0 +1,21 @@
1
+ module Mack
2
+ # Even though it's called, SimpleServer, this might be the only server you need to run
3
+ # a Mack application.
4
+ #
5
+ # $ ruby script/server
6
+ #
7
+ # This SimpleServer does not use Thin. But does work with anything that Rack has a handler for.
8
+ class SimpleServer
9
+
10
+ class << self
11
+
12
+ def run(options)
13
+ r = "Rack::Handler::#{options.handler.camelcase}"
14
+ puts "Starting app using: #{r} in #{options.environment} mode on port: #{options.port}"
15
+ eval(r).run(Mack::Utils::Server.build_app, :Port => options.port)
16
+ end
17
+
18
+ end
19
+
20
+ end
21
+ end
data/lib/utils/html.rb ADDED
@@ -0,0 +1,88 @@
1
+ module Mack
2
+ module Utils
3
+ # Useful utilities for dealing with HTML.
4
+ class Html
5
+
6
+ class << self
7
+
8
+ # Used in views to create href links. It takes link_text, url, and a Hash that gets added
9
+ # to the href as options.
10
+ #
11
+ # Examples:
12
+ # Mack::Utils::Html.href("http://www.mackframework.com") # => <a href="http://www.mackframework.com">http://www.mackframework.com</a>
13
+ # Mack::Utils::Html.href("Mack", "http://www.mackframework.com") # => <a href="http://www.mackframework.com">Mack</a>
14
+ # Mack::Utils::Html.href("Mack", "http://www.mackframework.com", :target => "_blank") # => <a href="http://www.mackframework.com" target="_blank">Mack</a>
15
+ # Mack::Utils::Html.href("Mack", "http://www.mackframework.com", :target => "_blank", :rel => :nofollow) # => <a href="http://www.mackframework.com" target="_blank" rel="nofollow">Mack</a>
16
+ # If you pass in :method as an option it will be a JavaScript form that will post to the specified link with the
17
+ # methd specified.
18
+ # Mack::Utils::Html.href("Mack", "http://www.mackframework.com", :method => :delete)
19
+ # If you use the :method option you can also pass in a :confirm option. The :confirm option will generate a
20
+ # javascript confirmation window. If 'OK' is selected the the form will submit. If 'cancel' is selected, then
21
+ # nothing will happen. This is extremely useful for 'delete' type of links.
22
+ # Mack::Utils::Html.href("Mack", "http://www.mackframework.com", :method => :delete, :confirm => "Are you sure?")
23
+ def href(link_text, url = link_text, html_options = {})
24
+ if html_options[:method]
25
+ meth = nil
26
+ confirm = nil
27
+
28
+ meth = %{var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var s = document.createElement('input'); s.setAttribute('type', 'hidden'); s.setAttribute('name', '_method'); s.setAttribute('value', '#{html_options[:method]}'); f.appendChild(s);f.submit()}
29
+ html_options.delete(:method)
30
+
31
+ if html_options[:confirm]
32
+ confirm = %{if (confirm('#{html_options[:confirm]}'))}
33
+ html_options.delete(:confirm)
34
+ end
35
+
36
+ html_options[:onclick] = (confirm ? (confirm + " { ") : "") << meth << (confirm ? (" } ") : "") << ";return false;"
37
+ end
38
+
39
+ html = "<a href=" << '"' << url
40
+ html << '"'
41
+ html << " " << html_options.join("%s=\"%s\"", " ") unless html_options.empty?
42
+ html << ">" << link_text
43
+ html << "</a>"
44
+ html
45
+ end
46
+
47
+ alias_method :a, :href
48
+
49
+ # Wraps the content_tag method.
50
+ #
51
+ # Examples:
52
+ # Mack::Utils::Html.b("hello") # => <b>hello</b>
53
+ # Mack::Utils::Html.div("hello world!", :class => :foo)) # => <div class="foo">hello world!</div>
54
+ def method_missing(sym, *args)
55
+ ags = args.from_args
56
+
57
+ tag = sym
58
+ content = nil
59
+ options = {}
60
+
61
+ if ags.is_a?(Array)
62
+ content = ags[0] if ags[0].is_a?(String)
63
+ options = ags[1] if ags[1].is_a?(Hash)
64
+ elsif ags.is_a?(String)
65
+ content = ags
66
+ elsif ags.is_a?(Hash)
67
+ options = ags
68
+ end
69
+
70
+ content = yield if block_given?
71
+
72
+ content_tag(tag, content, options)
73
+ end
74
+
75
+ # Builds an HTML tag.
76
+ #
77
+ # Examples:
78
+ # content_tag(:b, "hello") # => <b>hello</b>
79
+ # content_tag("div", "hello world!", :class => :foo) # => <div class="foo">hello world!</div>
80
+ def content_tag(tag, content, options = {})
81
+ html = "<#{tag} #{options.join("%s=\"%s\"", " ")}>#{content}</#{tag}>"
82
+ end
83
+
84
+ end # self
85
+
86
+ end # Html
87
+ end # Utils
88
+ end # Mack
@@ -0,0 +1,27 @@
1
+ module Mack
2
+ module Utils
3
+ module Server
4
+
5
+ # This method wraps all the necessary components of the Rack system around
6
+ # Mack::Runner. This can be used build your own server around the Mack framework.
7
+ def self.build_app
8
+ # Mack framework:
9
+ app = Mack::Runner.new
10
+ # Any urls listed will go straight to the public directly and will not be served up via the app:
11
+ app = Rack::Static.new(app, :urls => ["/css", "/images", "/files", "/images", "/stylesheets", "/javascripts", "/media"], :root => "public")
12
+ app = Rack::Lint.new(app) if app_config.mack.use_lint
13
+ app = Rack::ShowStatus.new(app)
14
+ app = Rack::ShowExceptions.new(app) if app_config.mack.show_exceptions
15
+ app = Rack::Recursive.new(app)
16
+ # This will reload any edited classes if the cache_classes config setting is set to true.
17
+ app = Rack::Reloader.new(app, 1) unless app_config.mack.cache_classes
18
+ # TODO: Not sure about this logger, investigate better ones.
19
+ # TODO: Depends on MACK_DEFAULT_LOGGER already being configured.
20
+ # This makes it a drag run this 'standalone' in another Ruby program.
21
+ # app = Rack::CommonLogger.new(app, MACK_DEFAULT_LOGGER)
22
+ app
23
+ end
24
+
25
+ end # Server
26
+ end # Utils
27
+ end # Mack
data/mack.rb ADDED
@@ -0,0 +1,124 @@
1
+ require File.join(File.dirname(__FILE__), "initialize", "initializer")
2
+
3
+ module Mack
4
+ # This is the heart and soul of the Mack framework! This class interfaces with the Rack framework.
5
+ # It handles all the dispatching back and forth between the Rack framework and a Mack application.
6
+ class Runner
7
+ include Mack::Routes::Urls
8
+
9
+ attr_reader :response # :nodoc:
10
+ attr_reader :request # :nodoc:
11
+ attr_reader :cookies # :nodoc:
12
+ # This method needs to be defined as part of the Rack framework. As is noted for the Mack::Runner
13
+ # class, this is where the center of the Mack framework lies.
14
+ def call(env)
15
+ begin
16
+ setup(env) do
17
+ begin
18
+ route = Mack::Routes::RouteMap.instance.get_route_from_request(self.request)
19
+ if route[:redirect_to]
20
+ # because the route is specified to be a redirect, let's do that:
21
+ redirect_to(route)
22
+ else
23
+ # let's handle a normal request:
24
+ c = "#{route[:controller].to_s.camelcase}Controller".constantize.new(self.request, self.response, self.cookies)
25
+ self.response.write(c.run)
26
+ end
27
+ rescue Mack::Errors::ResourceNotFound, Mack::Errors::UndefinedRoute => e
28
+ return try_to_find_resource(env, self.request.path_info, e)
29
+ end
30
+ end # setup
31
+ rescue Exception => e
32
+ MACK_DEFAULT_LOGGER.error(e)
33
+ raise e
34
+ end
35
+ end
36
+
37
+ private
38
+ def log_request
39
+ s_time = Time.now
40
+ x = yield
41
+ e_time = Time.now
42
+ p_time = e_time - s_time
43
+ if app_config.log.detailed_requests
44
+ msg = "\n\t[#{@request.request_method.upcase}] '#{@request.path_info}'\n"
45
+ msg << "\tSession ID: #{@request.session.id}\n"
46
+ msg << "\tParameters: #{@request.all_params.inspect}\n"
47
+ msg << "\tCompleted in #{p_time} (#{(1 / p_time).round} reqs/sec) | #{@response.status} [#{@request.full_host}]"
48
+ else
49
+ msg = "[#{@request.request_method.upcase}] '#{@request.path_info}' (#{p_time})"
50
+ end
51
+ MACK_DEFAULT_LOGGER.info(msg)
52
+ x
53
+ end
54
+
55
+ # Setup the request, response, cookies, session, etc...
56
+ # yield up, and then clean things up afterwards.
57
+ def setup(env)
58
+ log_request do
59
+ @request = Mack::Request.new(env)
60
+ @response = Mack::Response.new
61
+ @cookies = Mack::CookieJar.new(self.request, self.response)
62
+ session do
63
+ yield
64
+ end
65
+ self.response.finish
66
+ end
67
+ end
68
+
69
+ def session
70
+ sess_id = self.cookies[app_config.mack.session_id]
71
+ unless sess_id
72
+ sess_id = create_new_session
73
+ else
74
+ sess = Cachetastic::Caches::MackSessionCache.get(sess_id)
75
+ if sess
76
+ self.request.session = sess
77
+ else
78
+ # we couldn't find it in the store, so we need to create it:
79
+ sess_id = create_new_session
80
+ end
81
+ end
82
+
83
+ yield
84
+
85
+ Cachetastic::Caches::MackSessionCache.set(sess_id, self.request.session)
86
+ end
87
+
88
+ def create_new_session
89
+ id = String.randomize(40).downcase
90
+ self.cookies[app_config.mack.session_id] = {:value => id, :expires => nil}
91
+ sess = Mack::Session.new(id)
92
+ self.request.session = sess
93
+ Cachetastic::Caches::MackSessionCache.set(id, sess)
94
+ end
95
+
96
+ def try_to_find_resource(env, path_info, exception)
97
+ # we can't find a route for this, so let's try and see if it's in the public directory:
98
+ if File.extname(path_info).blank?
99
+ path_info << ".html"
100
+ end
101
+ if File.exists?(File.join(MACK_PUBLIC, path_info))
102
+ return Rack::File.new(File.join(MACK_PUBLIC)).call(env)
103
+ else
104
+ raise exception
105
+ end
106
+ end
107
+
108
+ # This will redirect the request to the specified url. A default status of
109
+ # 302, Moved Temporarily, is set if no status is specified. A simple HTML
110
+ # page is rendered in case the redirect does not occur.
111
+ def redirect_to(route)
112
+ status = route[:status] || 302
113
+ url = route[:redirect_to]
114
+ options = self.request.all_params
115
+ options.merge!(route)
116
+ options - [:controller, :action, :redirect_to, :method, :status]
117
+ url = url_for_pattern(url, options)
118
+ self.response.status = status
119
+ self.response[:location] = url
120
+ self.response.write(redirect_html(self.request.path_info, url, status))
121
+ end
122
+
123
+ end
124
+ end