Pistos-ramaze 2008.09 → 2008.12

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 (105) hide show
  1. data/benchmark/run.rb +1 -1
  2. data/examples/app/blog/spec/blog.rb +2 -2
  3. data/examples/app/rapaste/spec/rapaste.rb +1 -1
  4. data/examples/app/rapaste/start.rb +2 -2
  5. data/examples/app/rapaste/view/view.xhtml +3 -0
  6. data/examples/app/todolist/spec/todolist.rb +1 -1
  7. data/examples/app/whywiki/spec/whywiki.rb +1 -1
  8. data/examples/app/wikore/spec/wikore.rb +1 -1
  9. data/examples/app/wikore/src/model.rb +1 -1
  10. data/examples/app/wiktacular/spec/wiktacular.rb +1 -1
  11. data/examples/app/wiktacular/src/model.rb +1 -1
  12. data/examples/basic/partial.rb +28 -0
  13. data/examples/helpers/httpdigest.rb +68 -10
  14. data/examples/misc/ramaise.rb +2 -2
  15. data/examples/templates/template_amrita2.rb +1 -1
  16. data/examples/templates/template_erubis.rb +1 -1
  17. data/examples/templates/template_ezamar.rb +1 -1
  18. data/examples/templates/template_haml.rb +2 -2
  19. data/examples/templates/template_liquid.rb +1 -1
  20. data/examples/templates/template_markaby.rb +2 -2
  21. data/examples/templates/template_nagoro.rb +1 -1
  22. data/examples/templates/template_redcloth.rb +1 -1
  23. data/examples/templates/template_remarkably.rb +2 -2
  24. data/examples/templates/template_tenjin.rb +1 -1
  25. data/examples/templates/template_xslt.rb +1 -1
  26. data/lib/proto/controller/init.rb +2 -1
  27. data/lib/proto/model/init.rb +3 -3
  28. data/lib/proto/public/dispatch.fcgi +2 -2
  29. data/lib/proto/spec/main.rb +3 -3
  30. data/lib/proto/start.rb +4 -0
  31. data/lib/ramaze/action/render.rb +6 -5
  32. data/lib/ramaze/action.rb +7 -1
  33. data/lib/ramaze/cache/file.rb +71 -0
  34. data/lib/ramaze/cache.rb +1 -0
  35. data/lib/ramaze/contrib/email.rb +2 -0
  36. data/lib/ramaze/contrib/facebook.rb +2 -2
  37. data/lib/ramaze/contrib/file_cache.rb +2 -64
  38. data/lib/ramaze/contrib/sequel/image.rb +1 -1
  39. data/lib/ramaze/contrib.rb +1 -1
  40. data/lib/ramaze/controller/resolve.rb +8 -3
  41. data/lib/ramaze/controller.rb +9 -1
  42. data/lib/ramaze/current/request.rb +85 -68
  43. data/lib/ramaze/current/session/hash.rb +7 -11
  44. data/lib/ramaze/current/session.rb +3 -5
  45. data/lib/ramaze/dispatcher/action.rb +2 -0
  46. data/lib/ramaze/dispatcher/file.rb +6 -1
  47. data/lib/ramaze/helper/aspect.rb +2 -2
  48. data/lib/ramaze/helper/form.rb +5 -2
  49. data/lib/ramaze/helper/formatting.rb +4 -0
  50. data/lib/ramaze/helper/gravatar.rb +18 -1
  51. data/lib/ramaze/helper/httpdigest.rb +57 -28
  52. data/lib/ramaze/helper/maruku.rb +2 -0
  53. data/lib/ramaze/helper/paginate.rb +2 -3
  54. data/lib/ramaze/helper/partial.rb +1 -1
  55. data/lib/ramaze/helper/redirect.rb +22 -4
  56. data/lib/ramaze/helper/user.rb +4 -4
  57. data/lib/ramaze/helper.rb +12 -4
  58. data/lib/ramaze/log/rotatinginformer.rb +168 -0
  59. data/lib/ramaze/option/holder.rb +3 -3
  60. data/lib/ramaze/option.rb +1 -1
  61. data/lib/ramaze/reloader/watch_inotify.rb +85 -0
  62. data/lib/ramaze/reloader/watch_stat.rb +58 -0
  63. data/lib/ramaze/reloader.rb +25 -41
  64. data/lib/ramaze/snippets/divide.rb +2 -0
  65. data/lib/ramaze/snippets/numeric/time.rb +1 -1
  66. data/lib/ramaze/snippets/object/__dir__.rb +3 -3
  67. data/lib/ramaze/snippets/object/acquire.rb +3 -6
  68. data/lib/ramaze/snippets/ramaze/acquire.rb +31 -0
  69. data/lib/ramaze/snippets/ramaze/deprecated.rb +2 -1
  70. data/lib/ramaze/spec/helper/mock_http.rb +6 -5
  71. data/lib/ramaze/template/ezamar/render_partial.rb +8 -0
  72. data/lib/ramaze/tool/mime.rb +1 -1
  73. data/lib/ramaze/tool/project_creator.rb +2 -1
  74. data/lib/ramaze/version.rb +1 -1
  75. data/lib/ramaze.rb +6 -0
  76. data/rake_tasks/coverage.rake +4 -5
  77. data/rake_tasks/spec.rake +6 -6
  78. data/ramaze.gemspec +769 -756
  79. data/spec/contrib/profiling.rb +2 -2
  80. data/spec/ramaze/action/file_cache.rb +1 -1
  81. data/spec/ramaze/action/layout.rb +1 -1
  82. data/spec/ramaze/controller/actionless_templates.rb +1 -1
  83. data/spec/ramaze/controller/resolve.rb +1 -1
  84. data/spec/ramaze/controller/template_resolving.rb +1 -1
  85. data/spec/ramaze/dispatcher/directory.rb +3 -3
  86. data/spec/ramaze/helper/aspect.rb +1 -1
  87. data/spec/ramaze/helper/partial.rb +1 -1
  88. data/spec/ramaze/localize.rb +1 -1
  89. data/spec/ramaze/rewrite.rb +1 -1
  90. data/spec/ramaze/template/amrita2.rb +1 -1
  91. data/spec/ramaze/template/erubis.rb +1 -1
  92. data/spec/ramaze/template/ezamar.rb +1 -1
  93. data/spec/ramaze/template/haml.rb +2 -2
  94. data/spec/ramaze/template/nagoro.rb +1 -1
  95. data/spec/ramaze/template/redcloth.rb +1 -1
  96. data/spec/ramaze/template/sass.rb +1 -1
  97. data/spec/ramaze/template/tenjin.rb +1 -1
  98. data/spec/ramaze/template.rb +3 -3
  99. data/spec/snippets/object/__dir__.rb +6 -0
  100. data/spec/snippets/{object → ramaze}/acquire.rb +24 -18
  101. metadata +15 -12
  102. data/lib/ramaze/contrib/auto_params/get_args.rb +0 -58
  103. data/lib/ramaze/contrib/auto_params.rb +0 -135
  104. data/spec/contrib/auto_params.rb +0 -121
  105. data/spec/snippets/divide.rb +0 -19
