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.
- data/AUTHORS +8 -0
- data/ChangeLog +1546 -0
- data/LICENCE +32 -0
- data/README +278 -0
- data/RELEASES +7 -0
- data/Rakefile +79 -0
- data/bin/cluster.rb +219 -0
- data/doc/architecture.txt +28 -0
- data/doc/bugs.txt +7 -0
- data/doc/css.txt +20 -0
- data/doc/ideas.txt +120 -0
- data/doc/pg.txt +47 -0
- data/doc/svn.txt +82 -0
- data/doc/todo.txt +30 -0
- data/etc/new-project.rb +18 -0
- data/examples/simple/README +15 -0
- data/examples/simple/app.rb +31 -0
- data/examples/simple/conf/apache.conf +100 -0
- data/examples/simple/conf/config.rb +89 -0
- data/examples/simple/conf/debug-config.rb +53 -0
- data/examples/simple/conf/live-config.rb +48 -0
- data/examples/simple/conf/overrides.rb +9 -0
- data/examples/simple/conf/requires.rb +51 -0
- data/examples/simple/ctl +32 -0
- data/examples/simple/env.rb +33 -0
- data/examples/simple/install.rb +12 -0
- data/examples/simple/lib/articles/entities.rb +35 -0
- data/examples/simple/lib/articles/lc-en.rb +36 -0
- data/examples/simple/lib/articles/methods.rb +55 -0
- data/examples/simple/lib/articles/part.rb +58 -0
- data/examples/simple/logs/access_log +2 -0
- data/examples/simple/logs/apache.log +3 -0
- data/examples/simple/logs/app.log +1 -0
- data/examples/simple/logs/events.log +1 -0
- data/examples/simple/root/add-article.sx +15 -0
- data/examples/simple/root/article-form.ss +20 -0
- data/examples/simple/root/comments-form.ss +16 -0
- data/examples/simple/root/comments.si +30 -0
- data/examples/simple/root/index.sx +44 -0
- data/examples/simple/root/shader/shader.xsl +100 -0
- data/examples/simple/root/shader/style.css +9 -0
- data/examples/simple/root/view-article.sx +30 -0
- data/examples/tiny/app.rb +30 -0
- data/examples/tiny/conf/apache.conf +100 -0
- data/examples/tiny/conf/config.rb +67 -0
- data/examples/tiny/conf/requires.rb +40 -0
- data/examples/tiny/ctl +31 -0
- data/examples/tiny/logs/access_log +9 -0
- data/examples/tiny/logs/apache.log +9 -0
- data/examples/tiny/root/index.sx +35 -0
- data/lib/n/app/cluster.rb +219 -0
- data/lib/n/app/cookie.rb +86 -0
- data/lib/n/app/filters/autologin.rb +50 -0
- data/lib/n/app/fragment.rb +67 -0
- data/lib/n/app/handlers.rb +120 -0
- data/lib/n/app/handlers/code-handler.rb +184 -0
- data/lib/n/app/handlers/page-handler.rb +612 -0
- data/lib/n/app/request-part.rb +59 -0
- data/lib/n/app/request.rb +653 -0
- data/lib/n/app/script.rb +398 -0
- data/lib/n/app/server.rb +53 -0
- data/lib/n/app/session.rb +224 -0
- data/lib/n/app/user.rb +47 -0
- data/lib/n/app/webrick-servlet.rb +213 -0
- data/lib/n/app/webrick.rb +70 -0
- data/lib/n/application.rb +187 -0
- data/lib/n/config.rb +31 -0
- data/lib/n/db.rb +217 -0
- data/lib/n/db/README +232 -0
- data/lib/n/db/connection.rb +369 -0
- data/lib/n/db/make-release.sh +26 -0
- data/lib/n/db/managed.rb +235 -0
- data/lib/n/db/mixins.rb +282 -0
- data/lib/n/db/mysql.rb +342 -0
- data/lib/n/db/psql.rb +378 -0
- data/lib/n/db/tools.rb +110 -0
- data/lib/n/db/utils.rb +99 -0
- data/lib/n/events.rb +118 -0
- data/lib/n/l10n.rb +22 -0
- data/lib/n/logger.rb +33 -0
- data/lib/n/macros.rb +53 -0
- data/lib/n/mixins.rb +46 -0
- data/lib/n/parts.rb +154 -0
- data/lib/n/properties.rb +194 -0
- data/lib/n/server.rb +61 -0
- data/lib/n/server/PLAYBACK.txt +8 -0
- data/lib/n/server/RESEARCH.txt +13 -0
- data/lib/n/server/filter.rb +77 -0
- data/lib/n/shaders.rb +167 -0
- data/lib/n/sitemap.rb +188 -0
- data/lib/n/std.rb +69 -0
- data/lib/n/sync/clc.rb +108 -0
- data/lib/n/sync/handler.rb +221 -0
- data/lib/n/sync/server.rb +170 -0
- data/lib/n/tools/README +11 -0
- data/lib/n/ui/date-select.rb +74 -0
- data/lib/n/ui/pager.rb +187 -0
- data/lib/n/ui/popup.rb +45 -0
- data/lib/n/ui/select.rb +41 -0
- data/lib/n/ui/tabs.rb +34 -0
- data/lib/n/utils/array.rb +92 -0
- data/lib/n/utils/cache.rb +144 -0
- data/lib/n/utils/gfx.rb +108 -0
- data/lib/n/utils/hash.rb +148 -0
- data/lib/n/utils/html.rb +147 -0
- data/lib/n/utils/http.rb +98 -0
- data/lib/n/utils/mail.rb +28 -0
- data/lib/n/utils/number.rb +31 -0
- data/lib/n/utils/pool.rb +66 -0
- data/lib/n/utils/string.rb +297 -0
- data/lib/n/utils/template.rb +38 -0
- data/lib/n/utils/time.rb +91 -0
- data/lib/n/utils/uri.rb +193 -0
- data/lib/xsl/base.xsl +205 -0
- data/lib/xsl/ce.xsl +30 -0
- data/lib/xsl/localization.xsl +23 -0
- data/lib/xsl/xforms.xsl +26 -0
- data/test/run.rb +95 -0
- metadata +187 -0
data/lib/n/utils/mail.rb
ADDED
|
@@ -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
|
data/lib/n/utils/pool.rb
ADDED
|
@@ -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
|