manveru-ramaze 2008.07 → 2008.08

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/Rakefile +31 -2
  2. data/doc/meta/announcement.txt +16 -32
  3. data/examples/app/rapaste/controller/paste.rb +7 -0
  4. data/examples/app/sourceview/public/sourceview.js +2 -2
  5. data/lib/proto/view/error.xhtml +3 -3
  6. data/lib/ramaze/action.rb +2 -2
  7. data/lib/ramaze/adapter/base.rb +10 -19
  8. data/lib/ramaze/cache/memcached.rb +3 -5
  9. data/lib/ramaze/controller/resolve.rb +14 -4
  10. data/lib/ramaze/controller.rb +15 -11
  11. data/lib/ramaze/current/request.rb +6 -3
  12. data/lib/ramaze/current/session/flash.rb +8 -0
  13. data/lib/ramaze/dispatcher/error.rb +3 -3
  14. data/lib/ramaze/dispatcher.rb +5 -5
  15. data/lib/ramaze/gestalt.rb +8 -8
  16. data/lib/ramaze/helper/cgi.rb +1 -1
  17. data/lib/ramaze/helper/formatting.rb +8 -1
  18. data/lib/ramaze/helper/thread.rb +17 -0
  19. data/lib/ramaze/helper/ultraviolet.rb +44 -0
  20. data/lib/ramaze/helper/user.rb +4 -9
  21. data/lib/ramaze/option/holder.rb +1 -11
  22. data/lib/ramaze/option.rb +3 -3
  23. data/lib/ramaze/reloader.rb +186 -0
  24. data/lib/ramaze/setup.rb +1 -1
  25. data/lib/ramaze/snippets/dictionary.rb +2 -2
  26. data/lib/ramaze/snippets/fiber.rb +63 -0
  27. data/lib/ramaze/snippets/numeric/time.rb +10 -10
  28. data/lib/ramaze/snippets/ramaze/deprecated.rb +4 -2
  29. data/lib/ramaze/snippets/ramaze/fiber.rb +24 -0
  30. data/lib/ramaze/snippets/ramaze/state.rb +86 -0
  31. data/lib/ramaze/sourcereload.rb +1 -0
  32. data/lib/ramaze/template/maruku.rb +34 -0
  33. data/lib/ramaze/template.rb +4 -1
  34. data/lib/ramaze/tool/mime.rb +11 -1
  35. data/lib/ramaze/trinity.rb +4 -1
  36. data/lib/ramaze/version.rb +1 -1
  37. data/lib/ramaze.rb +2 -2
  38. data/rake_tasks/gem.rake +6 -0
  39. data/ramaze.gemspec +11 -5
  40. data/spec/ramaze/action/file_cache.rb +22 -0
  41. data/spec/ramaze/controller/actionless_templates.rb +1 -1
  42. data/spec/ramaze/controller/subclass.rb +15 -0
  43. data/spec/ramaze/controller/template_resolving.rb +1 -1
  44. data/spec/ramaze/controller/view/bar.xhtml +1 -0
  45. data/spec/ramaze/controller/view/base/another.xhtml +1 -0
  46. data/spec/ramaze/helper/aspect.rb +26 -17
  47. data/spec/ramaze/route.rb +1 -1
  48. data/spec/ramaze/template/tagz.rb +1 -1
  49. metadata +11 -5
  50. data/lib/ramaze/snippets/object/thread_accessor.rb +0 -5
  51. data/lib/ramaze/snippets/ramaze/thread_accessor.rb +0 -58
data/Rakefile CHANGED
@@ -28,8 +28,8 @@ load 'rake_tasks/git.rake'
28
28
  load 'rake_tasks/gem.rake'
29
29
  load 'rake_tasks/metric.rake'
30
30
 
31
- # task :default => ['spec']
32
- # task :test => ['spec']
31
+ task :default => ['spec']
32
+ task :test => ['spec']
33
33
  # task :package => ['jquery']
34
34
 
35
35
  desc 'download latest jquery and put in /lib/proto/public/js/jquery.js'
@@ -48,6 +48,35 @@ task :jquery do
48
48
  end
49
49
  end
50
50
 
