ramaze 2008.06 → 2008.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (184) hide show
  1. data/README.markdown +6 -6
  2. data/Rakefile +33 -3
  3. data/bin/ramaze +18 -0
  4. data/doc/CHANGELOG +960 -0
  5. data/doc/LEGAL +5 -1
  6. data/doc/meta/announcement.txt +20 -36
  7. data/doc/tutorial/todolist.html +421 -313
  8. data/doc/tutorial/todolist.mkd +33 -16
  9. data/examples/app/blog/spec/blog.rb +3 -3
  10. data/examples/app/rapaste/controller/paste.rb +8 -1
  11. data/examples/app/rapaste/model/paste.rb +3 -0
  12. data/examples/app/rapaste/spec/rapaste.rb +3 -1
  13. data/examples/app/rapaste/start.rb +3 -2
  14. data/examples/app/sourceview/public/sourceview.js +2 -2
  15. data/examples/app/todolist/spec/todolist.rb +6 -6
  16. data/examples/app/todolist/template/index.xhtml +1 -1
  17. data/examples/app/whywiki/spec/whywiki.rb +2 -2
  18. data/examples/app/wikore/spec/wikore.rb +2 -2
  19. data/examples/app/wikore/src/model.rb +4 -3
  20. data/examples/app/wiktacular/spec/wiktacular.rb +7 -7
  21. data/examples/basic/simple.rb +2 -2
  22. data/examples/helpers/paginate.rb +71 -0
  23. data/examples/misc/simple_auth.rb +20 -8
  24. data/lib/proto/controller/init.rb +10 -0
  25. data/lib/proto/controller/main.rb +1 -3
  26. data/lib/proto/model/init.rb +4 -0
  27. data/lib/proto/public/dispatch.fcgi +1 -1
  28. data/lib/proto/spec/main.rb +2 -1
  29. data/lib/proto/start.rb +3 -3
  30. data/lib/proto/start.ru +1 -1
  31. data/lib/proto/view/error.xhtml +4 -4
  32. data/lib/ramaze.rb +8 -3
  33. data/lib/ramaze/action.rb +6 -6
  34. data/lib/ramaze/adapter.rb +1 -6
  35. data/lib/ramaze/adapter/base.rb +30 -27
  36. data/lib/ramaze/adapter/cgi.rb +1 -0
  37. data/lib/ramaze/cache.rb +1 -3
  38. data/lib/ramaze/cache/memcached.rb +3 -5
  39. data/lib/ramaze/contrib/auto_params.rb +2 -2
  40. data/lib/ramaze/contrib/auto_params/get_args.rb +2 -1
  41. data/lib/ramaze/contrib/gems.rb +17 -18
  42. data/lib/ramaze/contrib/gzip_filter.rb +22 -9
  43. data/lib/ramaze/contrib/maruku_uv.rb +59 -0
  44. data/lib/ramaze/contrib/profiling.rb +1 -1
  45. data/lib/ramaze/contrib/rest.rb +16 -13
  46. data/lib/ramaze/contrib/sequel/create_join.rb +25 -0
  47. data/lib/ramaze/contrib/sequel/form_field.rb +129 -0
  48. data/lib/ramaze/contrib/sequel/image.rb +198 -0
  49. data/lib/ramaze/contrib/sequel/relation.rb +82 -0
  50. data/lib/ramaze/controller.rb +33 -34
  51. data/lib/ramaze/controller/resolve.rb +29 -9
  52. data/lib/ramaze/current.rb +60 -20
  53. data/lib/ramaze/current/request.rb +8 -7
  54. data/lib/ramaze/current/response.rb +15 -3
  55. data/lib/ramaze/current/session/flash.rb +8 -0
  56. data/lib/ramaze/dispatcher.rb +17 -9
  57. data/lib/ramaze/dispatcher/action.rb +4 -5
  58. data/lib/ramaze/dispatcher/directory.rb +1 -1
  59. data/lib/ramaze/dispatcher/error.rb +4 -4
  60. data/lib/ramaze/dispatcher/file.rb +4 -4
  61. data/lib/ramaze/gestalt.rb +15 -20
  62. data/lib/ramaze/helper/cgi.rb +7 -15
  63. data/lib/ramaze/helper/formatting.rb +41 -1
  64. data/lib/ramaze/helper/httpdigest.rb +20 -7
  65. data/lib/ramaze/helper/link.rb +4 -6
  66. data/lib/ramaze/helper/paginate.rb +233 -0
  67. data/lib/ramaze/helper/redirect.rb +1 -1
  68. data/lib/ramaze/helper/rest.rb +1 -1
  69. data/lib/ramaze/helper/thread.rb +17 -0
  70. data/lib/ramaze/helper/ultraviolet.rb +44 -0
  71. data/lib/ramaze/helper/user.rb +4 -9
  72. data/lib/ramaze/log.rb +2 -2
  73. data/lib/ramaze/log/analogger.rb +21 -23
  74. data/lib/ramaze/log/growl.rb +21 -23
  75. data/lib/ramaze/log/hub.rb +1 -1
  76. data/lib/ramaze/log/informer.rb +97 -99
  77. data/lib/ramaze/log/knotify.rb +14 -16
  78. data/lib/ramaze/log/logger.rb +11 -13
  79. data/lib/ramaze/log/logging.rb +61 -63
  80. data/lib/ramaze/log/rotatinginformer.rb +168 -0
  81. data/lib/ramaze/log/syslog.rb +41 -31
  82. data/lib/ramaze/log/xosd.rb +70 -72
  83. data/lib/ramaze/option.rb +9 -6
  84. data/lib/ramaze/option/holder.rb +5 -27
  85. data/lib/ramaze/reloader.rb +186 -0
  86. data/lib/ramaze/setup.rb +1 -1
  87. data/lib/ramaze/snippets.rb +13 -0
  88. data/lib/ramaze/snippets/array/put_within.rb +31 -24
  89. data/lib/ramaze/snippets/binding/locals.rb +23 -11
  90. data/lib/ramaze/snippets/dictionary.rb +2 -2
  91. data/lib/ramaze/snippets/fiber.rb +63 -0
  92. data/lib/ramaze/snippets/kernel/constant.rb +36 -21
  93. data/lib/ramaze/snippets/kernel/pretty_inspect.rb +12 -6
  94. data/lib/ramaze/snippets/numeric/filesize_format.rb +24 -17
  95. data/lib/ramaze/snippets/numeric/time.rb +63 -0
  96. data/lib/ramaze/snippets/object/__dir__.rb +29 -0
  97. data/lib/ramaze/snippets/object/acquire.rb +40 -0
  98. data/lib/ramaze/snippets/object/instance_variable_defined.rb +16 -5
  99. data/lib/ramaze/snippets/object/pretty.rb +14 -4
  100. data/lib/ramaze/snippets/object/scope.rb +14 -7
  101. data/lib/ramaze/snippets/ordered_set.rb +25 -14
  102. data/lib/ramaze/snippets/proc/locals.rb +17 -9
  103. data/lib/ramaze/snippets/ramaze/deprecated.rb +13 -0
  104. data/lib/ramaze/snippets/ramaze/fiber.rb +24 -0
  105. data/lib/ramaze/snippets/ramaze/state.rb +86 -0
  106. data/lib/ramaze/snippets/ramaze/struct.rb +45 -0
  107. data/lib/ramaze/snippets/string/camel_case.rb +13 -8
  108. data/lib/ramaze/snippets/string/color.rb +24 -20
  109. data/lib/ramaze/snippets/string/each.rb +14 -3
  110. data/lib/ramaze/snippets/string/end_with.rb +20 -0
  111. data/lib/ramaze/snippets/string/esc.rb +26 -21
  112. data/lib/ramaze/snippets/string/ord.rb +12 -6
  113. data/lib/ramaze/snippets/string/snake_case.rb +13 -7
  114. data/lib/ramaze/snippets/string/start_with.rb +16 -5
  115. data/lib/ramaze/snippets/string/unindent.rb +23 -15
  116. data/lib/ramaze/snippets/thread/into.rb +3 -3
  117. data/lib/ramaze/spec/helper/bacon.rb +5 -5
  118. data/lib/ramaze/spec/helper/mock_http.rb +1 -1
  119. data/lib/ramaze/spec/helper/pretty_output.rb +2 -2
  120. data/lib/ramaze/spec/helper/snippets.rb +8 -0
  121. data/lib/ramaze/template.rb +4 -1
  122. data/lib/ramaze/template/ezamar/textpow.syntax +34 -0
  123. data/lib/ramaze/template/maruku.rb +34 -0
  124. data/lib/ramaze/template/tagz.rb +2 -2
  125. data/lib/ramaze/template/xslt.rb +2 -2
  126. data/lib/ramaze/tool/create.rb +27 -53
  127. data/lib/ramaze/tool/localize.rb +8 -4
  128. data/lib/ramaze/tool/mime.rb +11 -1
  129. data/lib/ramaze/tool/project_creator.rb +110 -0
  130. data/lib/ramaze/trinity.rb +4 -1
  131. data/lib/ramaze/version.rb +1 -1
  132. data/lib/vendor/bacon.rb +323 -0
  133. data/rake_tasks/gem.rake +10 -1
  134. data/rake_tasks/maintenance.rake +40 -2
  135. data/rake_tasks/metric.rake +24 -0
  136. data/rake_tasks/release.rake +17 -4
  137. data/rake_tasks/spec.rake +1 -2
  138. data/ramaze.gemspec +549 -495
  139. data/spec/contrib/auto_params.rb +3 -3
  140. data/spec/contrib/profiling.rb +2 -2
  141. data/spec/examples/simple_auth.rb +2 -2
  142. data/spec/examples/templates/template_haml.rb +0 -2
  143. data/spec/ramaze/action/file_cache.rb +22 -0
  144. data/spec/ramaze/adapter.rb +2 -2
  145. data/spec/ramaze/controller/actionless_templates.rb +1 -1
  146. data/spec/ramaze/controller/subclass.rb +15 -0
  147. data/spec/ramaze/controller/template_resolving.rb +1 -1
  148. data/spec/ramaze/controller/view/bar.xhtml +1 -0
  149. data/spec/ramaze/controller/view/base/another.xhtml +1 -0
  150. data/spec/ramaze/current/session.rb +1 -1
  151. data/spec/ramaze/dispatcher/file.rb +2 -2
  152. data/spec/ramaze/helper/aspect.rb +26 -17
  153. data/spec/ramaze/helper/formatting.rb +13 -0
  154. data/spec/ramaze/log/informer.rb +10 -10
  155. data/spec/ramaze/log/syslog.rb +67 -4
  156. data/spec/ramaze/rewrite.rb +1 -1
  157. data/spec/ramaze/route.rb +1 -1
  158. data/spec/ramaze/struct.rb +47 -0
  159. data/spec/ramaze/template/markaby.rb +1 -1
  160. data/spec/ramaze/template/tagz.rb +1 -1
  161. data/spec/snippets/binding/locals.rb +9 -0
  162. data/spec/snippets/numeric/time.rb +12 -0
  163. data/spec/snippets/{kernel → object}/__dir__.rb +0 -0
  164. data/spec/snippets/{kernel → object}/acquire.rb +0 -0
  165. metadata +90 -81
  166. data/cache.yaml +0 -7
  167. data/examples/app/rammit/spec/rammit.rb +0 -31
  168. data/examples/app/rammit/src/controller/main.rb +0 -3
  169. data/examples/app/rammit/src/controller/page.rb +0 -16
  170. data/examples/app/rammit/src/model.rb +0 -33
  171. data/examples/app/rammit/start.rb +0 -8
  172. data/examples/app/rammit/template/index.xhtml +0 -14
  173. data/examples/app/rammit/template/page/view.xhtml +0 -4
  174. data/lib/ramaze/snippets/kernel/__dir__.rb +0 -23
  175. data/lib/ramaze/snippets/kernel/acquire.rb +0 -34
  176. data/lib/ramaze/snippets/object/thread_accessor.rb +0 -5
  177. data/lib/ramaze/snippets/ramaze/thread_accessor.rb +0 -58
  178. data/lib/ramaze/snippets/struct/fill.rb +0 -23
  179. data/lib/ramaze/snippets/struct/values_at.rb +0 -39
  180. data/lib/ramaze/snippets/symbol/to_proc.rb +0 -24
  181. data/lib/ramaze/sourcereload.rb +0 -176
  182. data/spec/snippets/struct/fill.rb +0 -26
  183. data/spec/snippets/struct/values_at.rb +0 -52
  184. data/spec/snippets/symbol/to_proc.rb +0 -13