@@ -1,65 +1,3 @@
1
- #
2
- # drop-in replacement for Ramaze's built-in MemoryCache built on the
3
- # filesystem. # to use with sessions do
4
- #
5
- # Ramaze::Global::cache_alternative[:sessions] = Ramaze::FileCache
6
- #
7
- # to use with everything do
8
- #
9
- # Ramaze::Global::cache = Ramaze::FileCache
10
- #
1
+ Ramaze::Log.warn("ramaze/contrib/file_cache is now ramaze/cache/file")
11
2
 
12
- module Ramaze::FileCache
13
- require "fileutils"
14
- require "socket"
15
-
16
- Host = Socket.gethostname
17
- Pid = Process.pid
18
- Fu = FileUtils
19
- Root = File.join Ramaze::APPDIR, "cache"
20
-
21
- Fu.mkdir_p(Root) rescue nil
22
-
23
- def self.[] key
24
- path = File.join Root, key, "data"
25
- Marshal.load(IO.read(path))
26
- rescue
27
- nil
28
- end
29
-
30
- def self.[]= key, value
31
- tmp = File.join Root, key, "data.#{ Host }.#{ Pid }"
32
- dirname = File.join Root, key
33
- path = File.join Root, key, "data"
34
- data = Marshal.dump value
35
- Fu.rm_rf dirname rescue nil
36
- Fu.mkdir_p dirname rescue nil
37
- open(tmp, 'w'){|fd| fd.write data}
38
- Fu.mv tmp, path
39
- rescue
40
- nil
41
- end
42
-
43
- def self.values_at *keys
44
- keys.map{|key| self[key]}
45
- end
46
-
47
- def self.delete *keys
48
- keys.map do |key|
49
- dirname = File.join Root, key
50
- Fu.rm_rf dirname rescue next
51
- end
52
- end
53
-
54
- def self.clear
55
- Dir["#{ Root }/*"].each{|entry| Fu.rm_rf entry}
56
- end
57
-
58
- def self.new
59
- self
60
- end
61
-
62
- def self.to_sym
63
- name.split(%r/::/).last.to_sym
64
- end
65
- end
3
+ require 'ramaze/cache/file'
@@ -31,7 +31,7 @@
31
31
  # # Creates a square thumbnail of the image cropping the longest edge
