nitro 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. data/AUTHORS +8 -0
  2. data/ChangeLog +1546 -0
  3. data/LICENCE +32 -0
  4. data/README +278 -0
  5. data/RELEASES +7 -0
  6. data/Rakefile +79 -0
  7. data/bin/cluster.rb +219 -0
  8. data/doc/architecture.txt +28 -0
  9. data/doc/bugs.txt +7 -0
  10. data/doc/css.txt +20 -0
  11. data/doc/ideas.txt +120 -0
  12. data/doc/pg.txt +47 -0
  13. data/doc/svn.txt +82 -0
  14. data/doc/todo.txt +30 -0
  15. data/etc/new-project.rb +18 -0
  16. data/examples/simple/README +15 -0
  17. data/examples/simple/app.rb +31 -0
  18. data/examples/simple/conf/apache.conf +100 -0
  19. data/examples/simple/conf/config.rb +89 -0
  20. data/examples/simple/conf/debug-config.rb +53 -0
  21. data/examples/simple/conf/live-config.rb +48 -0
  22. data/examples/simple/conf/overrides.rb +9 -0
  23. data/examples/simple/conf/requires.rb +51 -0
  24. data/examples/simple/ctl +32 -0
  25. data/examples/simple/env.rb +33 -0
  26. data/examples/simple/install.rb +12 -0
  27. data/examples/simple/lib/articles/entities.rb +35 -0
  28. data/examples/simple/lib/articles/lc-en.rb +36 -0
  29. data/examples/simple/lib/articles/methods.rb +55 -0
  30. data/examples/simple/lib/articles/part.rb +58 -0
  31. data/examples/simple/logs/access_log +2 -0
  32. data/examples/simple/logs/apache.log +3 -0
  33. data/examples/simple/logs/app.log +1 -0
  34. data/examples/simple/logs/events.log +1 -0
  35. data/examples/simple/root/add-article.sx +15 -0
  36. data/examples/simple/root/article-form.ss +20 -0
  37. data/examples/simple/root/comments-form.ss +16 -0
  38. data/examples/simple/root/comments.si +30 -0
  39. data/examples/simple/root/index.sx +44 -0
  40. data/examples/simple/root/shader/shader.xsl +100 -0
  41. data/examples/simple/root/shader/style.css +9 -0
  42. data/examples/simple/root/view-article.sx +30 -0
  43. data/examples/tiny/app.rb +30 -0
  44. data/examples/tiny/conf/apache.conf +100 -0
  45. data/examples/tiny/conf/config.rb +67 -0
  46. data/examples/tiny/conf/requires.rb +40 -0
  47. data/examples/tiny/ctl +31 -0
  48. data/examples/tiny/logs/access_log +9 -0
  49. data/examples/tiny/logs/apache.log +9 -0
  50. data/examples/tiny/root/index.sx +35 -0
  51. data/lib/n/app/cluster.rb +219 -0
  52. data/lib/n/app/cookie.rb +86 -0
  53. data/lib/n/app/filters/autologin.rb +50 -0
  54. data/lib/n/app/fragment.rb +67 -0
  55. data/lib/n/app/handlers.rb +120 -0
  56. data/lib/n/app/handlers/code-handler.rb +184 -0
  57. data/lib/n/app/handlers/page-handler.rb +612 -0
  58. data/lib/n/app/request-part.rb +59 -0
  59. data/lib/n/app/request.rb +653 -0
  60. data/lib/n/app/script.rb +398 -0
  61. data/lib/n/app/server.rb +53 -0
  62. data/lib/n/app/session.rb +224 -0
  63. data/lib/n/app/user.rb +47 -0
  64. data/lib/n/app/webrick-servlet.rb +213 -0
  65. data/lib/n/app/webrick.rb +70 -0
  66. data/lib/n/application.rb +187 -0
  67. data/lib/n/config.rb +31 -0
  68. data/lib/n/db.rb +217 -0
  69. data/lib/n/db/README +232 -0
  70. data/lib/n/db/connection.rb +369 -0
  71. data/lib/n/db/make-release.sh +26 -0
  72. data/lib/n/db/managed.rb +235 -0
  73. data/lib/n/db/mixins.rb +282 -0
  74. data/lib/n/db/mysql.rb +342 -0
  75. data/lib/n/db/psql.rb +378 -0
  76. data/lib/n/db/tools.rb +110 -0
  77. data/lib/n/db/utils.rb +99 -0
  78. data/lib/n/events.rb +118 -0
  79. data/lib/n/l10n.rb +22 -0
  80. data/lib/n/logger.rb +33 -0
  81. data/lib/n/macros.rb +53 -0
  82. data/lib/n/mixins.rb +46 -0
  83. data/lib/n/parts.rb +154 -0
  84. data/lib/n/properties.rb +194 -0
  85. data/lib/n/server.rb +61 -0
  86. data/lib/n/server/PLAYBACK.txt +8 -0
  87. data/lib/n/server/RESEARCH.txt +13 -0
  88. data/lib/n/server/filter.rb +77 -0
  89. data/lib/n/shaders.rb +167 -0
  90. data/lib/n/sitemap.rb +188 -0
  91. data/lib/n/std.rb +69 -0
  92. data/lib/n/sync/clc.rb +108 -0
  93. data/lib/n/sync/handler.rb +221 -0
  94. data/lib/n/sync/server.rb +170 -0
  95. data/lib/n/tools/README +11 -0
  96. data/lib/n/ui/date-select.rb +74 -0
  97. data/lib/n/ui/pager.rb +187 -0
  98. data/lib/n/ui/popup.rb +45 -0
  99. data/lib/n/ui/select.rb +41 -0
  100. data/lib/n/ui/tabs.rb +34 -0
  101. data/lib/n/utils/array.rb +92 -0
  102. data/lib/n/utils/cache.rb +144 -0
  103. data/lib/n/utils/gfx.rb +108 -0
  104. data/lib/n/utils/hash.rb +148 -0
  105. data/lib/n/utils/html.rb +147 -0
  106. data/lib/n/utils/http.rb +98 -0
  107. data/lib/n/utils/mail.rb +28 -0
  108. data/lib/n/utils/number.rb +31 -0
  109. data/lib/n/utils/pool.rb +66 -0
  110. data/lib/n/utils/string.rb +297 -0
  111. data/lib/n/utils/template.rb +38 -0
  112. data/lib/n/utils/time.rb +91 -0
  113. data/lib/n/utils/uri.rb +193 -0
  114. data/lib/xsl/base.xsl +205 -0
  115. data/lib/xsl/ce.xsl +30 -0
  116. data/lib/xsl/localization.xsl +23 -0
  117. data/lib/xsl/xforms.xsl +26 -0
  118. data/test/run.rb +95 -0
  119. metadata +187 -0
