ramaze 0.1.3 → 0.1.4

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 (149) hide show
  1. data/bin/ramaze +58 -26
  2. data/doc/AUTHORS +2 -0
  3. data/doc/CHANGELOG +401 -0
  4. data/doc/README +14 -9
  5. data/doc/README.html +737 -0
  6. data/doc/TODO +14 -14
  7. data/doc/changes.txt +401 -0
  8. data/doc/changes.xml +401 -0
  9. data/doc/meta/announcement.txt +28 -15
  10. data/doc/meta/configuration.txt +3 -3
  11. data/doc/meta/internals.txt +2 -2
  12. data/doc/meta/users.kml +62 -0
  13. data/doc/readme_chunks/examples.txt +1 -1
  14. data/doc/readme_chunks/features.txt +13 -8
  15. data/doc/tutorial/todolist.html +2 -2
  16. data/doc/tutorial/todolist.mkd +2 -2
  17. data/examples/blog/README +3 -0
  18. data/examples/blog/spec/blog.rb +101 -0
  19. data/examples/blog/{main.rb → start.rb} +0 -0
  20. data/examples/caching.rb +16 -5
  21. data/examples/layout.rb +41 -0
  22. data/examples/templates/template_amrita2.rb +1 -1
  23. data/examples/templates/template_erubis.rb +1 -1
  24. data/examples/templates/template_ezamar.rb +1 -1
  25. data/examples/templates/template_haml.rb +1 -1
  26. data/examples/templates/template_liquid.rb +1 -1
  27. data/examples/templates/template_markaby.rb +1 -1
  28. data/examples/templates/template_remarkably.rb +1 -1
  29. data/examples/todolist/README +1 -0
  30. data/{spec/examples → examples/todolist/spec}/todolist.rb +3 -3
  31. data/examples/todolist/{main.rb → start.rb} +0 -0
  32. data/examples/whywiki/{main.rb → start.rb} +0 -0
  33. data/examples/wiktacular/README +2 -0
  34. data/examples/wiktacular/spec/wiktacular.rb +146 -0
  35. data/examples/wiktacular/src/controller.rb +11 -0
  36. data/examples/wiktacular/src/model.rb +5 -1
  37. data/examples/wiktacular/{main.rb → start.rb} +0 -1
  38. data/examples/wiktacular/template/edit.xhtml +1 -2
  39. data/examples/wiktacular/template/html_layout.xhtml +27 -0
  40. data/examples/wiktacular/template/index.xhtml +8 -10
  41. data/examples/wiktacular/template/new.xhtml +1 -2
  42. data/lib/proto/{main.rb → start.rb} +0 -0
  43. data/lib/proto/template/index.xhtml +1 -1
  44. data/lib/ramaze/action/render.rb +58 -4
  45. data/lib/ramaze/action.rb +20 -0
  46. data/lib/ramaze/adapter/cgi.rb +7 -4
  47. data/lib/ramaze/adapter/fcgi.rb +6 -4
  48. data/lib/ramaze/adapter/mongrel.rb +4 -0
  49. data/lib/ramaze/adapter/webrick.rb +20 -9
  50. data/lib/ramaze/adapter.rb +3 -1
  51. data/lib/ramaze/cache/memcached.rb +2 -26
  52. data/lib/ramaze/cache.rb +8 -4
  53. data/lib/ramaze/controller/resolve.rb +26 -8
  54. data/lib/ramaze/controller.rb +44 -7
  55. data/lib/ramaze/dispatcher/action.rb +5 -1
  56. data/lib/ramaze/dispatcher/directory.rb +115 -0
  57. data/lib/ramaze/dispatcher/error.rb +19 -5
  58. data/lib/ramaze/dispatcher/file.rb +2 -2
  59. data/lib/ramaze/dispatcher.rb +52 -39
  60. data/lib/ramaze/global/dsl.rb +3 -2
  61. data/lib/ramaze/global/globalstruct.rb +26 -4
  62. data/lib/ramaze/global.rb +20 -11
  63. data/lib/ramaze/helper/aspect.rb +29 -11
  64. data/lib/ramaze/helper/auth.rb +2 -2
  65. data/lib/ramaze/helper/cache.rb +2 -0
  66. data/lib/ramaze/helper/identity.rb +21 -6
  67. data/lib/ramaze/helper/link.rb +1 -1
  68. data/lib/ramaze/helper/pager.rb +158 -100
  69. data/lib/ramaze/helper/partial.rb +22 -0
  70. data/lib/ramaze/helper/redirect.rb +1 -2
  71. data/lib/ramaze/helper/stack.rb +1 -1
  72. data/lib/ramaze/inform/informer.rb +20 -0
  73. data/lib/ramaze/inform/syslog.rb +5 -0
  74. data/lib/ramaze/snippets/kernel/__dir__.rb +21 -0
  75. data/lib/ramaze/snippets/kernel/aquire.rb +22 -12
  76. data/lib/ramaze/snippets/numeric/human_readable_filesize_format.rb +33 -0
  77. data/lib/ramaze/snippets/ramaze/caller_lines.rb +1 -1
  78. data/lib/ramaze/snippets/struct/values_at.rb +11 -4
  79. data/lib/ramaze/sourcereload.rb +29 -1
  80. data/{spec → lib/ramaze/spec}/helper/context.rb +0 -0
  81. data/{spec → lib/ramaze/spec}/helper/layout.rb +1 -1
  82. data/{spec → lib/ramaze/spec}/helper/minimal.rb +0 -0
  83. data/{spec → lib/ramaze/spec}/helper/mock_http.rb +0 -0
  84. data/{spec → lib/ramaze/spec}/helper/requester.rb +0 -0
  85. data/{spec → lib/ramaze/spec}/helper/simple_http.rb +0 -0
  86. data/{spec → lib/ramaze/spec}/helper/wrap.rb +0 -0
  87. data/lib/ramaze/spec/helper.rb +60 -0
  88. data/lib/ramaze/store/default.rb +3 -0
  89. data/lib/ramaze/template/ezamar/render_partial.rb +3 -0
  90. data/lib/ramaze/template/sass.rb +45 -0
  91. data/lib/ramaze/template.rb +1 -1
  92. data/lib/ramaze/tool/create.rb +5 -5
  93. data/lib/ramaze/tool/localize.rb +26 -5
  94. data/lib/ramaze/tool/mime.rb +7 -0
  95. data/lib/ramaze/trinity/response.rb +15 -0
  96. data/lib/ramaze/trinity/session.rb +1 -1
  97. data/lib/ramaze/version.rb +1 -1
  98. data/lib/ramaze.rb +5 -0
  99. data/rake_tasks/conf.rake +4 -4
  100. data/rake_tasks/maintaince.rake +12 -7
  101. data/rake_tasks/spec.rake +7 -4
  102. data/spec/examples/caching.rb +6 -8
  103. data/spec/helper.rb +3 -60
  104. data/spec/ramaze/action/basics.rb +17 -0
  105. data/spec/ramaze/action/cache.rb +28 -0
  106. data/spec/ramaze/action/layout.rb +110 -0
  107. data/spec/ramaze/action/render.rb +14 -0
  108. data/spec/ramaze/action/template/bar.xhtml +1 -0
  109. data/spec/ramaze/action/template/other_wrapper.xhtml +1 -0
  110. data/spec/ramaze/action/template/single_wrapper.xhtml +1 -0
  111. data/spec/ramaze/controller/template/edit/content.xhtml +1 -0
  112. data/spec/ramaze/controller/template/edit.xhtml +1 -0
  113. data/spec/ramaze/controller/template_resolving.rb +2 -2
  114. data/spec/ramaze/dispatcher/directory.rb +53 -0
  115. data/spec/ramaze/dispatcher/file.rb +0 -3
  116. data/spec/ramaze/error.rb +17 -2
  117. data/spec/ramaze/helper/aspect.rb +14 -20
  118. data/spec/ramaze/helper/pager.rb +83 -1
  119. data/spec/ramaze/helper/partial.rb +1 -1
  120. data/spec/ramaze/helper/template/test_template.xhtml +1 -0
  121. data/spec/ramaze/inform/informer.rb +37 -5
  122. data/spec/ramaze/localize.rb +1 -1
  123. data/spec/ramaze/template/haml.rb +5 -5
  124. data/spec/ramaze/template/sass/file.css.sass +5 -0
  125. data/spec/ramaze/template/sass.rb +46 -0
  126. data/spec/ramaze/template.rb +1 -1
  127. data/spec/ramaze/trinity/session.rb +27 -0
  128. data/spec/snippets/kernel/__dir__.rb +8 -0
  129. data/spec/snippets/kernel/aquire.rb +71 -0
  130. data/spec/snippets/kernel/constant.rb +27 -0
  131. data/spec/snippets/numeric/human_readable_filesize_format.rb +11 -0
  132. data/spec/snippets/ramaze/caller_info.rb +39 -0
  133. data/spec/snippets/ramaze/caller_lines.rb +27 -0
  134. data/spec/snippets/string/DIVIDE.rb +18 -0
  135. data/spec/snippets/string/camel_case.rb +25 -0
  136. data/spec/snippets/string/color.rb +11 -0
  137. data/spec/snippets/string/snake_case.rb +17 -0
  138. data/spec/snippets/struct/fill.rb +27 -0
  139. data/spec/snippets/struct/values_at.rb +39 -0
  140. metadata +71 -31
  141. data/examples/todolist/todolist.db +0 -5
  142. data/examples/wiktacular/src/page.rb +0 -66
  143. data/lib/ramaze/helper/feed.rb +0 -135
  144. data/lib/ramaze/helper/form.rb +0 -204
  145. data/lib/ramaze/snippets/openstruct/temp.rb +0 -13
  146. data/lib/ramaze/store/yaml.rb +0 -170
  147. data/spec/ramaze/helper/feed.rb +0 -127
  148. data/spec/ramaze/helper/form.rb +0 -146
  149. data/spec/ramaze/store/yaml.rb +0 -76