32
32
  # # to match the shortest edge, resizes to +size+.
33
33
  #
34
- # :agorithm => :thumbnail,
34
+ # :algorithm => :thumbnail,
35
35
  #
36
36
  #
37
37
  # # Key specifies the filename and accessors, value are arguments to the
@@ -49,7 +49,7 @@ module Ramaze
49
49
  const.startup if const.respond_to?(:startup)
50
50
  Log.dev "Loaded contrib: #{const}"
51
51
  rescue NameError
52
- files = Dir["{contrib,#{BASEDIR/:ramaze/:contrib}}/#{name}.{so,bundle,rb}"]
52
+ files = Dir["{contrib,#{BASEDIR}/ramaze/contrib}/#{name}.{so,bundle,rb}"]
53
53
  raise LoadError, "#{mod_name} not found" unless files.any?
54
54
  require(files.first) ? retry : raise
55
55
  end
@@ -136,10 +136,15 @@ module Ramaze
136
136
 
137
137
  def resolve_template(path)
138
138
  path = path.to_s
139
- path_converted = path.split('__').inject{|s,v| s/v}
139
+ path_converted = path.split('__').inject{|s,v| File.join(s, v) }
140
140
  possible_paths = [path, path_converted].compact
141
141
 
142
- paths = template_paths.map{|pa| possible_paths.map{|a| pa/a } }.flatten.uniq
142
+ paths = template_paths.map{|pa|
143
+ possible_paths.map{|a|
144
+ File.join(pa, a)
145
+ }
146
+ }.flatten.uniq
147
+
143
148
  glob = "{#{paths.join(',')}}.{#{extension_order.join(',')}}"
144
149
 
145
150
  Dir[glob].first
@@ -153,7 +158,7 @@ module Ramaze
153
158
  if paths = view_root
154
159
  paths
155
160
  else
156
- view_root(Global.view_root / Global.mapping.invert[self])
161
+ view_root(File.join(Global.view_root, Global.mapping.invert[self]))
157
162
  end
158
163
  end
159
164
 
@@ -67,13 +67,17 @@ module Ramaze
67
67
 
68
68
  # if trait[:automap] is set and controller is not in Global.mapping yet
69
69
  # this will build a new default mapping-point, MainController is put
70
- # at '/' by default.
70
+ # at '/' by default. For other Class names, String#snake_case is called,
71
+ # e.g. FooBarController is mapped at '/foo_bar'.
71
72
 
72
73
  def mapping
73
74
  global_mapping = Global.mapping.invert[self]
75
+
74
76
  return global_mapping if global_mapping
77
+
75
78
  if ancestral_trait[:automap] && self.to_s !~ /#<Class:/
76
79
  name = self.to_s.gsub('Controller', '').gsub('::', '/').clone
80
+ return if name.empty?
77
81
  name == 'Main' ? '/' : "/#{name.snake_case}"
78
82
  end
79
83
  end
@@ -262,6 +266,10 @@ module Ramaze
262
266
  action.render
