nitro 0.22.0 → 0.23.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/CHANGELOG +109 -1250
  2. data/INSTALL +3 -2
  3. data/README +5 -4
  4. data/Rakefile +1 -1
  5. data/bin/nitrogen +1 -1
  6. data/doc/AUTHORS +20 -6
  7. data/doc/CHANGELOG.3 +1314 -0
  8. data/doc/RELEASES +90 -0
  9. data/lib/nitro.rb +6 -17
  10. data/lib/nitro/adapter/cgi.rb +11 -0
  11. data/lib/nitro/adapter/webrick.rb +7 -1
  12. data/lib/nitro/caching/stores.rb +4 -6
  13. data/lib/nitro/compiler.rb +1 -1
  14. data/lib/nitro/compiler/errors.rb +1 -1
  15. data/lib/nitro/context.rb +11 -4
  16. data/lib/nitro/controller.rb +0 -3
  17. data/lib/nitro/cookie.rb +4 -3
  18. data/lib/nitro/dispatcher.rb +7 -1
  19. data/lib/nitro/dispatcher/nice.rb +6 -1
  20. data/lib/nitro/element.rb +2 -2
  21. data/lib/nitro/mixin/benchmark.rb +16 -0
  22. data/lib/nitro/mixin/form.rb +171 -55
  23. data/lib/nitro/mixin/rss.rb +1 -1
  24. data/lib/nitro/mixin/xhtml.rb +91 -4
  25. data/lib/nitro/render.rb +25 -6
  26. data/lib/nitro/request.rb +13 -3
  27. data/lib/nitro/scaffold.rb +91 -68
  28. data/lib/nitro/scaffold/relations.rb +54 -0
  29. data/lib/nitro/server.rb +8 -5
  30. data/lib/nitro/server/runner.rb +4 -3
  31. data/lib/nitro/service.rb +3 -1
  32. data/lib/nitro/service/xmlrpc.rb +1 -1
  33. data/lib/nitro/session.rb +69 -51
  34. data/lib/nitro/session/drb.rb +5 -7
  35. data/lib/nitro/session/drbserver.rb +4 -6
  36. data/lib/nitro/session/memory.rb +4 -6
  37. data/lib/part/admin.rb +6 -0
  38. data/lib/part/admin/controller.rb +24 -0
  39. data/lib/part/admin/skin.rb +21 -0
  40. data/lib/part/admin/template/index.xhtml +9 -0
  41. data/proto/public/js/cookies.js +122 -0
  42. data/proto/public/scaffold/edit.xhtml +4 -0
  43. data/proto/public/scaffold/form.xhtml +7 -0
  44. data/proto/public/scaffold/list.xhtml +15 -0
  45. data/proto/public/scaffold/new.xhtml +4 -0
  46. data/proto/public/scaffold/view.xhtml +0 -0
  47. data/proto/script/benchmark +19 -0
  48. data/test/nitro/adapter/tc_cgi.rb +32 -2
  49. data/test/nitro/mixin/tc_xhtml.rb +6 -0
  50. data/test/nitro/tc_dispatcher.rb +0 -17
  51. data/test/nitro/tc_render.rb +58 -0
  52. data/test/nitro/tc_server.rb +2 -0
  53. data/test/nitro/tc_session.rb +16 -0
  54. metadata +104 -85
@@ -0,0 +1,54 @@
1
+ require 'nitro/scaffold'
2
+
3
+ module Nitro::Scaffolding
4
+
5
+ # A collection of scaffolding helper for Og relations.
6
+
7
+ module Og
8
+
9
+ private
10
+
11
+ # Scaffold the relations of an Og managed object.
12
+
13
+ def scaffold_relations(obj)
14
+ end
15
+
16
+ # Scaffold a +belongs_to+ relation.
17
+
18
+ def belongs_to_editor(obj, rel, options)
19
+ entities = rel.target_class.all
20
+ labels = entities.map { |e| e.to_s }
21
+ values = entities.map { |e| e.oid }
22
+ element(
23
+ label(rel.name),
24
+ %{
25
+ <select id="#{rel.name}" name="#{rel.name}">
26
+ #{options(:labels => labels, :values => values, :selected => 1)}
27
+ </select>
28
+ }
29
+ )
30
+ end
31
+
32
+ # Scaffold a +has_many+ relation.
33
+
34
+ def has_many_editor(obj, rel, options)
35
+ entities = obj.send(rel.target_plural_name)
36
+ unless entities.empty?
37
+ str = entities.inject('') do |acc, e|
38
+ acc << "<tr><td>#{e.to_edit_link(@base)}</td></tr>"
39
+ end
40
+ str = "<table>#{str}</table>"
41
+ else
42
+ str = 'No entities found.<br /><br />'
43
+ end
44
+ element(
45
+ label(rel.name) + '&nbsp;<a href="#">Add</a>',
46
+ %{
47
+ #{str}
48
+ }
49
+ )
50
+ end
51
+
52
+ end
53
+
54
+ end
@@ -1,5 +1,4 @@
1
- require 'glue/autoreload'
2
-
1
+ require 'nitro/controller'
3
2
  require 'nitro/server/runner'
