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,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>