263
267
  end
264
268
 
269
+ # By default, returns all ancestors of current Controller that have
270
+ # Ramaze::Controller as their ancestor. Optional argument parent
271
+ # can be used return ancestors that have parent as an ancestor.
272
+
265
273
  def relevant_ancestors(parent = Ramaze::Controller)
266
274
  ancestors.select do |anc|
267
275
  anc.ancestors.include?(parent)
@@ -28,10 +28,14 @@ module Ramaze
28
28
  super
29
29
  end
30
30
 
31
+ # the full request URI provided by Rack::Request e.g. http://localhost:7000/controller/action?foo=bar.xhtml
32
+
31
33
  def request_uri
32
34
  env['REQUEST_URI'] || path_info
33
35
  end
34
36
 
37
+ # the IP address(s) making the request provided by Rack::Request. You shouldn't trust it
38
+
35
39
  def ip
36
40
  if addr = env['HTTP_X_FORWARDED_FOR']
37
41
  addr.split(',').last.strip
@@ -47,9 +51,8 @@ module Ramaze
47
51
  ipv6 = %w[ fc00::/7 fe80::/10 fec0::/10 ::1 ]
48
52
  LOCAL = (ipv4 + ipv6).map{|a| IPAddr.new(a)} unless defined?(LOCAL)
49
53
 
50
- # --
51
- # Mongrel somehow puts together multiple IPs when proxy is involved.
52
- # ++
54
+ # returns true if the IP address making the request is from local network.
55
+ # Optional argument address can be used to check any IP address.
53
56
 
54
57
  def local_net?(address = ip)
55
58
  addr = IPAddr.new(address)
@@ -63,6 +66,15 @@ module Ramaze
63
66
  [key, *rest].map{|k| params[k.to_s] }
64
67
  end
65
68
 
69
+ # Sets any arguments passed as @instance_variables for the current action.
70
+ #
71
+ # Usage:
72
+ # request.params # => {'name' => 'manveru', 'q' => 'google', 'lang' => 'de'}
73
+ # to_ivs(:name, :q)
74
+ # @q # => 'google'
75
+ # @name # => 'manveru'
76
+ # @lang # => nil
77
+
66
78
  def to_ivs(*args)
67
79
  instance = Action.current.instance
68
80
  args.each do |arg|
@@ -71,81 +83,77 @@ module Ramaze
71
83
  end
72
84
  end
73
85
 
74
- unless method_defined?(:rack_params)
75
- alias rack_params params
76
-
77
- # Wrapping Request#params to support a one-level hash notation.
78
- # It doesn't support anything really fancy, so be conservative in its use.
79
- #
80
- # See if following provides something useful for us:
81
- # http://redhanded.hobix.com/2006/01/25.html
82
- #
83
- # Example Usage:
84
- #
85
- # # Template:
86
- #
87
- # <form action="/paste">
88
- # <input type="text" name="paste[name]" />
89
- # <input type="text" name="paste[syntax]" />
90
- # <input type="submit" />
91
- # </form>
92
- #
93
- # # In your Controller:
94
- #
95
- # def paste
96
- # name, syntax = request['paste'].values_at('name', 'syntax')
97
- # paste = Paste.create_with(:name => name, :syntax => syntax)
98
- # redirect '/'
99
- # end
100
- #
101
- # # Or, easier:
102
- #
103
- # def paste
104
- # paste = Paste.create_with(request['paste'])
105
- # redirect '/'
106
- # end
107
-
108
- def params
109
- return {} if put?
110
- return @ramaze_params if @ramaze_params
111
-
112
- begin
113
- @rack_params ||= rack_params
114
- rescue EOFError => ex
115
- @rack_params = {}
116
- Log.error(ex)
117
- end
86
+ # Wrapping Request#params to support a one-level hash notation.
87
+ # It doesn't support anything really fancy, so be conservative in its use.
88
+ #
89
+ # See if following provides something useful for us:
90
+ # http://redhanded.hobix.com/2006/01/25.html
91
+ #
92
+ # Example Usage:
93
+ #
94
+ # # Template:
95
+ #
96
+ # <form action="/paste">
97
+ # <input type="text" name="paste[name]" />
98
+ # <input type="text" name="paste[syntax]" />
99
+ # <input type="submit" />
100
+ # </form>
101
+ #
102
+ # # In your Controller:
103
+ #
104
+ # def paste
105
+ # name, syntax = request['paste'].values_at('name', 'syntax')
106
+ # paste = Paste.create_with(:name => name, :syntax => syntax)
107
+ # redirect '/'
108
+ # end
109
+ #
110
+ # # Or, easier:
111
+ #
112
+ # def paste
113
+ # paste = Paste.create_with(request['paste'])
114
+ # redirect '/'
115
+ # end
116
+
117
+ def params
118
+ return {} if put?
119
+ return @ramaze_params if @ramaze_params
120
+
121
+ begin
122
+ @rack_params ||= super
123
+ rescue EOFError => ex
124
+ @rack_params = {}
125
+ Log.error(ex)
126
+ end
118
127
 