4
3
 
5
4
  module Nitro
@@ -29,6 +28,11 @@ class Server
29
28
 
30
29
  setting :access_log, :default => nil, :doc => 'The access log'
31
30
 
31
+ # Additional server options. Useful to pass options to
32
+ # Webrick for example.
33
+
34
+ setting :options, :default => {}, :doc => "Additional server options"
35
+
32
36
  # The name of the application.
33
37
 
34
38
  attr_accessor :name
@@ -68,7 +72,8 @@ class Server
68
72
  @address, @port = self.class.address, self.class.port
69
73
  @public_root = self.class.public_root
70
74
  @access_log = self.class.access_log
71
- @options = options
75
+ @options = self.class.options.dup
76
+ @options.update(options)
72
77
  end
73
78
 
74
79
  # Return the dispatcher.
@@ -146,5 +151,3 @@ end
146
151
  # Alias for the Server class.
147
152
 
148
153
  App = Nitro::Server unless Object.const_defined?(:App)
149
-
150
- # * George Moschovitis <gm@navel.gr>
@@ -1,6 +1,5 @@
1
1
  require 'optparse'
2
2
 
3
- require 'glue/misc'
4
3
  require 'glue/configuration'
5
4
 
6
5
  module Nitro
@@ -202,7 +201,7 @@ class Runner
202
201
  def setup_debug
203
202
  $DBG = true
204
203
  Compiler.reload = true
205
- require 'glue/autoreload'
204
+ require 'nano/kernel/autoreload'
206
205
  autoreload(3)
207
206
  Caching.caching_enabled = false
208
207
 
@@ -273,7 +272,9 @@ class Runner
273
272
 
274
273
  @server ||= Runner.adapter
275
274
 
276
- puts "\n==> Listening at #{server.address}:#{server.port}. (#{self.class.mode} mode)\n\n"
275
+ puts "\n",
276
+ "==> Listening at #{server.address}:#{server.port}. (#{self.class.mode} mode)",
277
+ "==> Press Ctrl-C to shutdown; Run with --help for options.\n\n"
277
278
 
278
279
  case @server
279
280
  when :webrick
@@ -2,6 +2,8 @@ require 'nitro/controller'
2
2
 
3
3
  module Nitro
4
4
 
5
+ # A Web Service endpoint. This is a specialized controller.
6
+
5
7
  class Service < Nitro::Controller
6
8
 
7
9
  def index
@@ -10,7 +12,7 @@ class Service < Nitro::Controller
10
12
  res = send(method, *args)
11
13
 
12
14
  response.content_type = 'text/xml'
13
-
15
+
14
16
  print encode_response(method, res)
15
17
 
16
18
  return :stop
@@ -20,7 +20,7 @@ module XmlRpc
20
20
 
21
21
  def decode_request(request)
22
22
  method, args = XMLRPC::Marshal.load_call(request)
23
- Logger.debug "Calling XML-RPC method '#{method}'" if $DBG
23
+ Logger.debug "Calling XML-RPC method '#{method}', args: #{args.inspect}" if $DBG
24
24
  return method.gsub(/\./, '__'), args
25
25
  end
26
26
 
@@ -1,7 +1,9 @@
1
1
  require 'md5'
2
2
  require 'webrick'
3
3
 
4
- require 'glue/hash'
4
+ require 'mega/synchash'
5
+ require 'mega/time_in_english'
6
+
5
7
  require 'glue/attribute'
6
8
  require 'glue/configuration'
7
9
 
@@ -30,51 +32,68 @@ class Session < Hash
30
32
 
31
33
  setting :cookie_name, :default => 'nsid', :doc => 'The name of the cookie that stores the session id'
32
34
 
35
+ # The session keepalive time. The session is eligable for
36
+ # garbage collection after this time passes.
37
+
38
+ setting :keepalive, :default => 30.minutes, :doc => 'The session keepalive time'
39
+
33
40
  # The sessions store. By default sessions are
34
41
  # stored in memory.
35
42
 
36
- cattr_accessor :store; @@store = Glue::SafeHash.new
43
+ cattr_accessor :store; @@store = SyncHash.new
37
44
 
