nitro 0.5.0 → 0.6.0

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 (50) hide show
  1. data/ChangeLog +4 -2201
  2. data/ChangeLog.1 +2344 -0
  3. data/README +4 -4
  4. data/RELEASES +22 -0
  5. data/bin/new_app.rb +17 -3
  6. data/bin/proto/README +34 -0
  7. data/bin/proto/apache.conf +1 -0
  8. data/bin/proto/app.rb +20 -0
  9. data/bin/proto/config.rb +77 -0
  10. data/bin/proto/root/index.xhtml +43 -0
  11. data/bin/proto/root/style.css +218 -0
  12. data/bin/proto/root/style.xsl +130 -0
  13. data/examples/blog/app.rb +1 -2
  14. data/examples/blog/config.rb +20 -18
  15. data/examples/blog/env.rb +22 -0
  16. data/examples/blog/lib/blog.rb +43 -15
  17. data/examples/blog/root/entry_form.xhtml +1 -1
  18. data/examples/blog/root/index.xhtml +5 -0
  19. data/examples/blog/root/login.xhtml +2 -0
  20. data/examples/blog/root/m/nitro.gif +0 -0
  21. data/examples/blog/root/style.css +83 -0
  22. data/examples/blog/root/style.xsl +7 -3
  23. data/examples/og/run.rb +41 -2
  24. data/examples/tiny/app.rb +1 -2
  25. data/examples/tiny/root/index.xhtml +8 -2
  26. data/examples/tiny/root/nitro-small.png +0 -0
  27. data/lib/glue.rb +1 -1
  28. data/lib/glue/property.rb +9 -3
  29. data/lib/nitro/application.rb +18 -1
  30. data/lib/nitro/builders/form.rb +84 -0
  31. data/lib/nitro/builders/rss.rb +4 -5
  32. data/lib/nitro/builders/table.rb +23 -0
  33. data/lib/nitro/filters.rb +157 -0
  34. data/lib/nitro/l10n.rb +11 -3
  35. data/lib/nitro/scaffold.rb +1 -1
  36. data/lib/nitro/server/render.rb +101 -4
  37. data/lib/nitro/server/shaders.rb +17 -5
  38. data/lib/nitro/service.rb +5 -5
  39. data/lib/nitro/ui/pager.rb +35 -11
  40. data/lib/nitro/version.rb +2 -2
  41. data/lib/og.rb +25 -17
  42. data/lib/og/backend.rb +15 -3
  43. data/lib/og/backends/mysql.rb +30 -3
  44. data/lib/og/backends/psql.rb +44 -3
  45. data/lib/og/meta.rb +117 -10
  46. data/lib/og/version.rb +1 -1
  47. data/lib/xsl/base.xsl +75 -6
  48. data/lib/xsl/ui.xsl +51 -0
  49. data/test/nitro/ui/tc_pager.rb +6 -0
  50. metadata +23 -2
@@ -7,7 +7,7 @@ code:
7
7
  * George Moschovitis <gm@navel.gr>
8
8
 
9
9
  (c) 2004 Navel, all rights reserved.
10
- $Id: style.xsl 167 2004-11-23 14:03:10Z gmosx $
10
+ $Id: style.xsl 185 2004-12-10 13:29:09Z gmosx $
11
11
  -->
12
12
 
13
13
  <!DOCTYPE shader
@@ -26,6 +26,7 @@ $Id: style.xsl 167 2004-11-23 14:03:10Z gmosx $
26
26
  exclude-result-prefixes="x xl">
27
27
 
28
28
  <xsl:include href="../../lib/xsl/base.xsl" />
29
+ <xsl:include href="../../lib/xsl/ui.xsl" />
29
30
 
30
31
  <xsl:output method="xml" indent="yes" encoding="iso-8859-1" />
31
32
 
@@ -51,7 +52,7 @@ $Id: style.xsl 167 2004-11-23 14:03:10Z gmosx $
51
52
 
52
53
  <xsl:template name="x:header">
53
54
  <div id="header">
54
- <h1>#$name</h1>
55
+ <h1><a href="/">#$name</a></h1>
55
56
  </div>
56
57
  </xsl:template>
57
58
 
@@ -108,7 +109,10 @@ $Id: style.xsl 167 2004-11-23 14:03:10Z gmosx $
108
109
 
109
110
  <br />
110
111
  <p>
