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,154 @@
1
+ # = Part
2
+ #
3
+ # A part encapsulates a service in the Framework.
4
+ #
5
+ # code:
6
+ # George Moschovitis <gm@navel.gr>
7
+ #
8
+ # (c) 2004 Navel, all rights reserved.
9
+ # $Id: parts.rb 71 2004-10-18 10:50:22Z gmosx $
10
+
11
+ require "singleton"
12
+
13
+ require "n/l10n"
14
+
15
+ # gmosx, FIXME: safe is probably NOT needed!
16
+ $parts = N::SafeHash.new
17
+ $rewrites = N::SafeHash.new
18
+ $roles = N::SafeArray.new
19
+
20
+ module Kernel
21
+
22
+ # Special require for part definitions.
23
+ #
24
+ def require_part(path)
25
+ require("p/#{path}/part")
26
+ for lc in $lc_use
27
+ begin
28
+ require("p/#{path}/#{lc}")
29
+ rescue LoadError => e
30
+ # Drink it!
31
+ # $log.debug "No localization files for part '#{path}'" if $DBG
32
+ end
33
+ end
34
+ end
35
+
36
+ # Register a part
37
+ #
38
+ def register_part(part_class)
39
+ part = part_class.instance()
40
+ $parts[part.name] = part
41
+
42
+ # gmosx: DOESNT work yet, we have to manage
43
+ # the require order, perhaps DI/Copland can help
44
+ # here?
45
+ # auto require the parts this one depends
46
+ # on.
47
+ #
48
+ #for dep_part in part.dependencies
49
+ # require_part(dep_part)
50
+ #end
51
+
52
+ part.start()
53
+ end
54
+
55
+ end
56
+
57
+ # ----------------------------------------------------------------------
58
+
59
+ module N
60
+
61
+ # = Part
62
+ #
63
+ # A module of functionality in the framework
64
+ #
65
+ # = Design:
66
+ #
67
+ # Q: Part should include Entity to allow optional runtime
68
+ # administration/customization ??
69
+ #
70
+ class Part
71
+ include Singleton
72
+
73
+ # the (internal) name of this part
74
+ attr_accessor :name
75
+ # the tile of this part (intended for humans)
76
+ attr_accessor :title
77
+ # a description of the part
78
+ attr_accessor :body
79
+ # the version of this part
80
+ attr_accessor :version
81
+ # the vendor
82
+ attr_accessor :vendor
83
+ # url of the vendor's homepage.
84
+ attr_accessor :vendor_url
85
+ # an array of part names this part depends on. The named
86
+ # parts are automatically required when requiring this part.
87
+ attr_accessor :dependencies
88
+
89
+ prop_accessor String, :path
90
+
91
+ def initialize
92
+ sitemap()
93
+ rewrites()
94
+ roles()
95
+ prepared_statements()
96
+ end
97
+
98
+ # Install this part to the application. Called
99
+ # by the application installation scripts. Typically
100
+ # inserts bootstrap data in the database
101
+ #
102
+ def install
103
+ end
104
+
105
+ # Uninstall this part. Typically cleans up the
106
+ # database.
107
+ #
108
+ def unistall
109
+ end
110
+
111
+ #
112
+ #
113
+ def start
114
+ end
115
+
116
+ #
117
+ #
118
+ def stop
119
+ end
120
+
121
+ # Define the pages this part introduces.
122
+ #
123
+ def sitemap
124
+ end
125
+
126
+ # Define the rewrite rules for this part.
127
+ #
128
+ def rewrites
129
+ end
130
+
131
+ # Define the roles this part introduces.
132
+ #
133
+ def roles
134
+ end
135
+
136
+ # Define usefull prepared statements for this
137
+ # part
138
+ #
139
+ def prepared_statements
140
+ end
141
+
142
+ #
143
+ #
144
+ def to_s
145
+ @name
146
+ end
147
+ end
148
+
149
+ end # module
150
+
151
+ # Namespace for parts.
152
+ #
153
+ module P
154
+ end # module
@@ -0,0 +1,194 @@
1
+ # = Properties support
2
+ #
3
+ # Ruby attributes are typeless and generally this is good. Some times
4
+ # we need extra metadata though, for example in relational mapping, or
5
+ # web form population.
6
+ #
7
+ # Only Fixnums, Strings, Floats, Times, Booleans are converted.
8
+ #
9
+ # The default = methods do not force the types. A special
10
+ # __force_set method should be used instead.
11
+ #
12
+ # TODO:
13
+ # Perhaps a sync is needed in evals (!!!!)
14
+ #
15
+ # code: gmosx, drak, ekarak
16
+ #
17
+ # (c) 2004 Navel, all rights reserved.
18
+ # $Id: properties.rb 71 2004-10-18 10:50:22Z gmosx $
19
+
20
+ require "n/utils/array"
21
+ require "n/utils/hash"
22
+
23
+ module N
24
+
25
+ # Property Metadata
26
+ #
27
+ # === Design:
28
+ # - add default value in the extra sql
29
+ #
30
+ class Property
31
+ # the symbol of the property
32
+ attr_accessor :symbol
33
+ # the string representation of the symbol
34
+ attr_accessor :name
35
+ # the class of the property
36
+ attr_accessor :klass
37
+ # extra sql options for the property. if set,
38
+ # it must contain the sql_type for this class, the
39
+ # default is overriden.
40
+ attr_accessor :sql
41
+
42
+ def initialize(symbol, klass, sql = nil)
43
+ @symbol, @klass = symbol, klass
44
+ @sql = sql
45
+ @name = @symbol.to_s()
46
+ end
47
+
48
+ def ==(other)
49
+ return @symbol == other.symbol
50
+ end
51
+ end
52
+
53
+ end # module
54
+
55
+ class Module
56
+
57
+ # Properties
58
+ # An array is used to enforce order.
59
+ attr_accessor :__props
60
+
61
+ # Metadata
62
+ # A hash of module metadata.
63
+ attr_accessor :__meta
64
+
65
+ # Define a property (== typed attribute)
66
+ # based on draks property redesign!
67
+ #
68
+ # ex:
69
+ # prop_accessor String, :title, :body
70
+ # prop_accessor String, "char(10) NOT NULL", :title, :body
71
+ #
72
+ def prop_accessor(*params)
73
+ klass = params.shift
74
+
75
+ # if the next param is a String, it is
76
+ # extra sql metadata.
77
+ if params.first.is_a?(String)
78
+ sql = params.shift
79
+ else
80
+ sql = nil
81
+ end
82
+
83
+ # the rest of params are symbols
84
+
85
+ @__props = N::SafeArray.new() unless @__props
86
+
87
+ params.each { |s|
88
+ add_prop(N::Property.new(s, klass, sql))
89
+ }
90
+ end
91
+ # to be compatible with ruby parlance
92
+ alias_method :prop, :prop_accessor
93
+
94
+ # Add the property
95
+ # Optimize this
96
+ #
97
+ def add_prop(prop)
98
+ if idx = @__props.index(prop)
99
+ # override in case of duplicates. Keep the order of the props.
100
+ @__props[idx] = prop
101
+ else
102
+ @__props << prop
103
+ end
104
+
105
+ # Precompile the property read/write methods
106
+
107
+ s, klass = prop.symbol, prop.klass
108
+
109
+ module_eval %{
110
+ def #{s}
111
+ return @#{s}
112
+ end
113
+
114
+ def #{s}=(val)
115
+ @#{s} = val
116
+ end
117
+
118
+ def __force_#{s}(val)
119
+ @#{s} = } + case klass.name
120
+ when Fixnum.name
121
+ "val.to_i()"
122
+ when String.name
123
+ "val.to_s()"
124
+ when Float.name
125
+ "val.to_f()"
126
+ when Time.name
127
+ "Time.parse(val.to_s())"
128
+ when TrueClass.name, FalseClass.name
129
+ "val.to_i() > 0"
130
+ else
131
+ "val"
132
+ end + %{
133
+ end
134
+ }
135
+ end
136
+
137
+ # Attach metadata
138
+ #
139
+ def meta(key, val)
140
+ @__meta = N::SafeHash.new unless @__meta
141
+ add_meta(key, val)
142
+ end
143
+
144
+ # Add the metadata
145
+ # TODO: Optimize this
146
+ #
147
+ def add_meta(key, val)
148
+ @__meta[key] = [] unless @__meta[key]
149
+
150
+ # guard against duplicates, no need to keep order.
151
+ @__meta[key].delete_if { |v| val == v }
152
+ @__meta[key] << val
153
+ end
154
+
155
+ # This method is typically called before including other
156
+ # modules to preserve properties order.
157
+ #
158
+ def inherit_meta(mod = superclass)
159
+ # concat props.
160
+ if mod.__props
161
+ @__props = N::SafeArray.new unless @__props
162
+
163
+ mod.__props.each { |p|
164
+ add_prop(p)
165
+ }
166
+ end
167
+
168
+ # concat metadata
169
+ if mod.__meta
170
+ mod.__meta.each { |k, val|
171
+ val.each { |v|
172
+ meta(k, v)
173
+ } if val
174
+ }
175
+ end
176
+ end
177
+
178
+ # Override the default include method to also include the metadata.
179
+ # WARNING: can cause infinite loop if overriden again!
180
+ #
181
+ alias_method :old_include, :include
182
+
183
+ # A new version of include that includes the properties too.
184
+ #
185
+ def include(*modules)
186
+ old_include(*modules)
187
+
188
+ for m in modules
189
+ inherit_meta(m)
190
+ end
191
+ end
192
+
193
+ end
194
+
@@ -0,0 +1,61 @@
1
+ # = Server
2
+ #
3
+ # Generic server infrastructure
4
+ #
5
+ # code:: gmosx
6
+ #
7
+ # (c) 2004 Navel, all rights reserved.
8
+ # $Id: server.rb 71 2004-10-18 10:50:22Z gmosx $
9
+
10
+ require "n/application"
11
+
12
+ module N
13
+
14
+ # = Server
15
+ #
16
+ # Base server class
17
+ #
18
+ class Server < N::Application
19
+ # the listening address/port for this server.
20
+ attr_reader :address, :port
21
+
22
+ def initialize(name = "Server")
23
+ super
24
+ end
25
+
26
+ # Start the server
27
+ #
28
+ def start
29
+ super
30
+ end
31
+
32
+ # Stop the server
33
+ #
34
+ def stop
35
+ super
36
+ end
37
+
38
+ # The main server loop
39
+ #
40
+ def run
41
+ begin
42
+ while :RUNNING == @status
43
+ if live = IO.select(@ios, nil, nil, 2.0)
44
+
45
+ end
46
+ end
47
+ rescue
48
+
49
+ end
50
+ end
51
+
52
+ # Override this method in your custom server. This method is very
53
+ # flexible, you can spawn threads, use keep alive connections,
54
+ # handle+close, use handler pools, anything.
55
+ #
56
+ def handle
57
+ end
58
+
59
+ end
60
+
61
+ end # module
@@ -0,0 +1,8 @@
1
+
2
+
3
+ overload the servers accept method to store socket data in RECORD mode
4
+ and read sockets from a previously recorded stream in PLAYBACK mode.
5
+
6
+ timing information must be stored along the socket data
7
+
8
+ the centralized accept methot makes the scheme possible.
@@ -0,0 +1,13 @@
1
+
2
+ patterns: ObjectPool, ProducerConsumer
3
+
4
+ produced consumer pattern: listener produces sockets, thread pool consumes
5
+ sockets from a queue.
6
+
7
+ --
8
+
9
+ gmosx: daemons does not belong here ??
10
+ gmosx: do not use a thread per connection, use a pool of conections that service
11
+ a fifo list of connections (sockets).
12
+
13
+ gmosx: use a pipeline request handling architecture
@@ -0,0 +1,77 @@
1
+ # = Server filter
2
+ #
3
+ # code:
4
+ # George Moschovitis <gm@navel.gr>
5
+ #
6
+ # (c) 20024 Navel, all rights reserved.
7
+ # $Id: filter.rb 71 2004-10-18 10:50:22Z gmosx $
8
+
9
+ require "socket"
10
+ require "thread"
11
+ require "sync"
12
+
13
+ module N
14
+
15
+ # == Filter
16
+ #
17
+ # A server serves client requests by feeding the request/request pair
18
+ # to a pipeline of processing filters. This is not a simple linear pipeline.
19
+ # Instead it is what we call a 'folding' (hierarchical) pipeline: each
20
+ # filter encapsulates the next. In effect, the pipeline is a generalized
21
+ # filter!
22
+ #
23
+ # === Design:
24
+ #
25
+ # Filters are NOT singleton classes. This way we can assign one filter
26
+ # class to multiple resources, and keep statistics and metrics for
27
+ # each resource.
28
+ # A filter may contain state (attributes) for example metrics.
29
+ #
30
+ class ServerFilter
31
+ # the next filter in the pipeline.
32
+ attr_reader :next_filter
33
+
34
+ # set the filters next.
35
+ #
36
+ # example:
37
+ # LogFilter.new(TimeFilter.new(PageFilter.new))
38
+
39
+ def initialize(next_filter = nil)
40
+ @next_filter = next_filter
41
+ end
42
+
43
+ # set the filters next (next_filter).
44
+ #
45
+ # example:
46
+ # LogFilter.new << TimeFilter.new << PageFilter.new
47
+
48
+ def << (next_filter = nil)
49
+ @next_filter = next_filter
50
+ end
51
+
52
+ # override this method to implement your filter.
53
+
54
+ def process(request)
55
+ # preprocessing comes here...
56
+
57
+ # walk the pipeline
58
+ return process_next(request)
59
+
60
+ # postprocessing comes here...
61
+
62
+ # return the result...
63
+ end
64
+
65
+ # process the next filter in the pipeline
66
+
67
+ def process_next(request)
68
+ if @next_filter
69
+ return @next_filter.process(request)
70
+ else
71
+ return nil
72
+ end
73
+ end
74
+
75
+ end
76
+
77
+ end # module