data/lib/ramaze/action.rb CHANGED
@@ -101,6 +101,26 @@ module Ramaze
101
101
  self[:binding] ||= instance.instance_eval{ binding }
102
102
  end
103
103
 
104
+ def name
105
+ File.basename((self[:method] || self[:template]).to_s).split('.').first
106
+ end
107
+
108
+ # TODO: find good names for this method.
109
+
110
+ def basepath
111
+ @basepath ||= "#{controller.mapping}/#{name}".gsub(/^\/+/, '/')
112
+ end
113
+
114
+ # TODO: find good names for this method.
115
+ def fullpath
116
+ "#{path}/#{params.join('/')}".gsub(/^\/+/, '/')
117
+ end
118
+
119
+ # TODO: find good names for this method.
120
+ def extended_path
121
+ @extended_path ||= File.join(path, *params)
122
+ end
123
+
104
124
  # Hook for AspectHelper
105
125
 
106
126
  def before_process
@@ -4,15 +4,18 @@
4
4
  require 'ramaze/adapter'
5
5
 
6
6
  module Ramaze::Adapter
7
+
8
+ # Our CGI adapter acts as wrapper for the Rack::Handler::CGI.
7
9
  class Cgi < Base
8
10
  class << self
9
- def start host, ports
11
+
12
+ # start CGI in a new thread, host and port parameter are only taken
13
+ # to make it compatible with other adapters but have no influence and
14
+ # can be omitted
15
+ def start host = nil, ports = nil
10
16
  global = Ramaze::Global
