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,221 @@
1
+ # = Synchronous Handler
2
+ #
3
+ # === Design:
4
+ #
5
+ # A handler can act as a multiplexer to implement multiple services
6
+ # per server.
7
+ #
8
+ # code: tml, drak
9
+ #
10
+ # (c) 2004 Navel, all rights reserved.
11
+ # $Id: handler.rb 71 2004-10-18 10:50:22Z gmosx $
12
+
13
+ require "timeout"
14
+ require "n/server"
15
+
16
+ module N; module Sync
17
+
18
+ class HandlerExitException < Exception; end
19
+
20
+ # = Worker
21
+ #
22
+ # Override this to create your worker.
23
+ #
24
+ class Handler
25
+ SEPARATOR = "\000"
26
+
27
+ # socket timeout in seconds
28
+ @@socket_timeout = 30
29
+
30
+ # handler timeout in seconds
31
+ @@handler_timeout = 60 * 60
32
+
33
+ attr :server, :socket
34
+
35
+ attr :thread, :touch_time
36
+
37
+ # status
38
+ attr_accessor :status
39
+
40
+ STATUS_IDLE = 0
41
+ STATUS_RUNNING = 10
42
+ STATUS_STOPPED = 20
43
+
44
+ def initialize(server, socket)
45
+ @server, @socket = server, socket
46
+ end
47
+
48
+ def start
49
+ touch!
50
+ @thread = Thread.new(&method("run").to_proc)
51
+ end
52
+
53
+ def stop
54
+ unless STATUS_STOPPED == @status
55
+ @status = STATUS_STOPPED
56
+ $log.debug "Stoping handler" if $DBG
57
+
58
+ begin
59
+ @socket.close()
60
+ rescue Exception, StandardError => e
61
+ # gmosx: this is needed to be FAULT TOLERANT
62
+ # DRINK IT!
63
+ $log.error "Cannot close exception when stoping handler."
64
+ end
65
+
66
+ # gmosx: why not? more FAULT TOLERANT.
67
+ @server.handlers.delete_if {|h| STATUS_STOPPED == h.status}
68
+
69
+ end
70
+ end
71
+
72
+ # called by the garbage collector.
73
+ #
74
+ def gc!
75
+ @thread.raise HandlerExitException.new()
76
+ end
77
+
78
+ def run
79
+ @status = STATUS_RUNNING
80
+
81
+ while (STATUS_RUNNING == @status) and (not @socket.closed?)
82
+ begin
83
+ unless cmd = read()
84
+ $log.error "Client closed connection"
85
+ @status = STATUS_IDLE
86
+ else
87
+ touch!
88
+ handle(cmd.chop())
89
+ end
90
+ rescue HandlerExitException => ex
91
+ @status = STATUS_IDLE
92
+ $log.debug "Handler exit" if $DBG
93
+ rescue Exception, StandardError => ex
94
+ @status = STATUS_IDLE
95
+ $log.debug ex if $DBG
96
+ end
97
+ end
98
+
99
+ begin
100
+ stop()
101
+ rescue Exception, StandardError => e
102
+ # gmosx: this rescue block needed to get debug info!
103
+ #
104
+ $log.error pp_exception(e)
105
+ end
106
+ end
107
+
108
+ def touch!
109
+ @touch_time = Time.now()
110
+ end
111
+
112
+ def live?
113
+ return Time.now < @touch_time + @@handler_timeout
114
+ end
115
+
116
+ # Read xml from the socket
117
+ #
118
+ def read
119
+ return unless @status == STATUS_RUNNING
120
+
121
+ cmd = nil
122
+
123
+ # gmosx: no timeout here!
124
+ cmd = @socket.gets(SEPARATOR)
125
+ $log.debug "in: #{cmd}" if $DBG
126
+
127
+ return cmd
128
+ end
129
+
130
+ # Write xml to the socket
131
+ #
132
+ def write(cmd)
133
+ return unless @status == STATUS_RUNNING
134
+
135
+ $log.debug "out: #{cmd}" if $DBG
136
+
137
+ begin
138
+ timeout(@@socket_timeout) { @socket << "#{cmd}#{SEPARATOR}" }
139
+ rescue Exception, StandardError => e
140
+ # gmosx: the socket is invalid close the handler.
141
+ $log.error pp_exception(e)
142
+ stop()
143
+ end
144
+ end
145
+
146
+ # parse the xml commnad to create a ruby method call.
147
+ #
148
+ def parse(cmd)
149
+ return unless @status == STATUS_RUNNING
150
+
151
+ cmd = REXML::Document.new(cmd).root()
152
+
153
+ method = cmd.name().gsub(/-/, "_")
154
+ unless cmd.attributes.empty?
155
+ args = "(#{cmd.attributes.collect { |k, v| ":#{k.gsub(/-/, "_")} => '#{v}'" }.join(", ")})"
156
+ else
157
+ args = nil
158
+ end
159
+
160
+ return "cmd_#{method}#{args}"
161
+ end
162
+
163
+ # Generic handler.
164
+ #
165
+ def handle(cmd)
166
+ if cmd = parse(cmd)
167
+ $log.debug "exec: #{cmd}" if $DBG
168
+ begin
169
+ eval(cmd)
170
+ rescue => ex
171
+ $log.error ex
172
+ end
173
+ end
174
+ end
175
+
176
+ # Send to another handler
177
+ #
178
+ def send(cmd, handler)
179
+ handler.write(cmd)
180
+ end
181
+
182
+ # Broadcast to all handlers (clients)
183
+ #
184
+ def broadcast(cmd)
185
+ @server.broadcast(cmd)
186
+ end
187
+
188
+ # Broadcast to all other handlers (clients)
189
+ #
190
+ def broadcast_to_others(cmd)
191
+ for handler in @server.handlers
192
+ unless self == handler
193
+ handler.write(cmd)
194
+ end
195
+ end
196
+ end
197
+
198
+ # ------------------------------------------------------------------
199
+
200
+ def info(txt)
201
+ write(%|<info text="#{txt}" />|)
202
+ end
203
+
204
+ def error(txt)
205
+ write(%|<error text="#{txt}" />|)
206
+ end
207
+
208
+ # ------------------------------------------------------------------
209
+ # Commands
210
+
211
+ def cmd_ping(args)
212
+ cmd = %{<pong time="#{Time.now}"}
213
+ cmd += %{ challenge="#{args[:challenge]}"} if args
214
+ cmd += " />"
215
+
216
+ write(cmd)
217
+ end
218
+
219
+ end
220
+
221
+ end; end #modules
@@ -0,0 +1,170 @@
1
+ # = Syncrhronous Server
2
+ #
3
+ # === Design:
4
+ #
5
+ # Should support clustered operation: A cluster of servers is spawned.
6
+ # The client connects to one of the servers at random. The client sticks
7
+ # to the server. Each server considers the others as clients and
8
+ # rebroadcasts all the events.
9
+ #
10
+ # We keep one service per server for simplicity, if we need multiple
11
+ # services we can implement a multiplexer service (handler).
12
+ #
13
+ # === TODO:
14
+ #
15
+ # - Investigate if this server can be done with select.
16
+ #
17
+ # code: gmosx, drak
18
+ #
19
+ # (c) 2004 Navel, all rights reserved.
20
+ # $Id: server.rb 71 2004-10-18 10:50:22Z gmosx $
21
+
22
+ require "thread"
23
+ require "socket"
24
+ require "rexml/document"
25
+
26
+ require "n/std"
27
+ require "n/application"
28
+ require "n/utils/array"
29
+ require "n/sync/handler"
30
+
31
+ module N; module Sync
32
+
33
+ # = Server
34
+ #
35
+ # A Synchronous server tha communicates with clients using
36
+ # application specific xml protocols. Typically communicates with
37
+ # Flash clients utilising the XmlSocket functionality to enable 'push'
38
+ # flash applications.
39
+ #
40
+ # The Macromedia XML Socket protocol is used, \000 is used as a eof
41
+ # marker. NO: the XML protocol is not really appropriate, better use
42
+ # a space optimized delimited ASCII protocol.
43
+ #
44
+ class Server < N::Application
45
+ MONITOR_INTERVAL = 2 * 60
46
+
47
+ # a single tcp server accepts all tcp requests
48
+ attr :tcp_server
49
+
50
+ # the listening address/port for this server.
51
+ attr_reader :address, :port
52
+
53
+ # the handler class, used to instantiate handlers
54
+ attr :handler_class
55
+
56
+ # maximum number of clients to connect.
57
+ attr_accessor :max_handlers
58
+
59
+ # the handler list, all handler attached to the server.
60
+ attr_accessor :handlers
61
+
62
+ # status
63
+ attr_accessor :status
64
+
65
+ STATUS_IDLE = 0
66
+ STATUS_RUNNING = 10
67
+ STATUS_STOPPED = 20
68
+
69
+ def initialize(address = "localhost", port = 2121, handler_class = N::Sync::Handler, max_handlers = nil)
70
+ @address, @port = address, port
71
+ @max_handlers = max_handlers
72
+ @name, @title = "nsync", "Navel Sync"
73
+ @status = STATUS_IDLE
74
+
75
+ @handlers = N::SafeArray.new()
76
+ @handler_class = handler_class
77
+
78
+ super()
79
+ end
80
+
81
+ def start()
82
+ # a single tcp server accepts all tcp requests
83
+ @tcp_server = TCPServer.new(address, port)
84
+
85
+ start_monitor()
86
+ run()
87
+ end
88
+
89
+ def stop()
90
+ @status = STATUS_STOPED
91
+ end
92
+
93
+ def run()
94
+ @status = STATUS_RUNNING
95
+ $log.info "Server is running."
96
+
97
+ begin
98
+ while (STATUS_RUNNING == @status)
99
+ socket = @tcp_server.accept()
100
+ $log.debug "Socket accepted" if $DBG
101
+ handler = @handler_class.new(self, socket)
102
+ handlers << handler
103
+ handler.start()
104
+ end
105
+ rescue Exception, StandardError => e
106
+ $log.error pp_exception(e)
107
+ # tml, FIXME:
108
+ # this is dangerous! make more FAULT TOLERANT!
109
+ end
110
+
111
+ @status = STATUS_IDLE
112
+ end
113
+
114
+ def shutdown()
115
+ end_monitor()
116
+ for handler in handlers
117
+ handler.stop()
118
+ end
119
+ Thread.exit()
120
+ end
121
+
122
+ # ------------------------------------------------------------------
123
+
124
+ def start_monitor
125
+ @monitor = Thread.new {
126
+ begin
127
+ while true
128
+ sleep(MONITOR_INTERVAL)
129
+ $log.debug "monitor beat -- #{@handlers.size()} handlers" if $DBG
130
+
131
+ for handler in @handlers
132
+ unless handler.live?
133
+ $log.info "Idle handler detected!"
134
+ handler.gc!()
135
+ end
136
+ end
137
+ end
138
+ rescue Exception, StandardError => e
139
+ $log.error pp_exception(e)
140
+ end
141
+ }
142
+ end
143
+
144
+ def end_monitor
145
+ Thread.kill(@monitor)
146
+ end
147
+
148
+ # ------------------------------------------------------------------
149
+
150
+ def send(cmd, handler)
151
+ handler.write(cmd)
152
+ end
153
+
154
+ def broadcast(cmd)
155
+ for handler in @handlers
156
+ handler.write(cmd)
157
+ end
158
+ end
159
+
160
+ end
161
+
162
+ if $0 == __FILE__
163
+ require "n/logger"
164
+
165
+ $log = Logger.new(STDERR)
166
+ Server.new().exec()
167
+ end
168
+
169
+ end; end #modules
170
+
@@ -0,0 +1,11 @@
1
+ = Software Enginnering Tools
2
+
3
+ This directory contains standalone tools typically used in
4
+ software engineering and configuration, system administration,
5
+ or network management.
6
+
7
+ === TODO:
8
+
9
+ - tool to replace all $xxx variables with english names.
10
+
11
+
@@ -0,0 +1,74 @@
1
+ # = Date Select
2
+ #
3
+ # code:
4
+ # George Moschovitis <gm@navel.gr>
5
+ #
6
+ # (c) 2004 Navel, all rights reserved.
7
+ # $Id: select.rb 39 2004-09-29 12:40:53Z elathan $
8
+
9
+ module N; module UI
10
+
11
+ MONTHS_EN = %w{ - January February March April May June July August September October November December }
12
+ MONTHS_EL = %w{ - ���������� ����������� ������� �������� ����� ������� ������� ��������� ����������� ��������� ��������� ���������� }
13
+
14
+ # Date select.
15
+ #
16
+ def self.date_select(prefix, day, month, year, yorder = 0, locale = "en")
17
+ str = ""
18
+ months = ("en" == locale ? MONTHS_EN : MONTHS_EL)
19
+
20
+ str << %{
21
+ <select name="#{prefix}day">
22
+ <option value="0">--</option>
23
+ }
24
+
25
+ for i in (1..31)
26
+ if i == day
27
+ str << %{<option value="#{i}" selected="1">#{i}</option>}
28
+ else
29
+ str << %{<option value="#{i}">#{i}</option>}
30
+ end
31
+ end
32
+
33
+ str << %{
34
+ </select>
35
+
36
+ <select name="#{prefix}month">
37
+ <option value="0">-------</option>
38
+ }
39
+
40
+ for i in (1..12)
41
+ if i == month
42
+ str << %{<option value="#{i}" selected="1">#{months[i]}</option>}
43
+ else
44
+ str << %{<option value="#{i}">#{months[i]}</option>}
45
+ end
46
+ end
47
+
48
+ str << %{
49
+ </select>
50
+
51
+ <select name="#{prefix}year">
52
+ <option value="0">--</option>
53
+ }
54
+
55
+ nowyear = Time.now.year
56
+
57
+ for i in (0..60)
58
+ y = yorder < 0 ? nowyear - i : nowyear + i
59
+ if y == year
60
+ str << %{<option value="#{y}" selected="1">#{y}</option>}
61
+ else
62
+ str << %{<option value="#{y}">#{y}</option>}
63
+ end
64
+ end
65
+
66
+ str << %{
67
+ </select>
68
+ }
69
+
70
+ return str
71
+ end
72
+
73
+ end; end # module
74
+