nitro 0.29.0 → 0.30.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/CHANGELOG +410 -0
  2. data/ProjectInfo +36 -44
  3. data/README +5 -5
  4. data/doc/AUTHORS +6 -0
  5. data/doc/RELEASES +159 -2
  6. data/lib/glue/sweeper.rb +2 -2
  7. data/lib/glue/webfile.rb +14 -1
  8. data/lib/nitro.rb +6 -9
  9. data/lib/nitro/adapter/mongrel.rb +36 -43
  10. data/lib/nitro/adapter/scgi.rb +1 -1
  11. data/lib/nitro/adapter/webrick.rb +96 -24
  12. data/lib/nitro/caching/actions.rb +2 -1
  13. data/lib/nitro/caching/fragments.rb +1 -8
  14. data/lib/nitro/caching/output.rb +14 -4
  15. data/lib/nitro/cgi.rb +19 -21
  16. data/lib/nitro/cgi/cookie.rb +5 -1
  17. data/lib/nitro/cgi/request.rb +20 -4
  18. data/lib/nitro/compiler.rb +74 -28
  19. data/lib/nitro/compiler/cleanup.rb +1 -1
  20. data/lib/nitro/compiler/elements.rb +1 -2
  21. data/lib/nitro/compiler/localization.rb +1 -1
  22. data/lib/nitro/compiler/markup.rb +1 -1
  23. data/lib/nitro/compiler/script.rb +52 -44
  24. data/lib/nitro/compiler/squeeze.rb +4 -3
  25. data/lib/nitro/compiler/xslt.rb +7 -6
  26. data/lib/nitro/context.rb +39 -20
  27. data/lib/nitro/controller.rb +24 -5
  28. data/lib/nitro/dispatcher.rb +13 -5
  29. data/lib/nitro/global.rb +63 -0
  30. data/lib/nitro/helper/feed.rb +432 -0
  31. data/lib/nitro/helper/form.rb +11 -3
  32. data/lib/nitro/helper/form/builder.rb +140 -0
  33. data/lib/nitro/helper/form/controls.rb +2 -1
  34. data/lib/nitro/helper/javascript.rb +6 -0
  35. data/lib/nitro/helper/javascript/morphing.rb +13 -6
  36. data/lib/nitro/helper/xhtml.rb +42 -6
  37. data/lib/nitro/helper/xml.rb +3 -0
  38. data/lib/nitro/part.rb +2 -2
  39. data/lib/nitro/render.rb +7 -2
  40. data/lib/nitro/router.rb +57 -16
  41. data/lib/nitro/scaffolding.rb +29 -20
  42. data/lib/nitro/server.rb +4 -10
  43. data/lib/nitro/server/drb.rb +1 -1
  44. data/lib/nitro/server/runner.rb +10 -0
  45. data/lib/nitro/session.rb +31 -12
  46. data/lib/nitro/session/drb.rb +13 -1
  47. data/lib/nitro/session/file.rb +1 -1
  48. data/lib/nitro/session/memcached.rb +1 -1
  49. data/lib/nitro/session/memory.rb +1 -1
  50. data/lib/nitro/session/og.rb +1 -1
  51. data/lib/nitro/test/testcase.rb +3 -0
  52. data/proto/public/error.xhtml +5 -5
  53. data/proto/public/js/controls.js +2 -2
  54. data/proto/public/js/dragdrop.js +320 -79
  55. data/proto/public/js/effects.js +200 -152
  56. data/proto/public/js/prototype.js +284 -63
  57. data/proto/public/js/scriptaculous.js +7 -5
  58. data/proto/public/js/unittest.js +11 -0
  59. data/proto/public/scaffold/advanced_search.xhtml +30 -0
  60. data/proto/public/scaffold/list.xhtml +8 -1
  61. data/proto/public/scaffold/search.xhtml +2 -1
  62. data/proto/script/scgi_service +1 -1
  63. data/src/part/admin/controller.rb +1 -1
  64. data/src/part/admin/skin.rb +1 -1
  65. data/test/nitro/CONFIG.rb +3 -0
  66. data/test/nitro/adapter/tc_webrick.rb +1 -1
  67. data/test/nitro/cgi/tc_cookie.rb +1 -1
  68. data/test/nitro/cgi/tc_request.rb +5 -5
  69. data/test/nitro/compiler/tc_client_morpher.rb +47 -0
  70. data/test/nitro/compiler/tc_compiler.rb +2 -0
  71. data/test/nitro/helper/tc_feed.rb +138 -0
  72. data/test/nitro/helper/tc_pager.rb +1 -1
  73. data/test/nitro/helper/tc_rss.rb +1 -1
  74. data/test/nitro/helper/tc_table.rb +1 -1
  75. data/test/nitro/helper/tc_xhtml.rb +1 -1
  76. data/test/nitro/tc_caching.rb +1 -1
  77. data/test/nitro/tc_cgi.rb +1 -1
  78. data/test/nitro/tc_context.rb +1 -1
  79. data/test/nitro/tc_controller.rb +31 -3
  80. data/test/nitro/tc_controller_aspect.rb +1 -1
  81. data/test/nitro/tc_dispatcher.rb +1 -1
  82. data/test/nitro/tc_element.rb +1 -1
  83. data/test/nitro/tc_flash.rb +1 -1
  84. data/test/nitro/tc_helper.rb +1 -1
  85. data/test/nitro/tc_render.rb +6 -6
  86. data/test/nitro/tc_router.rb +8 -4
  87. data/test/nitro/tc_server.rb +1 -3
  88. data/test/nitro/tc_session.rb +1 -3
  89. metadata +107 -104
  90. data/Rakefile +0 -232
  91. data/lib/nitro/adapter/acgi.rb +0 -237
  92. data/proto/public/Makefile.acgi +0 -40
  93. data/proto/public/acgi.c +0 -138