119
- @ramaze_params = {}
128
+ @ramaze_params = {}
120
129
 
121
- @rack_params.each do |key, value|
122
- if key =~ /^(.*?)(\[.*\])/
123
- prim, nested = $~.captures
124
- ref = @ramaze_params
130
+ @rack_params.each do |key, value|
131
+ if key =~ /^(.*?)(\[.*\])/
132
+ prim, nested = $~.captures
133
+ ref = @ramaze_params
125
134
 
126
- keys = nested.scan(/\[([^\]]+)\]/).flatten
127
- keys.unshift prim
135
+ keys = nested.scan(/\[([^\]]+)\]/).flatten
136
+ keys.unshift prim
128
137
 
129
- keys.each_with_index do |k, i|
130
- if i + 1 >= keys.size
131
- ref[k] = value
138
+ keys.each_with_index do |k, i|
139
+ if i + 1 >= keys.size
140
+ ref[k] = value
141
+ else
142
+ # in case the value is a string we cannot let it be ref next
143
+ # time, so throw it away
144
+ if ref[k].is_a?(String)
145
+ ref = ref[k] = {}
132
146
  else
133
- # in case the value is a string we cannot let it be ref next
134
- # time, so throw it away
135
- if ref[k].is_a?(String)
136
- ref = ref[k] = {}
137
- else
138
- ref = ref[k] ||= {}
139
- end
147
+ ref = ref[k] ||= {}
140
148
  end
141
149
  end
142
- else
143
- @ramaze_params[key] = value
144
150
  end
151
+ else
152
+ @ramaze_params[key] = value
145
153
  end
146
-
147
- @ramaze_params
148
154
  end
155
+
156
+ @ramaze_params
149
157
  end
150
158
 
151
159
  # Interesting HTTP variables from env
@@ -156,12 +164,18 @@ module Ramaze
156
164
  }
157
165
  end
158
166
 
167
+ # Returns a string presentation of the request, useful for debugging
168
+ # parameters of the action.
169
+
159
170
  def to_s
160
171
  p, c, e = params.inspect, cookies.inspect, http_vars.inspect