@@ -14,10 +14,13 @@ module Ramaze
14
14
  # The Dispatcher receives requests from adapters and sets up the proper environment
15
15
  # to process them and respond.
16
16
 
17
- module Dispatcher
17
+ class Dispatcher
18
+ def initialize(*args)
19
+ Dispatcher.call(*args)
20
+ end
18
21
 
19
22
  # requests are passed to every
20
- FILTER = [ Dispatcher::File, Dispatcher::Action ] unless defined?(FILTER)
23
+ FILTER = OrderedSet[ Dispatcher::File, Dispatcher::Action ]
21
24
 
22
25
  # Response codes to cache the output of for repeated requests.
23
26
  trait :shielded => [ STATUS_CODE["Not Found"] ]
@@ -28,8 +31,12 @@ module Ramaze
28
31
  # Entry point for Adapter#respond, takes a Rack::Request and
29
32
  # Rack::Response, sets up the environment and the goes on to dispatch
30
33
  # for the given path from rack_request.
31
- def handle
34
+ #
35
+ # +env+ will be ignored, it's just for compatibility with rack middleware
36
+ def call(env = nil)
32
37
  path = request.path_info.squeeze('/')
38
+ path.sub!(/^#{Regexp.escape(Global.prefix)}/, '/')
39
+ path.squeeze!('/')
33
40
 
34
41
  if new_path = Rewrite.resolve(path)
35
42
  path = new_path
@@ -47,12 +54,13 @@ module Ramaze
47
54
  rescue Object => exception
48
55
  error(exception)
49
56
  end
57
+ alias handle call
50
58
 
51
59
  # protects against recursive dispatch and reassigns the path_info in the
52
60
  # request, the rest of the request is kept intact.
53
61
  def dispatch_to(path)
54
62
  if request.path_info == path
55
- if error = Thread.current[:exception]
63
+ if error = STATE[:exception]
56
64
  raise error
57
65
  else
58
66
  raise "Recursive redirect from #{path} to #{path}"
@@ -119,17 +127,17 @@ module Ramaze
119
127
  end
120
128
 
121
129
  def error(obj, meta = {})
122
- controller = Thread.current[:controller]
130
+ controller = STATE[:controller]
123
131
  meta[:controller] ||= controller if controller
124
132
 
125
- if Global.middleware
133
+ if Global.error_page
134
+ Dispatcher::Error.call(obj, meta)
135
+ else
126
136
  message = "No action for '#{meta[:path]}'"
127
- message << " on '#{CGI.escapeHTML(controller.to_s)}'" if controller
137
+ message << " on '#{Rack::Utils.escape_html(controller)}'" if controller
128
138
 
129
139
  raise(obj) if obj.respond_to?(:message)
130
140
  raise(Ramaze::Error, message)
131
- else
132
- Dispatcher::Error.call(obj, meta)
133
141
  end
134
142
  end
135
143
  end
@@ -2,7 +2,7 @@
2
2
  # All files in this distribution are subject to the terms of the Ruby license.
3
3
 
4
4
  module Ramaze
5
- module Dispatcher
5
+ class Dispatcher
6
6
 
7
7
  # This dispatcher is responsible for relaying requests to Controller::handle
8
8
  # and filtering the results using FILTER.
@@ -11,9 +11,9 @@ module Ramaze
11
11
 
12
12
  # The response is passed to each filter by sending .call(response) to it.
13
13
 
14
- FILTER = OrderedSet.new(
14
+ FILTER = OrderedSet[
15
15
  # Ramaze::Tool::Localize,
16
- ) unless defined?(FILTER)
16
+ ] unless defined?(FILTER)
17
17
 
18
18
  class << self
19
19
  include Trinity
@@ -26,8 +26,7 @@ module Ramaze
26
26
  log(path)
27
27
 
28
28
  catch(:respond) {
29
- body = Controller.handle(path)
30
- Response.current.build(body)
29
+ response.write Controller.handle(path)
31
30
  }
32
31
 
33
32
  FILTER.each{|f| f.call(response)}
@@ -2,7 +2,7 @@
2
2
  # All files in this distribution are subject to the terms of the Ruby license.
3
3
 
4
4
  module Ramaze
5
- module Dispatcher
5
+ class Dispatcher
6
6
 
7
7
  # Generates a directory listing, see Ramaze::Controller::Directory for more
8
8
  # information and how to create your own directory listing page
@@ -2,7 +2,7 @@
2
2
  # All files in this distribution are subject to the terms of the Ruby license.
3
3
 
4
4
  module Ramaze
5
- module Dispatcher
5
+ class Dispatcher
6
6
 
7
7
  # Last resort dispatcher, tries to recover as much information as possible
8
8
  # from the past request and takes the appropiate actions.
@@ -32,7 +32,7 @@ module Ramaze
32
32
  def call(error, metainfo = {})
33
33
  log_error(error)
34
34
 
35
- Thread.current[:exception] = error
35
+ STATE[:exception] = error
36
36
  response = Response.current
37
37
 
38
38
  key = error.class.ancestors.find{|a| HANDLE_ERROR[a]}
@@ -51,7 +51,7 @@ module Ramaze
51
51
  end
52
52
  end
53
53
 
54
- if path and Global.error_page and error.message !~ /`#{path}'/
54
+ if path and error.message !~ /`#{path}'/
55
55
  response.status = status
56
56
  return Dispatcher.dispatch_to(path)
57
57
  else
@@ -99,7 +99,7 @@ module Ramaze
99
99
  # Handle to current exception.
100
100
  # Only works inside request/response cycle.
101
101
  def current
102
- Thread.current[:exception]
102
+ STATE[:exception]
103
103
  end
104
104
 
105
105
  end
@@ -5,7 +5,7 @@ require "time"
5
5
  require 'digest/md5'
6
6
 
7
7
  module Ramaze
8
- module Dispatcher
8
+ class Dispatcher
9
9
 
10
10
  # First of the dispatchers, looks up the public path and serves the
11
11
  # file if found.
@@ -22,7 +22,7 @@ module Ramaze
22
22
  # searches for the file and builds a response with status 200 if found.
23
23
 
24
24
  def call(path)
25
- return unless file = open_file(CGI.unescape(path))
25
+ return unless file = open_file(Rack::Utils.unescape(path))
26
26
  Session.current.drop! if Session.current
27
27
  if file == :NotModified
28
28
  return response.build([], STATUS_CODE['Not Modified'])
@@ -35,7 +35,7 @@ module Ramaze
35
35
 
36
36
  def open_file(path)
37
37
  file = resolve_path(path)
38
-
38
+
39
39
  if ::File.file?(file)
40
40
  return unless in_public?(file)
41
41
  response['Content-Type'] = Tool::MIME.type_for(file) unless ::File.extname(file).empty?
@@ -59,7 +59,7 @@ module Ramaze
59
59
  # there is an index file in that directory, in which case return path for that.
60
60
  # If path is not a directory, simply return given path in public_root.
61
61
  # Either way, the returned path always starts with public_root.
62
-
62
+
63
63
  def resolve_path(path)
64
64
  joined = ::File.join(Global.public_root, path)
65
65
 
@@ -7,21 +7,16 @@ Example:
7
7
  require 'ramaze'
8
8
  require 'ramaze/gestalt'
9
9
 
10
- def random_color
11
- ('#' << '%02x' * 3) % (1..3).map{ rand(255) }
12
- end
10
+ page = Ramaze::Gestalt.build{
11
+ title = 'Hello, World!'
13
12
 
14
- puts Ramaze::Gestalt.build{
15
13
  html do
16
- head do
17
- title{"Hello World"}
18
- end
14
+ head{ title(title) }
19
15
  body do
20
- h1{"Hello, World!"}
21
- div(:style => 'width:100%') do
22
- 10.times do
23
- div(:style => "width:#{rand(100)}%;height:#{rand(100)}%;background:#{random_color}"){ '&nbsp;' }
24
- end
16
+ h1(title)
17
+ p 'I count to 10'
18
+ ('1'..'10').each do |count|
19
+ div(:style => 'width: 25px; height: 25px'){ count }
25
20
  end
26
21
  end
27
22
  end
@@ -53,7 +48,7 @@ module Ramaze
53
48
  # end
54
49
  #
55
50
 
56
- def self.build &block
51
+ def self.build(&block)
57
52
  self.new(&block).to_s
58
53
  end
59
54
 
@@ -63,24 +58,24 @@ module Ramaze
63
58
  #
64
59
  # Useful for distributed building of one page.
65
60
 
66
- def initialize &block
67
- @out = ''
61
+ def initialize(&block)
62
+ @out = []
68
63
  instance_eval(&block) if block_given?
69
64
  end
70
65
 
71
66
  # catching all the tags. passing it to _gestalt_build_tag
72
67
 
73
- def method_missing meth, *args, &block
68
+ def method_missing(meth, *args, &block)
74
69
  _gestalt_call_tag meth, args, &block
75
70
  end
76
71
 
77
72
  # workaround for Kernel#p to make <p /> tags possible.
78
73
 
79
- def p *args, &block
74
+ def p(*args, &block)
80
75
  _gestalt_call_tag :p, args, &block
81
76
  end
82
77
 
83
- def _gestalt_call_tag name, args, &block
78
+ def _gestalt_call_tag(name, args, &block)
84
79
  if args.size == 1 and args[0].kind_of? Hash
85
80
  # args are just attributes, children in block...
86
81
  _gestalt_build_tag name, args[0], &block
@@ -93,7 +88,7 @@ module Ramaze
93
88
  # build a tag for `name`, using `args` and an optional block that
94
89
  # will be yielded
95
90
 
96
- def _gestalt_build_tag name, attr={}, text=[]
91
+ def _gestalt_build_tag(name, attr = {}, text = [])
97
92
  @out << "<#{name}"
98
93
  @out << attr.map{|k,v| %[ #{k}="#{_gestalt_escape_entities(v)}"] }.join
99
94
  if text != [] or block_given?
@@ -122,7 +117,7 @@ module Ramaze
122
117
  end
123
118
 
124
119
  def to_s
125
- @out.to_s
120
+ @out.join
126
121
  end
127
122
  alias to_str to_s
128
123
  end
@@ -6,38 +6,30 @@ module Ramaze
6
6
  # Shortcuts to some CGI methods
7
7
 
8
8
  module Helper::CGI
9
- # shortcut for CGI.escape
10
9
 
10
+ # shortcut for Rack::Utils.escape
11
11
  def url_encode(*args)
12
- ::CGI.escape(*args.map{|arg| arg.to_s})
12
+ Rack::Utils.escape(*args.map{|a| a.to_s })
13
13
  end
14
14
 
15
- # shortcut for CGI.unescape
16
-
15
+ # shortcut for Rack::Utils.unescape
17
16
  def url_decode(*args)
18
- ::CGI.unescape(*args.map{|arg| arg.to_s})
17
+ Rack::Utils.unescape(*args.map{|a| a.to_s })
19
18
  end
20
19
 
21
- # shortcut for CGI.escapeHTML
22
-
20
+ # shortcut for Rack::Utils.escape_html
23
21
  def html_escape(string)
24
- ::CGI.escapeHTML(string.to_s)
22
+ Rack::Utils.escape_html(string)
25
23
  end
26
24
 
27
25
  # shortcut for CGI.unescapeHTML
28
-
29
26
  def html_unescape(string)
30
27
  ::CGI.unescapeHTML(string.to_s)
31
28
  end
32
29
 
33
30
  # safely escape all HTML and code
34
31
  def h(string)
35
- ::CGI.escapeHTML(string.to_s).gsub(/#/, '&#35;')
36
- end
37
-
38
- def c(string)
39
- Ramaze::deprecated("Helper::CGI#c", "Helper::CGI#h")
40
- h(string)
32
+ Rack::Utils.escape_html(string).gsub(/#([{@$]@?)/, '&#35;\1')
41
33
  end
42
34
 
43
35
  # one-letter versions help in case like #{h foo.inspect}
@@ -104,15 +104,55 @@ module Ramaze
104
104
  all
105
105
  else
106
106
  text = b + c
107
+ text = yield(text) if block_given?
107
108
  %(#{a}<a href="#{b=="www."?"http://www.":b}#{c}"#{html_options}>#{text}</a>#{d})
108
109
  end
109
110
  end
110
111
  end
111
- alias :autolink :auto_link
112
+ alias autolink auto_link
112
113
 
113
114
  def nl2br(string, xhtml = true)
114
115
  br = xhtml ? '<br />' : '<br>'
115
116
  string.gsub(/\n/, br)
116
117
  end
118
+
119
+ # Maybe port to ruby < 1.8.7 ?
120
+ def obfuscate_email(string)
121
+ string = string.to_s
122
+ text = string.each_byte.map{|c| "&#%03d" % c}.join
123
+ %(<a href="mailto:#{string}">#{text}</a>)
124
+ end
125
+
126
+ # Returns Hash with tags as keys and their weight as value.
127
+ #
128
+ # Example:
129
+ # tags = %w[ruby ruby code ramaze]
130
+ # tagcloud(tags)
131
+ # # => {"code"=>0.75, "ramaze"=>0.75, "ruby"=>1.0}
132
+ #
133
+ # The weight can be influenced by adjusting the +min+ and +max+ parameters,
134
+ # please make sure that +max+ is larger than +min+ to get meaningful output.
135
+ #
136
+ # This is not thought as immediate output to your template but rather to
137
+ # help either implementing your own algorithm or using the result as input
138
+ # for your tagcloud.
139
+ #
140
+ # Example:
141
+ # - tagcloud(tags).each do |tag, weight|
142
+ # - style = "font-size: %0.2fem" % weight
143
+ # %a{:style => style, :href => Rs(tag)}= h(tag)
144
+
145
+ def tagcloud(tags, min = 0.5, max = 1.5)
146
+ result = {}
147
+ total = tags.size.to_f
148
+ diff = max - min
149
+
150
+ tags.uniq.each do |tag|
151
+ count = tags.respond_to?(:count) ? tags.count(tag) : tags.select{|t| t==tag }.size
152
+ result[tag] = ((count / total) * diff) + min
153
+ end
154
+
155
+ result
156
+ end
117
157
  end
118
158
  end
@@ -4,15 +4,23 @@ require 'md5'
4
4
  module Ramaze
5
5
  module Helper
6
6
  module HttpDigest
7
+
8
+ UUID_GENERATOR = UUID.new
9
+
10
+ @session_nonce = "authentication_digest_nonce"
11
+
12
+ def httpdigest_logout
13
+ session.delete( @session_nonce )
14
+ end
15
+
7
16
  def httpdigest(uid, realm)
8
17
  session_opaque = "authentication_digest_opaque_#{uid}"
9
- session_nonce = "authentication_digest_nonce"
10
18
 
11
- session[session_opaque] ||= UUID.new
19
+ session[session_opaque] ||= UUID_GENERATOR.generate
12
20
 
13
21
  authorized = false
14
22
 
15
- if session[session_nonce] and request.env['HTTP_AUTHORIZATION']
23
+ if session[@session_nonce] and request.env['HTTP_AUTHORIZATION']
16
24
 
17
25
  auth_split = request.env['HTTP_AUTHORIZATION'].split
18
26
  authentication_type = auth_split[0]
@@ -21,7 +29,7 @@ module Ramaze
21
29
  authorization.values_at(*%w[response username nonce nc cnonce qop])
22
30
 
23
31
  if authentication_type == 'Digest'
24
- if nonce == session[session_nonce]
32
+ if nonce == session[@session_nonce]
25
33
  ha1 = yield(username)
26
34
  ha2 = MD5.hexdigest("#{request.request_method}:#{request.fullpath}")
27
35
  md5 = MD5.hexdigest([ha1, nonce, nc, cnonce, qop, ha2].join(':'))
@@ -32,17 +40,22 @@ module Ramaze
32
40
  end
33
41
 
34
42
  unless authorized
35
- session[session_nonce] = UUID.new
43
+ session[@session_nonce] = UUID_GENERATOR.generate
36
44
  response['WWW-Authenticate'] =
37
45
  %|Digest realm="#{realm}",| +
38
46
  %|qop="auth,auth-int",| +
39
- %|nonce="#{session[session_nonce]}",| +
47
+ %|nonce="#{session[@session_nonce]}",| +
40
48
  %|opaque="#{session[session_opaque]}"|
41
- respond('Unauthorized', 401)
49
+ if respond_to?( :httpdigest_failure )
50
+ httpdigest_failure
51
+ else
52
+ respond('Unauthorized', 401)
53
+ end
42
54
  end
43
55
 
44
56
  authorization["username"]
45
57
  end
58
+
46
59
  end
47
60
  end
48
61
  end
@@ -7,13 +7,11 @@ module Ramaze
7
7
  # Usage is shown in spec/ramaze/helper/link.rb and the rdocs below.
8
8
 
9
9
  module Helper::Link
10
- private
11
-
12
10
  # Builds a basic <a> tag.
13
11
  #
14
12
  # `text` is mandatory, the second hash of options will be transformed into
15
13
  # arguments of the tag, :href is a special case and its segments will be
16
- # CGI.escaped.
14
+ # escaped.
17
15
  #
18
16
  # If you pass no :href, the text will be run through Rs and its result is
19
17
  # used instead. If you really want an empty href, use :href => ''
@@ -30,7 +28,7 @@ module Ramaze
30
28
 
31
29
  hash[:href] ||= Rs(*args)
32
30
  text = hash.delete(:text) || args.last || hash[:title] || hash[:href]
33
- hash[:href] = hash[:href].to_s.gsub(/[^\/?;=]+/) {|m| CGI.escape(m) }
31
+ hash[:href] = hash[:href].to_s.gsub(/[^\/?;=]+/){|m| Rack::Utils.escape(m) }
34
32
 
35
33
  args = ['']
36
34
  hash.each {|k,v| args << %(#{k}="#{v}") if k and v }
@@ -69,10 +67,10 @@ module Ramaze
69
67
  end or atom.to_s
70
68
  end
71
69
 
72
- front = atoms.join('/').squeeze('/')
70
+ front = [Global.prefix, *atoms].join('/').squeeze('/')
73
71
 
74
72
  if args
75
- rear = args.inject('?'){|s,(k,v)| s << "#{CGI.escape k.to_s}=#{CGI.escape v.to_s};"}[0..-2]
73
+ rear = args.inject('?'){|s,(k,v)| s << "#{Rack::Utils.escape(k)}=#{Rack::Utils.escape(v)};"}[0..-2]
76
74
  front + rear
77
75
  else
78
76
  front