11
17
  global.inform_to = :stderr if global.inform_to == $stdout
12
- run_server
13
- end
14
18
 
15
- def run_server
16
19
  Thread.new do
17
20
  Thread.current[:task] = :cgi
18
21
  Rack::Handler::CGI.run(self)
@@ -4,13 +4,15 @@
4
4
  require 'ramaze/adapter'
5
5
 
6
6
  module Ramaze::Adapter
7
+
8
+ # Our Fcgi adapter acts as wrapper for the Rack::Handler::FastCGI.
7
9
  class Fcgi < Base
8
10
  class << self
9
- def start host, ports
10
- run_server
11
- end
12
11
 
13
- def run_server
12
+ # start FastCGI in a new thread, host and port parameter are only taken
13
+ # to make it compatible with other adapters but have no influence and
14
+ # can be omitted
15
+ def start host = nil, ports = nil
14
16
  Thread.new do
15
17
  Thread.current[:task] = :cgi
16
18
  Rack::Handler::FastCGI.run(self)
@@ -16,8 +16,12 @@ module Ramaze
16
16
  require 'rack/handler/mongrel'
17
17
 
18
18
  module Adapter
19
+
20
+ # Our Mongrel adapter acts as wrapper for the Rack::Handler::Mongrel.
19
21
  class Mongrel < Base