51
+ desc 'Check gemspec file list against real file list'
52
+ task :check_gemspec do
53
+ base_dir = File.expand_path(File.dirname(__FILE__))
54
+ gemspec_files = eval(File.read(File.join(base_dir,'ramaze.gemspec'))).files.map{|file|File.join(base_dir,file)}
55
+
56
+ deleted_files = gemspec_files.select{|file|!File.exists?(file)}.map{|file|file[(base_dir.size+1)..-1]}
57
+
58
+ added_files = Dir.glob(File.join(File.dirname(__FILE__),'**/*')).select do |file|
59
+ !gemspec_files.index(file)
60
+ end.map do |file|
61
+ file[(base_dir.size+1)..-1]
62
+ end.select do |file|
63
+ !( file == 'pkg' or file =~ /.*\.gem/ )
64
+ end
65
+
66
+ unless deleted_files.empty?
67
+ puts "The following files appear in the gemspec but cannot be found:"
68
+ deleted_files.each do |file|
69
+ puts "\t#{file}"
70
+ end
71
+ end
72
+ unless added_files.empty?
73
+ puts "The following files exist, but cannot be found in the gemspec:"
74
+ added_files.each do |file|
75
+ puts "\t#{file}"
76
+ end
77
+ end
78
+ end
79
+
51
80
  task :rcov_dir do
52
81
  mkdir_p 'doc/output/tools/rcov/'
53
82
  end
@@ -1,4 +1,4 @@
1
- This time we are proud to announce Version 2008.06 of Ramaze, the light and
1
+ This time we are proud to announce Version 2008.07 of Ramaze, the light and
2
2
  modular open source web framework.
3
3
 
4
4
  This release features a lot of work directly from our community and we are
@@ -36,41 +36,25 @@ Simple example:
36
36
  Ramaze.start
37
37
 
38
38
 
39
- This is a special release, and the first of the upcoming new series of monthly releases.
40
- As you may have noticed, Ramaze has changed to a date base versioning system,
41
- although this means that people who have waited for a 1.0 for the past years
42
- may be disappointed it provides much larger flexibility in detecting new
43
- versions and comparing them with nightly builds.
39
+ Some of 52 patches since 2008.06:
44
40
 
45
- Another change is the switch from darcs to git and moving our primary
46
- repository to github. There have been serious performance issues regarding
47
- darcs as Ramaze gathered a longer history, using git allows us to move on at a
48
- faster pace again.
49
-
50
- Please regard this release as a major step from the previous one, over 450
51
- patches have been applied and there were changes in the internal API.
52
-
53
- We are unable to nicely summarize these changes, so this release will not have
54
- a list of the most important ones, if you are concerned about a specific area
55
- feel free to ask on the Mailing list or stop by on IRC.
41
+ - Loggers are now in Ramaze::Logger namespace
42
+ - Global.prefix for nested deployment via webserver in front
43
+ - Binding#locals fixed for Ruby 1.9
44
+ - Redirects now use HTTP status 302 instead of 303
45
+ - Logger::Syslog works again
56
46
 
57
47
  Special (alphabetic) thanks go to:
58
48
 
59
- Aman 'tmm1' Gupta - Tons of patches, support
60
- andy - Cleanup
61
- Ara T. Howard - Tagz templating engine
62
- Clive Crous - Patches, cleanup
63
- evaryont - Patches for identity helper
64
- James Tucker - OSX compatibility, cleanup and fixes
65
- Jonathan 'Kashia' Buch - Patches, support and the first ramaze paper
66
- Keita Yamaguchi - Much work on the benchmark suite
67
- Leo Borisenko - Fix for SourceReload on windows
68
- Pistos - Mathetes, patches and lots of friendly support
69
- Riku Räisäenen - Patches for scaffolding example
70
- Ryan Grove - Various fixes and patches
71
- Sam Carr - Patches and action matching speedup
72
- Thomas Leitner - Patches for identity helper
73
- Wang Jinjing - patches, 1.9/1.8.7 compatibility
49
+ Pistos - The usual Mathetes, patches and lots of friendly support
50
+ Aman 'tmm1' Gupta - Time snippets for numeric
51
+ Clinton R. Nixon - More REST and some fixes
52
+ Jean-Francois Chevrette - Restore --console feature
53
+ raggi - Various fixes
54
+ Rob Lievaart - Fix Logger::Syslog
55
+ Sam Carr - Cleanup of Cache
56
+ Wang Jinjing - 1.9 compatibility
57
+ Yasushi Abe - First patch!
74
58
 
