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,91 @@
1
+ # = General time utilities collection
2
+ #
3
+ # code: gmosx
4
+ #
5
+ # (c) 2004 Navel, all rights reserved.
6
+ # $Id: time.rb 71 2004-10-18 10:50:22Z gmosx $
7
+
8
+ require "time.rb"
9
+
10
+ module N;
11
+
12
+ # = TimeUtils
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
+ # - SOS: add test units.
24
+ # - add aliases for those methods in Kernel ?
25
+ #
26
+ module TimeUtils
27
+
28
+ NOW = Time.now
29
+ NEVER = Time.mktime(2038)
30
+ ZERO = Time.mktime(1972)
31
+
32
+ #
33
+ #
34
+ def self.date_time(time)
35
+ return nil unless time
36
+ return time.strftime("%d-%m-%Y %H:%M")
37
+ end
38
+
39
+ # this method calculates the days extrema given two time objects.
40
+ # start time is the given time1 at 00:00:00
41
+ # end time is the given time2 at 23:59:59:999
42
+ #
43
+ # Input:
44
+ # - the two times (if only time1 is provided then you get an extrema
45
+ # of exactly one day extrema.
46
+ #
47
+ # Output
48
+ # - the time range. you can get the start/end times using
49
+ # range methods.
50
+ #
51
+ def self.days_extrema(time1, time2=nil)
52
+ time2 = time1 if (not time2.valid? Time)
53
+ time2 = NEVER if (time2 <= time1)
54
+ start_time = Time.self.start_of_day(time1)
55
+ end_time = self.end_of_day(time2)
56
+ return (start_time..end_time)
57
+ end
58
+
59
+ #
60
+ # set time to start of day
61
+ #
62
+ def self.start_of_day(time)
63
+ return Time.mktime(time.year, time.month, time.day, 0, 0, 0, 0)
64
+ end
65
+
66
+ #
67
+ # set time to end of day
68
+ #
69
+ def self.end_of_day(time)
70
+ return Time.mktime(time.year, time.month, time.day, 23, 59, 59, 999)
71
+ end
72
+
73
+
74
+ # returns true only if day of time is included in the
75
+ # range (stime..etime). Only year days are checked.
76
+ #
77
+ def self.time_in_day_range(time, stime=ZERO, etime=NEVER)
78
+ if (etime <= stime)
79
+ $log.debug "Invalid end time (#{etime} < #{stime})" if $DBG
80
+ etime = NEVER
81
+ end
82
+
83
+ stime = start_of_day(stime)
84
+ etime = end_of_day(etime)
85
+
86
+ return (stime..etime).include?(time)
87
+ end
88
+
89
+ end
90
+
91
+ end # module
@@ -0,0 +1,193 @@
1
+ # = URI utilities collection
2
+ #
3
+ # code: gmosx
4
+ #
5
+ # (c) 2004 Navel, all rights reserved.
6
+ # $Id: uri.rb 71 2004-10-18 10:50:22Z gmosx $
7
+
8
+ require "uri"
9
+ require "cgi"
10
+
11
+ require "n/utils/string"
12
+
13
+ module N
14
+
15
+ # = UriUtils
16
+ #
17
+ # === Design:
18
+ #
19
+ # Implement as a module to avoid class polution. You can still
20
+ # use 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
+ # The uris passed as parameters are typically strings.
25
+ #
26
+ module UriUtils
27
+
28
+ # Decode the uri components.
29
+ #
30
+ def self.decode(uri)
31
+ # gmosx: hmm is this needed?
32
+ # guard against invalid filenames for example pictures with
33
+ # spaces uploaded by users
34
+ escaped_uri = uri.gsub(/ /, "+")
35
+
36
+ if md = URI::REGEXP::REL_URI.match(escaped_uri)
37
+
38
+ path = "#{md[5]}#{md[6]}"
39
+ type = N::StringUtils.extension_from_path(path)
40
+ query_string = md[7]
41
+
42
+ # real_path = "#{$root_dir}/#{path}"
43
+
44
+ parameters = N::UriUtils.query_string_to_hash(query_string)
45
+ path.gsub!(/\+/, " ")
46
+
47
+ return [path, type, parameters, query_string]
48
+
49
+ end # match
50
+
51
+ # this is usefull for uncovering bugs!
52
+ raise ArgumentError.new("the parameter '#{uri}' is not a valid uri")
53
+ end
54
+
55
+ # Extend the basic query string parser provided by the cgi module.
56
+ # converts single valued params (the most common case) to
57
+ # objects instead of arrays
58
+ #
59
+ # Input:
60
+ # the query string
61
+ #
62
+ # Output:
63
+ # hash of parameters, contains arrays for multivalued parameters
64
+ # (multiselect, checkboxes , etc)
65
+ # If no query string is provided (nil or "") returns an empty hash.
66
+ #
67
+ def self.query_string_to_hash(query_string)
68
+ return {} unless query_string
69
+
70
+ query_parameters = CGI::parse(query_string)
71
+
72
+ query_parameters.each { |key, val|
73
+ # replace the array with an object
74
+ query_parameters[key] = val[0] if 1 == val.length
75
+ }
76
+
77
+ # set default value to nil! cgi sets this to []
78
+ query_parameters.default = nil
79
+
80
+ return query_parameters
81
+ end
82
+
83
+ # Given a hash with parameter/value pairs construct a
84
+ # standard query string. This method only encodes simple
85
+ # types (Numeric, String) to avoid query string polution
86
+ # with marshal, etc.
87
+ #
88
+ # gmosx, FIXME: only numeric and strings are passed to
89
+ # the latest code, so update old code and optimize this!
90
+ #
91
+ # Input:
92
+ # the parameter hash
93
+ #
94
+ # Output:
95
+ # the query string
96
+
97
+ def self.hash_to_query_string(parameters)
98
+ return nil unless parameters
99
+ pairs = []
100
+ parameters.each { |param, value|
101
+ # only encode simple classes !
102
+
103
+ if value.is_a?(Numeric) or value.is_a?(String)
104
+ pairs << "#{param}=#{value}"
105
+ end
106
+ }
107
+ return pairs.join(";")
108
+ end
109
+
110
+ # This method returns the query string of a uri
111
+ #
112
+ # Input:
113
+ # the uri
114
+ #
115
+ # Output:
116
+ # the query string.
117
+ # returns nil if no query string
118
+
119
+ def self.get_query_string(uri)
120
+ return nil unless uri
121
+ # gmosx: INVESTIGATE ruby's URI seems to differently handle
122
+ # abs and rel uris.
123
+ if md = URI::REGEXP::ABS_URI.match(uri)
124
+ return md[8]
125
+ elsif md = URI::REGEXP::REL_URI.match(uri)
126
+ return md[7]
127
+ end
128
+ return nil
129
+ end
130
+
131
+ # Removes the query string from a uri
132
+ #
133
+ # Input:
134
+ # the uri
135
+ #
136
+ # Output:
137
+ # the chomped uri.
138
+
139
+ def self.chomp_query_string(uri)
140
+ return nil unless uri
141
+ query_string = self.get_query_string(uri)
142
+ return uri.dup.chomp("?#{query_string}")
143
+ end
144
+
145
+ # Get a uri and a hash of parameters. Inject the hash values
146
+ # as parameters in the query sting path. Returns the full
147
+ # uri.
148
+ #
149
+ # Input:
150
+ # the uri to filter (String)
151
+ # hash of parameters to update
152
+ #
153
+ # Output:
154
+ # the full updated query string
155
+ #
156
+ # === TODO:
157
+ # optimize this a litle bit.
158
+ #
159
+ def self.update_query_string(uri, parameters)
160
+ query_string = self.get_query_string(uri)
161
+ rest = uri.dup.gsub(/\?#{query_string}/, "")
162
+
163
+ hash = self.query_string_to_hash(query_string)
164
+ hash.update(parameters)
165
+ query_string = self.hash_to_query_string(hash)
166
+
167
+ if N::StringUtils.valid?(query_string)
168
+ return "#{rest}?#{query_string}"
169
+ else
170
+ return rest
171
+ end
172
+ end
173
+
174
+ # TODO: find a better name.
175
+ # Gets the request uri, injects extra parameters in the query string
176
+ # and returns a new uri. The request object is not modified.
177
+ # There is always a qs string so an extra test is skipped.
178
+ #
179
+ def self.update_request_uri(request, parameters)
180
+ hash = request.parameters.dup()
181
+ hash.update(parameters)
182
+
183
+ # use this in hash_to_querystring.
184
+ query_string = hash.collect { |k, v|
185
+ "#{k}=#{v}"
186
+ }.join(";")
187
+
188
+ return "#{request.translated_uri}?#{query_string}"
189
+ end
190
+
191
+ end
192
+
193
+ end # module
@@ -0,0 +1,205 @@
1
+ <?xml version='1.0' ?>
2
+
3
+ <!--
4
+ author: gmosx
5
+ -->
6
+
7
+ <!DOCTYPE shader
8
+ [
9
+ <!ENTITY nbsp "<![CDATA[&nbsp;]]>">
10
+ <!ENTITY copy "<![CDATA[&copy;]]>">
11
+ <!ENTITY euro "<![CDATA[&euro;]]>">
12
+ <!ENTITY laquo "<![CDATA[&laquo;]]>">
13
+ <!ENTITY raquo "<![CDATA[&raquo;]]>">
14
+ ]>
15
+
16
+ <xsl:stylesheet
17
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
18
+ xmlns:xl="http://www.w3.org/1999/xlink"
19
+ xmlns:x="http://www.navel.gr/xml/shader.xsd"
20
+ exclude-result-prefixes="x xl"
21
+ version="1.0">
22
+
23
+ <!-- parameters and constants -->
24
+
25
+ <!-- <xsl:variable name='css'>style.css</xsl:variable> -->
26
+ <!-- <xsl:variable name='lang'>el</xsl:variable> -->
27
+
28
+ <!-- strip comments -->
29
+ <xsl:template match="comment()">
30
+ <!-- strip -->
31
+ </xsl:template>
32
+
33
+ <!-- only copy ruby/r processing instructions -->
34
+
35
+ <xsl:template match='processing-instruction("ruby")'>
36
+ <xsl:copy/>
37
+ </xsl:template>
38
+ <xsl:template match='processing-instruction("r")'>
39
+ <xsl:copy/>
40
+ </xsl:template>
41
+ <xsl:template match='processing-instruction("include")'>
42
+ <xsl:copy/>
43
+ </xsl:template>
44
+
45
+ <!-- copy other tags -->
46
+ <xsl:template match="@* | * | text()">
47
+ <xsl:copy>
48
+ <xsl:apply-templates select="@* | * | text() | processing-instruction()"/>
49
+ </xsl:copy>
50
+ </xsl:template>
51
+
52
+ <!-- root element -->
53
+ <xsl:template match="root">
54
+ <xsl:apply-templates/>
55
+ </xsl:template>
56
+
57
+ <!-- create a new, nested output buffer -->
58
+ <xsl:template name="x:ob-start" match="x:ob-start">
59
+ <xsl:processing-instruction name='ruby'>
60
+ <![CDATA[__out_buffers = [] unless __out_buffers
61
+ __out_buffers.push(__out)
62
+ __out = ""]]>
63
+ </xsl:processing-instruction>
64
+ </xsl:template>
65
+
66
+ <!-- close a nested output buffer -->
67
+ <xsl:template name="x:ob-end" match="x:ob-end">
68
+ <xsl:processing-instruction name='ruby'>
69
+ <![CDATA[__out == __out_buffers.pop()]]>
70
+ </xsl:processing-instruction>
71
+ </xsl:template>
72
+
73
+ <!-- NOT WORKING YET -->
74
+ <xsl:template name="x:cache" match="x:cache">
75
+ <xsl:processing-instruction name='ruby'>
76
+ <![CDATA[__out == __out_buffers.pop()]]>
77
+ </xsl:processing-instruction>
78
+ </xsl:template>
79
+
80
+ <!-- form errors temlate -->
81
+ <xsl:template name='x:form-errors' match='x:form-errors'>
82
+ <xsl:processing-instruction name='ruby'>
83
+ <![CDATA[if errors = request.errors_to_a()
84
+ __out << %{ <div class="errors"><b>ERRORS:</b><br />#{errors.join("<br />")}</div>}
85
+ end]]>
86
+ </xsl:processing-instruction>
87
+ </xsl:template>
88
+
89
+ <xsl:template match='x:cell'>
90
+ <xsl:apply-templates/>
91
+ </xsl:template>
92
+
93
+ <!-- better use css :) -->
94
+ <xsl:template name="x:vblank" match="x:vblank">
95
+ <xsl:param name="height"><xsl:value-of select="@height"/></xsl:param>
96
+ <img src="d.gif" width="0" height="{$height}"/>
97
+ </xsl:template>
98
+
99
+ <xsl:template name="x:hblank" match="x:hblank">
100
+ <xsl:param name="width"><xsl:value-of select="@width"/></xsl:param>
101
+ <img src="d.gif" height="0" width="{$width}"/>
102
+ </xsl:template>
103
+
104
+ <!-- button links -->
105
+
106
+ <!--
107
+ ex:
108
+ <x:link class="m/delete.gif" title="Delete" href="r/glue/c/cmd.rb?oid=2" />
109
+ TODO: handle onclick too!
110
+ -->
111
+ <xsl:template match="x:link">
112
+ <xsl:param name="class"><xsl:value-of select="@class" /></xsl:param>
113
+ <xsl:param name="href"><xsl:value-of select="@href" /></xsl:param>
114
+ <xsl:param name="onclick"><xsl:value-of select="@onclick" /></xsl:param>
115
+ <a href="{$href}" class="{$class}">
116
+ <span><xsl:value-of select="@title" /></span>
117
+ <xsl:apply-templates />
118
+ </a>
119
+ </xsl:template>
120
+
121
+ <!--
122
+ ex:
123
+ <x:link class="m/delete.gif" title="Delete" onclick="javascript: alert('3')" />
124
+ -->
125
+ <xsl:template match="x:jslink">
126
+ <xsl:param name="class"><xsl:value-of select="@class"/></xsl:param>
127
+ <xsl:param name="onclick"><xsl:value-of select="@onclick"/></xsl:param>
128
+ <a href="#" onclick="{$onclick}" class="{$class}">
129
+ <span><xsl:value-of select="@title" /></span>
130
+ <xsl:apply-templates />
131
+ </a>
132
+ </xsl:template>
133
+
134
+ <!--
135
+ emit some extra divs to allow greater flexibility in css styling.
136
+ use those divs to add extra pictures and fancy stuff!
137
+
138
+ TODO:
139
+ find a better name.
140
+ -->
141
+ <xsl:template name="x:extra-divs" match="x:extra-divs">
142
+ <div id="extra0"><span></span></div>
143
+ <div id="extra1"><span></span></div>
144
+ <div id="extra2"><span></span></div>
145
+ <div id="extra3"><span></span></div>
146
+ <div id="extra4"><span></span></div>
147
+ <div id="extra5"><span></span></div>
148
+ <div id="extra6"><span></span></div>
149
+ <div id="extra7"><span></span></div>
150
+ </xsl:template>
151
+
152
+ <xsl:template match="x:clear" name="x:clear">
153
+ <div class="clear">.</div>
154
+ </xsl:template>
155
+
156
+ <!-- check for admin rights, gmosx: not really usefull I think -->
157
+ <xsl:template name='x:if-admin' match='x:if-admin'>
158
+ <xsl:processing-instruction name='ruby'>
159
+ <![CDATA[if admin]]>
160
+ </xsl:processing-instruction>
161
+ <xsl:apply-templates />
162
+ <xsl:processing-instruction name='ruby'>
163
+ <![CDATA[end]]>
164
+ </xsl:processing-instruction>
165
+ </xsl:template>
166
+
167
+
168
+ <!-- admin ui -->
169
+ <xsl:template name='x:admin-ui' match='x:admin-ui'>
170
+ <xsl:processing-instruction name='ruby'>
171
+ <![CDATA[if admin]]>
172
+ </xsl:processing-instruction>
173
+ <span class="admin">
174
+ <xsl:apply-templates />
175
+ </span>
176
+ <xsl:processing-instruction name='ruby'>
177
+ <![CDATA[end]]>
178
+ </xsl:processing-instruction>
179
+ </xsl:template>
180
+
181
+ <!-- transaction form -->
182
+ <xsl:template name='x:form-pass-txid' match='x:form-pass-txid'>
183
+ <input type="hidden" name="txid">
184
+ <!-- gmosx: keep in one line! -->
185
+ <xsl:attribute name="value"><![CDATA[#{request['txid']}]]></xsl:attribute>
186
+ </input>
187
+ </xsl:template>
188
+
189
+ <!--
190
+ Background dispatcher
191
+ A clever hack, web actions are performed in the background without
192
+ redirecting.
193
+ -->
194
+ <xsl:template name='x:dispatcher' match='x:dispatcher'>
195
+ <img id="_dispatch" src="d.gif" alt="" style="display: none" />
196
+ <script type="text/javascript">
197
+ <![CDATA[
198
+ function dispatch(dispatch_url) {
199
+ d = document.getElementById('_dispatch').src = dispatch_url;
200
+ }
201
+ ]]>
202
+ </script>
203
+ </xsl:template>
204
+
205
+ </xsl:stylesheet>