111
- powered by <b><a href="http://www.navel.gr/nitro">Nitro</a></b>
112
+ powered by:<br />
113
+ <div style="padding: 5px; background: #fff; text-align: center; border: 1px solid #ccc">
114
+ <a href="http://www.navel.gr/nitro"><img src="m/nitro.gif" style="border: none" /></a>
115
+ </div>
112
116
  <br />
113
117
  skin from <a href="http://www.blogger.com">Blogger.com</a>
114
118
  </p>
data/examples/og/run.rb CHANGED
@@ -6,7 +6,7 @@
6
6
  # * George Moschovitis <gm@navel.gr>
7
7
  #
8
8
  # (c) 2004 Navel, all rights reserved.
9
- # $Id: run.rb 167 2004-11-23 14:03:10Z gmosx $
9
+ # $Id: run.rb 185 2004-12-10 13:29:09Z gmosx $
10
10
 
11
11
  $:.unshift "../../lib"
12
12
 
@@ -55,6 +55,7 @@ class User
55
55
  end
56
56
  end
57
57
 
58
+
58
59
  # = A parent class
59
60
  #
60
61
  class Article
@@ -95,6 +96,21 @@ class Article
95
96
  end
96
97
  end
97
98
 
99
+ # = A parent class
100
+ #
101
+ class Category
102
+ prop_accessor :title, String
103
+ prop_accessor :body, String
104
+
105
+ # define a 'many to many' relation.
106
+ many_to_many Article
107
+
108
+ def initialize(title = nil)
109
+ @title = title
110
+ end
111
+ end
112
+
113
+
98
114
  # = Article comment
99
115
  #
100
116
  class ArticleComment < Comment
@@ -127,7 +143,6 @@ end
127
143
  $log = Logger.new(STDERR);
128
144
 
129
145
  # Og configuration.
130
-
131
146
  config = {
132
147
  :address => "localhost",
133
148
  :database => "test",
@@ -249,3 +264,27 @@ part.save!
249
264
 
250
265
  article.parts.each { |pa| puts pa }
251
266
 
267
+ puts "\n\n"
268
+ puts '---'
269
+
270
+ c1 = Category.new("Category1").save!
271
+ c2 = Category.new("Category2").save!
272
+
273
+ article.add_category(c1)
274
+ article.add_category(c2)
275
+
276
+ puts '---'
277
+
278
+ article.categories.each { |c| puts c.title }
279
+
280
+ puts '---'
281
+
282
+ c2.articles.each { |a| puts a.title }
283
+
284
+ article.del_category(c1)
285
+
286
+ puts '---'
287
+
288
+ article.categories.each { |c| puts c.title }
289
+
290
+
data/examples/tiny/app.rb CHANGED
@@ -8,11 +8,10 @@
8
8
  # * George Moschovitis <gm@navel.gr>
9
9
  #
10
10
  # (c) 2004 Navel, all rights reserved.
11
- # $Id: app.rb 146 2004-11-13 19:05:06Z gmosx $
11
+ # $Id: app.rb 185 2004-12-10 13:29:09Z gmosx $
12
12
 
13
13
  $DBG = false
14
14
 
15
- $LOAD_PATH.unshift "lib"
16
15
  $LOAD_PATH.unshift "../../lib"
17
16
 
18
17
  require "config"
@@ -15,11 +15,16 @@
15
15
 
16
16
  <!-- the template comes here -->
17
17
 
18
- <h1>Hello #{name}</h1>
18
+ <p>
19
+ <img src="nitro-small.png" />
20
+ </p>
21
+
22
+
23
+ <strong>Hello #{name}</strong>
19
24
 
20
25
  <p>
21
26
  <form id="my_form">
22
- <b>Enter your name:</b>
27
+ <strong>Enter your name:</strong>
23
28
  <input type="text" name="name" />
24
29
  <br />
25
30
  <input type="submit" />
@@ -29,4 +34,5 @@
29
34
  Counter: #{session[:counter]}
30
35
  </p>
31
36
 
37
+
32
38
  </html>
Binary file
data/lib/glue.rb CHANGED
@@ -6,7 +6,7 @@
6
6
  # * George Moschovitis <gm@navel.gr>
7
7
  #
8
8
  # (c) 2004 Navel, all rights reserved.
9
- # $Id$
9
+ # $Id: glue.rb 175 2004-11-26 16:11:27Z gmosx $
10
10
 
11
11
  require "English"
12
12
  require "pp"
data/lib/glue/property.rb CHANGED
@@ -5,7 +5,7 @@
5
5
  # * Elias Karakoulakis <ekarak@ktismata.com>
6
6
  #
7
7
  # (c) 2004 Navel, all rights reserved.
8
- # $Id: property.rb 167 2004-11-23 14:03:10Z gmosx $
8
+ # $Id: property.rb 185 2004-12-10 13:29:09Z gmosx $
9
9
 
10
10
  require "glue/array"
11
11
  require "glue/hash"
@@ -48,6 +48,10 @@ class Property
48
48
  def ==(other)
49
49
  return @symbol == other.symbol
50
50
  end
51
+
52
+ def to_s
53
+ return name
54
+ end
51
55
  end
52
56
 
53
57
  end # module
@@ -236,6 +240,8 @@ class Module
236
240
  }