75
59
  A complete Changelog is available at
76
60
  http://github.com/manveru/ramaze/tree/master/doc/CHANGELOG?raw=true
@@ -1,4 +1,5 @@
1
1
  Ramaze::Route[%r!^/(\d+)\.(?:te?xt|plain|rb|css|js)$!] = '/plain/%d'
2
+ Ramaze::Route[%r!^/(\d+)\.(?:html)$!] = '/html/%d'
2
3
  Ramaze::Route[%r!^/(?:te?xt|plain|rb|css|js)/(\d+)$!] = '/plain/%d'
3
4
  Ramaze::Route[%r!^/(\d+)\.(\w+)$!] = '/view/%d/%s'
4
5
  Ramaze::Route[%r!^/(\d+)$!] = '/view/%d/html'
@@ -64,6 +65,12 @@ class PasteController < Ramaze::Controller
64
65
  respond paste.text
65
66
  end
66
67
 
68
+ def html(id)
69
+ paste = paste_for(id)
70
+ response['Content-Type'] = 'text/html'
71
+ respond paste.text
72
+ end
73
+
67
74
  def save_theme( theme_name )
68
75
  session[ :theme ] = theme_name
69
76
  end
@@ -22,7 +22,7 @@ function setup() {
22
22
 
23
23
  if (curfile) {
24
24
  $('#repourl').empty().append(
25
- $('<a/>').attr('href', 'http://darcs.ramaze.net/ramaze'+curfile)
25
+ $('<a/>').attr('href', 'http://github.com/manveru/ramaze/tree/master'+curfile)
26
26
  .text('download '+curfile.substr(1))
27
27
  );
28
28
  urchinTracker(curfile);
@@ -49,4 +49,4 @@ $(function(){
49
49
  } else {
50
50
  setup();
51
51
  }
52
- });
52
+ });
@@ -40,9 +40,9 @@ Click on any of them to view the surrounding source code.</p>
40
40
  </table>
41
41
 
42
42
  <?r
