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,28 @@
1
+ # = Mail utilities
2
+ #
3
+ # A thin wrapper arround net/smtp
4
+ #
5
+ # code:
6
+ # George Moschovitis <gm@navel.gr>
7
+ #
8
+ # (c) 2004 Navel, all rights reserved.
9
+ # $Id: mail.rb 71 2004-10-18 10:50:22Z gmosx $
10
+
11
+ require "net/smtp"
12
+
13
+ module N
14
+
15
+ module Mail
16
+
17
+ # Send an email
18
+ #
19
+ #
20
+ def self.send(from, to, body)
21
+ Net::SMTP.start($smtp_server, 25) { |smtp|
22
+ smtp.send_message(body, from, to)
23
+ }
24
+ end
25
+
26
+ end
27
+
28
+ end # module
@@ -0,0 +1,31 @@
1
+ # = General number utilities collection
2
+ #
3
+ # code: gmosx
4
+ #
5
+ # (c) 2004 Navel, all rights reserved.
6
+ # $Id: number.rb 71 2004-10-18 10:50:22Z gmosx $
7
+
8
+ module N;
9
+
10
+ # = NumberUtils
11
+ #
12
+ # === Design:
13
+ #
14
+ # Implement as a module to avoid class polution. You can
15
+ # still Ruby's advanced features to include the module in your
16
+ # class. Passing the object to act upon allows to check for nil,
17
+ # which isn't possible if you use self.
18
+ #
19
+ module NumberUtils
20
+
21
+ # Returns the multiple ceil of a number
22
+ #
23
+ def self.ceil_multiple(num, multiple)
24
+ # gmosx: to_f is needed!s
25
+ # gmosx: IS THERE a more optimized way to do this?
26
+ return ((num.to_f/multiple).ceil*multiple)
27
+ end
28
+
29
+ end
30
+
31
+ end # module
@@ -0,0 +1,66 @@
1
+ # = Pool
2
+ #
3
+ # Generalized object pool implementation.
4
+ #
5
+ # code: gmosx
6
+ #
7
+ # (c) 2004 Navel, all rights reserved.
8
+ # $Id: pool.rb 71 2004-10-18 10:50:22Z gmosx $
9
+
10
+ require "thread"
11
+ require "monitor"
12
+
13
+ module N
14
+
15
+ # = Pool
16
+ #
17
+ # Implemente a thread safe stack. Exclusive locking is needed
18
+ # both for push and pop.
19
+ #
20
+ # INVESTIGATE: Could use the SizedQueue/Queue.
21
+ #
22
+ class Pool < Array
23
+ include MonitorMixin
24
+
25
+ def initialize
26
+ super
27
+ @cv = new_cond()
28
+ end
29
+
30
+ # Add, restore an object to the pool.
31
+ #
32
+ def push(obj)
33
+ synchronize do
34
+ super
35
+ @cv.signal()
36
+ end
37
+ end
38
+
39
+ # Obtain an object from the pool.
40
+ #
41
+ def pop
42
+ synchronize do
43
+ @cv.wait_while { empty? }
44
+ super
45
+ end
46
+ end
47
+
48
+ # Obtains an object, passes it to a block for processing
49
+ # and restores it to the pool.
50
+ def obtain
51
+ result = nil
52
+
53
+ begin
54
+ obj = pop()
55
+
56
+ result = yield(obj)
57
+ ensure
58
+ push(obj)
59
+ end
60
+
61
+ return result
62
+ end
63
+
64
+ end
65
+
66
+ end # module
@@ -0,0 +1,297 @@
1
+ # = General string utilities collection
2
+ #
3
+ # code: gmosx, drak, ekarak
4
+ #
5
+ # (c) 2004 Navel, all rights reserved.
6
+ # $Id: string.rb 71 2004-10-18 10:50:22Z gmosx $
7
+
8
+ require "uri"
9
+
10
+ module N;
11
+
12
+ # = StringUtils
13
+ #
14
+ # === Design:
15
+ #
16
+ # Implement as a module to avoid class polution. You can
17
+ # still Ruby's advanced features to include the module in your
18
+ # class. Passing the object to act upon allows to check for nil,
19
+ # which isn't possible if you use self.
20
+ #
21
+ # === TODO:
22
+ #
23
+ # - implement a method that returns easy to remember
24
+ # pseudo-random strings
25
+ # - add aliases for those methods in Kernel.
26
+ #
27
+ module StringUtils
28
+
29
+ @@map_to_greeklish = {
30
+ "�" => "a", "�" => "A", "�" => "a", "�" => "A",
31
+ "�" => "b", "�" => "B",
32
+ "�" => "g", "�" => "G",
33
+ "�" => "d", "�" => "D",
34
+ "�" => "e", "�" => "E", "�" => "e", "�" => "E",
35
+ "�" => "z", "�" => "Z",
36
+ "�" => "h", "�" => "H", "�" => "h", "�" => "H",
37
+ "�" => "8", "�" => "8",
38
+ "�" => "i", "�" => "I", "�" => "i", "�" => "I",
39
+ "�" => "k", "�" => "K",
40
+ "�" => "l", "�" => "L",
41
+ "�" => "m", "�" => "M",
42
+ "�" => "n", "�" => "N",
43
+ "�" => "3", "�" => "3",
44
+ "�" => "o", "�" => "O", "�" => "o", "�" => "O",
45
+ "�" => "p", "�" => "P",
46
+ "�" => "r", "�" => "R",
47
+ "�" => "s", "�" => "s", "�" => "S",
48
+ "�" => "t", "�" => "T",
49
+ "�" => "y", "�" => "Y", "�" => "y", "�" => "Y",
50
+ "�" => "f", "�" => "F",
51
+ "�" => "x", "�" => "X",
52
+ "�" => "ps","�" => "PS",
53
+ "�" => "w", "�" => "W", "�" => "w", "�"=>"W"
54
+ }
55
+
56
+ # Convert the input string to greeklish
57
+ #
58
+ def self.to_greeklish(input)
59
+ return nil unless input
60
+ output = ""
61
+ # gmosx: also parse new lines
62
+ input.scan(/./m) { |w|
63
+ c = @@map_to_greeklish[w]
64
+ output << (c.nil?? w: c)
65
+ }
66
+ return output
67
+ end
68
+
69
+ # Move this in String class?
70
+ #
71
+ # Tests a string for a valid value (non nil, not empty)
72
+ #
73
+ def self.valid?(string)
74
+ return (not ((nil == string) or (string.empty?)))
75
+ end
76
+
77
+ # returns short abstract of long strings (first 'count'
78
+ # characters, chopped at the nearest word, appended by '...')
79
+ # force_cutoff: break forcibly at 'count' chars. Does not accept
80
+ # count < 2.
81
+ #
82
+ def self.head(string, count = 128, force_cutoff = false, ellipsis="...")
83
+ return nil unless string
84
+ return nil if count < 2
85
+
86
+ if string.size > count
87
+ cut_at = force_cutoff ? count : (string.index(' ', count-1) || count)
88
+ xstring = string.slice(0, cut_at)
89
+ return xstring.chomp(" ") + ellipsis
90
+ else
91
+ return string
92
+ end
93
+ end
94
+
95
+ # Apply a set of rules (regular expression matches) to the
96
+ # string
97
+ #
98
+ # === Requirements:
99
+ # - the rules must be applied in order! So we cannot use a
100
+ # hash because the ordering is not guaranteed! we use an
101
+ # array instead.
102
+ #
103
+ # === Input:
104
+ # the string to rewrite
105
+ # the array containing rule-pairs (match, rewrite)
106
+ #
107
+ # === Output:
108
+ # the rewritten string
109
+
110
+ MATCH = 0
111
+ REWRITE = 1
112
+
113
+ def self.rewrite(string, rules)
114
+ return nil unless string
115
+
116
+ # gmosx: helps to find bugs
117
+ raise ArgumentError.new("the rules parameter is nil") unless rules
118
+
119
+ rewritten_string = string.dup
120
+
121
+ for rule in rules
122
+ rewritten_string.gsub!(rule[MATCH], rule[REWRITE])
123
+ end
124
+
125
+ return (rewritten_string or string)
126
+ end
127
+
128
+ # Enforces a maximum width of a string inside an
129
+ # html container. If the string exceeds this maximum width
130
+ # the string gets wraped
131
+ #
132
+ # === Input:
133
+ # the string to be wrapped
134
+ # the enforced width
135
+ # the separator used for wrapping
136
+ #
137
+ # === Output:
138
+ # the wrapped string
139
+ #
140
+ # === Example:
141
+ # text = "1111111111111111111111111111111111111111111"
142
+ # text = Web::Utils::Html.wrap(text, 10, " ")
143
+ # p text # => "1111111111 1111111111 1111111111"
144
+ #
145
+ # See the test cases to better understand the behaviour!
146
+ #
147
+ def self.wrap(string, width = 20, separator = " ")
148
+ return nil unless string
149
+
150
+ re = /([^#{separator}]{1,#{width}})/
151
+ wrapped_string = string.scan(re).join(separator)
152
+
153
+ return wrapped_string
154
+ end
155
+
156
+ # extracts the extension from a path or filename.
157
+ #
158
+ # === Input:
159
+ # the path to a file (or just a plain filename)
160
+ #
161
+ # === Output:
162
+ # the extension of the filename
163
+ # returns empty string if no exception
164
+ # the extension is DOWNCASED!
165
+
166
+ EXTENSION_REGEX = /\.(\w+)$/
167
+
168
+ def self.extension_from_path(path)
169
+ if md = EXTENSION_REGEX.match(path)
170
+ return md[1].downcase
171
+ else
172
+ # gmosx: "" is safer, no??? and it is logical too.
173
+ return ""
174
+ end
175
+ end
176
+
177
+ # Extracts the (file)name from a path or filename.
178
+ #
179
+ # === Input:
180
+ # the path to a file (or just a plain filename)
181
+ #
182
+ # === Output:
183
+ # the name part of the filename (the extension is stripped)
184
+ # returns empty string if input is nil (safer?)
185
+ #
186
+ def self.filename_from_path(path)
187
+ # gmosx: "" is safer, no??? and it is logical too.
188
+ return "" unless path
189
+ parts = path.split(EXTENSION_REGEX)
190
+ return parts[0]
191
+ end
192
+
193
+ # Extracts the file part from a path or filename.
194
+ #
195
+ # === Input:
196
+ # the path to a file (or just a plain filename)
197
+ #
198
+ # === Output:
199
+ # the file part (the directory is stripped)
200
+ # returns empty string if input is nil (safer?)
201
+ #
202
+ def self.file_from_path(path)
203
+ return "" unless path
204
+ return path.split("/").slice(-1)
205
+ end
206
+
207
+ # Extracts the directory part from a path or filename.
208
+ #
209
+ # === Input:
210
+ # the path to a file (or just a plain filename)
211
+ #
212
+ # === Output:
213
+ # the directory part (the filename is stripped)
214
+ # returns empty string if input is nil (safer?)
215
+ #
216
+ def self.directory_from_path(path)
217
+ return "" unless path
218
+ return path.chomp(self.file_from_path(path)).chop()
219
+ end
220
+
221
+ # Replace dangerours chars in filenames
222
+ #
223
+ def self.rationalize_filename(filename)
224
+ return nil unless filename
225
+ # gmosx: rationalize a copy!!! (add unit test)
226
+ xfilename = filename.dup()
227
+ # gmosx: replace some dangerous chars!
228
+ xfilename.gsub!(/ /, "-")
229
+ xfilename.gsub!(/!/, "")
230
+ xfilename.gsub!(/'/, "")
231
+ xfilename.gsub!(/\(/, "")
232
+ xfilename.gsub!(/\)/, "")
233
+ xfilename = self.to_greeklish(xfilename)
234
+ return xfilename
235
+ end
236
+
237
+ # Returns a random string. one possible use is
238
+ # password initialization.
239
+ #
240
+ # === Input:
241
+ # the maximum length of the string
242
+ #
243
+ # === Output:
244
+ # the random string
245
+ #
246
+ def self.random(max_length = 8, char_re = /[\w\d]/)
247
+ # gmosx: this is a nice example of input parameter checking.
248
+ # this is NOT a real time called method so we can add this
249
+ # check. Congrats to the author.
250
+ raise ArgumentError.new("char_re must be a regular expression!") unless char_re.is_a?(Regexp)
251
+
252
+ string = ""
253
+
254
+ while string.length < max_length
255
+ ch = rand(255).chr
256
+ string << ch if ch =~ char_re
257
+ end
258
+
259
+ return string
260
+ end
261
+
262
+ # Converts unicode to ISO8859-7 (unfortunately Ruby is a little poor at i18n)
263
+ # Usefull for parsing xmls with libxml.
264
+ #
265
+ # === Input:
266
+ # the string to convert
267
+ #
268
+ # === Output:
269
+ # the converted string
270
+ #
271
+ # === TODO:
272
+ # - MORE TEST UNITS !!!!
273
+ #
274
+ def self.unicode_to_iso88597(string)
275
+ return string.to_s.unpack('U*').collect {|ch|
276
+ ch>127 ? ch-0x02d0 : ch
277
+ }.pack('C*')
278
+ end
279
+
280
+
281
+ # Screen an IP address
282
+ #
283
+ # gmosx: copied this method from n1, check how it works!
284
+ #
285
+ def self.screen_ip_address(address)
286
+ if address
287
+ return address.split(',').collect { |hostip|
288
+ hostip.gsub(/\.[^\.]*$/, ".*")
289
+ }.join(', ')
290
+ else
291
+ return "*.*.*.*"
292
+ end
293
+ end
294
+
295
+ end
296
+
297
+ end # module
@@ -0,0 +1,38 @@
1
+ # = Template
2
+ #
3
+ # A simple templating mechanism.
4
+ #
5
+ # code:
6
+ # George Moschovitis <gm@navel.gr>
7
+ #
8
+ # (c) 2004 Navel, all rights reserved.
9
+ # $Id$
10
+
11
+ module N;
12
+
13
+ # = Template
14
+ #
15
+ class Template
16
+ attr_accessor :body
17
+
18
+ #
19
+ #
20
+ def initialize(filename)
21
+ @body = File.read(filename)
22
+ end
23
+
24
+ # Apply the substitutions to the template.
25
+ #
26
+ def gsub(hash)
27
+ res = body.dup()
28
+
29
+ hash.each {|k, v|
30
+ res.gsub!(k, v)
31
+ }
32
+
33
+ return res
34
+ end
35
+ alias_method :render, :gsub
36
+ end
37
+
38
+ end # module