merb 0.3.7 → 0.4.0
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.
- data/README +25 -26
- data/Rakefile +48 -36
- data/app_generators/merb/USAGE +5 -0
- data/app_generators/merb/merb_generator.rb +107 -0
- data/app_generators/merb/templates/Rakefile +99 -0
- data/{examples/skeleton/dist → app_generators/merb/templates}/app/controllers/application.rb +1 -1
- data/app_generators/merb/templates/app/controllers/exceptions.rb +13 -0
- data/{examples/skeleton/dist → app_generators/merb/templates}/app/helpers/global_helper.rb +0 -0
- data/{examples/skeleton/dist/app/mailers → app_generators/merb/templates/app/mailers/views}/layout/application.erb +0 -0
- data/app_generators/merb/templates/app/views/exceptions/internal_server_error.html.erb +207 -0
- data/app_generators/merb/templates/app/views/exceptions/not_acceptable.html.erb +38 -0
- data/app_generators/merb/templates/app/views/exceptions/not_found.html.erb +40 -0
- data/app_generators/merb/templates/app/views/layout/application.html.erb +11 -0
- data/app_generators/merb/templates/config/boot.rb +11 -0
- data/app_generators/merb/templates/config/dependencies.rb +41 -0
- data/{examples/skeleton/dist/conf → app_generators/merb/templates/config}/environments/development.rb +0 -0
- data/{examples/skeleton/dist/conf → app_generators/merb/templates/config}/environments/production.rb +0 -0
- data/{examples/skeleton/dist/conf → app_generators/merb/templates/config}/environments/test.rb +0 -0
- data/app_generators/merb/templates/config/merb.yml +64 -0
- data/app_generators/merb/templates/config/merb_init.rb +16 -0
- data/app_generators/merb/templates/config/plugins.yml +1 -0
- data/app_generators/merb/templates/config/router.rb +32 -0
- data/{lib/merb/core_ext/merb_array.rb → app_generators/merb/templates/config/upload.conf} +0 -0
- data/app_generators/merb/templates/public/images/merb.jpg +0 -0
- data/app_generators/merb/templates/public/merb.fcgi +6 -0
- data/app_generators/merb/templates/public/stylesheets/master.css +119 -0
- data/app_generators/merb/templates/script/destroy +28 -0
- data/app_generators/merb/templates/script/generate +28 -0
- data/{examples/skeleton → app_generators/merb/templates}/script/stop_merb +0 -0
- data/app_generators/merb/templates/script/win_script.cmd +1 -0
- data/app_generators/merb/templates/spec/spec.opts +6 -0
- data/app_generators/merb/templates/spec/spec_helper.rb +10 -0
- data/app_generators/merb/templates/test/test_helper.rb +13 -0
- data/app_generators/merb_plugin/USAGE +5 -0
- data/app_generators/merb_plugin/merb_plugin_generator.rb +64 -0
- data/app_generators/merb_plugin/templates/LICENSE +20 -0
- data/app_generators/merb_plugin/templates/README +4 -0
- data/app_generators/merb_plugin/templates/Rakefile +35 -0
- data/app_generators/merb_plugin/templates/TODO +5 -0
- data/app_generators/merb_plugin/templates/merbtasks.rb +6 -0
- data/app_generators/merb_plugin/templates/sampleplugin.rb +10 -0
- data/app_generators/merb_plugin/templates/sampleplugin_spec.rb +7 -0
- data/app_generators/merb_plugin/templates/spec_helper.rb +2 -0
- data/bin/merb +1 -1
- data/lib/autotest/discover.rb +3 -0
- data/lib/autotest/merb_rspec.rb +79 -0
- data/lib/merb.rb +72 -93
- data/lib/merb/{merb_abstract_controller.rb → abstract_controller.rb} +28 -5
- data/lib/merb/caching/action_cache.rb +65 -29
- data/lib/merb/caching/fragment_cache.rb +9 -4
- data/lib/merb/caching/store/file_cache.rb +22 -14
- data/lib/merb/caching/store/memory_cache.rb +26 -8
- data/lib/merb/{merb_constants.rb → constants.rb} +9 -7
- data/lib/merb/controller.rb +178 -0
- data/lib/merb/core_ext.rb +13 -11
- data/lib/merb/core_ext/array.rb +0 -0
- data/lib/merb/core_ext/{merb_class.rb → class.rb} +0 -0
- data/lib/merb/core_ext/{merb_enumerable.rb → enumerable.rb} +0 -0
- data/lib/merb/core_ext/get_args.rb +52 -0
- data/lib/merb/core_ext/{merb_hash.rb → hash.rb} +40 -11
- data/lib/merb/core_ext/{merb_inflections.rb → inflections.rb} +0 -0
- data/lib/merb/core_ext/{merb_inflector.rb → inflector.rb} +1 -1
- data/lib/merb/core_ext/{merb_kernel.rb → kernel.rb} +56 -3
- data/lib/merb/core_ext/mash.rb +88 -0
- data/lib/merb/core_ext/{merb_module.rb → module.rb} +0 -0
- data/lib/merb/core_ext/{merb_numeric.rb → numeric.rb} +0 -0
- data/lib/merb/core_ext/{merb_object.rb → object.rb} +10 -47
- data/lib/merb/core_ext/string.rb +56 -0
- data/lib/merb/core_ext/{merb_symbol.rb → symbol.rb} +0 -0
- data/lib/merb/dispatcher.rb +109 -0
- data/lib/merb/{merb_drb_server.rb → drb_server.rb} +0 -0
- data/lib/merb/erubis_ext.rb +10 -0
- data/lib/merb/exceptions.rb +173 -0
- data/lib/merb/generators/merb_app/merb_app.rb +5 -25
- data/lib/merb/generators/merb_generator_helpers.rb +317 -0
- data/lib/merb/generators/merb_plugin.rb +19 -0
- data/lib/merb/logger.rb +65 -0
- data/lib/merb/{merb_mail_controller.rb → mail_controller.rb} +102 -49
- data/lib/merb/{merb_mailer.rb → mailer.rb} +31 -27
- data/lib/merb/mixins/{basic_authentication_mixin.rb → basic_authentication.rb} +3 -3
- data/lib/merb/mixins/{controller_mixin.rb → controller.rb} +131 -112
- data/lib/merb/mixins/{erubis_capture_mixin.rb → erubis_capture.rb} +12 -21
- data/lib/merb/mixins/{form_control_mixin.rb → form_control.rb} +6 -12
- data/lib/merb/mixins/render.rb +401 -0
- data/lib/merb/mixins/responder.rb +378 -0
- data/lib/merb/mixins/{view_context_mixin.rb → view_context.rb} +65 -10
- data/lib/merb/mixins/web_controller.rb +29 -0
- data/lib/merb/{merb_handler.rb → mongrel_handler.rb} +59 -38
- data/lib/merb/part_controller.rb +19 -0
- data/lib/merb/plugins.rb +16 -0
- data/lib/merb/rack_adapter.rb +37 -0
- data/lib/merb/request.rb +421 -0
- data/lib/merb/router.rb +576 -0
- data/lib/merb/{merb_server.rb → server.rb} +275 -71
- data/lib/merb/session.rb +10 -10
- data/lib/merb/session/cookie_store.rb +125 -0
- data/lib/merb/session/{merb_mem_cache_session.rb → mem_cache_session.rb} +22 -9
- data/lib/merb/session/{merb_memory_session.rb → memory_session.rb} +15 -11
- data/lib/merb/template.rb +35 -8
- data/lib/merb/template/erubis.rb +16 -10
- data/lib/merb/template/haml.rb +33 -20
- data/lib/merb/template/markaby.rb +16 -14
- data/lib/merb/template/xml_builder.rb +8 -4
- data/lib/merb/test/{merb_fake_request.rb → fake_request.rb} +11 -5
- data/lib/merb/test/helper.rb +31 -0
- data/lib/merb/test/hpricot.rb +136 -0
- data/lib/merb/test/{merb_multipart.rb → multipart.rb} +1 -1
- data/lib/merb/test/rspec.rb +93 -0
- data/lib/merb/{merb_upload_handler.rb → upload_handler.rb} +5 -6
- data/lib/merb/{merb_upload_progress.rb → upload_progress.rb} +1 -1
- data/lib/merb/{merb_view_context.rb → view_context.rb} +27 -42
- data/lib/{merb_tasks.rb → tasks.rb} +0 -0
- data/lib/tasks/merb.rake +21 -11
- data/merb_default_generators/model/USAGE +0 -0
- data/merb_default_generators/model/model_generator.rb +16 -0
- data/merb_default_generators/model/templates/new_model_template.erb +5 -0
- data/merb_default_generators/resource_controller/USAGE +0 -0
- data/merb_default_generators/resource_controller/resource_controller_generator.rb +26 -0
- data/merb_default_generators/resource_controller/templates/controller.rb +30 -0
- data/merb_default_generators/resource_controller/templates/edit.html.erb +1 -0
- data/merb_default_generators/resource_controller/templates/helper.rb +5 -0
- data/merb_default_generators/resource_controller/templates/index.html.erb +1 -0
- data/merb_default_generators/resource_controller/templates/new.html.erb +1 -0
- data/merb_default_generators/resource_controller/templates/show.html.erb +1 -0
- data/merb_generators/controller/USAGE +5 -0
- data/merb_generators/controller/controller_generator.rb +16 -0
- data/merb_generators/controller/templates/controller.rb +8 -0
- data/merb_generators/controller/templates/helper.rb +5 -0
- data/merb_generators/controller/templates/index.html.erb +3 -0
- data/merb_generators/resource/USAGE +0 -0
- data/merb_generators/resource/resource_generator.rb +60 -0
- data/rspec_generators/merb_controller_test/merb_controller_test_generator.rb +67 -0
- data/rspec_generators/merb_controller_test/templates/controller_spec.rb +8 -0
- data/rspec_generators/merb_controller_test/templates/edit_spec.rb +12 -0
- data/rspec_generators/merb_controller_test/templates/helper_spec.rb +5 -0
- data/rspec_generators/merb_controller_test/templates/index_spec.rb +12 -0
- data/rspec_generators/merb_controller_test/templates/new_spec.rb +12 -0
- data/rspec_generators/merb_controller_test/templates/show_spec.rb +5 -0
- data/rspec_generators/merb_model_test/merb_model_test_generator.rb +26 -0
- data/rspec_generators/merb_model_test/templates/model_spec_template.erb +7 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/test_unit_generators/merb_controller_test/merb_controller_test_generator.rb +53 -0
- data/test_unit_generators/merb_controller_test/templates/functional_test.rb +17 -0
- data/test_unit_generators/merb_controller_test/templates/helper_test.rb +9 -0
- data/test_unit_generators/merb_model_test/merb_model_test_generator.rb +29 -0
- data/test_unit_generators/merb_model_test/templates/model_test_unit_template.erb +9 -0
- metadata +172 -94
- data/examples/README_EXAMPLES +0 -10
- data/examples/skeleton/Rakefile +0 -68
- data/examples/skeleton/dist/app/views/layout/application.herb +0 -12
- data/examples/skeleton/dist/conf/database.yml +0 -23
- data/examples/skeleton/dist/conf/merb.yml +0 -57
- data/examples/skeleton/dist/conf/merb_init.rb +0 -24
- data/examples/skeleton/dist/conf/router.rb +0 -22
- data/examples/skeleton/dist/conf/upload.conf +0 -5
- data/examples/skeleton/dist/schema/migrations/001_add_sessions_table.rb +0 -14
- data/examples/skeleton/script/new_migration +0 -21
- data/lib/merb/core_ext/merb_string.rb +0 -18
- data/lib/merb/merb_controller.rb +0 -206
- data/lib/merb/merb_dispatcher.rb +0 -87
- data/lib/merb/merb_exceptions.rb +0 -319
- data/lib/merb/merb_part_controller.rb +0 -42
- data/lib/merb/merb_plugins.rb +0 -293
- data/lib/merb/merb_request.rb +0 -165
- data/lib/merb/merb_router.rb +0 -309
- data/lib/merb/merb_yaml_store.rb +0 -31
- data/lib/merb/mixins/render_mixin.rb +0 -283
- data/lib/merb/mixins/responder_mixin.rb +0 -159
- data/lib/merb/session/merb_ar_session.rb +0 -131
- data/lib/merb/vendor/paginator/README.txt +0 -84
- data/lib/merb/vendor/paginator/paginator.rb +0 -124
- data/lib/tasks/db.rake +0 -55
|
@@ -6,11 +6,16 @@ module Merb
|
|
|
6
6
|
@cache ||= determine_cache_store
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
+
def clear
|
|
10
|
+
cache.clear
|
|
11
|
+
@cache = nil
|
|
12
|
+
end
|
|
13
|
+
|
|
9
14
|
def get(name)
|
|
10
15
|
cache.get(name)
|
|
11
16
|
end
|
|
12
17
|
|
|
13
|
-
def put(name, content = nil)
|
|
18
|
+
def put(name, content = nil)
|
|
14
19
|
cache.put(name, content)
|
|
15
20
|
content
|
|
16
21
|
end
|
|
@@ -20,12 +25,12 @@ module Merb
|
|
|
20
25
|
end
|
|
21
26
|
|
|
22
27
|
def determine_cache_store
|
|
23
|
-
if ::Merb::Server.cache_store.to_s == "file"
|
|
28
|
+
if ::Merb::Server.config[:cache_store].to_s == "file"
|
|
24
29
|
require 'merb/caching/store/file_cache'
|
|
25
30
|
::Merb::Caching::Store::FileCache.new
|
|
26
31
|
else
|
|
27
|
-
require 'merb/caching/store/memory_cache'
|
|
28
|
-
::Merb::Caching::Store::MemoryCache.new
|
|
32
|
+
require 'merb/caching/store/memory_cache'
|
|
33
|
+
::Merb::Caching::Store::MemoryCache.new
|
|
29
34
|
end
|
|
30
35
|
end
|
|
31
36
|
end
|
|
@@ -10,29 +10,31 @@ module Merb
|
|
|
10
10
|
|
|
11
11
|
def initialize(name = "cache", keepalive = nil)
|
|
12
12
|
@path = File.join(MERB_ROOT, name)
|
|
13
|
-
@keepalive = keepalive
|
|
14
|
-
|
|
15
|
-
FileUtils.mkdir_p(@path, :mode => 0700)
|
|
13
|
+
@keepalive = keepalive
|
|
16
14
|
end
|
|
17
15
|
|
|
18
|
-
def []=(
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
def []=(key,val)
|
|
17
|
+
key = escape_filenames([key].flatten)
|
|
18
|
+
FileUtils.mkdir_p(File.join(@path, *key[0..-2]), :mode => 0700)
|
|
19
|
+
fn = File.join(@path, *key )
|
|
20
|
+
encode_file(fn, val)
|
|
21
21
|
end
|
|
22
22
|
alias :put :[]=
|
|
23
23
|
alias :write :[]=
|
|
24
24
|
|
|
25
|
-
def [](
|
|
26
|
-
|
|
25
|
+
def [](key)
|
|
26
|
+
key = escape_filenames([key].flatten)
|
|
27
|
+
fn = File.join(@path, *key )
|
|
27
28
|
return nil unless File.exists?(fn)
|
|
28
29
|
decode_file(fn)
|
|
29
30
|
end
|
|
30
31
|
alias :get :[]
|
|
31
32
|
alias_method :read, :[]
|
|
32
33
|
|
|
33
|
-
def delete(
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
def delete(key)
|
|
35
|
+
key = escape_filenames([key].flatten)
|
|
36
|
+
f = File.join(@path, *key)
|
|
37
|
+
FileUtils.rm_rf(f)
|
|
36
38
|
end
|
|
37
39
|
|
|
38
40
|
def gc!
|
|
@@ -44,12 +46,16 @@ module Merb
|
|
|
44
46
|
File.delete(fn) if now > expire_time
|
|
45
47
|
end
|
|
46
48
|
end
|
|
49
|
+
|
|
50
|
+
def clear
|
|
51
|
+
all.each{|file| delete(File.basename(file)) }
|
|
52
|
+
end
|
|
47
53
|
|
|
48
54
|
private
|
|
49
55
|
|
|
50
56
|
def decode_file(fn)
|
|
51
57
|
val = nil
|
|
52
|
-
File.open(fn,"
|
|
58
|
+
File.open(fn,"r+b") do |f|
|
|
53
59
|
f.flock(File::LOCK_EX)
|
|
54
60
|
val = Marshal.load( f.read )
|
|
55
61
|
f.flock(File::LOCK_UN)
|
|
@@ -70,8 +76,10 @@ module Merb
|
|
|
70
76
|
Dir.glob( File.join(@path, '*' ) )
|
|
71
77
|
end
|
|
72
78
|
# need this for fat filesystems
|
|
73
|
-
def
|
|
74
|
-
|
|
79
|
+
def escape_filenames(fns)
|
|
80
|
+
fns.collect do |fn|
|
|
81
|
+
URI.escape(fn.to_s, /["\/:;|=,\[\]]/)
|
|
82
|
+
end
|
|
75
83
|
end
|
|
76
84
|
|
|
77
85
|
end
|
|
@@ -13,26 +13,41 @@ module Merb
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def [](key)
|
|
16
|
+
key = [key].flatten.collect{|k| k.to_s}
|
|
16
17
|
@mutex.synchronize {
|
|
17
18
|
@timestamps[key] = Time.now
|
|
18
|
-
@cache
|
|
19
|
+
sub_cache = @cache
|
|
20
|
+
key[0..-2].each do |subkey|
|
|
21
|
+
sub_cache = (sub_cache[subkey] ||= {})
|
|
22
|
+
end
|
|
23
|
+
sub_cache[key[-1]]
|
|
19
24
|
}
|
|
20
25
|
end
|
|
21
26
|
alias_method :get, :[]
|
|
22
27
|
alias_method :read, :[]
|
|
23
28
|
|
|
24
|
-
def []=(key, val)
|
|
29
|
+
def []=(key, val)
|
|
30
|
+
key = [key].flatten.collect{|k| k.to_s}
|
|
25
31
|
@mutex.synchronize {
|
|
32
|
+
sub_cache = @cache
|
|
33
|
+
key[0..-2].each do |subkey|
|
|
34
|
+
sub_cache = (sub_cache[subkey] ||= {})
|
|
35
|
+
end
|
|
36
|
+
sub_cache[key[-1]] = val
|
|
26
37
|
@timestamps[key] = Time.now
|
|
27
|
-
@cache[key] = val
|
|
28
38
|
}
|
|
29
39
|
end
|
|
30
40
|
alias_method :put, :[]=
|
|
31
41
|
alias_method :write, :[]=
|
|
32
42
|
|
|
33
43
|
def delete(key)
|
|
44
|
+
key = [key].flatten.collect{|k| k.to_s}
|
|
34
45
|
@mutex.synchronize {
|
|
35
|
-
@cache
|
|
46
|
+
sub_cache = @cache
|
|
47
|
+
key[0..-2].each do |subkey|
|
|
48
|
+
sub_cache = (sub_cache[subkey] ||= {})
|
|
49
|
+
end
|
|
50
|
+
sub_cache.delete(key[-1])
|
|
36
51
|
}
|
|
37
52
|
end
|
|
38
53
|
alias_method :remove, :delete
|
|
@@ -57,11 +72,14 @@ module Merb
|
|
|
57
72
|
def keys
|
|
58
73
|
@cache.keys
|
|
59
74
|
end
|
|
75
|
+
|
|
76
|
+
def clear
|
|
77
|
+
@cache = Hash.new
|
|
78
|
+
@timestamps = Hash.new
|
|
79
|
+
@mutex = Mutex.new
|
|
80
|
+
end
|
|
60
81
|
|
|
61
82
|
end
|
|
62
|
-
|
|
63
83
|
end
|
|
64
|
-
|
|
65
|
-
end
|
|
66
|
-
|
|
84
|
+
end
|
|
67
85
|
end
|
|
@@ -15,6 +15,7 @@ module Merb
|
|
|
15
15
|
}.freeze
|
|
16
16
|
|
|
17
17
|
SET_COOKIE = " %s=%s; path=/; expires=%s".freeze
|
|
18
|
+
COOKIE_EXPIRATION_FORMAT = "%a, %d-%b-%Y %H:%M:%S GMT".freeze
|
|
18
19
|
COOKIE_SPLIT = /[;,] */n.freeze
|
|
19
20
|
COOKIE_REGEXP = /\s*(.+)=(.*)\s*/.freeze
|
|
20
21
|
COOKIE_EXPIRED_TIME = Time.at(0).freeze
|
|
@@ -27,7 +28,8 @@ module Merb
|
|
|
27
28
|
APPLICATION_JSON = 'application/json'.freeze
|
|
28
29
|
TEXT_JSON = 'text/x-json'.freeze
|
|
29
30
|
APPLICATION_XML = 'application/xml'.freeze
|
|
30
|
-
TEXT_XML = 'text/xml'.freeze
|
|
31
|
+
TEXT_XML = 'text/xml'.freeze
|
|
32
|
+
FORM_URL_ENCODED_REGEXP = %r{^application/x-www-form-urlencoded}.freeze
|
|
31
33
|
UPCASE_CONTENT_TYPE = 'CONTENT_TYPE'.freeze
|
|
32
34
|
CONTENT_TYPE = "Content-Type".freeze
|
|
33
35
|
LAST_MODIFIED = "Last-Modified".freeze
|
|
@@ -40,11 +42,11 @@ module Merb
|
|
|
40
42
|
HTTP_X_FORWARDED_FOR = "HTTP_X_FORWARDED_FOR".freeze
|
|
41
43
|
HTTP_IF_MODIFIED_SINCE = "HTTP_IF_MODIFIED_SINCE".freeze
|
|
42
44
|
HTTP_IF_NONE_MATCH = "HTTP_IF_NONE_MATCH".freeze
|
|
43
|
-
UPLOAD_ID
|
|
44
|
-
PATH_INFO="PATH_INFO".freeze
|
|
45
|
-
SCRIPT_NAME="SCRIPT_NAME".freeze
|
|
46
|
-
REQUEST_URI=
|
|
47
|
-
REQUEST_PATH=
|
|
48
|
-
REMOTE_ADDR="REMOTE_ADDR".freeze
|
|
45
|
+
UPLOAD_ID = "upload_id".freeze
|
|
46
|
+
PATH_INFO = "PATH_INFO".freeze
|
|
47
|
+
SCRIPT_NAME = "SCRIPT_NAME".freeze
|
|
48
|
+
REQUEST_URI = "REQUEST_URI".freeze
|
|
49
|
+
REQUEST_PATH = "REQUEST_PATH".freeze
|
|
50
|
+
REMOTE_ADDR = "REMOTE_ADDR".freeze
|
|
49
51
|
end
|
|
50
52
|
end
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
module Merb
|
|
2
|
+
|
|
3
|
+
# All of your web controllers will inherit from Merb::Controller. This
|
|
4
|
+
# superclass takes care of parsing the incoming headers and body into
|
|
5
|
+
# params and cookies and headers. If the request is a file upload it will
|
|
6
|
+
# stream it into a tempfile and pass in the filename and tempfile object
|
|
7
|
+
# to your controller via params. It also parses the ?query=string and
|
|
8
|
+
# puts that into params as well.
|
|
9
|
+
class Controller < AbstractController
|
|
10
|
+
cattr_accessor :_subclasses
|
|
11
|
+
self._subclasses = []
|
|
12
|
+
|
|
13
|
+
class_inheritable_accessor :_session_id_key, :_session_expiry
|
|
14
|
+
self._session_id_key = :_session_id
|
|
15
|
+
self._session_expiry = Time.now + Merb::Const::WEEK * 2
|
|
16
|
+
|
|
17
|
+
include Merb::ControllerMixin
|
|
18
|
+
include Merb::ResponderMixin
|
|
19
|
+
include Merb::ControllerExceptions
|
|
20
|
+
|
|
21
|
+
class << self
|
|
22
|
+
def inherited(klass)
|
|
23
|
+
_subclasses << klass.to_s
|
|
24
|
+
super
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def callable_actions
|
|
28
|
+
@callable_actions ||= begin
|
|
29
|
+
hsh = {}
|
|
30
|
+
(public_instance_methods - hidden_actions).each {|action| hsh[action.to_s] = true}
|
|
31
|
+
hsh
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def hidden_actions
|
|
36
|
+
write_inheritable_attribute(:hidden_actions, Merb::Controller.public_instance_methods) unless read_inheritable_attribute(:hidden_actions)
|
|
37
|
+
read_inheritable_attribute(:hidden_actions)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Hide each of the given methods from being callable as actions.
|
|
41
|
+
def hide_action(*names)
|
|
42
|
+
write_inheritable_attribute(:hidden_actions, hidden_actions | names.collect { |n| n.to_s })
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def build(request, response = StringIO.new, status=200, headers={'Content-Type' => 'text/html; charset=utf-8'})
|
|
46
|
+
cont = new
|
|
47
|
+
cont.set_dispatch_variables(request, response, status, headers)
|
|
48
|
+
cont
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def set_dispatch_variables(request, response, status, headers)
|
|
53
|
+
if request.params.key?(_session_id_key)
|
|
54
|
+
if Merb::Server.config[:session_id_cookie_only]
|
|
55
|
+
# This condition allows for certain controller/action paths to allow
|
|
56
|
+
# a session ID to be passed in a query string. This is needed for
|
|
57
|
+
# Flash Uploads to work since flash will not pass a Session Cookie
|
|
58
|
+
# Recommend running session.regenerate after any controller taking
|
|
59
|
+
# advantage of this in case someone is attempting a session fixation
|
|
60
|
+
# attack
|
|
61
|
+
if Merb::Server.config[:query_string_whitelist].include?("#{request.controller_name}/#{request.action}")
|
|
62
|
+
# FIXME to use routes not controller and action names -----^
|
|
63
|
+
request.cookies[_session_id_key] = request.params[_session_id_key]
|
|
64
|
+
end
|
|
65
|
+
else
|
|
66
|
+
request.cookies[_session_id_key] = request.params[_session_id_key]
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
@_request = request
|
|
70
|
+
@_response = response
|
|
71
|
+
@_status = status
|
|
72
|
+
@_headers = headers
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def dispatch(action=:index)
|
|
76
|
+
start = Time.now
|
|
77
|
+
if self.class.callable_actions[action.to_s]
|
|
78
|
+
params[:action] ||= action
|
|
79
|
+
setup_session
|
|
80
|
+
super(action)
|
|
81
|
+
finalize_session
|
|
82
|
+
else
|
|
83
|
+
raise ActionNotFound, "Action '#{action}' was not found in #{self.class}"
|
|
84
|
+
end
|
|
85
|
+
@_benchmarks[:action_time] = Time.now - start
|
|
86
|
+
MERB_LOGGER.info("Time spent in #{self.class}##{action} action: #{@_benchmarks[:action_time]} seconds")
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Accessor for @_body. Please use body and never @body directly.
|
|
90
|
+
def body
|
|
91
|
+
@_body
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Accessor for @_status. Please use status and never @_status directly.
|
|
95
|
+
def status
|
|
96
|
+
@_status
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Accessor for @_request. Please use request and never @_request directly.
|
|
100
|
+
def request
|
|
101
|
+
@_request
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def params
|
|
105
|
+
request.params
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def cookies
|
|
109
|
+
request.cookies
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Accessor for @_headers. Please use headers and never @_headers directly.
|
|
113
|
+
def headers
|
|
114
|
+
@_headers
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Accessor for @_session. Please use session and never @_session directly.
|
|
118
|
+
def session
|
|
119
|
+
request.session
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Accessor for @_response. Please use response and never @_response directly.
|
|
123
|
+
def response
|
|
124
|
+
@_response
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Accessor for @_route. Please use route and never @_route directly.
|
|
128
|
+
def route
|
|
129
|
+
request.route
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Sends mail via a MailController (a tutorial can be found in the
|
|
133
|
+
# MailController docs).
|
|
134
|
+
#
|
|
135
|
+
# send_mail FooMailer, :bar, :from => "foo@bar.com", :to => "baz@bat.com"
|
|
136
|
+
#
|
|
137
|
+
# would send an email via the FooMailer's bar method.
|
|
138
|
+
#
|
|
139
|
+
# The mail_params hash would be sent to the mailer, and includes items
|
|
140
|
+
# like from, to subject, and cc. See
|
|
141
|
+
# Merb::MailController#dispatch_and_deliver for more details.
|
|
142
|
+
#
|
|
143
|
+
# The send_params hash would be sent to the MailController, and is
|
|
144
|
+
# available to methods in the MailController as <tt>params</tt>. If you do
|
|
145
|
+
# not send any send_params, this controller's params will be available to
|
|
146
|
+
# the MailController as <tt>params</tt>
|
|
147
|
+
def send_mail(klass, method, mail_params, send_params = nil)
|
|
148
|
+
klass.new(send_params || params, self).dispatch_and_deliver(method, mail_params)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Dispatches a PartController. Use like:
|
|
152
|
+
#
|
|
153
|
+
# <%= part TodoPart => :list %>
|
|
154
|
+
#
|
|
155
|
+
# will instantiate a new TodoPart controller and call the :list action
|
|
156
|
+
# invoking the Part's before and after filters as part of the call.
|
|
157
|
+
#
|
|
158
|
+
# returns a string containing the results of the Part controllers dispatch
|
|
159
|
+
#
|
|
160
|
+
# You can compose parts easily as well, these two parts will stil be wrapped
|
|
161
|
+
# in the layout of the Foo controller:
|
|
162
|
+
#
|
|
163
|
+
# class Foo < Application
|
|
164
|
+
# def some_action
|
|
165
|
+
# wrap_layout(part(TodoPart => :new) + part(TodoPart => :list))
|
|
166
|
+
# end
|
|
167
|
+
# end
|
|
168
|
+
#
|
|
169
|
+
def part(opts={})
|
|
170
|
+
res = opts.inject([]) do |memo,(klass,action)|
|
|
171
|
+
memo << klass.new(self).dispatch(action)
|
|
172
|
+
end
|
|
173
|
+
res.size == 1 ? res[0] : res
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
end
|
data/lib/merb/core_ext.rb
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
corelib =
|
|
1
|
+
corelib = File.dirname(__FILE__) + '/core_ext'
|
|
2
2
|
|
|
3
|
-
%w[
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
%w[ inflector
|
|
4
|
+
class
|
|
5
|
+
kernel
|
|
6
|
+
object
|
|
7
|
+
mash
|
|
8
|
+
enumerable
|
|
9
|
+
module
|
|
10
|
+
string
|
|
11
|
+
hash
|
|
12
|
+
numeric
|
|
13
|
+
symbol
|
|
14
|
+
get_args
|
|
13
15
|
].each {|fn| require File.join(corelib, fn)}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require 'ruby2ruby'
|
|
3
|
+
|
|
4
|
+
class ParseTreeArray < Array
|
|
5
|
+
def self.translate(*args)
|
|
6
|
+
self.new(ParseTree.translate(*args))
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def deep_array_node(type = nil)
|
|
10
|
+
each do |node|
|
|
11
|
+
return ParseTreeArray.new(node) if node.is_a?(Array) && (!type || node[0] == type)
|
|
12
|
+
next unless node.is_a?(Array)
|
|
13
|
+
return ParseTreeArray.new(node).deep_array_node(type)
|
|
14
|
+
end
|
|
15
|
+
nil
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def arg_nodes
|
|
19
|
+
self[1..-1].inject([]) do |sum,item|
|
|
20
|
+
sum << [item] unless item.is_a?(Array)
|
|
21
|
+
sum
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def get_args
|
|
26
|
+
arg_node = deep_array_node(:args)
|
|
27
|
+
args = arg_node.arg_nodes
|
|
28
|
+
lasgns = arg_node.deep_array_node(:block)[1..-1]
|
|
29
|
+
lasgns.each do |asgn|
|
|
30
|
+
args.assoc(asgn[1]) << eval(RubyToRuby.new.process(asgn[2]))
|
|
31
|
+
end
|
|
32
|
+
args
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
module GetArgs
|
|
38
|
+
def get_args
|
|
39
|
+
klass, meth = self.to_s.split(/ /).to_a[1][0..-2].split("#")
|
|
40
|
+
ParseTreeArray.translate(Object.const_get(klass), meth).get_args
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
class UnboundMethod
|
|
45
|
+
include GetArgs
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
class Method
|
|
49
|
+
include GetArgs
|
|
50
|
+
end
|
|
51
|
+
rescue LoadError
|
|
52
|
+
end
|