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,110 @@
1
+ # = Database Tools
2
+ #
3
+ # Useful methods wor working with the Db BAckend
4
+ #
5
+ # code:
6
+ # George Moschovitis <gm@navel.gr>
7
+ # Elias Athanasopoulos <elathan@navel.gr>
8
+ #
9
+ # (c) 2004 Navel, all rights reserved.
10
+ # $Id: tools.rb 71 2004-10-18 10:50:22Z gmosx $
11
+
12
+ module N;
13
+
14
+ require "n/db"
15
+
16
+ # = DbConnection
17
+ #
18
+ # A Connection to the Database.
19
+ #
20
+ module DbTools
21
+
22
+ # Lets say you have changed the definition of a managed object
23
+ # (for example you have added a new prop_accessor, and want to
24
+ # automatically update the database schema.
25
+ # Compares the given class to the actual db schema and
26
+ # automatically alters the backend table if needed.
27
+ # No need to optimize this method.
28
+ #
29
+ def self.alter_table(klass)
30
+ #
31
+ # Use the following query to see the fields in system level:
32
+ #
33
+ # sql = "SELECT attname, attnum FROM pg_attribute, pg_class "
34
+ # sql << "WHERE attrelid = pg_class.oid "
35
+ # sql << "AND relname = '#{klass::DBTABLE}' AND attnum > 0;"
36
+ #
37
+ # In orer to test alter_table() use the following tests:
38
+ #
39
+ # klass.__props << N::Property.new("new_field", String)
40
+ # klass.__props.delete_if{ |member| member.name == "new_field" }
41
+ #
42
+ # Remember you must not uncomment both of the above statements.
43
+ # Uncomment the first one, use alter_table(), the uncomment the
44
+ # seconde one and re-use alter_table().
45
+ #
46
+ $db.open { |db|
47
+
48
+ sql = "SELECT * FROM #{klass::DBTABLE} LIMIT 1;"
49
+ table_fields = db.exec(sql).fields
50
+
51
+ # find fields to be added.
52
+ properties_to_add = []
53
+ klass.__props.each { |klass_member|
54
+ properties_to_add << klass_member unless table_fields.include? klass_member.name
55
+ }
56
+
57
+ # find fields to be removed.
58
+ properties_to_remove = []
59
+ table_fields.each { |field|
60
+ properties_to_remove << field unless klass.__props.map{ |member| member.name }.include? field
61
+ }
62
+
63
+ # Add new fields
64
+ fields = []
65
+ properties_to_add.each { |p|
66
+ field = "#{p.symbol}"
67
+ if p.sql
68
+ field << " #{p.sql}"
69
+ else
70
+ field << " #{db.class::TYPEMAP[p.klass]}"
71
+ end
72
+ field << " #{p.sql}" if p.sql
73
+
74
+ fields << field
75
+ }
76
+
77
+ for field in fields
78
+ sql = "ALTER TABLE #{klass::DBTABLE} ADD COLUMN #{field}"
79
+ db.exec_clear(sql)
80
+ end
81
+
82
+ removed = nil
83
+ properties_to_remove.each { |p|
84
+ sql = "ALTER TABLE #{klass::DBTABLE} DROP COLUMN #{p} RESTRICT"
85
+ db.exec_clear(sql)
86
+ removed = true
87
+ }
88
+
89
+ if removed
90
+ sql = "UPDATE #{klass::DBTABLE}; VACUUM FULL #{klass::DBTABLE};"
91
+ db.exec_clear(sql)
92
+ end
93
+
94
+ }
95
+ end
96
+
97
+ # NOT IMPLEMENTED
98
+ #
99
+ def self.alter_column(klass, old_field, new_field)
100
+ end
101
+
102
+ # NOT IMPLEMENTED
103
+ #
104
+ def self.rename_table(old_klass, new_klass)
105
+ end
106
+
107
+ end
108
+
109
+ end # module
110
+
@@ -0,0 +1,99 @@
1
+ # = Database Utilities
2
+ #
3
+ # A collection of database utilities.
4
+ #
5
+ # code:
6
+ # George Moschovitis <gm@navel.gr>
7
+ #
8
+ # (c) 2004 Navel, all rights reserved.
9
+ # $Id$
10
+
11
+ module N;
12
+
13
+ require "n/properties"
14
+ require "n/utils/array"
15
+ require "n/utils/time"
16
+
17
+ # = DbUtils
18
+ #
19
+ # A collection of Database utilities.
20
+ # Additional backend specific utilities are defined in
21
+ # the backend implementations.
22
+ #
23
+ module DbUtils
24
+
25
+ # Escape an sql string
26
+ #
27
+ def self.escape(str)
28
+ # defined in the backend
29
+ end
30
+
31
+ # Escape bytes
32
+ #
33
+ def self.escape_bytes(bytes)
34
+ # defined in the backend
35
+ end
36
+
37
+ # The name of the SQL table where entities of this class are stored.
38
+ # The Module separators are replaced with _ and NOT stripped out so
39
+ # that we can convert back to the original notation if needed.
40
+ #
41
+ def self.sql_table(klass)
42
+ return "#{klass}".gsub(/::/, "_").downcase
43
+ end
44
+
45
+ # Convert a ruby time to an sql timestamp.
46
+ #
47
+ def self.sql_timestamp(time = Time.now)
48
+ # defined in the backend
49
+ end
50
+
51
+ # Output YYY-mm-dd
52
+ #
53
+ def self.sql_date(date)
54
+ # defined in the backend
55
+ end
56
+
57
+ # Parse sql datetime
58
+ #
59
+ def self.parse_sql_timestamp(str)
60
+ # defined in the backend
61
+ end
62
+
63
+ # Input YYYY-mm-dd
64
+ #
65
+ def self.parse_sql_date(str)
66
+ # defined in the backend
67
+ end
68
+
69
+ # Return an sql string evaluator for the property.
70
+ # No need to optimize this, used only to precalculate code.
71
+ #
72
+ # FIXME: add extra handling for float.
73
+ #
74
+ def self.write_prop(p)
75
+ if String == p.klass
76
+ return "'#\{DbUtils.escape(@#{p.symbol})\}'"
77
+ elsif Time == p.klass
78
+ return %|#\{@#{p.symbol} ? "'#\{DbUtils.sql_timestamp(@#{p.symbol})\}'" : 'NULL'\}|
79
+ elsif Date == p.klass
80
+ return %|#\{@#{p.symbol} ? "'#\{DbUtils.sql_date(@#{p.symbol})\}'" : 'NULL'\}|
81
+ elsif Object == p.klass or Array == p.klass or Hash == p.klass
82
+ #return "'#\{DbUtils.escape_bytes(Marshal.dump(@#{p.symbol}))\}'"
83
+ return "'#\{DbUtils.escape_bytes(Marshal.dump(@#{p.symbol}))\}'"
84
+ else
85
+ # Fixnum, TrueClass
86
+ return "#\{@#{p.symbol} || 'NULL'\}"
87
+ end
88
+ end
89
+
90
+ # Return an evaluator for reading the property
91
+ # No need to optimize this, used only to precalculate code.
92
+ #
93
+ def self.read_prop(p)
94
+ # defined in the backend
95
+ end
96
+ end
97
+
98
+ end # namespace
99
+
@@ -0,0 +1,118 @@
1
+ # = Events
2
+ #
3
+ # A simple events mechanism.
4
+ #
5
+ # === Design:
6
+ #
7
+ # As always we try to keep the design simple:
8
+ # Events = strings (hiearchical notation)
9
+ # Handlers = named Procs
10
+ # The handlers are named so that we can remove them
11
+ # by name. Also usefull for documentation purposes.
12
+ #
13
+ # === TODO:
14
+ #
15
+ # Add a class of events to allow filtering of certain
16
+ # events. Perhaps name can be used for this!
17
+ #
18
+ # code: tml
19
+ #
20
+ # (c) 2002-2003 Navel, all rights reserved.
21
+ # $Id: events.rb 71 2004-10-18 10:50:22Z gmosx $
22
+
23
+ module N;
24
+
25
+ # = EventManager
26
+ #
27
+ # === Example:
28
+ #
29
+ # $ev.event("id/user/login", user)
30
+ # $ev.add_handler("id/user/login", "login-score", proc { |user|
31
+ # user["score"] += 1
32
+ # })
33
+ #
34
+ class EventManager
35
+ attr :events
36
+ attr_accessor :logger
37
+
38
+ def initialize(logger = nil)
39
+ @events = Hash.new
40
+ @logger = logger
41
+ end
42
+
43
+ # Register an event handler.
44
+ #
45
+ # === Input:
46
+ # event = the event
47
+ # name = the name of the handler
48
+ # proc = the proc of the hadler
49
+ #
50
+ def add_handler(event, name, proc)
51
+ unless event_handlers = @events[event]
52
+ @events[event] = event_handlers = Hash.new
53
+ end
54
+ event_handlers[name] = proc
55
+ end
56
+
57
+ # Remove the named handler from the event.
58
+ #
59
+ def remove_handler(event, name)
60
+ if event_handlers = @events[event]
61
+ event_handlers.delete(name)
62
+ else
63
+ $log.debug "ev: cannot remove, handler #{name} not found for event #{event}" if $DBG
64
+ end
65
+ end
66
+
67
+ # Remove all handlers for the event.
68
+ #
69
+ # === Input:
70
+ # event = the event
71
+ # name = the name of the handler
72
+ #
73
+ def remove_all_handlers(event)
74
+ @events[event] = Hash.new
75
+ end
76
+
77
+ # Fire an event
78
+ #
79
+ # === Input:
80
+ # event = the event to fire
81
+ # param = parameters for the handler, use an array
82
+ # for multiple parameters.
83
+ #
84
+ def event(event, params)
85
+ if event_handlers = @events[event]
86
+ # call all event handler procs
87
+ for handler in event_handlers.values
88
+ # call the handler with the params.
89
+ handler.call(params)
90
+ end
91
+ end
92
+ if @logger
93
+ if params.is_a?(Array)
94
+ pstr = params.collect{|i| i.to_s()}.join(", ")
95
+ else
96
+ pstr = params.to_s()
97
+ end
98
+ @logger.info("#{event}: #{pstr}")
99
+ end
100
+ end
101
+ alias_method :fire, :event
102
+ end
103
+
104
+ #
105
+ #
106
+ #
107
+ class Event
108
+ @@manager = EventManager.new()
109
+
110
+ def self.add_handler(event, name, proc)
111
+ end
112
+
113
+ def self.fire(event, params)
114
+ @@manager.fire(event, params)
115
+ end
116
+ end
117
+
118
+ end # module
@@ -0,0 +1,22 @@
1
+ # = L10N, Localization support
2
+ #
3
+ # code: tml
4
+ #
5
+ # (c) 2002-2003 Navel, all rights reserved.
6
+ # $Id: l10n.rb 71 2004-10-18 10:50:22Z gmosx $
7
+
8
+ $lc_en = {}
9
+ $lc_el = {}
10
+
11
+ # = Configuration
12
+ #
13
+ # Override as needed in your application.
14
+ #
15
+
16
+ $lc_map = {
17
+ "en" => $lc_en,
18
+ "el" => $lc_el
19
+ }
20
+
21
+ # The locales to use for this application.
22
+ $lc_use = %w{lc-en lc-el}
@@ -0,0 +1,33 @@
1
+ # = Logger
2
+ #
3
+ # A simple wrapper arround the Ruby logger. Mainly for compatibility
4
+ # purposes.
5
+ #
6
+ # code: tml
7
+ #
8
+ # (c) 2004 Navel, all rights reserved.
9
+ # $Id: logger.rb 71 2004-10-18 10:50:22Z gmosx $
10
+
11
+ require "logger"
12
+
13
+ class Logger
14
+ alias_method :devel, :debug
15
+ alias_method :fine, :debug
16
+
17
+ def detach
18
+ end
19
+
20
+ # Used for debuging, remove this in release code.
21
+ #
22
+ def d(str)
23
+ self << "#{str}\n"
24
+ end
25
+
26
+ # Inspect an object. Used for debugging, remove this in release
27
+ # code.
28
+ #
29
+ def i(obj)
30
+ self << "Inspect #{obj.inspect()}\n"
31
+ end
32
+ end
33
+
@@ -0,0 +1,53 @@
1
+ # = Macros
2
+ #
3
+ # A powerfull macro implementation for Ruby. Allows definition
4
+ # of new macro.
5
+ #
6
+ # code: gmosx
7
+ #
8
+ # (c) 2004 Navel, all rights reserved.
9
+ # $Id: macros.rb 71 2004-10-18 10:50:22Z gmosx $
10
+
11
+ $__macros__ = {}
12
+ $__required__ = {}
13
+
14
+ module Kernel
15
+
16
+ alias_method :old_require, :require
17
+ def require(path)
18
+ return if $__required__[path]
19
+
20
+ source = File.read(path)
21
+
22
+ # parse macro
23
+ source.gsub!(/defmacro\s*\/(.*?)\/\s(.*?)endmacro/m) {
24
+ $__macros__[Regexp.new($1)] = $2 ; ""
25
+ }
26
+
27
+ # expand macros
28
+ $__macros__.each { |match, replace|
29
+ source.gsub!(match, replace)
30
+ }
31
+
32
+ $__required__[path] = true
33
+
34
+ eval(source)
35
+ end
36
+
37
+ end
38
+
39
+ require "n/test1.rb"
40
+ require "n/test2.rb"
41
+
42
+ __END__
43
+
44
+ Examples:
45
+
46
+ defmacro /my_macro\((.*)\)/
47
+ begin
48
+ my_function(\1)
49
+ rescue => ex
50
+ puts ex
51
+ end
52
+ endmacro
53
+
@@ -0,0 +1,46 @@
1
+ # = Mixins
2
+ #
3
+ # A collection of useful mixins. Use these to synthesize your
4
+ # entities.
5
+ #
6
+ # code:
7
+ # George Moschovitis <gm@navel.gr>
8
+ #
9
+ # (c) 2004 Navel, all rights reserved.
10
+ # $Id$
11
+
12
+ module N;
13
+
14
+ # = Expirable
15
+ #
16
+ # Generic expiring functionality mixin. This is not exclusive
17
+ # for entities.
18
+ #
19
+ module Expirable
20
+ attr_accessor :expires
21
+
22
+ # Set the expires timeout for this entry.
23
+
24
+ def expires_after(timeout = (60*60*24))
25
+ @expires = Time.now + timeout
26
+ end
27
+
28
+ # Set the expire timeout for this entry. The timeout happens
29
+ # after (base + rand(spread)) seconds.
30
+
31
+ def expires_spread(base, spread)
32
+ @expires = Time.now + base + rand(spread)
33
+ end
34
+
35
+ # Is this entry expired?
36
+
37
+ def expired?
38
+ if @expires.nil? or (Time.now > @expires)
39
+ return true
40
+ else
41
+ return false
42
+ end
43
+ end
44
+ end
45
+
46
+ end # module