nitro 0.30.0 → 0.31.0

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.
@@ -199,8 +199,6 @@ class WebrickAdapter < WEBrick::HTTPServlet::AbstractServlet
199
199
 
200
200
  def handle(req, res)
201
201
  unless handle_file(req, res)
202
- path = req.request_uri.path
203
-
204
202
  begin
205
203
  path = req.request_uri.path
206
204
 
data/lib/nitro/caching.rb CHANGED
@@ -1,4 +1,3 @@
1
- require 'glue/attribute'
2
1
  require 'glue/configuration'
3
2
  require 'glue/sweeper'
4
3
 
@@ -1,7 +1,6 @@
1
1
  require 'fileutils'
2
2
 
3
3
  require 'glue/configuration'
4
- require 'glue/attribute'
5
4
  require 'glue/cache/memory'
6
5
 
7
6
  module Nitro
@@ -20,11 +19,11 @@ module Caching
20
19
  setting :cache, :default => Glue::MemoryCache.new, :doc => 'The cache used to store the fragments'
21
20
 
22
21
  def self.get(name, options = {})
23
- return @@cache.get(name, options)
22
+ return self.cache.get(name, options)
24
23
  end
25
24
 
26
25
  def self.put(name, content = nil, options = {})
27
- @@cache.put(name, content, options)
26
+ self.cache.put(name, content, options)
28
27
  return content
29
28
  end
30
29
 
@@ -6,6 +6,8 @@ module Nitro
6
6
 
7
7
  module Caching
8
8
 
9
+ setting :output_cache_root, :default => 'public', :doc => 'The directory where cached pages are generated'
10
+
9
11
  # The Output caching subsystem stores whole pages in the
10
12
  # filesystem to be served directly be the front web server
11
13
  # (Lighttpd, Apache, etc) for optimal performance.
@@ -22,9 +24,6 @@ module Caching
22
24
 
23
25
  def self.included(base) # :nodoc:
24
26
  base.extend(ClassMethods)
25
- base.module_eval do
26
- cattr_accessor :output_cache_root, 'public'
27
- end
28
27
  end
29
28
 
30
29
  module ClassMethods
@@ -54,7 +53,7 @@ module Caching
54
53
  filename = ((path.empty? || path == '/') ? 'index.html' : path.dup)
55
54
  # filename.gsub!(/\/$/, '')
56
55
  filename << '/index.html' unless (filename.split('/').last || filename).include? '.'
57
- return output_cache_root + '/' + filename
56
+ return Caching.output_cache_root + '/' + filename
58
57
  end
59
58
 
60
59
  end
data/lib/nitro/cgi.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require 'cgi'
2
2
 
3
+ require 'stringio'
4
+
3
5
  require 'glue/configuration'
4
6
  require 'nitro/cgi/http'
5
7
 
@@ -21,10 +23,22 @@ class Cgi
21
23
 
22
24
  # Process a CGI request. This is a general method reused by
23
25
  # many adapters.
26
+ #--
27
+ # A CGI request is process-based so there is no need for Og
28
+ # connection cleanup.
29
+ #++
24
30
 
25
31
  def self.process(server, cgi, inp, out)
26
32
  context = Context.new(server)
27
33
 
34
+ unless inp.respond_to?(:rewind)
35
+ # The module Request#raw_body requires a rewind method,
36
+ # so if the input stream doesn't have one, *cough* FCgi,
37
+ # we convert it to a StringIO.
38
+
39
+ inp = StringIO.new(inp.read.to_s) # if read returns nil, to_s makes it ""
40
+ end
41
+
28
42
  context.in = inp
29
43
  context.headers = cgi.env
30
44
 
@@ -64,7 +64,7 @@ module Request
64
64
  # www.nitroproject.org: request.domain # => 'nitroproject.org'
65
65
  # www.nitroproject.co.uk: request.domain(2) # => 'nitroproject.co.uk'
66
66
 
67
- def domain(tld_length = 1)
67
+ def domain tld_length = 1
68
68
  host.split('.').last(1 + tld_length).join('.')
