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,67 @@
1
+ # = Configuration
2
+ #
3
+ # === Design:
4
+ #
5
+ # Use a separate file for configuration, makes the
6
+ # main file more readable, and allows for reconfiguring
7
+ # (reload) the webapp without restarting the server.
8
+ #
9
+ # FIXME: redesign this!
10
+ #
11
+ # code: gmosx
12
+ #
13
+ # (c) 2004 Navel, all rights reserved.
14
+ # $Id: config.rb 90 2004-10-20 12:56:43Z gmosx $
15
+
16
+ require "n/std"
17
+ require "n/properties"
18
+ require "n/logger"
19
+ require "n/config"
20
+
21
+ $name = "Tiny"
22
+ $root_dir = "tiny/root"
23
+
24
+ # Main logger
25
+ $log = Logger.new(STDERR, 10);
26
+
27
+ $reload_scripts = $DBG
28
+
29
+ require "n/config"
30
+
31
+ require "tiny/conf/requires"
32
+
33
+ $srv_extension_map = {
34
+ "sx" => ["text/html",
35
+ N::App::PageHandler.new
36
+ ],
37
+ "si" => ["text/html",
38
+ N::App::PageHandler.new
39
+ ],
40
+ "rx" => ["text/html",
41
+ N::App::CodeHandler.new
42
+ ]
43
+ }
44
+
45
+ $appsrv_address = "127.0.0.1"
46
+ $appsrv_port = 9090
47
+ $srv_url = "http://127.0.0.1:8080"
48
+
49
+ module App
50
+
51
+ # Config
52
+ #
53
+ module Config
54
+
55
+ def initialize_sitemap
56
+ end
57
+
58
+ def initialize_shaders
59
+ $default_shader = N::NilShader.new
60
+ end
61
+
62
+ def initialize_events
63
+ end
64
+
65
+ end
66
+
67
+ end # module
@@ -0,0 +1,40 @@
1
+ # = Requires all needed files
2
+ #
3
+ # === Design:
4
+ #
5
+ # Collect all requires in one file includable
6
+ # in multiple executable scripts. Moreover, it
7
+ # makes the main script file more readable.
8
+ #
9
+ # === Ideas:
10
+ #
11
+ # - use load instead of require to make reloadable?
12
+ #
13
+ # code:
14
+ # George Moschovitis <gm@navel.gr>
15
+ #
16
+ # (c) 2004 Navel, all rights reserved.
17
+ # $Id: requires.rb 90 2004-10-20 12:56:43Z gmosx $
18
+
19
+ require "n/std"
20
+ require "n/properties"
21
+
22
+ require "n/db"
23
+ require "n/l10n"
24
+ require "n/logger"
25
+ require "n/parts"
26
+ require "n/events"
27
+ require "n/shaders"
28
+ require "n/mixins"
29
+ require "n/sitemap"
30
+
31
+ require "n/utils/number"
32
+ require "n/utils/string"
33
+ require "n/utils/gfx"
34
+ require "n/utils/html"
35
+ require "n/utils/hash"
36
+ require "n/utils/array"
37
+
38
+ require "n/app/handlers/page-handler"
39
+ require "n/app/handlers/code-handler"
40
+
@@ -0,0 +1,31 @@
1
+ #! /bin/sh
2
+
3
+ ARGV="$@"
4
+
5
+ case $ARGV in
6
+ start)
7
+ /usr/sbin/httpd -d `pwd` -f conf/apache.conf
8
+ ruby -C.. tiny/app.rb --start # --daemon
9
+ ERROR=$?
10
+ ;;
11
+ restart)
12
+ # restart appserver only!
13
+ export ASPID= `ps ax | grep app.rb | grep ruby | cut -d" " -f1`
14
+ if [ -n "$ASPID" ]; then
15
+ echo $ASPID
16
+ kill -9 $ASPID
17
+ fi
18
+ ruby -C.. tiny/app.rb --restart # --daemon
19
+ ERROR=$?
20
+ ;;
21
+ stop)
22
+ killall -9 ruby httpd
23
+ ERROR=$?
24
+ ;;
25
+ *)
26
+ echo "NOP"
27
+ ERROR=$?
28
+ esac
29
+
30
+ exit $ERROR
31
+
@@ -0,0 +1,9 @@
1
+ 127.0.0.1 - - [20/Oct/2004:16:50:12 +0300] "GET /favicon.ico HTTP/1.1" 404 209
2
+ 127.0.0.1 - - [20/Oct/2004:16:50:14 +0300] "GET /index.sx HTTP/1.1" 200 390
3
+ 127.0.0.1 - - [20/Oct/2004:16:50:14 +0300] "GET /favicon.ico HTTP/1.1" 404 209
4
+ 127.0.0.1 - - [20/Oct/2004:16:50:16 +0300] "GET /index.sx?name=dasdsa HTTP/1.1" 200 403
5
+ 127.0.0.1 - - [20/Oct/2004:16:50:17 +0300] "GET /favicon.ico HTTP/1.1" 404 209
6
+ 127.0.0.1 - - [20/Oct/2004:16:50:20 +0300] "GET /index.sx?name=dasdsa HTTP/1.1" 200 403
7
+ 127.0.0.1 - - [20/Oct/2004:16:50:20 +0300] "GET /favicon.ico HTTP/1.1" 404 209
8
+ 127.0.0.1 - - [20/Oct/2004:17:55:45 +0300] "GET / HTTP/1.1" 200 390
9
+ 127.0.0.1 - - [20/Oct/2004:17:55:45 +0300] "GET /favicon.ico HTTP/1.1" 404 209
@@ -0,0 +1,9 @@
1
+ [Wed Oct 20 16:50:06 2004] [warn] pid file /tmp/tiny-apache.pid overwritten -- Unclean shutdown of previous Apache run?
2
+ [Wed Oct 20 16:50:06 2004] [notice] Apache/2.0.50 (Fedora) configured -- resuming normal operations
3
+ [Wed Oct 20 16:50:12 2004] [error] [client 127.0.0.1] File does not exist: /navel/nitro/examples/tiny/root/favicon.ico
4
+ [Wed Oct 20 16:50:14 2004] [error] [client 127.0.0.1] File does not exist: /navel/nitro/examples/tiny/root/favicon.ico
5
+ [Wed Oct 20 16:50:17 2004] [error] [client 127.0.0.1] File does not exist: /navel/nitro/examples/tiny/root/favicon.ico
6
+ [Wed Oct 20 16:50:20 2004] [error] [client 127.0.0.1] File does not exist: /navel/nitro/examples/tiny/root/favicon.ico
7
+ [Wed Oct 20 17:55:39 2004] [warn] pid file /tmp/tiny-apache.pid overwritten -- Unclean shutdown of previous Apache run?
8
+ [Wed Oct 20 17:55:39 2004] [notice] Apache/2.0.50 (Fedora) configured -- resuming normal operations
9
+ [Wed Oct 20 17:55:45 2004] [error] [client 127.0.0.1] File does not exist: /navel/nitro/examples/tiny/root/favicon.ico
@@ -0,0 +1,35 @@
1
+ <?xml version="1.0"?>
2
+
3
+ <html>
4
+
5
+ <?r
6
+ # the code that populates the template comes here
7
+
8
+ unless name = request["name"]
9
+ name = "World"
10
+ end
11
+
12
+ # maintain a session variable
13
+
14
+ session = request.session
15
+ session[:counter] = 0 unless session[:counter]
16
+ session[:counter] += 1
17
+ ?>
18
+
19
+ <!-- the template comes here -->
20
+
21
+ <h1>Hello #{name}</h1>
22
+
23
+ <p>
24
+ <form id="my_form" action="#{request.uri}">
25
+ <b>Enter your name:</b>
26
+ <input type="text" name="name" />
27
+ <br />
28
+ <input type="submit" />
29
+ </form>
30
+ </p>
31
+ <p>
32
+ Counter: #{session[:counter]}
33
+ </p>
34
+
35
+ </html>
@@ -0,0 +1,219 @@
1
+ # = Cluster
2
+ #
3
+ # TODO: use Sync instead of Monitor
4
+ #
5
+ # code:: gmosx
6
+ #
7
+ # (c) 2004 Navel, all rights reserved.
8
+ # $Id: cluster.rb 74 2004-10-18 11:30:20Z gmosx $
9
+
10
+ $:.unshift "nitro/lib"
11
+
12
+ require "drb"
13
+ require "monitor"
14
+
15
+ require "n/application"
16
+ require "n/server"
17
+ require "n/utils/cache"
18
+ require "n/app/session"
19
+
20
+ module N
21
+
22
+ # = Cluster
23
+ #
24
+ # A Cluster is a collection of servers. The cluster synchronizes the
25
+ # servers and distributes the state. An older version used a polling
26
+ # system, ie: the servers polled the cluster to obtain the state. This
27
+ # version uses a push system, ie when the state is changed a delta
28
+ # is pushed to the clients.
29
+ #
30
+ class Cluster < N::Application
31
+
32
+ # = CHash ClusterHash
33
+ #
34
+ class CHash < Hash
35
+ attr :mon
36
+
37
+ # drbobject for this hash (local)
38
+ attr_accessor :ldrb
39
+
40
+ # the cluster, use a cluster to implement a set
41
+ # (one server per drb_uri)
42
+ attr_accessor :cluster
43
+
44
+ #
45
+ #
46
+ def initialize(ldrb_uri = "druby://:8000")
47
+ @mon = Monitor.new
48
+ @ldrb = DRb.start_service(ldrb_uri, self)
49
+ @cluster = {}
50
+ end
51
+
52
+ #
53
+ #
54
+ def join(sdrb_uri)
55
+ @mon.synchronize {
56
+ cluster[sdrb_uri] = DRbObject.new(nil, sdrb_uri)
57
+ }
58
+ end
59
+
60
+ alias_method :old_set, :[]=
61
+
62
+ # Not really usefull
63
+ #
64
+ def []=(key, value)
65
+ # store the value (useful on server restarts)
66
+ @mon.synchronize {
67
+ old_set(key, value)
68
+
69
+ puts "CLUSTER #{key} = #{value}"
70
+
71
+ cluster.each { |uri, sdrb|
72
+ begin
73
+ sdrb.server_sync(key, value)
74
+ rescue => ex
75
+ $log.error "Server at #{uri} is down, removing from cluster"
76
+ cluster.delete(uri)
77
+ end
78
+ }
79
+ }
80
+ end
81
+
82
+ # Use this, avoids syncing the original server, and avoids a
83
+ # nasty deadlock.
84
+ #
85
+ def cluster_sync(key, value, server_uri)
86
+ # store the value (useful on server restarts)
87
+ @mon.synchronize {
88
+ old_set(key, value)
89
+
90
+ puts "CLUSTER #{key} = #{value}"
91
+
92
+ cluster.each { |uri, sdrb|
93
+ begin
94
+ sdrb.server_sync(key, value) unless uri == server_uri
95
+ rescue => ex
96
+ $log.error "Server at #{uri} is down, removing from cluster"
97
+ cluster.delete(uri)
98
+ end
99
+ }
100
+ }
101
+ end
102
+
103
+ def [](key)
104
+ @mon.synchronize {
105
+ puts "LOOKUP #{key}"
106
+ return super
107
+ }
108
+ end
109
+
110
+ end
111
+
112
+ # = SHash ServerHash
113
+ #
114
+ class SHash < Hash
115
+ attr :mon
116
+
117
+ # drbobject for this hash (local)
118
+ attr_accessor :ldrb
119
+
120
+ # drb for the cluster hash
121
+ attr_accessor :cdrb
122
+
123
+ # ldrb = local drb uri
124
+ # cdrb = cluster drb uri
125
+ #
126
+ def initialize(ldrb_uri = "druby://:9000", cdrb_uri = "druby://:8000")
127
+ @mon = Monitor.new
128
+ @ldrb_uri = ldrb_uri
129
+ @ldrb = DRb.start_service(ldrb_uri, self)
130
+ @cdrb = DRbObject.new(nil, cdrb_uri)
131
+ @cdrb.join(ldrb_uri)
132
+ end
133
+
134
+ alias_method :old_set, :[]=
135
+
136
+ #
137
+ #
138
+ def []=(key, value)
139
+ # store the value in the local hash
140
+ @mon.synchronize {
141
+ puts "LOCAL #{key} = #{value}"
142
+ old_set(key, value)
143
+ @cdrb.cluster_sync(key, value, @ldrb_uri)
144
+ }
145
+ end
146
+
147
+ # If the key is not found in the local hash, try the
148
+ # cluster hash.
149
+ #
150
+ def [](key)
151
+ @mon.synchronize {
152
+ unless value = super
153
+ value = @cdrb[key]
154
+ old_set(key, value)
155
+ end
156
+ return value
157
+ }
158
+ end
159
+
160
+ # Called by the cluster
161
+ #
162
+ def server_sync(key, value)
163
+ puts "SYNC #{key} = #{value}"
164
+ @mon.synchronize {
165
+ old_set(key, value)
166
+ }
167
+ end
168
+
169
+ end
170
+
171
+ # = Clm Cluster Last Modified Hash
172
+ #
173
+ class Clm < CHash
174
+ def [](key)
175
+ @mon.synchronize {
176
+ unless value = super
177
+ puts "INIT #{key}"
178
+ value = Time.now.to_i
179
+ old_set(key, value)
180
+ end
181
+ return value
182
+ }
183
+ end
184
+ end
185
+
186
+ # = Slm Server Last Modified Hash
187
+ #
188
+ class Slm < SHash
189
+ def set!(key, lm = nil)
190
+ lm = Time.now.to_i unless lm
191
+ self[key] = lm
192
+ return lm
193
+ end
194
+ end
195
+
196
+ def initialize(name = "Cluster")
197
+ super
198
+ end
199
+
200
+ def run
201
+ N::Cluster::Clm.new
202
+ DRb.start_service("druby://:8001", N::App::SessionManager.new)
203
+
204
+ while true
205
+ sleep(5000)
206
+ end
207
+
208
+ super
209
+ end
210
+
211
+ end
212
+
213
+ end # module
214
+
215
+ if $0 == __FILE__
216
+ require "logger"; $log = Logger.new(STDERR)
217
+
218
+ N::Cluster.new.exec()
219
+ end
@@ -0,0 +1,86 @@
1
+ # = Http Cookie
2
+ #
3
+ # code:: gmosx
4
+ #
5
+ # (c) 2004 Navel, all rights reserved.
6
+ # $Id: cookie.rb 71 2004-10-18 10:50:22Z gmosx $
7
+
8
+ require "cgi"
9
+
10
+ class CGI
11
+
12
+ # Override the default class.
13
+
14
+ class Cookie
15
+
16
+ =begin
17
+ # Override default implementation to convert a single value
18
+ # array to a simple value.
19
+
20
+ def value
21
+ val = @value
22
+
23
+ if 1 == val.size
24
+ return val.first
25
+ else
26
+ return val
27
+ end
28
+ end
29
+ =end
30
+
31
+ end
32
+
33
+ end # class CGI
34
+
35
+ module N; module App
36
+
37
+ # Cookie
38
+ #
39
+ # === Design:
40
+ #
41
+ # Ruby's default cgi library implements the functionality,
42
+ # so we reuse it here!
43
+ #
44
+ # The http request contains only key/values pairs so we
45
+ # dont keep a full object.
46
+ #
47
+ # === Todo:
48
+ #
49
+ # - switch to libapreq!
50
+ #
51
+ class Cookie < CGI::Cookie
52
+
53
+ # Override default implementation
54
+
55
+ def initialize(name, *value)
56
+ super
57
+
58
+ # this is a temporal fix! We should switch to libapreq,
59
+ # or a custom implementation anyway, because cgi.rb
60
+ # sucks.
61
+ @path = "/"
62
+ end
63
+
64
+ # parse:
65
+ # parses cookies from a header string
66
+ #
67
+ # Example cookie string, all cookies in one line separated by ;
68
+ #
69
+ # Cookie: nsid=293230807; nauth=gmosx:meMXs0ifW7JBQ; multi=123&456
70
+ #
71
+ # Input:
72
+ # the header string
73
+ # Output:
74
+ # a hash object containing key-values pairs. notice that multiple
75
+ # values can be assigned to one key, so values is an array. The
76
+ # separator for mulriple values is '&'
77
+ #
78
+ # uses the default CGI implementation
79
+ #
80
+ # === Todo:
81
+ #
82
+ # - change this to return an array of Cookie objects!
83
+
84
+ end
85
+
86
+ end; end # module