161
172
  %{#<Ramaze::Request params=#{p} cookies=#{c} env=#{e}>}
162
173
  end
163
174
  alias inspect to_s
164
175
 
176
+ # Pretty prints current action with parameters, cookies and
177
+ # enviroment variables.
178
+
165
179
  def pretty_print pp
166
180
  p, c, e = params, cookies, http_vars
167
181
  pp.object_group(self){
@@ -198,6 +212,9 @@ module Ramaze
198
212
  URI("#{scheme}://#{host}#{path}")
199
213
  end
200
214
 
215
+ # Returns and array of locales from env['HTTP_ACCEPT_LANGUAGE].
216
+ # e.g. ["fi", "en", "ja", "fr", "de", "es", "it", "nl", "sv"]
217
+
201
218
  def locales
202
219
  env['HTTP_ACCEPT_LANGUAGE'].to_s.split(/(?:,|;q=[\d.,]+)/)
203
220
  end
@@ -9,8 +9,8 @@ module Ramaze
9
9
 
10
10
  # Sets @hash to an empty Hash
11
11
 
12
- def initialize sess
13
- @session = sess
12
+ def initialize(session)
13
+ @session = session
14
14
  @hash = {}
15
15
  end
16
16
 
@@ -18,11 +18,8 @@ module Ramaze
18
18
  # Session.current.sessions if anything changes.
19
19
 
20
20
  def method_missing(*args, &block)
21
- old = @hash.dup
22
21
  result = @hash.send(*args, &block)
23
- unless old == @hash
24
- Cache.sessions[@session.session_id] = self
25
- end
22
+ Cache.sessions[@session.session_id] = self
26
23
  result
27
24
  end
28
25
 
@@ -48,11 +45,10 @@ module Ramaze
48
45
 
49
46
  # Unmarshal cookie data to a hash and verify its integrity.
50
47
  def unmarshal(cookie)
51
- if cookie
52
- data, digest = cookie.split('--')
53
- return nil unless digest == generate_digest(data)
54
- Marshal.load(data.unpack('m').first)
55
- end
48
+ return unless cookie
49
+ data, digest = cookie.split('--')
50
+ return nil unless digest == generate_digest(data)
51
+ Marshal.load(data.unpack('m').first)
56
52
  end
57
53
 
58
54
  # Generate the inline SHA512 message digest. Larger (128 bytes) than SHA256
@@ -96,7 +96,7 @@ module Ramaze
96
96
  def initialize(sess_or_request = Current.request)
97
97
  return unless Global.sessions
98
98
 
99
- if sess_or_request.is_a?(Request)
99
+ if sess_or_request.respond_to?(:cookies)
100
100
  request = sess_or_request
101
101
  @session_id = request.cookies[SESSION_KEY] || Session.random_key
102
102
  else
@@ -125,10 +125,8 @@ module Ramaze
125
125
  # existing already, the session itself is an instance of SessionHash
126
126
 
127
127
  def current
128
- unless @current
129
- @current = ( sessions[session_id] ||= Session::Hash.new(self) )
130
- end
131
- @current
128
+ return @current if @current
129
+ @current = ( sessions[session_id] ||= Session::Hash.new(self) )
132
130
  end
133
131
 
134
132
  # shortcut to Cache.sessions
@@ -35,6 +35,8 @@ module Ramaze
35
35
  ex
36
36
  end
37
37
 
38
+ # Logs the request via Log#info unless it's boring.
39
+
38
40
  def log(path)
39
41
  case path
40
42
  when *Global.boring
@@ -64,7 +64,8 @@ module Ramaze
64
64
  joined = ::File.join(Global.public_root, path)
65
65
 
66
66
  if ::File.directory?(joined)
67
- Dir[joined/"{#{INDICES.join(',')}}"].first || joined
67
+ glob = ::File.join(joined, "{#{INDICES.join(',')}}")
68
+ Dir[glob].first || joined
68
69
  else
69
70
  joined
70
71
  end
@@ -78,6 +79,10 @@ module Ramaze
78
79
 
79
80
  private
80
81
 
82
+ # Shortcut for Ramaze::Dispatcher::File#expand_path(path).
83
+ # Returns the absolute path of passed argument e.g.
84
+ # "/Users/rikur/ramaze_tests/public/foo.txt"
85
+
81
86
  def expand(path)
82
87
  ::File.expand_path(path)
83
88
  end
@@ -76,7 +76,7 @@ module Ramaze
76
76
  class Action
77
77
 
78
78
  # overwrites the default Action hook and runs the neccesary blocks in its
79
- # scope. before actions are run starting from Ramaze::Controller down the
79
+ # scope before actions are run, starting from Ramaze::Controller down the
80
80
  # ancestor chain.
81
81
  def before_process
82
82
  common_aspect(:before)
@@ -84,7 +84,7 @@ module Ramaze
84
84
 
85
85
 
86
86
  # overwrites the default Action hook and runs the neccesary blocks in its
87
- # scope. before actions are run starting from Ramaze::Controller down the
87
+ # scope after actions are run, starting from Ramaze::Controller down the
88
88
  # ancestor chain.
89
89
  def after_process
90
90
  common_aspect(:after)
@@ -219,16 +219,19 @@ module Ramaze
219
219
 
220
220
  # Form for instances of the model class
221
221
  class InstanceForm < Form
222
- # <input type='text' name='name' value='value' />
222
+ # returns <input type='text' name='name' value='value' />
223
223
  def field_input(name, value)
224
224
  "<input type='text' name='#{name}' value='#{value}'/>"
225
225
  end
226
226
 
227
+ # returns <textarea name='name'>#{value}</textarea>
228
+
227
229
  def field_textarea(name, value)
228
230
  "<textarea name='#{name}'>#{value}</textarea>"
229
231
  end
230
232
 
231
- # <input type="text" name="name" value="value" />
233
+ # returns <input type="text" name="name" value="value" />
234
+
232
235
  def field_integer(name, value)
233
236
  field_input(name, value)
234
237
  end
@@ -111,6 +111,10 @@ module Ramaze
111
111
  end
112
112
  alias autolink auto_link
113
113
 
114
+ # takes a string and optional argument for outputting compliance HTML
115
+ # instead of XHTML.
116
+ # e.g nl2br "a\nb\n\c" #=> 'a<br />b<br />c'
117
+
114
118
  def nl2br(string, xhtml = true)
115
119
  br = xhtml ? '<br />' : '<br>'
116
120
  string.gsub(/\n/, br)
@@ -1,12 +1,29 @@
1
1
  module Ramaze
2
2
  module Helper
3
3
  module Gravatar
4
+
5
+ # fetches a gravatar from http//www.gravatar.com based on 'email'
6
+ # and 'size'. Falls back to 'fallback_path' if no gravatar is found.
7
+ # default 'fallback_path' is "/images/gravatar_default.jpg".
8
+ # example:
9
+ #
10
+ # class GravatarController < Ramaze::Controller
11
+ # helper :gravatar
12
+ #
13
+ # def index
14
+ # @gravatar_thumbnail_src = gravatar(session[:email] || 'riku@helloit.fi')
15
+ # end
16
+ # end
17
+ #
18
+ # /view/gravatar/index.html:
19
+ # <img src="#{@gravatar_thumbnail_src}" />
20
+
4
21
  def gravatar(email, size = 32, fallback_path = "/images/gravatar_default.jpg")
5
22
  emailhash = Digest::MD5.hexdigest(email)
6
23
 
7
24
  fallback = Request.current.domain
8
25
  fallback.path = fallback_path
9
- default = h(fallback.to_s)
26
+ default = Rack::Utils.escape(fallback.to_s)
10
27
 
11
28
  return "http://www.gravatar.com/avatar.php?gravatar_id=#{emailhash}&default=#{default}&size=#{size}"
12
29
  end
@@ -5,50 +5,79 @@ module Ramaze
5
5
  module Helper
6
6
  module HttpDigest
7
7
 
8
- @session_nonce = "authentication_digest_nonce"
8
+ UUID_GENERATOR = UUID.new
9
+
10
+ SESSION_NONCE = 'httpdigest_authentication_nonce'
11
+ SESSION_OPAQUE = 'httpdigest_authentication_opaque'
9
12
 
10
13
  def httpdigest_logout
11
- session.delete( @session_nonce )
14
+ session.delete( SESSION_NONCE )
15
+ session.delete( SESSION_OPAQUE )
16
+ end
17
+
18
+ def httpdigest_headers uid, realm
19
+ session[ SESSION_NONCE ] = UUID_GENERATOR.generate
20
+ session[ SESSION_OPAQUE ][ realm ][ uid ] = UUID_GENERATOR.generate
21
+ response['WWW-Authenticate'] =
22
+ %|Digest realm="#{realm}",| +
23
+ %|qop="auth,auth-int",| +
24
+ %|nonce="#{session[SESSION_NONCE]}",| +
25
+ %|opaque="#{session[SESSION_OPAQUE][realm][uid]}"|
12
26
  end
13
27
 
14
28
  def httpdigest(uid, realm)
15
- session_opaque = "authentication_digest_opaque_#{uid}"
29
+ session[ SESSION_OPAQUE ] ||= {}
30
+ session[ SESSION_OPAQUE ][ realm ] ||= {}
16
31
 
17
- session[session_opaque] ||= UUID.new
32
+ if request.env['HTTP_AUTHORIZATION']
18
33
 
19
- authorized = false
34
+ authorized = false
20
35
 
21
- if session[@session_nonce] and request.env['HTTP_AUTHORIZATION']
36
+ if session[ SESSION_NONCE ] and session[ SESSION_OPAQUE ][ realm ][ uid ]
22
37
 
23
- auth_split = request.env['HTTP_AUTHORIZATION'].split
24
- authentication_type = auth_split[0]
25
- authorization = Rack::Auth::Digest::Params.parse( auth_split[1..-1].join(' ') )
26
- digest_response, username, nonce, nc, cnonce, qop =
27
- authorization.values_at(*%w[response username nonce nc cnonce qop])
38
+ auth_split = request.env['HTTP_AUTHORIZATION'].split
39
+ authentication_type = auth_split[0]
40
+ authorization = Rack::Auth::Digest::Params.parse( auth_split[1..-1].join(' ') )
28
41
 
29
- if authentication_type == 'Digest'
30
- if nonce == session[@session_nonce]
31
- ha1 = yield(username)
32
- ha2 = MD5.hexdigest("#{request.request_method}:#{request.fullpath}")
33
- md5 = MD5.hexdigest([ha1, nonce, nc, cnonce, qop, ha2].join(':'))
42
+ digest_response, username, nonce, nc, cnonce, qop, opaque =
43
+ authorization.values_at(*%w[response username nonce nc cnonce qop opaque])
34
44
 
35
- authorized = digest_response == md5
45
+ if authentication_type == 'Digest'
46
+ if nonce == session[SESSION_NONCE] and opaque == session[SESSION_OPAQUE][realm][uid]
47
+ h1 = nil
48
+ if respond_to?( :httpdigest_lookup_password )
49
+ ha1 = httpdigest_lookup_password( username )
50
+ else
51
+ if respond_to?( :httpdigest_lookup_plaintext_password )
52
+ ha1 = MD5.hexdigest( "#{username}:#{realm}:#{httpdigest_lookup_plaintext_password( username )}" )
53
+ else
54
+ if block_given?
55
+ ha1 = yield( username )
56
+ else
57
+ raise "No password lookup handler found"
58
+ end
59
+ end
60
+ end
61
+ ha2 = MD5.hexdigest([request.request_method,request.fullpath].join(':'))
62
+ md5 = MD5.hexdigest([ha1, nonce, nc, cnonce, qop, ha2].join(':'))
63
+
64
+ authorized = digest_response == md5
65
+ end
36
66
  end
67
+
37
68
  end
38
- end
39
69
 
40
- unless authorized
41
- session[@session_nonce] = UUID.new
42
- response['WWW-Authenticate'] =
43
- %|Digest realm="#{realm}",| +
44
- %|qop="auth,auth-int",| +
45
- %|nonce="#{session[@session_nonce]}",| +
46
- %|opaque="#{session[session_opaque]}"|
47
- if respond_to?( :httpdigest_failure )
48
- httpdigest_failure
49
- else
70
+ unless authorized
71
+ httpdigest_headers( uid, realm )
50
72
  respond('Unauthorized', 401)
51
73
  end
74
+
75
+ else
76
+
77
+ httpdigest_headers( uid, realm )
78
+ httpdigest_failure if respond_to?( :httpdigest_failure )
79
+ respond('Unauthorized', 401)
80
+
52
81
  end
53
82
 
54
83
  authorization["username"]
@@ -1,3 +1,5 @@
1
+ require 'maruku'
2
+
1
3
  module Ramaze
2
4
  module Helper::Maruku
3
5
  def maruku(text)
@@ -165,9 +165,8 @@ module Ramaze
165
165
  text = h(text.to_s)
166
166
 
167
167
  params = Ramaze::Request.current.params.merge(@var.to_s => n)
168
- name = Ramaze::Action.stack.first.name
169
- name = '/' if name == 'index' # make nicer...
170
- hash[:href] = Rs(name, params)
168
+ name = Ramaze::Request.current.request_path
169
+ hash[:href] = R(name, params)
171
170
 
172
171
  g.a(hash){ text }
173
172
  end