69
69
  end
70
70
 
@@ -74,7 +74,7 @@ module Request
74
74
  #
75
75
  # my.name.nitroproject.org: request.subdomains # => ['my', 'name']
76
76
 
77
- def subdomains(tld_length = 1)
77
+ def subdomains tld_length = 1
78
78
  parts = host.split('.')
79
79
  parts[0..-(tld_length+2)]
80
80
  end
@@ -104,7 +104,7 @@ module Request
104
104
  # if request.get?
105
105
 
106
106
  def method
107
- @headers['REQUEST_METHOD'].downcase.intern
107
+ @headers['REQUEST_METHOD'].downcase.to_sym
108
108
  end
109
109
 
110
110
  #--
@@ -176,6 +176,7 @@ module Request
176
176
  def referer
177
177
  return @headers['HTTP_REFERER'] || '/'
178
178
  end
179
+ alias referrer referer
179
180
 
180
181
  # The content_length
181
182
 
@@ -242,19 +243,19 @@ module Request
242
243
 
243
244
  # Lookup a query parameter.
244
245
 
245
- def [](param)
246
+ def [] param
246
247
  @params[param]
247
248
  end
248
249
 
249
250
  # Set a query parameter.
250
251
 
251
- def []=(param, value)
252
+ def []= param, value
252
253
  @params[param] = value
253
254
  end
254
255
 
255
256
  # Check if a boolean param (checkbox) is true.
256
257
 
257
- def true?(param)
258
+ def true? param
258
259
  @params[param] == 'on'
259
260
  end
260
261
  alias_method :enabled?, :true?
@@ -262,19 +263,19 @@ module Request
262
263
 
263
264
  # Check if a boolean param (checkbox) is false.
264
265
 
265
- def false?(param)
266
+ def false? param
266
267
  !true?(param)
267
268
  end
268
269
 
269
270
  # Fetch a parameter with default value.
270
271
 
271
- def fetch(param, default = nil)
272
+ def fetch param, default = nil
272
273
  @params.fetch(param, default)
273
274
  end
274
275
 
275
276
  # Check if a param is available.
276
277
 
277
- def has_key?(key)
278
+ def has_key? key
278
279
  @params.has_key?(key)
279
280
  end
280
281
  alias_method :has_param?, :has_key?
@@ -0,0 +1,45 @@
1
+ require 'nitro/render'
2
+
3
+ module Nitro
4
+
5
+ module Render
6
+
7
+ # Send a file download to the client.
8
+ #
9
+ # Like render and redirect, the action is exited upon calling
10
+ #
11
+ # [+fname+] That name of the file
12
+ # [+path+] Specifying true mean fname contains the full path.
13
+ # The default, false, uses Server.public_root as the path.
14
+ #
15
+ # [+return+] true on success, false on failure
16
+ #
17
+ # === Examples
18
+ #
19
+ # require 'nitro/cgi/sendfile'
20
+ # class MyController < Nitro:Controller
21
+ # def download(fname)
22
+ # sendfile(fname)
23
+ # end
24
+ # end
25
+ #
26
+ # class MyController < Nitro:Controller
27
+ # def download()
28
+ # sendfile('/etc/password', true)
29
+ # end
30
+ # end
31
+
32
+ def sendfile(fname=nil, fullpath=false)
33
+ fname = fullpath ? fname : "#{Server.public_root}/#{fname}"
34
+ f = File.open(fname, "rb")
35
+ @context.response_headers["Cache-control"] = 'private'
36
+ @context.response_headers["Content-Length"] = "#{File.size?(f) || 0}"
37
+ @context.response_headers["Content-Type"] = 'application/force-download'
38
+ @context.out = f
39
+ raise RenderExit
40
+ end
41
+
42
+ end
43
+
44
+ end
45
+
@@ -258,7 +258,7 @@ class Compiler
258
258
  end
259
259
 
260
260
  # Concatenate some extracted parameters.
