nitro 0.1.2

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