20
22
  class << self
23
+
24
+ # start server on given host and port.
21
25
  def run_server host, port
22
26
  server = ::Mongrel::HttpServer.new(host, port)
23
27
  server.register('/', ::Rack::Handler::Mongrel.new(self))
@@ -5,19 +5,14 @@ require 'ramaze/adapter'
5
5
  require 'webrick'
6
6
  require 'rack/handler/webrick'
7
7
 
8
- module WEBrick
9
- module HTTPServlet
10
- class ProcHandler
11
- alias do_PUT do_GET
12
- alias do_DELETE do_GET
13
- end
14
- end
15
- end
16
-
17
8
  module Ramaze
18
9
  module Adapter
10
+
11
+ # Our WEBrick adapter acts as wrapper for the Rack::Handler::WEBrick.
19
12
  class WEBrick < Base
20
13
  class << self
14
+
15
+ # start server on given host and port, see below for possible options.
21
16
  def run_server host, port, options = {}
22
17
  options = {
23
18
  :Port => port,
@@ -41,3 +36,19 @@ module Ramaze
41
36
  end
42
37
  end
43
38
  end
39
+
40
+ # Extending on WEBrick module
41
+ module WEBrick
42
+
43
+ # Extending on HTTPServlet
44
+ module HTTPServlet
45
+
46
+ # Extending on ProcHandler
47
+ #
48
+ # We alias PUT to GET and DELETE to GET so WEBrick handles them as well.
49
+ class ProcHandler
50
+ alias do_PUT do_GET
51
+ alias do_DELETE do_GET
52
+ end
53
+ end
54
+ end
@@ -109,7 +109,9 @@ module Ramaze
109
109
 
110
110
  def test_connection host, port
111
111
  Timeout.timeout(1) do
112
- TCPServer.open(host, port){ true }
112
+ testsock = TCPServer.new(host, port)
113
+ testsock.close
114
+ true
113
115
  end
114
116
  rescue => ex
115
117
  Inform.error(ex)
@@ -62,33 +62,9 @@ module Ramaze
62
62
  def values_at(*keys)
63
63
  get_multi(*keys).values_at(*keys)
64
64
  end
65
- end
66
- end
67
-
68
- # add the MemCache#clear method
69
-
70
- class MemCache
71
-
72
- # MemCache.clear sends 'flush_all' command to all registered MemCache
73
- # servers.
74
-
75
- def clear
76
- raise MemCacheError, "Update of readonly cache" if @readonly
77
-
78
- @servers.each do |server|
79
- server.flush_all
80
- end
81
- end
82
-
83
- # implements the flushing of MemCache server. Flushes a single server,
84
- # MemCache#clear can be used for clearing out all MemCache servers.
85
-
86
- class Server
87
-
88
- # Serverside implementation of the #clear functionality for MemCache
89
65
 
90
- def flush_all
91
- socket.write "flush_all\r\n"
66
+ def clear
67
+ @cache.flush_all
92
68
  end
93
69
  end
94
70
  end
data/lib/ramaze/cache.rb CHANGED
@@ -12,6 +12,8 @@ module Ramaze
12
12
 
13
13
  class Cache
14
14
  include Enumerable
15
+
16
+ # Holds all the instances of Cache that are being added.
15
17
  CACHES = {} unless defined?(CACHES)
16
18
 
17
19
  attr_accessor :cache
@@ -47,33 +49,35 @@ module Ramaze
47
49
  end
48
50
 
49
51
  # Initializes the cache, defined by Global.cache
50
-
51
52
  def initialize(cache = Global.cache)
52
53
  @cache = cache.new
53
54
  end
54
55
 
56
+ # Get key.
55
57
  def [](key)
56
58
  @cache["#{@cache_name}:#{key}"]
57
59
  end
58
60
 
61
+ # Set key to value.
59
62
  def []=(key, value)
60
63
  @cache["#{@cache_name}:#{key}"] = value
61
64
  end
62
65
 
63
66
  # deletes the keys of each argument passed from Cache instance.
64
-
65
67
  def delete(*args)
66
68
  args.each do |arg|
67
69
  @cache.delete("#{@cache_name}:#{arg}")
68
70
  end
69
71
  end
70
72
 
73
+ # Empty this cache
71
74
  def clear
72
75
  @cache.clear
73
76
  end
74
77
 
75
- def values_at(*args)
76
- @cache.values_at(*args.map {|key| "#{@cache_name}:#{key}" })
78
+ # Answers with value for each key.
79
+ def values_at(*keys)
80
+ @cache.values_at(*keys.map {|key| "#{@cache_name}:#{key}" })
77
81
  end
78
82
  end
79
83
  end
@@ -15,7 +15,7 @@ module Ramaze
15
15
  def resolve(path)
16
16
  if found = Cache.resolved[path]
17
17
  if found.respond_to?(:relaxed_hash)
18
- return found
18
+ return found.dup
19
19
  else
20
20
  Inform.warn("Found faulty `#{path}' in Cache.resolved, deleting it for sanity.")
21
21
  Cache.resolved.delete path
@@ -39,7 +39,10 @@ module Ramaze
39
39
 
40
40
  valid_action = (action.method or (params.empty? && template))
41
41
 
42
- return Cache.resolved[path] = action if valid_action
42
+ if valid_action
43
+ Cache.resolved[path] = action
44
+ return action.dup
45
+ end
43
46
  end
44
47
  end
45
48
 
@@ -47,6 +50,8 @@ module Ramaze
47
50
  raise_no_controller(path)
48
51
  end
49
52
 
53
+ # Try to produce an Action from the given path and paremters with the
54
+ # appropiate template if one exists.
50
55
  def resolve_action(path, *parameter)
51
56
  path, parameter = path.to_s, parameter.map(&:to_s)
52
57
  if alternate_template = trait["#{path}_template"]
@@ -67,22 +72,30 @@ module Ramaze
67
72
  :controller => self
68
73
  end
69
74
 
70
- def resolve_template(action)
71
- action = action.to_s
72
- action_converted = action.split('__').inject{|s,v| s/v}
73
- actions = [action, action_converted].compact
75
+ # Search the #template_paths for a fitting template for path.
76
+ # Only the first found possibility for the generated glob is returned.
77
+ def resolve_template(path)
78
+ path = path.to_s
79
+ path_converted = path.split('__').inject{|s,v| s/v}
80
+ possible_paths = [path, path_converted].compact
74
81
 
75
- paths = template_paths.map{|pa| actions.map{|a| pa/a } }.flatten.uniq
82
+ paths = template_paths.map{|pa| possible_paths.map{|a| pa/a } }.flatten.uniq
76
83
  glob = "{#{paths.join(',')}}.{#{extension_order.join(',')}}"
77
84
 
78
85
  Dir[glob].first
79
86
  end
80
87
 
88
+ # Composes an array with the template-paths to look up in the right order.
89
+ # Usually this is composed of Global.template_root and the mapping of the
90
+ # controller and a second element for Global.public_root, which makes
91
+ # it possible to convert CSS on the fly and things like that.
92
+
81
93
  def template_paths
82
94
  @template_root ||= Global.template_root / Global.mapping.invert[self]
83
95
  [ @template_root, Global.public_root ].compact
84
96
  end
85
97
 
98
+ # Based on methodname and arity, tries to find the right method on current controller.
86
99
  def resolve_method(name, *params)
87
100
  if method = action_methods.delete(name)
88
101
  arity = instance_method(method).arity
@@ -93,6 +106,7 @@ module Ramaze
93
106
  return nil, []
94
107
  end
95
108
 
109
+ # methodnames that may be used for current controller.
96
110
  def action_methods
97
111
  exclude = Controller.trait[:exclude_action_modules]
98
112
 
@@ -102,6 +116,7 @@ module Ramaze
102
116
  meths - ancs.map(&:to_s)
103
117
  end
104
118
 
119
+ # Generate all possible permutations for given path.
105
120
  def pattern_for(path)
106
121
  atoms = path.split('/').grep(/\S/)
107
122
  atoms.unshift('')
@@ -129,6 +144,9 @@ module Ramaze
129
144
  patterns.reverse!
130
145
  end
131
146
 
147
+ # Uses custom defined engines and all available engines and throws it
148
+ # against the extensions for the template to find the most likely
149
+ # templating-engine to use ordered by priority and likelyhood.
132
150
  def extension_order
133
151
  t_extensions = Template::ENGINES
134
152
  engine = trait[:engine]
@@ -146,7 +164,7 @@ module Ramaze
146
164
  # Raises Ramaze::Error::NoAction
147
165
 
148
166
  def raise_no_action(controller, path)
149
- Thread.current[:failed_controller] = controller
167
+ Thread.current[:controller] = controller
150
168
  raise Ramaze::Error::NoAction, "No Action found for `#{path}' on #{controller}"
151
169
  end
152
170
  end
@@ -43,7 +43,12 @@ module Ramaze
43
43
 
44
44
  def inherited controller
45
45
  controller.trait :actions_cached => Set.new
46
+ controller.trait :layout => {:all => nil, :deny => Set.new}
46
47
  Global.controllers << controller
48
+ if map = controller.mapping
49
+ Inform.debug("mapping #{map} => #{controller}")
50
+ Global.mapping[map] ||= controller
51
+ end
47
52
  end
48
53
 
49
54
  # called from Ramaze.startup, adds Cache.actions and Cache.patterns, walks
@@ -52,13 +57,9 @@ module Ramaze
52
57
 
53
58
  def startup options = {}
54
59
  Inform.debug("found Controllers: #{Global.controllers.inspect}")
55
-
56
- Global.controllers.each do |controller|
57
- if map = controller.mapping
58
- Inform.debug("mapping #{map} => #{controller}")
59
- Global.mapping[map] ||= controller
60
- end
61
- end
60
+ tr, pr = Global.template_root, Global.public_root
61
+ Inform.warn("Template root: #{tr} doesn't exist") unless File.directory?(tr)
62
+ Inform.warn("Public root: #{pr} doesn't exist") unless File.directory?(pr)
62
63
 
63
64
  if Global.mapping.empty?
64
65
  Inform.warn("No Controllers mapped, will serve /public only.")
@@ -87,8 +88,12 @@ module Ramaze
87
88
  end
88
89
 
89
90
  # Map Controller to the given syms or strings.
91
+ # Replaces old mappings.
92
+ # If you want to _add_ a mapping, just modify Global.mapping.
90
93
 
91
94
  def map(*syms)
95
+ Global.mapping.delete_if{|k,v| v == self}
96
+
92
97
  syms.each do |sym|
93
98
  Global.mapping[sym.to_s] = self
94
99
  end
@@ -100,6 +105,37 @@ module Ramaze
100
105
  Global.mapping[mapping.to_s]
101
106
  end
102
107
 
108
+ # Define a layout for all actions on this controller
109
+ #
110
+ # Example:
111
+ # class Foo < Ramaze::Controller
112
+ # layout :foo
113
+ # end
114
+ #
115
+ # This defines the action :foo to be layout of the controller and will
116
+ # render the layout after any other action has been rendered, assigns
117
+ # @content to the result of the action and then goes on rendering
118
+ # the layout-action where @content may or may not be used, returning
119
+ # whatever the layout returns.
120
+
121
+ def layout(meth_or_hash, &block)
122
+ if meth_or_hash.respond_to?(:to_hash)
123
+ meth_or_hash.each do |layout_name, *actions|
124
+ actions.flatten.each do |action|
125
+ trait[:layout][action.to_s] = R(self, layout_name)
126
+ end
127
+ end
128
+ else
129
+ trait[:layout][:all] = R(self, meth_or_hash)
130
+ end
131
+ end
132
+
133
+ def deny_layout(*actions)
134
+ actions.each do |action|
135
+ trait[:layout][:deny] << action.to_s
136
+ end
137
+ end
138
+
103
139
  # Define a template_root for Controller, returns the current template_root
104
140
  # if no argument is given.
105
141
  # Runs every given path through Controller::check_path
@@ -148,6 +184,7 @@ module Ramaze
148
184
 
149
185
  def handle path
150
186
  action = resolve(path)
187
+ Thread.current[:controller] = action.controller
151
188
  action.render
152
189
  end
153
190
  end
@@ -3,6 +3,10 @@
3
3
 
4
4
  module Ramaze
5
5
  module Dispatcher
6
+
7
+ # This dispatcher is responsible for relaying requests to Controller::handle
8
+ # and filtering the results using FILTER.
9
+
6
10
  class Action
7
11
 
8
12
  # The response is passed to each filter by sending .call(response) to it.
@@ -20,7 +24,7 @@ module Ramaze
20
24
 
21
25
  def process(path)
22
26
  body = Controller.handle(path)
23
- response = Dispatcher.build_response(body)
27
+ response = Response.current.build(body)
24
28
  FILTER.inject(response){|r,f| f.call(r) }
25
29
  rescue Ramaze::Error => ex
26
30
  ex
@@ -0,0 +1,115 @@
1
+ # Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ module Ramaze
5
+ module Dispatcher
6
+
7
+ # Generates a directory listing, see Ramaze::Controller::Directory for more
8
+ # information and how to create your own directory listing page
9
+ class Directory
10
+ class << self
11
+
12
+ # Entry point from Dispatcher::filter.
13
+ # Just a forwarder to build_listing, automatticly exiting if there is
14
+ # an error (defined by returning false in build_listing)
15
+ def process(path)
16
+ if Global.list_directories
17
+ response = build_listing(path)
18
+ Response.current.build(*response) if response
19
+ end
20
+ end
21
+
22
+ # Makes a request for http://yourserver/dirlist/path and returns the
23
+ # result. Due to this method, you can overwrite the action and create your
24
+ # own page. See Ramaze::Controller::Directory for more.
25
+ def build_listing(path)
26
+ dir = ::File.expand_path(Global.public_root/::File.expand_path(path, '/'))
27
+
28
+ if ::File.directory?(dir)
29
+ Inform.debug("Serving directory listing: #{dir}")
30
+
31
+ status = Ramaze::STATUS_CODE['OK']
32
+ header = {'Content-Type' => "text/html"}
33
+ body = list_for(dir)
34
+ [body, status, header]
35
+ end
36
+ end
37
+
38
+ def list_for(path)
39
+ display = path.gsub(/^#{Regexp.escape(Global.public_root)}\/?/, '/')
40
+ wrapper =
41
+ %(<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
42
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
43
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
44
+ <head>
45
+ <title>Directory listing of #{display}</title>
46
+
47
+ <style type="text/css"> /*<![CDATA[*/ a, a:active {text-decoration: none; color: blue;} a:visited {color: #48468F;} a:hover, a:focus {text-decoration: underline; color: red;} body {background-color: #F5F5F5;} h2 {margin-bottom: 12px;} table {margin-left: 12px;} th, td { font-family: "Courier New", Courier, monospace; font-size: 10pt; text-align: left;} th { font-weight: bold; padding-right: 14px; padding-bottom: 3px;} td {padding-right: 14px;} td.s, th.s {text-align: right;} div.list { background-color: white; border-top: 1px solid #646464; border-bottom: 1px solid #646464; padding-top: 10px; padding-bottom: 14px;} div.foot { font-family: "Courier New", Courier, monospace; font-size: 10pt; color: #787878; padding-top: 4px;} /*]]>*/ </style>
48
+ </head>
49
+ <body>
50
+ <h2>Directory listing of #{display}</h2>
51
+ <div class="list">
52
+ <table summary="Directory Listing" cellpadding="0" cellspacing="0">
53
+ <thead>
54
+ <tr>
55
+ <th class="n">Name</th>
56
+ <th class="m">Last Modified</th>
57
+ <th class="s">Size</th>
58
+ <th class="t">Type</th>
59
+ </tr>
60
+ </thead>
61
+ <tbody>
62
+ <tr>
63
+ <td class="n"><a href="#{display/'..'}/">Parent Directory</a>/</td>
64
+ <td class="m">&nbsp;</td>
65
+ <td class="s">- &nbsp;</td>
66
+ <td class="t">Directory</td>
67
+ </tr>
68
+ %s
69
+ %s
70
+ </tbody>
71
+ </table>
72
+ </div>
73
+ <div class="foot">%s</div>
74
+ </body>
75
+ </html>
76
+ )
77
+
78
+ dirs, files = Dir[path/'*'].partition{|file| ::File.directory?(file) }
79
+ dir_body, file_body = [], []
80
+
81
+ dirs.each do |dir|
82
+ basename = ::File.basename(dir)
83
+ dir_body << %[<tr>
84
+ <td class="n"><a href="#{display/basename}">#{basename}/</a></td>
85
+ <td class="m">&nbsp;</td>
86
+ <td class="s">- &nbsp;</td>
87
+ <td class="t">Directory</td>
88
+ </tr>]
89
+ end
90
+
91
+ time_format = "%Y-%b-%d %H:%M:%S"
92
+ files.each do |file|
93
+ basename = ::File.basename(file)
94
+ time = ::File.mtime(file).strftime(time_format)
95
+ size = ::File.size(file).human_readable_filesize_format
96
+ mime = Tool::MIME.type_for(file)
97
+ file_body << %[<tr>
98
+ <td class="n"><a href="#{display/basename}">#{basename}</a></td>
99
+ <td class="m">#{time}</td>
100
+ <td class="s">#{size}</td>
101
+ <td class="t">#{mime}</td>
102
+ </tr>]
103
+ end
104
+
105
+ version = "ramaze/#{Ramaze::VERSION}"
106
+ wrapper % [
107
+ dir_body. join("\n "),
108
+ file_body.join("\n "),
109
+ version
110
+ ]
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end