data/Rakefile DELETED
@@ -1,232 +0,0 @@
1
- require 'rake/rdoctask'
2
- require 'rake/testtask'
3
- require 'rake/gempackagetask'
4
-
5
- # Initialize some variables.
6
-
7
- readme = File.read('README')
8
- Release = (readme[/^= (.+) README$/, 1] || 'unknown').downcase.tr(" ", "-")
9
- Name = Release[/\D+/].sub(/\-+$/, '') || 'unknown'
10
- Version = Release[/[\d.]+/] || 'unknown'
11
-
12
- AuthorName, AuthorMail = 'George Moschovitis', 'gm@navel.gr'
13
- RubyVersion = '1.8.3'
14
-
15
- # Description = (readme[/README\s+(.+?)\n\n/m, 1] || "unknown").gsub(/\s+/, " ")
16
- # Summary = Description[/^.+?>/] || "unknown"
17
-
18
- # DocFiles = %w(README NEWS TODO COPYING GPL)
19
- # RDocFiles = DocFiles - %w(GPL)
20
- RDocOpts = ["--inline-source", "--line-numbers","--title", Name ]
21
- # AdditionalFiles = DocFiles + %w(setup.rb)
22
- VersionFile = MainFile = File.join("lib", Name + '.rb')
23
-
24
- RubyForgeProject = Name
25
- RubyForgeUser = 'gmosx'
26
- Homepage = "http://www.nitrohq.org/"
27
-
28
- task :default => :package
29
-
30
- $NITRO_NO_ENVIRONMENT = true
31
-
32
- # Run the tests.
33
-
34
- Rake::TestTask.new do |t|
35
- cwd = File.expand_path(File.join(File.dirname(__FILE__), '..'))
36
- t.libs << 'test'
37
- %w[glue nitro og].each do |dir|
38
- t.libs << File.join(cwd, dir, 'lib')
39
- end
40
- t.test_files = FileList['test/**/tc*.rb']
41
- t.verbose = true
42
- end
43
-
44
- # Generate RDoc documentation.
45
-
46
- Rake::RDocTask.new do |rd|
47
- rd.main = 'README'
48
- rd.rdoc_dir = 'rdoc'
49
- rd.rdoc_files.include('README', 'INSTALL', 'doc/RELEASES', 'lib/**/*.rb')
50
- rd.options << '--all --inline-source'
51
- end
52
-
53
- # Build gem.
54
-
55
- spec = Gem::Specification.new do |s|
56
- s.name = 'nitro'
57
- if File.read('lib/nitro.rb') =~ /Version\s+=\s+'(\d+\.\d+\.\d+)'/
58
- s.version = $1
59
- else
60
- raise 'No version found'
61
- end
62
- s.summary = 'Nitro Web Engine'
63
- s.description =
64
- 'Nitro provides everything you need to develop real-world, scalable ' +
65
- 'web applications.'
66
-
67
- s.add_dependency 'glue', "= #{s.version}"
68
- s.add_dependency 'og', "= #{s.version}"
69
- s.add_dependency 'gen', "= #{s.version}"
70
- s.add_dependency 'ruby-breakpoint', '= 0.5'
71
- s.add_dependency 'RedCloth', '= 3.0.3'
72
-
73
- s.required_ruby_version = '= 1.8.3'
74
-
75
- s.files = FileList[
76
- '[A-Z]*', 'setup.rb', '{bin,benchmark,examples,doc,proto,lib,test,vendor}/**/*'
77
- ].exclude("_darcs").exclude("_darcs/**/*").exclude('*.og').exclude('**/*.log').to_a
78
-
79
- s.require_path = 'lib'
80
- s.autorequire = 'nitro'
81
-
82
- s.has_rdoc = true
83
- s.extra_rdoc_files = FileList['[A-Z]*'].to_a
84
- s.rdoc_options << '--main' << 'README' << '--title' << 'Nitro Documentation'
85
- s.rdoc_options << '--all' << '--inline-source'
86
-
87
- s.test_files = []
88
-
89
- s.bindir = 'bin'
90
- s.executables = ['nitro', 'nitrogen']
91
- s.default_executable = 'nitro'
92
-
93
- s.author = 'George Moschovitis'
94
- s.email = 'gm@navel.gr'
95
- s.homepage = 'http://www.nitrohq.com'
96
- s.rubyforge_project = 'nitro'
97
- end
98
-
99
- Rake::GemPackageTask.new(spec) do |pkg|
100
- pkg.package_dir = 'dist'
101
- pkg.need_zip = true
102
- pkg.need_tar = true
103
- end
104
-
105
- # Manual install (not recommended).
106
-
107
- task :install do
108
- ruby 'install.rb'
109
- end
110
-
111
- # Release files to Rubyforge.
112
- # The code for this task provided by Florian Gross.
113
-
114
- desc "Publish the release files to RubyForge."
115
- task :publish => [:package] do
116
- files = ['gem', 'tgz', 'zip'].map { |ext| "dist/#{Release}.#{ext}" }
117
-
118
- if RubyForgeProject then
119
- require 'net/http'
120
- require 'open-uri'
121
-
122
- changes = ''
123
- if File.exist?('doc/RELEASES') then
124
- changes_re = /^== \s+ Version \s+ #{Regexp.quote(Version)} \s*
125
- (.+?) (?:==|\Z)/mx
126
- changes = File.read('doc/RELEASES')[changes_re, 1] || ''
127
- end
128
-
129
- project_uri = "http://rubyforge.org/projects/#{RubyForgeProject}/"
130
- project_data = open(project_uri) { |data| data.read }
131
- group_id = project_data[/[?&]group_id=(\d+)/, 1]
132
- raise "Couldn't get group id" unless group_id
133
-
134
- print "#{RubyForgeUser}@rubyforge.org's password: "
135
- password = STDIN.gets.chomp
136
-
137
- login_response = Net::HTTP.start('rubyforge.org', 80) do |http|
138
- data = [
139
- "login=1",
140
- "form_loginname=#{RubyForgeUser}",
141
- "form_pw=#{password}"
142
- ].join("&")
143
- http.post('/account/login.php', data)
144
- end
145
-
146
- cookie = login_response['set-cookie']
147
- raise 'Login failed' unless cookie
148
- headers = { 'Cookie' => cookie }
149
-
150
- release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}"
151
- release_data = open(release_uri, headers) { |data| data.read }
152
- package_id = release_data[/[?&]package_id=(\d+)/, 1]
153
- raise "Couldn't get package id" unless package_id
154
-
155
- first_file = true
156
- release_id = ""
157
-
158
- files.each do |filename|
159
- basename = File.basename(filename)
160
- file_ext = File.extname(filename)
161
- file_data = File.open(filename, "rb") { |file| file.read }
162
-
163
- puts "Releasing #{basename}..."
164
-
165
- release_response = Net::HTTP.start('rubyforge.org', 80) do |http|
166
- release_date = Time.now.strftime('%Y-%m-%d %H:%M')
167
- type_map = {
168
- '.zip' => '3000',
169
- '.tgz' => '3110',
170
- '.gz' => '3110',
171
- '.gem' => '1400',
172
- '.md5sum' => '8100'
173
- }; type_map.default = '9999'
174
- type = type_map[file_ext]
175
- boundary = 'rubyqMY6QN9bp6e4kS21H4y0zxcvoor'
176
-
177
- query_hash = if first_file then
178
- {
179
- 'group_id' => group_id,
180
- 'package_id' => package_id,
181
- 'release_name' => Release,
182
- 'release_date' => release_date,
183
- 'type_id' => type,
184
- 'processor_id' => '8000', # Any
185
- 'release_notes' => '',
186
- 'release_changes' => changes,
187
- 'preformatted' => '1',
188
- 'submit' => '1'
189
- }
190
- else
191
- {
192
- 'group_id' => group_id,
193
- 'release_id' => release_id,
194
- 'package_id' => package_id,
195
- 'step2' => '1',
196
- 'type_id' => type,
197
- 'processor_id' => '8000', # Any
198
- 'submit' => 'Add This File'
199
- }
200
- end
201
-
202
- query = '?' + query_hash.map do |(name, value)|
203
- [name, URI.encode(value)].join('=')
204
- end.join('&')
205
-
206
- data = [
207
- "--" + boundary,
208
- "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"",
209
- "Content-Type: application/octet-stream",
210
- "Content-Transfer-Encoding: binary",
211
- "", file_data, ""
212
- ].join("\x0D\x0A")
213
-
214
- release_headers = headers.merge(
215
- 'Content-Type' => "multipart/form-data; boundary=#{boundary}"
216
- )
217
-
218
- target = first_file ? '/frs/admin/qrs.php' : '/frs/admin/editrelease.php'
219
- http.post(target + query, data, release_headers)
220
- end
221
-
222
- if first_file then
223
- release_id = release_response.body[/release_id=(\d+)/, 1]
224
- raise("Couldn't get release id") unless release_id
225
- end
226
-
227
- first_file = false
228
- end
229
- end
230
- end
231
-
232
- # * George Moschovitis <gm@navel.gr>
@@ -1,237 +0,0 @@
1
- require 'cgi'
2
- require 'posixlock'
3
-
4
- STDOUT.sync = STDERR.sync = true
5
- $VERBOSE = nil
6
-
7
- require 'nitro/context'
8
- require 'nitro/dispatcher'
9
- require 'nitro/cgi'
10
-
11
- # Speeds things up, more comaptible with OSX.
12
-
13
- Socket.do_not_reverse_lookup = true
14
-
15
- # No multi-threading.
16
-
17
- Og.thread_safe = false if defined?(Og) and Og.respond_to?(:thread_safe)
18
-
19
- module Nitro
20
-
21
- # ACGI Adaptor. ACGI is a language independent,
22
- # scalable, open extension to CGI that provides high
23
- # performance without the limitations of server
24
- # specific APIs.
25
- #
26
- # This code is directly from the author. Please go to
27
- # http://codeforpeople.com/lib/ruby/acgi/ for more
28
- # information about ACGI.
29
- # or email: ara [dot] t [dot] howard [at] noaa [dot] gov
30
- #
31
- # It uses a compiled C cgi program to handle
32
- # connections compile the acgi.c by executing
33
- # "make -f Makefile.acgi" in your public/ folder.
34
- # then make your .htaccess redirect all calls to acgi.cgi
35
- # instead of fcgi.rb / cgi.rb
36
- #
37
- #--
38
- # gmosx: not tested! Use at your own risk!
39
- #++
40
-
41
- class ACGI < ::CGI
42
- THIS = File::expand_path $0
43
- COMMAND_LINE = [THIS, ARGV].join ' '
44
- LOADED = Time::now
45
- IPC_DIR = "/tmp/acgi_ipc"
46
- CLIENT_LOCK_PATH = File::join IPC_DIR, "client.lock"
47
- SERVER_LOCK_PATH = File::join IPC_DIR, "server.lock"
48
- SERVER_ENVIRONMENT_PATH = File::join IPC_DIR, "server.environment"
49
- SERVER_STDIN_PATH = File::join IPC_DIR, "server.stdin"
50
- SERVER_STDOUT_PATH = File::join IPC_DIR, "server.stdout"
51
- SERVER_STDERR_PATH = File::join IPC_DIR, "server.stderr"
52
- SERVER_PID_PATH = File::join IPC_DIR, "server.pid"
53
-
54
- RE_ENV = %r/^ ([^=]+) = (.*) $/ox
55
- RE_NUL = %r/#{ Regexp::escape "\0" }/ox
56
-
57
- SERVER = ENV['ACGI_SERVER'] || ARGV.delete('--server') || ARGV.delete('-s')
58
-
59
- if SERVER
60
- trap('HUP'){ exec ::ACGI::COMMAND_LINE }
61
- %w( INT KILL TERM ).each{|s| trap(s){ exit }}
62
- end
63
-
64
- class << self
65
- def each_cgi(*a, &b)
66
- if SERVER
67
- start_server(*a, &b)
68
- else
69
- munge_environment
70
- @cgi = new(*a)
71
- catching_errors{ b[ @cgi ] }
72
- end
73
- end
74
-
75
- def start_server(*a, &b)
76
- daemon do
77
- ENV.clear # __very__ important for speed!
78
- aquire_server_lock
79
- record_pid
80
- loop do
81
- load_environment
82
- munge_environment
83
- @cgi = redirecting_stdin{ new(*a) }
84
- redirecting_stdout_and_stderr{ catching_errors{ b[ @cgi ] }}
85
- restart_if_updated
86
- end
87
- end
88
- end
89
-
90
- def restart_if_updated
91
- # put the full path to your run.rb here if it doesn't work
92
- #th = "/path/to/app/run.rb"
93
- if File::stat(THIS).mtime > LOADED
94
- #if File::stat(th).mtime > LOADED
95
- exec COMMAND_LINE
96
- end
97
- end
98
-
99
- def aquire_server_lock
100
- lockfile = File.open(SERVER_LOCK_PATH)
101
- lockfile.reopen(SERVER_LOCK_PATH, 'w')
102
- at_exit{ lockfile.close }
103
- ret = lockfile.posixlock(File::LOCK_EX|File::LOCK_NB)
104
-
105
- raise("#{ File::basename $0 } already running..") if(!ret or !ret.zero?)
106
- end
107
-
108
- def record_pid
109
- begin
110
- f = File::open(SERVER_PID_PATH)
111
- f.reopen(SERVER_PID_PATH, 'w')
112
- f.print Process::pid
113
- f.chmod 0777 rescue nil
114
- ensure
115
- f.close
116
- end
117
- end
118
-
119
- def env_table
120
- SERVER ? (@environment ||= {}) : ENV
121
- end
122
-
123
- def env
124
- env_table
125
- end
126
-
127
- def load_environment
128
- begin
129
- f = File::open(SERVER_ENVIRONMENT_PATH)
130
- f.reopen(SERVER_ENVIRONMENT_PATH, "r")
131
- env_table.clear
132
- kvs = f.read.chop.split RE_NUL
133
- kvs.each do |kv|
134
- m = RE_ENV.match(kv)
135
- k, v = m[1], m[2]
136
- env_table[k] = v
137
- end
138
- ensure
139
- f.close
140
- end
141
- end
142
-
143
- def munge_environment # because CGI::Cookie::parse is broken!
144
- env_table['HTTP_COOKIE'] =
145
- munge_http_cookie env_table['HTTP_COOKIE']
146
- end
147
-
148
- def munge_http_cookie http_cookie
149
- return unless http_cookie
150
- kvs = http_cookie.split %r/[;,]\s+/o
151
- h = Hash::new{|h,k| h[k] = []}
152
- kvs.each do |kv|
153
- k, v = kv.split %r/=/o, 2
154
- next unless k
155
- k = CGI::unescape k
156
- vs = v.to_s.split(%r/&/).map{|v| CGI::unescape v}
157
- h[k].push(*vs)
158
- end
159
- h.sort.map{|k,vs| [k, vs.join('&')].join('=')}.join('; ')
160
- end
161
-
162
- def redirecting_stdin
163
- stdin = $stdin
164
- begin
165
- @stdin = File::open(SERVER_STDIN_PATH)
166
- @stdin.reopen(SERVER_STDIN_PATH, "r")
167
- $stdin = @stdin
168
- yield
169
- ensure
170
- @stdin.close if @stdin
171
- $stdin = stdin
172
- end
173
- end
174
-
175
- def redirecting_stdout_and_stderr
176
- stdout, stderr = $stdout, $stderr
177
- begin
178
- @stdout = File::open(SERVER_STDOUT_PATH)
179
- @stdout.reopen(SERVER_STDOUT_PATH, "w")
180
- @stderr = File::open(SERVER_STDERR_PATH)
181
- @stderr.reopen(SERVER_STDERR_PATH, "w")
182
- $stdout, $stderr = @stdout, @stderr
183
- yield
184
- ensure
185
- @stdout.close if @stdout
186
- @stderr.close if @stderr
187
- $stdout, $stderr = stdout, stderr
188
- end
189
- end
190
-
191
- def catching_errors
192
- @cgi ||= CGI::new
193
- begin
194
- yield
195
- rescue Exception => e
196
- m, c, b = e.message, e.class, e.backtrace.join("<br>\n")
197
- @cgi.out{ "<hr><b><i>#{ m } (#{ c })</b></i><hr><hr>#{ b }" }
198
- end
199
- end
200
-
201
- def daemon
202
- exit!(0) if fork
203
- Process::setsid
204
- exit!(0) if fork
205
- # Dir::chdir("/")
206
- # File::umask(0)
207
-
208
- # uncomment these if you don't want logs
209
- #STDIN.reopen("/dev/null")
210
- #STDOUT.reopen("/dev/null", "w")
211
- #STDERR.reopen("/dev/null", "w")
212
- yield if block_given?
213
- end
214
- end
215
-
216
- def env_table
217
- self::class.env_table
218
- end
219
- def env
220
- self::class.env
221
- end
222
-
223
- # use this to start the ACGI server.
224
-
225
- def self.start(server)
226
- ACGI.each_cgi do |cgi|
227
- begin
228
- Cgi.process(server, cgi, $stdin, $stdout)
229
- end
230
- end
231
- end
232
-
233
- end
234
-
235
- end
236
-
237
- # * Ara Howard <ara.t.howard@noaa.gov>