237
241
  end
238
242
 
243
+ # gmosx: __force_xxx reuses xxx= to allow for easier
244
+ # overrides.
239
245
  if writer
240
246
  module_eval %{
241
247
  def #{s}=(val)
@@ -243,7 +249,7 @@ class Module
243
249
  end
244
250
 
245
251
  def __force_#{s}(val)
246
- @#{s} = } + case klass.name
252
+ self.#{s}=(} + case klass.name
247
253
  when Fixnum.name
248
254
  "val.to_i()"
249
255
  when String.name
@@ -256,7 +262,7 @@ class Module
256
262
  "val.to_i() > 0"
257
263
  else
258
264
  "val"
259
- end + %{
265
+ end + %{)
260
266
  end
261
267
  }
262
268
  end
@@ -9,7 +9,7 @@
9
9
  # Elias Karakoulakis <ekarak@ktismata.com>
10
10
  #
11
11
  # (c) 2004 Navel, all rights reserved.
12
- # $Id: application.rb 167 2004-11-23 14:03:10Z gmosx $
12
+ # $Id: application.rb 174 2004-11-26 16:00:21Z gmosx $
13
13
 
14
14
  require 'optparse'
15
15
  require 'ostruct'
@@ -161,6 +161,7 @@ class Application
161
161
  # FIXME: handle logging for daemons.
162
162
  # ???: How does this work !?!?
163
163
  #
164
+ =begin
164
165
  def daemonize
165
166
  unless @daemonized
166
167
  trap "SIGCLD", "IGNORE"
@@ -183,6 +184,22 @@ class Application
183
184
 
184
185
  return self
185
186
  end
187
+ =end
188
+ def daemonize
189
+ unless @daemonized
190
+ exit!(0) if fork
191
+ Process::setsid
192
+ exit!(0) if fork
193
+ File::umask(0)
194
+ [ STDIN, STDOUT, STDERR ].each do |io|
195
+ io.reopen("/dev/null", "r+")
196
+ end
197
+ end
198
+ @daemonized = true
199
+
200
+ return self
201
+ end
202
+
186
203
 
187
204
  # Returns the pid of the running daemon
188
205
  #
@@ -0,0 +1,84 @@
1
+ # code:
2
+ # * George Moschovitis <gm@navel.gr>
3
+ #
4
+ # (c) 2004 Navel, all rights reserved.
5
+ # $Id: form.rb 187 2004-12-10 13:34:28Z gmosx $
6
+
7
+ module N
8
+
9
+ # = FormBuilder
10
+ #
11
+ class FormBuilder
12
+
13
+ @@forms_cache = G::SafeHash.new
14
+
15
+ # Render a standard form for the given managed object.
16
+ # If show_all is false then apply field filtering.
17
+ #
18
+ # Example:
19
+ #
20
+ # <p>
21
+ # <form name="test">
22
+ # #{N::FormBuilder.render(entry)}
23
+ # </form>
24
+ # </p>
25
+ #
26
+ def self.render(obj, lc = nil, show_all = false)
27
+ str = '<dl>'
28
+
29
+ for p in obj.class.__props
30
+ unless show_all
31
+ next if :oid == p.symbol
32
+ end
33
+
34
+ if p.klass.ancestors.include?(Integer) or
35
+ p.klass.ancestors.include?(Float)
36
+ str << %{
37
+ <dt><label for="#{p.name}">#{p.name}</label></dt>
38
+ <dd>
39
+ <input type="text" name="#{p.name}" value="#{obj.send(p.symbol)}" />
40
+ </dd>
41
+ }
42
+ elsif p.klass.ancestors.include?(String)
43
+ str << %{
44
+ <dt><label for="#{p.name}">#{p.name}</label></dt>
45
+ <dd>
46
+ }
47
+ if :textarea == p.meta[:form]
48
+ str << %{
49
+ <textarea name="#{p.name}">#{obj.send(p.symbol)}</textarea>
50
+ }
51
+ else
52
+ str << %{
53
+ <input type="text" name="#{p.name}" value="#{obj.send(p.symbol)}" />
54
+ }
55
+ end
56
+ str << %{
57
+ </dd>
58
+ }
59
+ elsif p.klass.ancestors.include?(TrueClass)
60
+ str << %{
61
+ <dt><label for="#{p.name}">#{p.name}</label></dt>
62
+ <dd>
63
+ <input type="checkbox" name="${p.name}" />
64
+ </dd>
65
+ }
66
+ =begin
67
+ elsif p.klass.ancestors.include?(Time)
68
+ return %|#\{@#{p.symbol} ? "'#\{Og::Utils.timestamp(@#{p.symbol})\}'" : 'NULL'\}|
69
+ elsif p.klass.ancestors.include?(Date)
70
+ return %|#\{@#{p.symbol} ? "'#\{Og::Utils.date(@#{p.symbol})\}'" : 'NULL'\}|
71
+ else
72
+ return %|#\{@#{p.symbol} ? "'#\{Og::Utils.escape(@#{p.symbol}.to_yaml)\}'" : "''"\}|
73
+ =end
74
+ end
75
+ end
76
+
77
+ str << '</dl>'
78
+
79
+ return str
80
+ end
81
+
82
+ end
83
+
84
+ end # module
@@ -2,7 +2,7 @@
2
2
  # * George Moschovitis <gm@navel.gr>
3
3
  #
4
4
  # (c) 2004 Navel, all rights reserved.
5
- # $Id$
5
+ # $Id: rss.rb 185 2004-12-10 13:29:09Z gmosx $
6
6
 
7
7
  require 'rss/0.9'
8
8
 
@@ -15,8 +15,7 @@ module N
15
15
  #--
16
16
  # TODO: add more options here, 1.0/2.0 support and more.
17
17
  #++
18
- module RssBuilder
19
- include RSS
18
+ class RssBuilder
20
19
 
21
20
  def self.render(objects)
22
21
  channel = RSS::Rss::Channel.new
@@ -24,14 +23,14 @@ module RssBuilder
24
23
  channel.link = $srv_url
25
24
 
26
25
  for obj in objects
27
- item = Rss::Channel::Item.new
26
+ item = RSS::Rss::Channel::Item.new
28
27
  item.title = obj.title if obj.respond_to?(:title)
29
28
  item.description = G::StringUtils.head(obj.body, 256) if obj.respond_to?(:body)
30
29
  item.link = "#$srv_url/#{obj.view_uri}" if obj.respond_to?(:view_uri)
31
30
  channel.items << item
32
31
  end
33
32
 
34
- rss = Rss.new '0.9'
33
+ rss = RSS::Rss.new '0.9'
35
34
  rss.channel = channel
36
35
 
37
36
  return rss.to_s
@@ -0,0 +1,23 @@
1
+ # code:
2
+ # * George Moschovitis <gm@navel.gr>
3
+ #
4
+ # (c) 2004 Navel, all rights reserved.
5
+ # $Id: table.rb 185 2004-12-10 13:29:09Z gmosx $
6
+
7
+ module N
8
+
9
+ # = TableBuilder
10
+ #
11
+ # Example:
12
+ #
13
+ # users = User.all
14
+ # header = ['Username', 'First name', 'Last name', 'Email']
15
+ # N::TableBuilder.render(users, header)
16
+ #
17
+ class TableBuilder
18
+ end
19
+
20
+ end # module
21
+
22
+
23
+
@@ -0,0 +1,157 @@
1
+ # code:
2
+ # * George Moschovitis <gm@navel.gr>
3
+ #
4
+ # (c) 2004 Navel, all rights reserved.
5
+ # $Id: filters.rb 184 2004-12-07 14:42:22Z gmosx $
6
+
7
+ module N
8
+
9
+ # = Filtering
10
+ #
11
+ # Filtering functionality for renders/services. The design
12
+ # and implementation is HEAVILY influenced by Rails.
13
+ #
14
+ # Examples:
15
+ #
16
+ # Filter as class:
17
+ #
18
+ # class TouchFilter
19
+ # end
20
+ #
21
+ # Filter
22
+ # before
23
+ # filter
24
+ # after
25
+ #
26
+ # TODO:
27
+ # implement inheritable filters.
28
+ #
29
+ module Filtering
30
+
31
+ # Ruby is sometimes VERY surprising, the following trick is needed
32
+ # to include singleton methods in other classes.
33
+ #
34
+ def self.append_features(base)
35
+ super; base.extend(ClassMethods)
36
+ end
37
+
38
+ module ClassMethods
39
+ # the filters to be evaluated before the method
40
+ @@before_filters = []
41
+
42
+ # the filters to be evaluated after the method
43
+ @@after_filters = []
44
+
45
+ #
46
+ #
47
+ def before_filters
48
+ @@before_filters
49
+ end
50
+
51
+ #
52
+ #
53
+ def after_filters
54
+ @@after_filters
55
+ end
56
+
57
+ #
58
+ #
59
+ def prepend_before_filter(*filters, &block)
60
+ filters << block if block_given?
61
+ @@before_filters = filters + @@before_filters
62
+ end
63
+
64
+ #
65
+ #
66
+ def append_before_filter(*filters, &block)
67
+ filters << block if block_given?
68
+ @@before_filters = @@before_filters + filters
69
+ end
70
+
71
+ # Alias for the most common case.
72
+ alias :before_filter :prepend_before_filter
73
+
74
+ #
75
+ #
76
+ def prepend_after_filter(*filters, &block)
77
+ filters << block if block_given?
78
+ @@after_filters = filters + @@after_filters
79
+ end
80
+
81
+ #
82
+ #
83
+ def append_after_filter(*filters, &block)
84
+ filters << block if block_given?
85
+ @@after_filters = @@after_filters + filters
86
+ end
87
+
88
+ # Alias for the most common case.
89
+ alias :after_filter :append_after_filter
90
+
91
+ # Install an arround Filter. A filter is a class that responds
92
+ # to the before and after methods. Both methods are prepended to
93
+ # the respective lists.
94
+ #
95
+ def prepend_arround_filter(*filters)
96
+ filters = [filters].flatten
97
+
98
+ for filter in filters
99
+ if filter.respond_to?(:before)
100
+ prepend_before_filter { |c| filter.before(c) }
101
+ elsif filter.respond_to?(:filter)
102
+ # consider 'filter' as synonym of before.
103
+ prepend_before_filter { |c| filter.filter(c) }
104
+ end
105
+ prepend_after_filter { |c| filter.after(c) } if filter.respond_to?(:after)
106
+ end
107
+ end
108
+
109
+ # Install an arround Filter. A filter is a class that responds
110
+ # to the before and after methods. Both methods are appended to
111
+ # the respective lists.
112
+ #
113
+ def append_arround_filter(*filters)
114
+ filters = [filters].flatten
115
+
116
+ for filter in filters
117
+ if filter.respond_to?(:before)
118
+ append_before_filter { |c| filter.before(c) }
119
+ elsif filter.respond_to?(:filter)
120
+ # consider 'filter' as synonym of before.
121
+ append_before_filter { |c| filter.filter(c) }
122
+ end
123
+ append_after_filter { |c| filter.after(c) } if filter.respond_to?(:after)
124
+ end
125
+ end
126
+
127
+ # Alias for the most common case.
128
+ alias :filter :append_arround_filter
129
+
130
+ #
131
+ #
132
+ def gen_filters_call_code(filters)
133
+ code = ""
134
+
135
+ filters.each do |filter|
136
+ if Symbol === filter
137
+ code << "if #{filter} == false then return false end;"
138
+ elsif filter.respond_to?('call') && (filter.arity == 1 || filter.arity == -1)
139
+ code << 'if filter.call(self) == false then return false end;'
140
+ elsif filter.is_a?(Module) and filter.instance_methods.size > 0
141
+ class_eval "include #{filter};"
142
+ meth = filter.instance_methods[0]
143
+ code << "if #{meth} == false then return false end;"
144
+ elsif filter.respond_to?('filter')
145
+ code << "if #{filter}.filter(self) == false then return false end"
146
+ else
147
+ raise 'Valid filters are either a symbol or a proc/method.'
148
+ end
149
+ end
150
+
151
+ return code
152
+ end
153
+ end
154
+
155
+ end
156
+
157
+ end # module