38
- # Set the session store. The following options are
39
- # available:
40
- #
41
- # * :memory [default]
42
- # * :drb
43
- # * :memcached (not available yet)
44
- # * :og (not available yet)
45
- # * :file (not available yet)
46
-
47
- def self.store_type=(store_type)
48
- # gmosx: RDoc complains about this, so lets use an
49
- # eval, AAAAAAAARGH!
50
- # require "nitro/session/#{store_type}"
51
- eval %{ require 'nitro/session/#{store_type}' }
52
- end
53
-
54
- # Lookup the session in the store by using the session
55
- # cookie value as a key. If the session does not exist
56
- # creates a new session, inserts it in the store and
57
- # appends a new session cookie in the response.
45
+ class << self
58
46
 
59
- def self.lookup(context)
60
- if session_id = context.cookies[Session.cookie_name]
61
- session = Session.store[session_id]
47
+ # Set the session store. The following options are
48
+ # available:
49
+ #
50
+ # * :memory [default]
51
+ # * :drb
52
+ # * :memcached (not available yet)
53
+ # * :og (not available yet)
54
+ # * :file (not available yet)
55
+
56
+ def store_type=(store_type)
57
+ # gmosx: RDoc complains about this, so lets use an
58
+ # eval, AAAAAAAARGH!
59
+ # require "nitro/session/#{store_type}"
60
+ eval %{ require 'nitro/session/#{store_type}' }
62
61
  end
63
62
 
64
- unless session
65
- # Create new session.
66
- session = Session.new(context)
67
- cookie = Cookie.new(Session.cookie_name, session.session_id)
68
- context.add_cookie(cookie)
69
- Session.store[session.session_id] = session
70
- else
71
- # Access ('touch') the existing session.
72
- session.touch!
63
+ # Lookup the session in the store by using the session
64
+ # cookie value as a key. If the session does not exist
65
+ # creates a new session, inserts it in the store and
66
+ # appends a new session cookie in the response.
67
+
68
+ def lookup(context)
69
+ if session_id = context.cookies[Session.cookie_name]
70
+ session = Session.store[session_id]
71
+ end
72
+
73
+ unless session
74
+ # Create new session.
75
+ session = Session.new(context)
76
+ cookie = Cookie.new(Session.cookie_name, session.session_id)
77
+ context.add_cookie(cookie)
78
+ Session.store[session.session_id] = session
79
+ else
80
+ # Access ('touch') the existing session.
81
+ session.touch!
82
+ end
83
+
84
+ return session
73
85
  end
86
+
87
+ # Perform session garbage collection. Typically this method
88
+ # is called from a cron like mechanism (for example using
89
+ # script/runner).
74
90
 
75
- return session
91
+ def garbage_collection!
92
+ Session.store.delete_if { |key, s| s.invalid? }
93
+ end
94
+ alias_method :gc!, :garbage_collection!
76
95
  end
77
-
96
+
78
97
  # The unique id of this session.
79
98
 
80
99
  attr_reader :session_id
@@ -101,7 +120,7 @@ class Session < Hash
101
120
  @ctime = @mtime = @atime = Time.now
102
121
  end
103
122
 
104
- # Like the unix touch command, upadtes
123
+ # Like the unix touch command, updates
105
124
  # the atime to now.
106
125
 
107
126
  def touch!
@@ -117,6 +136,19 @@ class Session < Hash
117
136
  end
118
137
  alias_method :restore, :sync
119
138
 
139
+ # Keep this session alive?
140
+
141
+ def valid?
142
+ Time.now < @atime + Session.keepalive
143
+ end
144
+ alias_method :alive?, :valid?
145
+
146
+ # The reverse of keepalive?
147
+
148
+ def invalid?
149
+ Time.now > @atime + Session.keepalive
150
+ end
151
+
120
152
  protected
121
153
 
122
154
  # Calculates a unique id.
@@ -138,20 +170,6 @@ protected
138
170
 
139
171
  end
140
172
 
141
- # Abstract class for a session store manager.
142
-
143
- class SessionStore
144
- def []=(sid, session)
145
- end
146
-
147
- def [](sid)
148
- end
149
-
150
- def delete(sid)
151
- end
152
-
153
- end
154
-
155
173
  end
156
174
 
157
175
  # * George Moschovitis <gm@navel.gr>
@@ -1,10 +1,6 @@
1
- # * George Moschovitis <gm@navel.gr>
2
- # (c) 2004-2005 Navel, all rights reserved.
3
- # $Id: drb.rb 182 2005-07-22 10:07:50Z gmosx $
4
-
5
1
  require 'drb'