@@ -0,0 +1,70 @@
1
+ # = Webrick AppServer
2
+ #
3
+ # Used temporarily unitl we build our own app server.
4
+ #
5
+ # code:: gmosx, elathan
6
+ #
7
+ # (c) 2004 Navel, all rights reserved.
8
+ # $Id: webrick.rb 71 2004-10-18 10:50:22Z gmosx $
9
+
10
+ require "drb"
11
+ require "cgi"
12
+ require "webrick"
13
+
14
+ require "n/logger"
15
+ require "n/application"
16
+ require "n/app/server"
17
+ require "n/app/webrick-servlet"
18
+
19
+ module N; module App
20
+
21
+ # = Webrick AppServer
22
+ #
23
+ # The Application Server. Handles dynamic requests in a web application.
24
+ # Dont keepalive (or use a VERY SMALL keepalive). Typically this server
25
+ # is used along with a standard http server that handles other resources.
26
+ #
27
+ class Webrick < N::Server
28
+ include N::App::ServerMixin
29
+ include WEBrick
30
+
31
+ attr_accessor :webrick
32
+
33
+ def initialize(name = "WebrickServer")
34
+ super
35
+ initialize_app()
36
+ end
37
+
38
+ def start
39
+ accesslog = WEBrick::BasicLog::new("/dev/null")
40
+ referer = WEBrick::BasicLog::new("/dev/null")
41
+
42
+ @webrick = HTTPServer.new(
43
+ :BindAddress => $appsrv_address,
44
+ :Port => $appsrv_port,
45
+ :DirectoryIndex => ["index.sx"],
46
+ # gmosx, FIXME: this shit still logs!!
47
+ :Logger => Log.new(nil, WEBrick::Log::WARN),
48
+ # elathan: amateur...
49
+ :AccessLog => [
50
+ [accesslog, AccessLog::COMMON_LOG_FORMAT],
51
+ [referer, AccessLog::REFERER_LOG_FORMAT]
52
+ ]
53
+ )
54
+
55
+ @webrick.mount("/", N::App::WebrickServlet)
56
+
57
+ trap("INT") {
58
+ @webrick.shutdown()
59
+ }
60
+
61
+ @webrick.start()
62
+ end
63
+
64
+ def stop
65
+ @webrick.stop
66
+ end
67
+
68
+ end
69
+
70
+ end; end # module
@@ -0,0 +1,187 @@
1
+ # = Application
2
+ #
3
+ # code: gmosx, ekarak, drak, elathan
4
+ #
5
+ # (c) 2004 Navel, all rights reserved.
6
+ # $Id: application.rb 71 2004-10-18 10:50:22Z gmosx $
7
+
8
+ require 'optparse'
9
+ require 'ostruct'
10
+
11
+ require "n/logger"
12
+ require "n/std"
13
+
14
+ module N
15
+
16
+ # == Application
17
+ #
18
+ # the default Application object of the Framework.
19
+ #
20
+ class Application
21
+ # credentials of the application
22
+ attr_accessor :name, :title, :description, :version
23
+
24
+ # the status of the application
25
+ # use symbols to denote status.
26
+ # valid status symbols:
27
+ # * :run = The server is running
28
+ # * :stop = The server is stopped
29
+ attr_accessor :status
30
+
31
+ # startup time of the application
32
+ attr_accessor :create_time
33
+
34
+ attr_reader :daemonized
35
+
36
+ # the pid of the application
37
+ attr_reader :pid, :pidfile
38
+
39
+ #
40
+ #
41
+ def initialize(name = "Unknown")
42
+ @name = name
43
+ @pidfile = "/tmp/#{@name}.pid"
44
+ @create_time = Time.now()
45
+ @status = :stop
46
+ end
47
+
48
+ # FIXME: deleting of arguments is wrong, recode
49
+ # this using GETOPT.
50
+ #
51
+ def parse_arguments(args = ARGV)
52
+
53
+ opts = OptionParser.new { |opts|
54
+ opts.banner = "Usage: application.rb [action]"
55
+
56
+ opts.separator ""
57
+ opts.separator "Specific options:"
58
+
59
+ opts.on("-s", "--start",
60
+ "Start Navel's Application Server.") {
61
+ start()
62
+ }
63
+
64
+ opts.on("-S", "--stop",
65
+ "Stop Navel's Application Server.") {
66
+ stop()
67
+ }
68
+
69
+ opts.on("-r", "--restart",
70
+ "Restart Navel's Application Server.") {
71
+ restart()
72
+ }
73
+
74
+ opts.on("-d", "--daemon",
75
+ "Run Navel's Application Server as a daemon.") {
76
+ daemonize()
77
+ start()
78
+ }
79
+
80
+ opts.on_tail("-?", "--help", "Show this message.") {
81
+ puts opts
82
+ exit
83
+ }
84
+ }
85
+ begin
86
+ opts.parse!(args)
87
+ rescue => ex
88
+ puts ex
89
+ puts "Please, either specify a valid option or invoke the usage using -? or --help."
90
+ end
91
+ end
92
+ alias_method :exec, :parse_arguments
93
+
94
+ #
95
+ #
96
+ def start()
97
+ raise "Application allready started!" unless :stop == @status
98
+
99
+ begin
100
+ run()
101
+ rescue => ex
102
+ puts ex
103
+ end
104
+
105
+ # to allow for chaining
106
+ return self
107
+ end
108
+
109
+ # Override to properly restart the application
110
+ #
111
+ def restart()
112
+ stop()
113
+ start()
114
+
115
+ # to allow for chaining
116
+ return self
117
+ end
118
+
119
+ # Stop the application. Typically kills ths application daemon.
120
+ #
121
+ def stop
122
+ if dpid = daemon_pid()
123
+ begin
124
+ File.delete(@pidfile)
125
+ Process.kill("SIGKILL", dpid)
126
+ $log.info "Successfully killed #{@name} instance, pid=#{dpid}"
127
+ rescue => ex
128
+ $log.error "Cannot kill #{@name} instance, pid=#{dpid}"
129
+ $log.error ex
130
+ end
131
+ else
132
+ $log.error "Cannot locate pid of running instance!"
133
+ end
134
+
135
+ # to allow for chaining
136
+ return self
137
+ end
138
+
139
+ # Begin the application loop.
140
+ # Override this method in your application.
141
+ #
142
+ def run
143
+ # to allow for chaining
144
+ return self
145
+ end
146
+
147
+ # Run the application as a daemon
148
+ # FIXME: handle logging for daemons.
149
+ # ???: How does this work !?!?
150
+ #
151
+ def daemonize
152
+ unless @daemonized
153
+ trap "SIGCLD", "IGNORE"
154
+
155
+ pid = fork()
156
+
157
+ if pid # parent process
158
+ @pid = pid
159
+ File.open(@pidfile, 'w') {|f| f << "#{pid}\n" }
160
+ exit!
161
+ else # child
162
+ $log.info "Daemon for '#{@name}', process id: #{Process.pid}"
163
+ end
164
+
165
+ # change process group and lose control tty
166
+ Process.setpgrp()
167
+ end
168
+
169
+ @daemonized = true
170
+
171
+ return self
172
+ end
173
+
174
+ # Returns the pid of the running daemon
175
+ #
176
+ def daemon_pid()
177
+ begin
178
+ return File.open(@pidfile).read.chomp.to_i
179
+ rescue
180
+ $log.info "Could not read pid from #{@pidfile}"
181
+ return nil
182
+ end
183
+ end
184
+ end
185
+
186
+ end # module
187
+
@@ -0,0 +1,31 @@
1
+ # = Config
2
+ #
3
+ # Configuration
4
+ #
5
+ # code:
6
+ # George Moschovitis <gm@navel.gr>
7
+ #
8
+ # (c) 2004 Navel, all rights reserved.
9
+ # $Id: config.rb 89 2004-10-20 12:55:58Z gmosx $
10
+
11
+ $srv_name = "Nitro"
12
+ $srv_version = "0.1.2"
13
+
14
+ $srv_monitor_scripts = true
15
+ $srv_default_file = "index.sx"
16
+ $srv_autologin_expires = 60*60*24*30
17
+
18
+ # session timeout (in seconds)
19
+ $srv_session_timeout = 35*60
20
+
21
+ # session timeout for anonymous user (in seconds)
22
+ $srv_anon_session_timeout = 30*60
23
+
24
+ # enable distributed state?
25
+ $drb_state = false
26
+
27
+ # use the default error page.
28
+ $error_page_url = nil
29
+
30
+ # default encoding for the app.
31
+ $conf_encoding = "iso-8859-1"
@@ -0,0 +1,217 @@
1
+ # = Database
2
+ #
3
+ # An efficient, yet simple Object-Relational Mapper.
4
+ #
5
+ # === Design
6
+ #
7
+ # Keep this class backend agnostic. Put backend specific code in
8
+ # the Connection / Managed class.
9
+ #
10
+ # Try to make the methods work with oids. We do keep
11
+ # a unified id space. Include the N::Sequenced Marker to
12
+ # denote custom id space.
13
+ # Do NOT implement descendants use a root id (rid).
14
+ #
15
+ # For class ids we use the name instead of a hash. Class ids are
16
+ # typically not used in querys, they are stored for completeness.
17
+ # If we store a hash we cannot reclaim the class thus invalidating
18
+ # the point. Instead of .name(), to_s() is used so the methods
19
+ # are more flexible (they accept class names too!!)
20
+ #
21
+ # === WARNING:
22
+ #
23
+ # When creating a new db exec the following:
24
+ # CREATE SEQUENCE oids_seq;
25
+ #
26
+ # or
27
+ #
28
+ # DbTools.create_oids_seq
29
+ #
30
+ #
31
+ # === Todo
32
+ #
33
+ # - support caching
34
+ # - support prepared statements
35
+ # - foreign keys (delete cascade)
36
+ # - keep attribudes as marshaled!!
37
+ #
38
+ # code:
39
+ # George Moschovitis <gm@navel.gr>
40
+ #
41
+ # (c) 2004 Navel, all rights reserved.
42
+ # $Id: db.rb 79 2004-10-18 16:38:19Z gmosx $
43
+
44
+ module N;
45
+
46
+ require "n/properties"
47
+ require "n/utils/array"
48
+ require "n/utils/time"
49
+ require "n/utils/pool"
50
+
51
+ require "n/db/utils"
52
+ require "n/db/managed"
53
+ require "n/db/connection"
54
+ require "n/db/mixins"
55
+
56
+ # Configuration
57
+
58
+ # if true, enables the read only mode
59
+ $db_read_only_mode = false
60
+
61
+ # = Database
62
+ #
63
+ # === Design:
64
+ #
65
+ # - This is NOT a singleton, an application may access multiple
66
+ # databases.
67
+ #
68
+ class Db
69
+ # hash of configuration options.
70
+ attr_accessor :config
71
+
72
+ # Pool of connections to the backend.
73
+ attr_accessor :pool
74
+
75
+ # Entities cache.
76
+ attr_accessor :cache
77
+
78
+ # Managed classes fields. A hash of hashes.
79
+ attr_accessor :fields
80
+
81
+ # Initialize the database interface.
82
+ #
83
+ def initialize(config)
84
+ @config = config
85
+
86
+ if backend = config[:backend]
87
+ require "n/db/#{backend}"
88
+ else
89
+ require "n/db/psql"
90
+ end
91
+
92
+ $log.info "Connecting to database '#{config[:database]}'."
93
+
94
+ @pool = N::Pool.new
95
+ @fields = N::SafeHash.new
96
+
97
+ for i in (0...config[:connection_count])
98
+ @pool << DbConnection.new(config)
99
+ end
100
+ end
101
+
102
+ # Shutdown the database interface.
103
+ #
104
+ def shutdown
105
+ for con in @pool
106
+ con.close()
107
+ end
108
+ end
109
+ alias_method :close, :shutdown
110
+
111
+ # Get a connection from the pool to access the database.
112
+ #
113
+ def get_connection
114
+ return @pool.pop()
115
+ end
116
+
117
+ # Restore an unused connection to the pool.
118
+ #
119
+ def put_connection(connection)
120
+ return @pool.push(connection)
121
+ end
122
+
123
+ # Utility method, automatically restores a connection to the pool.
124
+ #
125
+ def connect(deserialize = nil, &block)
126
+ result = nil
127
+
128
+ begin
129
+ db = @pool.pop()
130
+ db.deserialize = deserialize unless deserialize.nil?
131
+
132
+ result = yield(db)
133
+
134
+ db.deserialize = true
135
+ ensure
136
+ @pool.push(db)
137
+ end
138
+
139
+ return result
140
+ end
141
+ alias_method :open, :connect
142
+
143
+ # Utility method, gets connection and encloses in transaction.
144
+ #
145
+ def transaction(deserialize = nil, &block)
146
+ result = nil
147
+
148
+ begin
149
+ db = @pool.pop()
150
+ db.deserialize = deserialize if deserialize
151
+
152
+ db.start()
153
+ result = yield(db)
154
+ db.commit()
155
+
156
+ db.deserialize = true
157
+ ensure
158
+ @pool.push(db)
159
+ end
160
+
161
+ return result
162
+ end
163
+
164
+ # Utility method, creates an entity from a row
165
+ #
166
+ def entity_from_row(row, klass)
167
+ entity = klass.new()
168
+ entity.__db_read_row__(row)
169
+ return entity
170
+ end
171
+
172
+ private
173
+
174
+ # Automatically wrap connection methods.
175
+ #
176
+ def self.wrap_method(method, args)
177
+ args = args.split(/,/)
178
+ class_eval %{
179
+ def #{method}(#{args.join(", ")})
180
+ begin
181
+ db = @pool.pop()
182
+ res = db.#{method}(#{args.collect {|a| a.split(/=/)[0]}.join(", ")})
183
+ ensure
184
+ @pool.push(db)
185
+ end
186
+ return res
187
+ end
188
+ }
189
+ end
190
+
191
+ wrap_method :put, "entity"
192
+ alias_method :<<, :put
193
+ wrap_method :insert, "obj"
194
+ wrap_method :update, "obj"
195
+ wrap_method :update_properties, "update_sql, ent_or_oid, klass = nil"
196
+ wrap_method :pupdate, "update_sql, ent_or_oid, klass = nil"
197
+ wrap_method :get, "oid, klass"
198
+ wrap_method :get_by_oid, "oid, klass"
199
+ wrap_method :get_by_name, "name, klass"
200
+ wrap_method :get_all, "klass, extrasql = nil"
201
+ wrap_method :select, "sql, klass, join_fields = nil"
202
+ wrap_method :select_one, "sql, klass, join_fields = nil"
203
+ wrap_method :child, "entity, klass, extrasql = nil"
204
+ wrap_method :children, "entity, klass, extrasql = nil"
205
+ wrap_method :count_children, "entity, klass, extrasql = nil"
206
+ wrap_method :delete, "entity, klass = nil, cascade = true"
207
+ wrap_method :query, "sql"
208
+ wrap_method :query_one, "sql"
209
+ wrap_method :count, "sql"
210
+ wrap_method :match, "sql"
211
+ wrap_method :exec, "sql"
212
+ wrap_method :exec_and_clear, "sql"
213
+ wrap_method :exec_clear, "sql"
214
+ end
215
+
216
+ end # module
217
+