43
- { 'Session' => Thread.current[:session],
44
- 'Request' => Thread.current[:request],
45
- 'Response' => Thread.current[:response],
43
+ { 'Session' => Ramaze::STATE[:session],
44
+ 'Request' => Ramaze::STATE[:request],
45
+ 'Response' => Ramaze::STATE[:response],
46
46
  'Global' => Global,
47
47
  }.each do |title, content|
48
48
  hash = [title, content].object_id.abs
data/lib/ramaze/action.rb CHANGED
@@ -41,7 +41,7 @@ module Ramaze
41
41
 
42
42
  # Return the stacked actions for the current request
43
43
  def stack
44
- Thread.current[:action_stack] ||= []
44
+ STATE[:action_stack] ||= []
45
45
  end
46
46
  end
47
47
 
@@ -116,7 +116,7 @@ module Ramaze
116
116
 
117
117
  # combined path to current action, from path and params
118
118
  def extended_path
119
- Array[path, *params].join('/')
119
+ (path == "index" && !params.empty? ? params : Array[path, *params]).join('/')
120
120
  end
121
121
 
122
122
  def full_path
@@ -7,14 +7,17 @@ module Ramaze
7
7
  # (Rack) middleware injected around Adapter::Base::call
8
8
  MIDDLEWARE = OrderedSet.new(
9
9
  Ramaze::Current,
10
+ Ramaze::Reloader,
10
11
  Rack::ShowStatus,
11
12
  Rack::ShowExceptions
12
13
  )
13
14
 
15
+ trait :middleware => MIDDLEWARE.inject{|app, middleware| middleware.new(app) }
16
+
14
17
  # Helper to assign a new block to before_call
15
18
  # Usage:
16
19
  # Ramaze::Adapter.before do |env|
17
- # if env['PATH_INFO'] =~ /suerpfast/
20
+ # if env['PATH_INFO'] =~ /superfast/
18
21
  # [200, {'Content-Type' => 'text/plain'}, ['super fast!']]
19
22
  # end
20
23
  # end
@@ -30,10 +33,10 @@ module Ramaze
30
33
  class << self
31
34
  attr_reader :thread
32
35
 
33
- # For the specified host and for all given ports call run_server and
34
- # add the returned thread to the Global.adapters ThreadGroup.
35
- # Afterwards adds a trap for the value of Global.shutdown_trap which
36
- # calls Ramaze.shutdown when triggered (usually by SIGINT).
36
+ # Call ::startup with the given host and port.
37
+ # Sets Global.server to itself.
38
+ # Adds a trap that is triggered by the value of Global.shutdown_trap,
39
+ # which is SIGINT by default.
37
40
 
38
41
  def start(host = nil, port = nil)
39
42
  @thread = startup(host, port)
@@ -98,20 +101,8 @@ module Ramaze
98
101
  # Then goes on and calls Dispatcher::handle with request and response.
99
102
 
100
103
  def respond(env)
101
- if Global.server.respond_to?(:thread) and Global.server.thread == Thread.current
102
- Thread.new{ middleware_respond(env) }.value
103
- else
104
- middleware_respond(env)
105
- end
106
- end
107
-
108
- def middleware_respond(env)
109
- Thread.current.priority = 1
110
-
111
- if Global.middleware
112
- MIDDLEWARE.inject{|app, middleware| middleware.new(app) }.call(env)
113
- else
114
- Current.call(env)
104
+ Ramaze::STATE.wrap do
105
+ Adapter.trait[:middleware].call(env)
115
106
  end
116
107
  end
117
108
  end
@@ -43,13 +43,11 @@ module Ramaze
43
43
  nil
44
44
  end
45
45
 
46
- # out of some reason MemCache sometimes doesn't respond to
47
- # get_multi, have to investigate this further.
48
- #
49
- # for now, i'll just use the dumbed down version and ask it
50
- # whether it implements this functionality or not.
46
+ # Fetch for multiple keys at once.
51
47
 
52
48
  def get_multi(*keys)
49
+ # MemCache only responds to get_multi if the memcache-client_extensions gem
50
+ # is installed, so we check first and resort to another approach if not.
53
51
  if @cache.respond_to?(:get_multi)
54
52
  @cache.get_multi(*keys)
55
53
  else
@@ -104,10 +104,13 @@ module Ramaze
104
104
 
105
105
  def resolve_action(path, *parameter)
106
106
  path, parameter = path.to_s, parameter.map{|e| e.to_s}
107
- if info = trait["#{path}_template"]
107
+ # Use ancestral_trait so if template is set in superclass, it is still found.
108
+ if info = ancestral_trait["#{path}_template"]
108
109
  template = info[:file]
109
110
  unless template
110
111
  controller, action = info.values_at :controller, :action
112
+ # Controller may not have been explicitly set, in which case use self.
113
+ controller ||= self
111
114
  template = controller.resolve_template(action)
112
115
  end
113
116
  end
@@ -184,8 +187,7 @@ module Ramaze
184
187
 
185
188
  # methodnames that may be used for current controller.
186
189
  def action_methods
187
- ancs = relevant_ancestors + Helper::LOOKUP.to_a
188
-
190
+ ancs = relevant_ancestors + action_modules
189
191
  ancs.reverse.inject [] do |meths, anc|
190
192
  meths +
191
193
  anc.public_instance_methods(false).map{|im| im.to_s } -
@@ -193,6 +195,14 @@ module Ramaze
193
195
  end
194
196
  end
195
197
 
198
+ # Array of all modules (so including Ramaze helpers) that are included in
199
+ # this controller and where the module is also in the Helper::LOOKUP set.
200
+ # Hence this is the included modules whose public methods may be exposed
201
+ # as actions of this controller.
202
+ def action_modules
203
+ Helper::LOOKUP.find_all {|mod| self.include?(mod)}
204
+ end
205
+
196
206
  # Iterator that yields potential ways in which a given path could be mapped
197
207
  # to controller, action and params. It produces them in strict order, with
198
208
  # longest controller path favoured, then longest action path.
@@ -255,7 +265,7 @@ module Ramaze
255
265
  # Raises Ramaze::Error::NoAction
256
266
 
257
267
  def raise_no_action(controller, path)
258
- Thread.current[:controller] = controller
268
+ STATE[:controller] = controller
259
269
  raise Ramaze::Error::NoAction, "No Action found for `#{path}' on #{controller}"
260
270
  end
261
271
  end
@@ -85,7 +85,7 @@ module Ramaze
85
85
  def map(*syms)
86
86
  Global.mapping.delete_if{|k,v| v == self}
87
87
 
88
- syms.each do |sym|
88
+ syms.compact.each do |sym|
89
89
  Global.mapping[sym.to_s] = self
90
90
  end
91
91
  end
@@ -150,12 +150,10 @@ module Ramaze
150
150
  # Runs every given path through Controller::check_path
151
151
 
152
152
  def view_root *args
153
- if args.empty?
154
- @view_root
155
- else
156
- check_path("#{self}.view_root: '%s' doesn't exist", *args)
157
- @view_root = args.flatten
158
- end
153
+ return @view_root if args.empty?
154
+
155
+ check_path("#{self}.view_root: '%s' doesn't exist", *args)
156
+ @view_root = args.flatten
159
157
  end
160
158
 
161
159
  # This is used for template rerouting, takes action, optionally a
@@ -218,9 +216,15 @@ module Ramaze
218
216
  end
219
217
  trait "#{this}_template" => info
220
218
  else
221
- controller, action, *ignored = argv
222
- controller, action = self, controller unless action
223
- trait "#{this}_template" => {:controller => controller, :action => action}
219
+ # Only explicitly set the controller to use, if it was explicitly given.
220
+ # This helps ensure that template mappings still work in subclasses
221
+ # of this controller.
222
+ first, second, *ignored = argv
223
+ if second
224
+ trait "#{this}_template" => {:controller => first, :action => second}
225
+ else
226
+ trait "#{this}_template" => {:action => first}
227
+ end
224
228
  end
225
229
  end
226
230
 
@@ -254,7 +258,7 @@ module Ramaze
254
258
 
255
259
  def handle path
256
260
  action = resolve(path)
257
- Thread.current[:controller] = action.controller
261
+ STATE[:controller] = action.controller
258
262
  action.render
259
263
  end
260
264
 
@@ -11,7 +11,7 @@ module Ramaze
11
11
  class Request < ::Rack::Request
12
12
  class << self
13
13
 
14
- # get the current request out of Thread.current[:request]
14
+ # get the current request out of STATE[:request]
15
15
  #
16
16
  # You can call this from everywhere with Ramaze::Request.current
17
17
 
@@ -33,7 +33,11 @@ module Ramaze
33
33
  end
34
34
 
35
35
  def ip
36
- env['HTTP_X_FORWARDED_FOR'] || env['REMOTE_ADDR']
36
+ if addr = env['HTTP_X_FORWARDED_FOR']
37
+ addr.split(',').last.strip
38
+ else
39
+ env['REMOTE_ADDR']
40
+ end
37
41
  end
38
42
 
39
43
  # Request is from a local network?
@@ -48,7 +52,6 @@ module Ramaze
48
52
  # ++
49
53
 
50
54
  def local_net?(address = ip)
51
- address = address.to_s.split(',').first
52
55
  addr = IPAddr.new(address)
53
56
  LOCAL.find{|range| range.include?(addr) }
54
57
  rescue ArgumentError => ex
@@ -67,6 +67,14 @@ module Ramaze
67
67
  combined.empty?
68
68
  end
69
69
 
70
+ def merge!(hash)
71
+ current.merge!(hash)
72
+ end
73
+
74
+ def merge(hash)
75
+ current.merge(hash)
76
+ end
77
+
70
78
  private
71
79
 
72
80
  # Associated session object
@@ -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
@@ -54,7 +54,7 @@ module Ramaze
54
54
  # request, the rest of the request is kept intact.
55
55
  def dispatch_to(path)
56
56
  if request.path_info == path
57
- if error = Thread.current[:exception]
57
+ if error = STATE[:exception]
58
58
  raise error
59
59
  else
60
60
  raise "Recursive redirect from #{path} to #{path}"
@@ -121,17 +121,17 @@ module Ramaze
121
121
  end
122
122
 
123
123
  def error(obj, meta = {})
124
- controller = Thread.current[:controller]
124
+ controller = STATE[:controller]
125
125
  meta[:controller] ||= controller if controller
126
126
 
127
- if Global.middleware
127
+ if Global.error_page
128
+ Dispatcher::Error.call(obj, meta)
129
+ else
128
130
  message = "No action for '#{meta[:path]}'"
129
131
  message << " on '#{Rack::Utils.escape_html(controller)}'" if controller
130
132
 
131
133
  raise(obj) if obj.respond_to?(:message)
132
134
  raise(Ramaze::Error, message)
133
- else
134
- Dispatcher::Error.call(obj, meta)
135
135
  end
136
136
  end
137
137
  end
@@ -48,7 +48,7 @@ module Ramaze
48
48
  # end
49
49
  #
50
50
 
51
- def self.build &block
51
+ def self.build(&block)
52
52
  self.new(&block).to_s
53
53
  end
54
54
 
@@ -58,24 +58,24 @@ module Ramaze
58
58
  #
59
59
  # Useful for distributed building of one page.
60
60
 
61
- def initialize &block
62
- @out = ''
61
+ def initialize(&block)
62
+ @out = []
63
63
  instance_eval(&block) if block_given?
64
64
  end
65
65
 
66
66
  # catching all the tags. passing it to _gestalt_build_tag
67
67
 
68
- def method_missing meth, *args, &block
68
+ def method_missing(meth, *args, &block)
69
69
  _gestalt_call_tag meth, args, &block
70
70
  end
71
71
 
72
72
  # workaround for Kernel#p to make <p /> tags possible.
73
73
 
74
- def p *args, &block
74
+ def p(*args, &block)
75
75
  _gestalt_call_tag :p, args, &block
76
76
  end
77
77
 
78
- def _gestalt_call_tag name, args, &block
78
+ def _gestalt_call_tag(name, args, &block)
79
79
  if args.size == 1 and args[0].kind_of? Hash
80
80
  # args are just attributes, children in block...
81
81
  _gestalt_build_tag name, args[0], &block
@@ -88,7 +88,7 @@ module Ramaze
88
88
  # build a tag for `name`, using `args` and an optional block that
89
89
  # will be yielded
90
90
 
91
- def _gestalt_build_tag name, attr={}, text=[]
91
+ def _gestalt_build_tag(name, attr = {}, text = [])
92
92
  @out << "<#{name}"
93
93
  @out << attr.map{|k,v| %[ #{k}="#{_gestalt_escape_entities(v)}"] }.join
94
94
  if text != [] or block_given?
@@ -117,7 +117,7 @@ module Ramaze
117
117
  end
118
118
 
119
119
  def to_s
120
- @out.to_s
120
+ @out.join
121
121
  end
122
122
  alias to_str to_s
123
123
  end
@@ -29,7 +29,7 @@ module Ramaze
29
29
 
30
30
  # safely escape all HTML and code
31
31
  def h(string)
32
- Rack::Utils.escape_html(string).gsub(/#/, '&#35;')
32
+ Rack::Utils.escape_html(string).gsub(/#([{@$]@?)/, '&#35;\1')
33
33
  end
34
34
 
35
35
  # one-letter versions help in case like #{h foo.inspect}
@@ -108,11 +108,18 @@ module Ramaze
108
108
  end
109
109
  end
110
110
  end
111
- alias :autolink :auto_link
111
+ alias autolink auto_link
112
112
 
113
113
  def nl2br(string, xhtml = true)
114
114
  br = xhtml ? '<br />' : '<br>'
115
115
  string.gsub(/\n/, br)
116
116
  end
117
+
118
+ # Maybe port to ruby < 1.8.7 ?
119
+ def obfuscate_email(string)
120
+ string = string.to_s
121
+ text = string.each_byte.map{|c| "&#%03d" % c}.join
122
+ %(<a href="mailto:#{string}">#{text}</a>)
123
+ end
117
124
  end
118
125
  end
@@ -0,0 +1,17 @@
1
+ # Copyright (c) 2008 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 Helper::Thread
6
+ def thread &block
7
+ parent_thread = Thread.current
8
+ Thread.new do
9
+ begin
10
+ block.call
11
+ rescue Exception => e
12
+ parent_thread.raise(e)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,44 @@
1
+ module Ramaze
2
+ module Helper
3
+ module Ultraviolet
4
+ trait :ultraviolet => {
5
+ :output => 'xhtml',
6
+ :syntax => nil, # syntax_name, nil|false indicates automatic detection
7
+ :line_numbers => false,
8
+ :style => 'classic', # render_style
9
+ :headers => false, # ouput document with all headers
10
+ }
11
+
12
+ # Parse and output the file at the given path.
13
+ # Please head over to the Ultraviolet documentation for more information
14
+ # on possible options.
15
+ def ultraviolet(path, options = {})
16
+ o = ancestral_trait[:ultraviolet].merge(options)
17
+ output, syntax, lines, style, headers =
18
+ o.values_at(:output, :syntax, :line_numbers, :style, :headers)
19
+
20
+ syntax ||= Uv.syntax_for_file(path).first.first
21
+ code = File.read(path)
22
+
23
+ p [code, output, syntax, lines, style, headers]
24
+ Uv.parse(code, output, syntax, lines, style, headers)
25
+ end
26
+
27
+ # Return absolute path to the css of given name.
28
+ #
29
+ # Usually this will point to somewhere in the gem tree.
30
+ #
31
+ # It seems like Uv will add support for user-defined PATH in the future,
32
+ # so we will, to be future-proof, traverse the Uv.path even though it
33
+ # currently will only have one directory.
34
+
35
+ def ultraviolet_css(theme)
36
+ Uv.path.each do |path|
37
+ Dir[path/"render/xhtml/files/css/*.css"].each do |css|
38
+ return css if File.basename(css, '.css') == theme
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -25,7 +25,7 @@ module Ramaze
25
25
  def user
26
26
  model = ancestral_trait[:user_model] ||= ::User
27
27
  callback = ancestral_trait[:user_callback] ||= nil
28
- Thread.current[:user] ||= Wrapper.new(model, callback)
28
+ STATE[:user] ||= Wrapper.new(model, callback)
29
29
  end
30
30
 
31
31
  # shortcut for user.user_login but default argument are request.params
@@ -51,12 +51,7 @@ module Ramaze
51
51
  # In order to not interfere with the wrapped instance/model we start our
52
52
  # methods with an underscore.
53
53
  # Suggestions on improvements as usual welcome.
54
- class Wrapper
55
- # make it a BlankSlate
56
- instance_methods.each do |meth|
57
- undef_method(meth) unless meth.to_s =~ /^__.+__$/
58
- end
59
-
54
+ class Wrapper < BlankSlate
60
55
  attr_accessor :_model, :_callback, :_user
61
56
 
62
57
  def initialize(model, callback)
@@ -82,14 +77,14 @@ module Ramaze
82
77
  elsif _model.respond_to?(:authenticate)
83
78
  _model.authenticate(creds)
84
79
  else
85
- Log.warn("Helper::User has no callback and model doesn't respond to #authenticate")
80
+ Log.warn("Helper::User has no callback and %p doesn't respond to #authenticate" % _model)
86
81
  nil
87
82
  end
88
83
  end
89
84
 
90
85
  def _logout
91
86
  _persistence.clear
92
- Thread.current[:user] = nil
87
+ STATE[:user] = nil
93
88
  end
94
89
 
95
90
  def _logged_in?
@@ -104,17 +104,7 @@ module Ramaze
104
104
  end
105
105
 
106
106
  def sourcereload=(interval)
107
- if interval
108
- if interval.is_a?(Numeric)
109
- @sourcereload = interval
110
- Ramaze::SourceReload.restart
111
- else
112
- Log.warn("sourcereload= %p not Numeric, ignoring." % interval)
113
- end
114
- else
115
- @sourcereload = interval
116
- Ramaze::SourceReload.shutdown
117
- end
107
+ Ramaze::Reloader::OPTIONS[:cooldown] = interval
118
108
  end
119
109
 
120
110
  private