261
- params.concat(context.params.values)
261
+ # params.concat(context.params.values)
262
262
 
263
263
  # Fill the array with nils for the missing params.
264
264
  (#{param_count} - params.size).times { params << nil }
@@ -10,7 +10,7 @@ require 'facet/ormsupport'
10
10
  # or something.
11
11
  #++
12
12
 
13
- class Exception
13
+ class Exception # :nodoc: all
14
14
 
15
15
  # Radius of the source code to display arround the error line.
16
16
 
@@ -45,7 +45,7 @@ class Exception
45
45
  source = File.read(file)
46
46
 
47
47
  if file =~ /\.xhtml$/
48
- source = Compiler.new.transform_template(source)
48
+ source = Compiler.new(Nitro::Controller).transform_template(:action, source)
49
49
  no -= 2
50
50
  end
51
51
 
@@ -105,7 +105,7 @@ class Exception
105
105
 
106
106
  def source_for_backtrace(indent = 0)
107
107
  backtrace.inject([]) do |sources, step|
108
- sources << source_extract(indent,step)
108
+ sources << source_extract(step, indent)
109
109
  end
110
110
  end
111
111
 
data/lib/nitro/context.rb CHANGED
@@ -63,6 +63,11 @@ class Context
63
63
  # initialize the output buffer.
64
64
 
65
65
  @out ||= OutputBuffer.new
66
+
67
+ # Store this instance in a thread local variable for easy
68
+ # access.
69
+
70
+ Thread.current[:CURRENT_CONTEXT] = self
66
71
  end
67
72
 
68
73
 
@@ -162,7 +167,17 @@ class Context
162
167
  alias_method :is_top?, :is_top_level?
163
168
  alias_method :in_top_level?, :is_top_level?
164
169
  alias_method :top_level?, :is_top_level?
165
-
170
+
171
+ class << self
172
+
173
+ # Returns the context for the current thread.
174
+
175
+ def current
176
+ Thread.current[:CURRENT_CONTEXT]
177
+ end
178
+
179
+ end
180
+
166
181
  end
167
182
 
168
183
  end
@@ -46,6 +46,22 @@ module Publishable
46
46
  include ::Aspects
47
47
  include Flashing
48
48
  include Helpers
49
+
50
+ # The collection of 'models' ie classes that are linked
51
+ # to this Publishable/Controller.
52
+
53
+ ann :self, :models => []
54
+
55
+ # This is a helper that 'links' one or more classes to this
56
+ # controller. In practice it annotates each class with the
57
+ # controller and stores the controller's list of 'models'.
58
+
59
+ def self.model *classes
60
+ for c in classes
61
+ c.ann :self, :controller => self
62
+ self.ann.self.models! << c
63
+ end
64
+ end
49
65
  end
50
66
 
51
67
  # Aliases an action
@@ -171,7 +187,7 @@ private
171
187
 
172
188
  # Cookie helpers.
173
189
  #--
174
- # TODO: move elsewhere.
190
+ # TODO: move elsewhere, probably to a default helper.
175
191
  #++
176
192
 
177
193
  def cookies
@@ -207,13 +223,34 @@ private
207
223
  # encode_url ForaController, :post, :title, 'Hello', :body, 'World'
208
224
  # encode_url :post, :title, 'Hello', :body, 'World' # => implies controller == self
209
225
  # encode_url :kick, :oid, 4
226
+ # encode_url article # => article.to_href
227
+ #
228
+ # Alternatively you can pass options with a hash:
229
+ #
230
+ # encode_url :controller => ForaController, :action => :delete, :params => { :title => 'Hello' }
231
+ # encode_url :action => :delete
210
232
  #--
211
233
  # FIXME: better implementation? optimize this?
212
234
  # TODO: move elsewhere.
213
235
  #++
214
236
 
215
- def encode_url(*args)
216
- if args.first.is_a?(Symbol) or args.first.is_a?(String)
237
+ def encode_url *args
238
+ f = args.first
239
+
240
+ # A standard url as string, return as is.
241
+
242
+ if f.is_a? String
243
+ return f
244
+ end
245
+
246
+ # If the passed param is an object that responds to :to_href
247
+ # returns the url to this object.
248
+
249
+ if f.respond_to? :to_href
250
+ return args.first.to_href
251
+ end
252
+
253
+ if f.is_a? Symbol
217
254
  # no controller passed, imply controller == self!
218
255
  args.unshift(self.class)
219
256
  end
@@ -278,10 +315,10 @@ class Controller
278
315
 
279
316
  # This callback is called after the Controller is mounted.
280
317
 
281
- def self.mounted(path)
318
+ def self.mounted path
282
319
  # Resolve aspects.
283
320
 
284
- ::Aspects.include_advice_modules(self)
321
+ Aspects.include_advice_modules(self)
285
322
 
286
323
  # The scaffolding code is compiled after the mount, so
287
324
  # that template roots are finalized.
@@ -289,6 +326,24 @@ class Controller
289
326
  compile_scaffolding_code()
290
327
  end
291
328
 
329
+ # Returns the current controller from the context thread local
330
+ # variable.
331
+
332
+ def self.current
333
+ Thread.current[:CURRENT_CONTROLLER]
334
+ end
335
+
336
+ #--
337
+ # Replaces the current controller (helper for render).
338
+ # This is an internal method.
339
+ #++
340
+
341
+ def self.replace_current controller # :nodoc:
342
+ old = Thread.current[:CURRENT_CONTROLLER]
343
+ Thread.current[:CURRENT_CONTROLLER] = controller
344
+ return old
345
+ end
346
+
292
347
  end
293
348
 
294
349
  end
@@ -128,7 +128,7 @@ class Dispatcher
128
128
  for m in c.action_methods
129
129
  m = m.to_sym
130
130
  if route = c.ann(m).route and (!route.nil?)
131
- add_route(route.first, :controller => c, :action => m, :params => route.last)
131
+ add_rule(route.first, :controller => c, :action => m, :params => route.last)
132
132
  end
133
133
  end
134
134
  end
@@ -168,6 +168,7 @@ class Dispatcher
168
168
  return klass, "#{action}_action", klass.mount_path
169
169
  end
170
170
 
171
+ path = path.sub(/#{Router.strip_path}/, '') if Router.strip_path
171
172
  parts = path.split('/')
172
173
  parts.shift # get rid of the leading '/'.
173
174
 
data/lib/nitro/helper.rb CHANGED
@@ -1,8 +1,6 @@
1
1
  require 'facet/kernel/constant'
2
2
  require 'facet/string/camelize'
3
3
 
4
- require 'glue/attribute'
5
-
6
4
  module Nitro
7
5
 
8
6
  # Helpers are standard Ruby modules that contain utility
@@ -90,6 +90,10 @@ module FormHelper
90
90
  # for this form. If you pass a class an empty object is
91
91
  # instantiated.
92
92
  #
93
+ # * :action = The action of this form. The parameter is
94
+ # passed through the R operator (encode_url) to support
95
+ # advanced url encoding.
96
+ #
93
97
  # === Example
94
98
  #
95
99
  # #{form(:object => @owner, :action => :save_profile) do |f|
@@ -120,7 +124,7 @@ module FormHelper
120
124
  b = FormXmlBuilder.new('', options)
121
125
 
122
126
  b << '<form'
123
- b << %| action="#{options[:action]}"| if options[:action]
127
+ b << %| action="#{R options[:action]}"| if options[:action]
124
128
  b << %| method="#{options[:method]}"| if options[:method]
125
129
  b << %| enctype="#{options[:enctype]}"| if options[:enctype]
126
130
  b << '>'
@@ -28,7 +28,7 @@ private
28
28
  # filename. Override if you don't like the defaults.
29
29
 
30
30
  def name_to_jsfile(name)
31
- "js/#{name}.js"
31
+ "/js/#{name}.js"
32
32
  end
33
33
  end
34
34