manveru-ramaze 2008.07 → 2008.08

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 (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