6
2
 
7
- require 'glue/attribute'
3
+ require 'glue/configuration'
8
4
  require 'nitro/session'
9
5
 
10
6
  Logger.debug 'Using Drb sessions.'
@@ -15,11 +11,11 @@ class Session
15
11
 
16
12
  # The address of the Session DRb server.
17
13
 
18
- cattr_accessor :drb_address, '127.0.0.1'
14
+ setting :drb_address, :default => '127.0.0.1', :doc => 'The address of the Session DRb server'
19
15
 
20
16
  # The port of the Session DRb server.
21
17
 
22
- cattr_accessor :drb_port, 9069
18
+ setting :drb_port, :default => 9069, :doc => 'The port of the Session DRb server'
23
19
 
24
20
  end
25
21
 
@@ -29,3 +25,5 @@ Session.store = DRbObject.new(
29
25
  )
30
26
 
31
27
  end
28
+
29
+ # * George Moschovitis <gm@navel.gr>
@@ -1,13 +1,9 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- # * George Moschovitis <gm@navel.gr>
4
- # (c) 2004-2005 Navel, all rights reserved.
5
- # $Id: drbserver.rb 182 2005-07-22 10:07:50Z gmosx $
6
-
7
3
  require 'drb'
8
4
  require 'optparse'
9
5
 
10
- require 'glue/hash'
6
+ require 'mega/synchash'
11
7
  require 'nitro/session'
12
8
 
13
9
  # A distributes session store implemented as
@@ -49,7 +45,7 @@ rescue OptionParser::InvalidOption
49
45
  exit
50
46
  end
51
47
 
52
- sessions = Glue::SafeHash.new
48
+ sessions = SyncHash.new
53
49
 
54
50
  if debug
55
51
 
@@ -69,3 +65,5 @@ end
69
65
 
70
66
  DRb.start_service("druby://#{address}:#{port}", sessions)
71
67
  DRb.thread.join
68
+
69
+ # * George Moschovitis <gm@navel.gr>
@@ -1,13 +1,11 @@
1
- # * George Moschovitis <gm@navel.gr>
2
- # (c) 2004-2005 Navel, all rights reserved.
3
- # $Id: memory.rb 1 2005-04-11 11:04:30Z gmosx $
4
-
5
- require 'glue/hash'
1
+ require 'mega/synchash'
6
2
 
7
3
  Logger.debug 'Using In-Memory sessions.'
8
4
 
9
5
  module Nitro
10
6
 
11
- Session.store = SafeHash.new
7
+ Session.store = SyncHash.new
12
8
 
13
9
  end
10
+
11
+ # * George Moschovitis <gm@navel.gr>
@@ -0,0 +1,6 @@
1
+ require 'nitro/server'
2
+
3
+ require 'part/admin/controller'
4
+ require 'part/admin/skin'
5
+
6
+ Nitro::Server.map['/admin'] = AdminController
@@ -0,0 +1,24 @@
1
+ require 'nitro/controller'
2
+
3
+ class AdminController < Nitro::Controller
4
+
5
+ @template_root = File.join(File.dirname(__FILE__), 'template')
6
+
7
+ def index
8
+ @classes = self.class.managed_classes
9
+ end
10
+
11
+ class << self
12
+ # The managed classes of this application.
13
+
14
+ attr_accessor :managed_classes
15
+
16
+ # Called when this controller is mounted.
17
+
18
+ def mounted
19
+ @managed_classes = Og.manager.manageable_classes
20
+ @managed_classes.each { |c| scaffold(c) }
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,21 @@
1
+ require 'nitro/element'
2
+
3
+ class SystemPage < Nitro::Element
4
+ def render
5
+ %~
6
+ <html>
7
+ <head>
8
+ <title>#@name</title>
9
+ <base href="\#{context.host_url}/" />
10
+ <link rel="stylesheet" href="/system.css" type="text/css" media="screen" />
11
+ </head>
12
+ <body>
13
+ <h1>#@name</h1>
14
+ #{content}
15
+ <br />
16
+ Powered by <a href="http://www.nitrohq.com">Nitro</a> version #{Nitro::Version}
17
+ </body>
18
+ </html>
19
+ ~
20
+ end
21
+ end
@@ -0,0 +1,9 @@
1
+ <SystemPage name="System">
2
+ <table>
3
+ <?r for c in @classes ?>
4
+ <tr>
5
+ <td><a href="#@base/#{c.name.plural.underscore}">#{c.name}</a> (#{c.count})</td>
6
+ </tr>
7
+ <?r end ?>
8
+ </table>
9
+ </SystemPage>