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/gfx.rb
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# = General graphics utilities collection
|
|
2
|
+
#
|
|
3
|
+
# code:
|
|
4
|
+
# George Moschovitis <gm@navel.gr>
|
|
5
|
+
# Elias Athanasopoulos <elathan@navel.gr>
|
|
6
|
+
# Asteraki <stella@navel.gr>
|
|
7
|
+
#
|
|
8
|
+
# (c) 2004 Navel, all rights reserved.
|
|
9
|
+
# $Id: gfx.rb 71 2004-10-18 10:50:22Z gmosx $
|
|
10
|
+
|
|
11
|
+
module N
|
|
12
|
+
|
|
13
|
+
# = GfxUtils
|
|
14
|
+
#
|
|
15
|
+
# === Design:
|
|
16
|
+
#
|
|
17
|
+
# A simple wrapper around ImageMagick.
|
|
18
|
+
#
|
|
19
|
+
# Implement as a module to avoid class polution. You can
|
|
20
|
+
# still Ruby's advanced features to include the module in your
|
|
21
|
+
# class. Passing the object to act upon allows to check for nil,
|
|
22
|
+
# which isn't possible if you use self.
|
|
23
|
+
#
|
|
24
|
+
#
|
|
25
|
+
module GfxUtils
|
|
26
|
+
|
|
27
|
+
# === Input:
|
|
28
|
+
# width, height = dimensions for the scaled image.
|
|
29
|
+
#
|
|
30
|
+
def self.create_thumbnail(src, dest, width, height)
|
|
31
|
+
# gmosx: [0] selects the 1st frame in case of animated gifs.
|
|
32
|
+
# gmosx: SOS!!! the +profile "*" is need to strip metadata that
|
|
33
|
+
# fuckup the internet explorer!
|
|
34
|
+
if (dest =~ /jpg$/i) or (File.stat(src).size > 60000)
|
|
35
|
+
# keep only the first frame
|
|
36
|
+
system %|convert +profile "*" +compress -scale '#{width}x#{height}>' -antialias #{src}[0] #{dest}|
|
|
37
|
+
else
|
|
38
|
+
system %|convert +profile "*" +compress -scale '#{width}x#{height}>' -antialias #{src} #{dest}|
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Use ImageMagick to grab the EXIF data
|
|
43
|
+
# contained in a jpeg file and store it to a
|
|
44
|
+
# hash: EXIF field => EXIF value.
|
|
45
|
+
#
|
|
46
|
+
# A sample EXIF table:
|
|
47
|
+
#
|
|
48
|
+
# Make=Canon
|
|
49
|
+
# Model=Canon PowerShot S110
|
|
50
|
+
# Orientation=1
|
|
51
|
+
# X Resolution=180/1
|
|
52
|
+
# YResolution=180/1
|
|
53
|
+
# ResolutionUnit=2
|
|
54
|
+
# DateTime=2002:05:16 21:02:36
|
|
55
|
+
# YCbCrPositioning=1
|
|
56
|
+
# ExifOffset=196
|
|
57
|
+
# ExposureTime=1/80
|
|
58
|
+
# FNumber=28/10
|
|
59
|
+
# ExifVersion=0210
|
|
60
|
+
# DateTimeOriginal=2002:05:16 21:02:36
|
|
61
|
+
# DateTimeDigitized=2002:05:16 21:02:36
|
|
62
|
+
# ComponentsConfiguration=...
|
|
63
|
+
# CompressedBitsPerPixel=3/1
|
|
64
|
+
# ShutterSpeedValue=202/32
|
|
65
|
+
# ApertureValue=95/32
|
|
66
|
+
# ExposureBiasValue=0/3
|
|
67
|
+
# MaxApertureValue=194698/65536
|
|
68
|
+
# SubjectDistance=772/1000
|
|
69
|
+
# MeteringMode=5
|
|
70
|
+
# Flash=1
|
|
71
|
+
# FocalLength=173/32
|
|
72
|
+
# MakerNote=.
|
|
73
|
+
# UserComment=
|
|
74
|
+
# FlashPixVersion=0100
|
|
75
|
+
# ColorSpace=1
|
|
76
|
+
# ExifImageWidth=1600
|
|
77
|
+
# ExifImageLength=1200
|
|
78
|
+
# InteroperabilityOffset=1328
|
|
79
|
+
# unknown=R98
|
|
80
|
+
# unknown=0100
|
|
81
|
+
# unknown=1600
|
|
82
|
+
# unknown=1200
|
|
83
|
+
# FocalPlaneXResolution=1600000/206
|
|
84
|
+
# FocalPlaneYResolution=1200000/155
|
|
85
|
+
# FocalPlaneResolutionUnit=2
|
|
86
|
+
# SensingMethod=2
|
|
87
|
+
# FileSource=.
|
|
88
|
+
#
|
|
89
|
+
def self.grab_exif(path)
|
|
90
|
+
info = %x|identify -format "%[EXIF:*]" #{path}|.split("\n")
|
|
91
|
+
|
|
92
|
+
exif = {}
|
|
93
|
+
info.each { |l|
|
|
94
|
+
tag, value = l.split("=")
|
|
95
|
+
exif[tag] = value
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
unless exif.empty?
|
|
99
|
+
return exif
|
|
100
|
+
else
|
|
101
|
+
return nil
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
end # module
|
|
108
|
+
|
data/lib/n/utils/hash.rb
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# = Hash
|
|
2
|
+
#
|
|
3
|
+
# various hash utilities.
|
|
4
|
+
#
|
|
5
|
+
# Design:
|
|
6
|
+
# uses the delegator pattern to allow for multiple
|
|
7
|
+
# implementations!
|
|
8
|
+
#
|
|
9
|
+
# *code: gmosx
|
|
10
|
+
#
|
|
11
|
+
# (c) 2004 Navel, all rights reserved.
|
|
12
|
+
# $Id: hash.rb 71 2004-10-18 10:50:22Z gmosx $
|
|
13
|
+
|
|
14
|
+
require "sync"
|
|
15
|
+
|
|
16
|
+
module N;
|
|
17
|
+
|
|
18
|
+
# == SafeHash
|
|
19
|
+
#
|
|
20
|
+
# A thread-safe hash. We use a sync object instead of a mutex,
|
|
21
|
+
# because it is re-entrant.
|
|
22
|
+
# An exclusive lock is needed when writing, a shared lock IS NEEDED
|
|
23
|
+
# when reading
|
|
24
|
+
|
|
25
|
+
class SafeHash < Hash
|
|
26
|
+
attr :sync
|
|
27
|
+
|
|
28
|
+
# gmosx: delegator is not used.
|
|
29
|
+
|
|
30
|
+
def initialize(delegator = nil)
|
|
31
|
+
@sync = ::Sync.new
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def [](key)
|
|
35
|
+
return @sync.synchronize(::Sync::SH) {
|
|
36
|
+
super
|
|
37
|
+
}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def []=(key, value)
|
|
41
|
+
return @sync.synchronize(::Sync::EX) {
|
|
42
|
+
super
|
|
43
|
+
}
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def delete(key)
|
|
47
|
+
return @sync.synchronize(::Sync::EX) {
|
|
48
|
+
super
|
|
49
|
+
}
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def clear
|
|
53
|
+
@sync.synchronize(::Sync::EX) {
|
|
54
|
+
super
|
|
55
|
+
}
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def size
|
|
59
|
+
return @sync.synchronize(::Sync::SH) {
|
|
60
|
+
super
|
|
61
|
+
}
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def values
|
|
65
|
+
return @sync.synchronize(::Sync::SH) {
|
|
66
|
+
super
|
|
67
|
+
}
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def keys
|
|
71
|
+
return @sync.synchronize(::Sync::SH) {
|
|
72
|
+
super
|
|
73
|
+
}
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
end # SafeHash
|
|
77
|
+
|
|
78
|
+
# == SafeHashDelegator
|
|
79
|
+
#
|
|
80
|
+
# A thread-safe hash. We use a sync object instead of a mutex,
|
|
81
|
+
# because it is re-entrant.
|
|
82
|
+
# An exclusive lock is needed when writing, a shared lock IS NEEDED
|
|
83
|
+
# when reading
|
|
84
|
+
#
|
|
85
|
+
# Design:
|
|
86
|
+
# This class uses the delegator pattern. However we dont use rubys
|
|
87
|
+
# delegation facilities, they are more general and powerfull than we
|
|
88
|
+
# need here (and slower). Instead a custom (but simple) solution is
|
|
89
|
+
# used.
|
|
90
|
+
#
|
|
91
|
+
# Example:
|
|
92
|
+
#
|
|
93
|
+
# hash = SafeHashDelegator.new(Hash.new)
|
|
94
|
+
# hash = SafeHashDelegator.new(Hash.new)
|
|
95
|
+
|
|
96
|
+
class SafeHashDelegator < Hash
|
|
97
|
+
attr :delegate, :sync
|
|
98
|
+
|
|
99
|
+
def initialize(delegate)
|
|
100
|
+
@delegate = delegate
|
|
101
|
+
@sync = ::Sync.new
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def [](key)
|
|
105
|
+
return @sync.synchronize(::Sync::SH) {
|
|
106
|
+
@delegate[key]
|
|
107
|
+
}
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def []=(key, value)
|
|
111
|
+
return @sync.synchronize(::Sync::EX) {
|
|
112
|
+
@delegate[key] = value
|
|
113
|
+
}
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def delete(key)
|
|
117
|
+
return @sync.synchronize(::Sync::EX) {
|
|
118
|
+
@delegate.delete(key)
|
|
119
|
+
}
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def clear
|
|
123
|
+
@sync.synchronize(::Sync::EX) {
|
|
124
|
+
@delegate.clear
|
|
125
|
+
}
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def size
|
|
129
|
+
return @sync.synchronize(::Sync::SH) {
|
|
130
|
+
@delegate.size()
|
|
131
|
+
}
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def values
|
|
135
|
+
return @sync.synchronize(::Sync::SH) {
|
|
136
|
+
@delegate.values()
|
|
137
|
+
}
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def keys
|
|
141
|
+
return @sync.synchronize(::Sync::SH) {
|
|
142
|
+
@delegate.keys()
|
|
143
|
+
}
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
end # SafeHashDelegator
|
|
147
|
+
|
|
148
|
+
end # module
|
data/lib/n/utils/html.rb
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# = HTML utilities collection
|
|
2
|
+
#
|
|
3
|
+
# code:: gmosx, tkout, ekarak
|
|
4
|
+
#
|
|
5
|
+
# (c) 2004 Navel, all rights reserved.
|
|
6
|
+
# $Id: html.rb 71 2004-10-18 10:50:22Z gmosx $
|
|
7
|
+
|
|
8
|
+
require "uri"
|
|
9
|
+
require "cgi"
|
|
10
|
+
|
|
11
|
+
module N;
|
|
12
|
+
|
|
13
|
+
# = HtmlUtils
|
|
14
|
+
#
|
|
15
|
+
# === Design:
|
|
16
|
+
#
|
|
17
|
+
# Implement as a module to avoid class polution. You can still Ruby's
|
|
18
|
+
# advanced features to include the module in your class.
|
|
19
|
+
# Passing the object to act upon allows to check for nil, which isn't
|
|
20
|
+
# possible if you use self.
|
|
21
|
+
#
|
|
22
|
+
# The older text_sum, text_block methods are not needed in the latest
|
|
23
|
+
# code
|
|
24
|
+
#
|
|
25
|
+
# === TODO:
|
|
26
|
+
# - add xxx! versions
|
|
27
|
+
#
|
|
28
|
+
module HtmlUtils
|
|
29
|
+
|
|
30
|
+
# escape html tags.
|
|
31
|
+
# usefull to make text entered by end users html safe.
|
|
32
|
+
#
|
|
33
|
+
# Input:
|
|
34
|
+
# the string to be escaped
|
|
35
|
+
#
|
|
36
|
+
# Output:
|
|
37
|
+
# the escaped string
|
|
38
|
+
#
|
|
39
|
+
def self.escape(string)
|
|
40
|
+
# gmosx: no need to return "" on nil, will be interpolated to ""
|
|
41
|
+
return nil unless string
|
|
42
|
+
return CGI::escapeHTML(string)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# TODO: move to markup!
|
|
46
|
+
#
|
|
47
|
+
# Expands the urls found in the given string. Use the target parameter
|
|
48
|
+
# to apply presentation semantics (ie open in new window)
|
|
49
|
+
#
|
|
50
|
+
# Example:
|
|
51
|
+
# text = "visit this site: www.navel.gr"
|
|
52
|
+
# text = Web::Utils::Html::expand_urls(text)
|
|
53
|
+
# p text # =>
|
|
54
|
+
# "visit this site: <a href='http://www.navel.gr'>http://www.navel.gr</a>"
|
|
55
|
+
#
|
|
56
|
+
def self.expand_urls(string, target = nil)
|
|
57
|
+
return nil unless string
|
|
58
|
+
|
|
59
|
+
xstring = string.gsub(/\s(www\.[^\s]*)/, " http://\\1")
|
|
60
|
+
xstring.gsub!(/\s(ftp\.[^\s]*)/, " ftp://\\1")
|
|
61
|
+
|
|
62
|
+
xstring.gsub!(URI::REGEXP::ABS_URI_REF) { |uriref|
|
|
63
|
+
if /(http|ftp):/.match(uriref)
|
|
64
|
+
"<a" + (target.nil?? "" : " target='#{target}'") +
|
|
65
|
+
" href='#{uriref}'>#{uriref}</a>"
|
|
66
|
+
else
|
|
67
|
+
uriref
|
|
68
|
+
end
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return xstring
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Strips potentially dangerous html tags, leaving only safe
|
|
75
|
+
# tags. Usefull for simple Html formatting.
|
|
76
|
+
#
|
|
77
|
+
# === Design:
|
|
78
|
+
#
|
|
79
|
+
# Escapes ALL quotes for security, use html without quotes:
|
|
80
|
+
#
|
|
81
|
+
# <font size=+1>kok</font>
|
|
82
|
+
# <a href=http://www.navel.gr
|
|
83
|
+
# ...
|
|
84
|
+
#
|
|
85
|
+
# Should handle the following case:
|
|
86
|
+
#
|
|
87
|
+
# <tr><td><a href='koko</td></tr>...
|
|
88
|
+
# passes with obvious results :(
|
|
89
|
+
# even the following fucks up browsers:
|
|
90
|
+
# <tr><td><p href='koko</td></tr>
|
|
91
|
+
#
|
|
92
|
+
# We HAVE TO CHECK VALID XHTML/XML before using this method.
|
|
93
|
+
#
|
|
94
|
+
# <img> is NOT a safe tag, because it can fuckup the
|
|
95
|
+
# layout, so it is not included in the default safe tags
|
|
96
|
+
#
|
|
97
|
+
# on open
|
|
98
|
+
#
|
|
99
|
+
# === Input:
|
|
100
|
+
# the string to be filtered
|
|
101
|
+
# extra exclude_tags
|
|
102
|
+
# extra include_tags
|
|
103
|
+
#
|
|
104
|
+
# === Output:
|
|
105
|
+
# the filtered string, only contains safe html tags
|
|
106
|
+
|
|
107
|
+
OPEN_TAGS = /<([^<>]*)(?=<)/
|
|
108
|
+
VALID_TAGS = /<([^<>]*)>(?=<)/
|
|
109
|
+
OPEN_QUOTES = /['"]([^'"]*)(?!['"])/
|
|
110
|
+
|
|
111
|
+
def self.only_safe_tags(string, exclude_tags = nil, include_tags = nil)
|
|
112
|
+
return nil unless string
|
|
113
|
+
|
|
114
|
+
# default safe tags
|
|
115
|
+
# FIXME: move the array outside of the method to avoid
|
|
116
|
+
# excessive array creation
|
|
117
|
+
|
|
118
|
+
safe_tags = ["A", "B", "I", "U", "BR", "STRONG", "LI"]
|
|
119
|
+
|
|
120
|
+
# customize if necessary
|
|
121
|
+
safe_tags += exclude_tags if exclude_tags
|
|
122
|
+
safe_tags -= include_tags if include_tags
|
|
123
|
+
|
|
124
|
+
# try to fix up invalid XHTML tags: close brackets, and
|
|
125
|
+
# escape quotes of open tags.
|
|
126
|
+
# SOS: keep the order of the escapes!
|
|
127
|
+
|
|
128
|
+
escaped = string.gsub(OPEN_TAGS, '<\1>')
|
|
129
|
+
escaped = CGI::escapeHTML(escaped)
|
|
130
|
+
escaped = CGI::unescapeElement(escaped, safe_tags)
|
|
131
|
+
escaped.gsub!(/"/, '"')
|
|
132
|
+
escaped.gsub!(/'/, ''')
|
|
133
|
+
|
|
134
|
+
return escaped
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# convert plain newlines into line breaks <br/>
|
|
138
|
+
|
|
139
|
+
def self.convert_newlines(string)
|
|
140
|
+
return nil unless N::StringUtils.valid?(string)
|
|
141
|
+
xstring = string.gsub(/\n/, "<br/>")
|
|
142
|
+
return xstring;
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
end # module
|
data/lib/n/utils/http.rb
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# = HTTP utilities collection
|
|
2
|
+
#
|
|
3
|
+
# Some older functionality is removed, use open-uri instead.
|
|
4
|
+
#
|
|
5
|
+
# code:: tml, drak, ekarak
|
|
6
|
+
#
|
|
7
|
+
# (c) 2004 Navel, all rights reserved.
|
|
8
|
+
# $Id: http.rb 71 2004-10-18 10:50:22Z gmosx $
|
|
9
|
+
|
|
10
|
+
require "uri"
|
|
11
|
+
require "cgi"
|
|
12
|
+
require "net/http"
|
|
13
|
+
|
|
14
|
+
module N
|
|
15
|
+
|
|
16
|
+
module HTTP
|
|
17
|
+
# HTTP protocol EOL constants
|
|
18
|
+
|
|
19
|
+
CR = "\x0d"
|
|
20
|
+
LF = "\x0a"
|
|
21
|
+
CRLF = "\x0d\x0a"
|
|
22
|
+
EOL = CRLF
|
|
23
|
+
|
|
24
|
+
# Http protocol status codes maps.
|
|
25
|
+
|
|
26
|
+
# constants for readable code
|
|
27
|
+
|
|
28
|
+
STATUS_OK = 200
|
|
29
|
+
STATUS_PARTIAL_CONTENT = 206
|
|
30
|
+
STATUS_MOVED = 301
|
|
31
|
+
STATUS_REDIRECT = 302
|
|
32
|
+
STATUS_SEE_OTHER = 303 # gmosx: VERIFY THIS
|
|
33
|
+
STATUS_SEE_OTHER_307 = 307 # gmosx: VERIFY THIS
|
|
34
|
+
STATUS_NOT_MODIFIED = 304
|
|
35
|
+
STATUS_BAD_REQUEST = 400
|
|
36
|
+
STATUS_AUTH_REQUIRED = 401
|
|
37
|
+
STATUS_FORBIDDEN = 403
|
|
38
|
+
STATUS_NOT_FOUND = 404
|
|
39
|
+
STATUS_METHOD_NOT_ALLOWED = 405
|
|
40
|
+
STATUS_NOT_ACCEPTABLE = 406
|
|
41
|
+
STATUS_LENGTH_REQUIRED = 411
|
|
42
|
+
STATUS_PRECONDITION_FAILED = 412
|
|
43
|
+
STATUS_SERVER_ERROR = 500
|
|
44
|
+
STATUS_NOT_IMPLEMENTED = 501
|
|
45
|
+
STATUS_BAD_GATEWAY = 502
|
|
46
|
+
STATUS_VARIANT_ALSO_VARIES = 506
|
|
47
|
+
|
|
48
|
+
# hash to allow id to description maping.
|
|
49
|
+
|
|
50
|
+
STATUS_STRINGS = {
|
|
51
|
+
200 => "OK",
|
|
52
|
+
206 => "Partial Content",
|
|
53
|
+
300 => "Multiple Choices",
|
|
54
|
+
301 => "Moved Permanently",
|
|
55
|
+
302 => "Found",
|
|
56
|
+
303 => "See other", # gmosx: VERIFY THIS
|
|
57
|
+
304 => "Not Modified",
|
|
58
|
+
307 => "See other 07", # gmosx: VERIFY THIS
|
|
59
|
+
400 => "Bad Request",
|
|
60
|
+
401 => "Authorization Required",
|
|
61
|
+
403 => "Forbidden",
|
|
62
|
+
404 => "Not Found",
|
|
63
|
+
405 => "Method Not Allowed",
|
|
64
|
+
406 => "Not Acceptable",
|
|
65
|
+
411 => "Length Required",
|
|
66
|
+
412 => "Rrecondition Failed",
|
|
67
|
+
500 => "Internal Server Error",
|
|
68
|
+
501 => "Method Not Implemented",
|
|
69
|
+
502 => "Bad Gateway",
|
|
70
|
+
506 => "Variant Also Negotiates"
|
|
71
|
+
}
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# = HttpUtils
|
|
75
|
+
#
|
|
76
|
+
module HttpUtils
|
|
77
|
+
|
|
78
|
+
# Converts the given time object to an http time string.
|
|
79
|
+
# Example:
|
|
80
|
+
# Sat, 01 Jan 2000 00:00:00 GMT
|
|
81
|
+
#
|
|
82
|
+
def self.time_to_string(time)
|
|
83
|
+
return CGI::rfc1123_date(time)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# NOT IMPLEMENTED
|
|
87
|
+
#
|
|
88
|
+
# Converts an http time string to a time object.
|
|
89
|
+
# Example:
|
|
90
|
+
# Sat, 01 Jan 2000 00:00:00 GMT
|
|
91
|
+
#
|
|
92
|
+
def self.string_to_time(string)
|
|
93
|
+
raise "Not implemented"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
end # module
|