waves 0.7.3 → 0.7.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. data/app/Rakefile +11 -19
  2. data/app/bin/waves-console +3 -5
  3. data/app/bin/waves-server +3 -5
  4. data/app/configurations/development.rb.erb +19 -11
  5. data/app/configurations/mapping.rb.erb +4 -5
  6. data/app/configurations/production.rb.erb +18 -13
  7. data/app/{doc/EMTPY → controllers/.gitignore} +0 -0
  8. data/app/{public/css/EMPTY → doc/.gitignore} +0 -0
  9. data/app/{public/flash/EMPTY → helpers/.gitignore} +0 -0
  10. data/app/lib/application.rb.erb +4 -51
  11. data/app/{public/images/EMPTY → lib/tasks/.gitignore} +0 -0
  12. data/app/{public/javascript/EMPTY → log/.gitignore} +0 -0
  13. data/app/{tmp/sessions/EMPTY → models/.gitignore} +0 -0
  14. data/app/public/css/.gitignore +0 -0
  15. data/app/public/flash/.gitignore +0 -0
  16. data/app/public/images/.gitignore +0 -0
  17. data/app/public/javascript/.gitignore +0 -0
  18. data/app/schema/migrations/.gitignore +0 -0
  19. data/app/startup.rb +5 -0
  20. data/app/templates/layouts/default.mab +2 -2
  21. data/app/tmp/sessions/.gitignore +0 -0
  22. data/app/views/.gitignore +0 -0
  23. data/bin/waves +38 -27
  24. data/bin/waves-console +3 -25
  25. data/bin/waves-server +4 -45
  26. data/lib/commands/waves-console.rb +21 -0
  27. data/lib/commands/waves-server.rb +55 -0
  28. data/lib/controllers/base.rb +11 -0
  29. data/lib/controllers/mixin.rb +130 -102
  30. data/lib/dispatchers/base.rb +65 -50
  31. data/lib/dispatchers/default.rb +79 -52
  32. data/lib/foundations/default.rb +26 -0
  33. data/lib/foundations/simple.rb +30 -0
  34. data/lib/helpers/common.rb +60 -56
  35. data/lib/helpers/default.rb +13 -0
  36. data/lib/helpers/form.rb +39 -38
  37. data/lib/helpers/formatting.rb +11 -11
  38. data/lib/helpers/model.rb +12 -12
  39. data/lib/helpers/view.rb +13 -13
  40. data/lib/layers/default_errors.rb +29 -0
  41. data/lib/layers/mvc.rb +58 -0
  42. data/lib/layers/orm/active_record.rb +41 -0
  43. data/lib/layers/orm/active_record/migrations/empty.rb.erb +9 -0
  44. data/lib/layers/orm/active_record/tasks/schema.rb +30 -0
  45. data/lib/layers/orm/data_mapper.rb +42 -0
  46. data/lib/layers/orm/filebase.rb +22 -0
  47. data/lib/layers/orm/migration.rb +70 -0
  48. data/lib/layers/orm/sequel.rb +82 -0
  49. data/lib/layers/orm/sequel/migrations/empty.rb.erb +9 -0
  50. data/lib/layers/orm/sequel/tasks/schema.rb +24 -0
  51. data/lib/layers/simple.rb +39 -0
  52. data/lib/layers/simple_errors.rb +26 -0
  53. data/lib/mapping/mapping.rb +222 -120
  54. data/lib/mapping/pretty_urls.rb +42 -41
  55. data/lib/renderers/erubis.rb +54 -31
  56. data/lib/renderers/markaby.rb +28 -28
  57. data/lib/renderers/mixin.rb +49 -52
  58. data/lib/runtime/application.rb +66 -48
  59. data/lib/runtime/blackboard.rb +57 -0
  60. data/lib/runtime/configuration.rb +117 -101
  61. data/lib/runtime/console.rb +19 -20
  62. data/lib/runtime/debugger.rb +9 -0
  63. data/lib/runtime/logger.rb +43 -37
  64. data/lib/runtime/mime_types.rb +19 -19
  65. data/lib/runtime/request.rb +72 -46
  66. data/lib/runtime/response.rb +37 -37
  67. data/lib/runtime/response_mixin.rb +26 -23
  68. data/lib/runtime/response_proxy.rb +25 -24
  69. data/lib/runtime/server.rb +99 -80
  70. data/lib/runtime/session.rb +63 -53
  71. data/lib/tasks/cluster.rb +26 -0
  72. data/lib/tasks/gem.rb +31 -0
  73. data/lib/tasks/generate.rb +80 -0
  74. data/lib/utilities/hash.rb +22 -0
  75. data/lib/utilities/inflect.rb +194 -0
  76. data/lib/utilities/integer.rb +15 -12
  77. data/lib/utilities/kernel.rb +32 -32
  78. data/lib/utilities/module.rb +11 -4
  79. data/lib/utilities/object.rb +5 -5
  80. data/lib/utilities/proc.rb +10 -0
  81. data/lib/utilities/string.rb +44 -38
  82. data/lib/utilities/symbol.rb +4 -4
  83. data/lib/views/base.rb +9 -0
  84. data/lib/views/mixin.rb +91 -89
  85. data/lib/waves.rb +29 -9
  86. metadata +52 -26
  87. data/app/configurations/default.rb.erb +0 -8
  88. data/app/controllers/default.rb.erb +0 -29
  89. data/app/helpers/default.rb.erb +0 -13
  90. data/app/lib/startup.rb.erb +0 -3
  91. data/app/lib/tasks/cluster.rb +0 -24
  92. data/app/lib/tasks/generate.rb +0 -15
  93. data/app/lib/tasks/schema.rb +0 -29
  94. data/app/models/default.rb.erb +0 -13
  95. data/app/schema/migrations/templates/empty.rb.erb +0 -9
  96. data/app/views/default.rb.erb +0 -13
@@ -1,56 +1,66 @@
1
1
  module Waves
2
-
2
+
3
3
  # Encapsulates the session associated with a given request. A session has an expiration
4
- # and path. You must set these in your configuration file. See Waves::Configuration for
5
- # more information.
6
- #
7
- class Session
8
-
9
- # Create a new session object using the given request. This is not necessarily the
10
- # same as constructing a new session. The session_id cookie for the request domain
11
- # is used to store a session id. The actual session data will be stored in a directory
12
- # specified by the application's configuration file.
13
- def initialize( request )
14
- @request = request
15
- @data ||= ( File.exist?( session_path ) ? load_session : {} )
16
- end
17
-
18
- # Save the session data. You shouldn't typically have to call this directly, since it
19
- # is called by Waves::Response#finish.
20
- def save
21
- if @data && @data.length > 0
22
- File.write( session_path, @data.to_yaml )
23
- @request.response.set_cookie( 'session_id',
24
- :value => session_id, :path => '/',
25
- :expires => Time.now + Waves::Server.config.session[:duration] )
26
- end
27
- end
28
-
29
- # Access a given data element of the session using the given key.
30
- def [](key) ; @data[key] ; end
31
- # Set the given data element of the session using the given key and value.
32
- def []=(key,val) ; @data[key] = val ; end
33
-
34
- private
35
-
36
- def session_id
37
- @session_id ||= ( @request.cookies['session_id'] || generate_session_id )
38
- end
39
-
40
- def generate_session_id # from Camping ...
41
- chars = [*'A'..'Z'] + [*'0'..'9'] + [*'a'..'z']
42
- (0..48).inject(''){|s,x| s+=chars[ rand(chars.length) ] }
43
- end
44
-
45
- def session_path
46
- Waves::Server.config.session[:path] / session_id
47
- end
48
-
49
- def load_session
50
- YAML.load( File.read( session_path ) )
51
- end
52
-
53
- end
54
-
4
+ # and path, which must be provided in a Waves::Configuration. Sensible defaults are defined
5
+ # in Waves::Configurations::Default
6
+ class Session
7
+
8
+ # Concoct a (probably) unique session id
9
+ def self.generate_session_id
10
+ # from Camping ...
11
+ chars = [*'A'..'Z'] + [*'0'..'9'] + [*'a'..'z']
12
+ (0..48).inject(''){|s,x| s+=chars[ rand(chars.length) ] }
13
+ end
14
+
15
+ # Create a new session object using the given request. This is not necessarily the
16
+ # same as constructing a new session. The session_id cookie for the request domain
17
+ # is used to store a session id. The actual session data will be stored in a directory
18
+ # specified by the application's configuration file.
19
+ def initialize( request )
20
+ @request = request
21
+ @data ||= ( File.exist?( session_path ) ? load_session : {} )
22
+ end
23
+
24
+ # Return the session data as a hash
25
+ def to_hash
26
+ @data.to_hash
27
+ end
28
+
29
+ def self.base_path
30
+ Waves::Application.instance.config.session[:path]
31
+ end
32
+
33
+ # Save the session data. You shouldn't typically have to call this directly, since it
34
+ # is called by Waves::Response#finish.
35
+ def save
36
+ if @data && @data.length > 0
37
+ File.write( session_path, @data.to_yaml )
38
+ @request.response.set_cookie( 'session_id',
39
+ :value => session_id, :path => '/',
40
+ :expires => Time.now + Waves::Server.config.session[:duration] )
41
+ end
42
+ end
43
+
44
+ # Access a given data element of the session using the given key.
45
+ def [](key) ; @data[key] ; end
46
+ # Set the given data element of the session using the given key and value.
47
+ def []=(key,val) ; @data[key] = val ; end
48
+
49
+ private
50
+
51
+ def session_id
52
+ @session_id ||= ( @request.cookies['session_id'] || Waves::Session.generate_session_id )
53
+ end
54
+
55
+ def session_path
56
+ Waves::Session.base_path / session_id
57
+ end
58
+
59
+ def load_session
60
+ YAML.load( File.read( session_path ) )
61
+ end
62
+
63
+ end
64
+
55
65
  end
56
-
66
+
@@ -0,0 +1,26 @@
1
+ namespace :cluster do
2
+
3
+ desc 'Start a cluster of waves applications.'
4
+ task :start do |task|
5
+ using_waves_src = defined?(WAVES) || ENV['WAVES'] || File.exist( File.dirname(__FILE__) / :waves )
6
+ script = using_waves_src ? :bin / 'waves-server' : 'waves-server'
7
+ ( Waves::Console.config.ports || [ Waves::Console.config.port ] ).each do |port|
8
+ cmd = "#{script} -p #{port} -c #{ENV['mode']||'development'} -d"
9
+ puts cmd ; `#{cmd}`
10
+ end
11
+ end
12
+
13
+ desc 'Stop a cluster of waves applications.'
14
+ task :stop do |task|
15
+ Dir[ :log / '*.pid' ].each do |pidfile|
16
+ pid = File.read(pidfile).to_i
17
+ puts "Stopping process #{pid} ..."
18
+ Process.kill( 'INT', pid ) rescue nil
19
+ end
20
+ end
21
+
22
+ desc 'Restart a cluster of waves applications.'
23
+ task :restart => [ :stop, :start ] do |task|
24
+ end
25
+
26
+ end
data/lib/tasks/gem.rb ADDED
@@ -0,0 +1,31 @@
1
+ namespace :gem do
2
+ desc "freeze a gem using gem=<gem name> [version=<gem version>]"
3
+ task :freeze do
4
+ raise "No gem specified" unless gem_name = ENV['gem']
5
+
6
+ require 'rubygems'
7
+ Gem.manage_gems
8
+
9
+ gem = (version = ENV['version']) ?
10
+ Gem.cache.search(gem_name, "= #{version}").first :
11
+ Gem.cache.search(gem_name).sort_by { |g| g.version }.last
12
+
13
+ version ||= gem.version.version rescue nil
14
+
15
+ target_dir = File.join(Waves::Configurations::Default.root, 'gems')
16
+ mkdir_p target_dir
17
+ sh "gem install #{gem_name} --version #{version} -i #{target_dir} --no-rdoc --no-ri"
18
+
19
+ puts "Unpacked #{gem_name} #{version} to '#{target_dir}'"
20
+ end
21
+
22
+ desc "unfreeze a gem using gem=<gem>"
23
+ task :unfreeze do
24
+ raise "No gem specified" unless gem_name = ENV['gem']
25
+
26
+ target_dir = File.join(Waves::Configurations::Default.root, 'gems')
27
+ ENV['GEM_HOME'] = target_dir # no install_dir option for gem uninstall
28
+
29
+ sh "gem uninstall #{gem_name}"
30
+ end
31
+ end
@@ -0,0 +1,80 @@
1
+ namespace :generate do
2
+
3
+ desc 'Generate a new controller, with name=<name>'
4
+ task :controller do |task|
5
+ name = ENV['name']
6
+ controller_name = name.camel_case
7
+ raise "Cannot generate Default yet" if controller_name == 'Default'
8
+
9
+ filename = File.expand_path "controllers/#{name}.rb"
10
+ if File.exist?(filename)
11
+ $stderr.puts "#{filename} already exists"
12
+ exit
13
+ end
14
+
15
+ controller = <<TEXT
16
+ module #{Waves.application.name}
17
+ module Controllers
18
+ class #{controller_name} < Default
19
+
20
+ end
21
+ end
22
+ end
23
+ TEXT
24
+
25
+ File.write( filename, controller )
26
+ end
27
+
28
+ desc 'Generate new view, with name=<name>'
29
+ task :view do |task|
30
+ name = ENV['name']
31
+ view_name = name.camel_case
32
+ raise "Cannot generate Default yet" if view_name == 'Default'
33
+
34
+ filename = File.expand_path "views/#{name}.rb"
35
+ if File.exist?(filename)
36
+ $stderr.puts "#{filename} already exists"
37
+ exit
38
+ end
39
+
40
+ view = <<TEXT
41
+ module #{Waves.application.name}
42
+ module Views
43
+ class #{view_name} < Default
44
+
45
+ end
46
+ end
47
+ end
48
+ TEXT
49
+
50
+ File.write( filename, view )
51
+ end
52
+
53
+ desc 'Generate a new helper, with name=<name>'
54
+ task :helper do |task|
55
+ name = ENV['name']
56
+ helper_name = name.camel_case
57
+ raise "Cannot generate Default yet" if helper_name == 'Default'
58
+
59
+ filename = File.expand_path "helpers/#{name}.rb"
60
+ if File.exist?(filename)
61
+ $stderr.puts "#{filename} already exists"
62
+ exit
63
+ end
64
+
65
+ helper = <<TEXT
66
+ module #{Waves.application.name}
67
+ module Helpers
68
+ module #{helper_name}
69
+ include Waves::Helpers::Default
70
+
71
+ end
72
+ end
73
+ end
74
+ TEXT
75
+
76
+ File.write( filename, helper )
77
+ end
78
+
79
+
80
+ end
@@ -0,0 +1,22 @@
1
+ class Hash
2
+
3
+ def stringify_keys
4
+ inject({}) do |options, (key, value)|
5
+ options[key.to_s] = value
6
+ options
7
+ end
8
+ end
9
+
10
+ # Destructively convert all keys to symbols.
11
+ def symbolize_keys!
12
+ keys.each do |key|
13
+ unless key.is_a?(Symbol)
14
+ self[key.to_sym] = self[key]
15
+ delete(key)
16
+ end
17
+ end
18
+ self
19
+ end
20
+
21
+
22
+ end
@@ -0,0 +1,194 @@
1
+ # Much love to Facets (more specifically English) for this module
2
+ # http://english.rubyforge.org/
3
+ # changed slightly in the hopes of one day implementing a different set
4
+ # of rules for different languages
5
+ # NOTE: this is NOT implemented yet.
6
+ # plural and singular work directly with the English class
7
+
8
+ module Inflect # :nodoc:
9
+ module InflectorMethods
10
+
11
+ # Define a general exception.
12
+ def word(singular, plural=nil)
13
+ plural = singular unless plural
14
+ singular_word(singular, plural)
15
+ plural_word(singular, plural)
16
+ end
17
+
18
+ # Define a singularization exception.
19
+ def singular_word(singular, plural)
20
+ @singular_of[plural] = singular
21
+ end
22
+
23
+ # Define a pluralization exception.
24
+ def plural_word(singular, plural)
25
+ @plural_of[singular] = plural
26
+ end
27
+
28
+ # Define a general rule.
29
+ def rule(singular, plural)
30
+ singular_rule(singular, plural)
31
+ plural_rule(singular, plural)
32
+ end
33
+
34
+ # Define a singularization rule.
35
+ def singular_rule(singular, plural)
36
+ @singular_rules << [singular, plural]
37
+ end
38
+
39
+ # Define a plurualization rule.
40
+ def plural_rule(singular, plural)
41
+ @plural_rules << [singular, plural]
42
+ end
43
+
44
+ # Read prepared singularization rules.
45
+ def singularization_rules
46
+ return @singularization_rules if @singularization_rules
47
+ sorted = @singular_rules.sort_by{ |s, p| "#{p}".size }.reverse
48
+ @singularization_rules = sorted.collect do |s, p|
49
+ [ /#{p}$/, "#{s}" ]
50
+ end
51
+ end
52
+
53
+ # Read prepared pluralization rules.
54
+ def pluralization_rules
55
+ return @pluralization_rules if @pluralization_rules
56
+ sorted = @plural_rules.sort_by{ |s, p| "#{s}".size }.reverse
57
+ @pluralization_rules = sorted.collect do |s, p|
58
+ [ /#{s}$/, "#{p}" ]
59
+ end
60
+ end
61
+
62
+ #
63
+ def plural_of
64
+ @plural_of
65
+ end
66
+
67
+ #
68
+ def singular_of
69
+ @singular_of
70
+ end
71
+
72
+ # Convert an English word from plurel to singular.
73
+ #
74
+ # "boys".singular #=> boy
75
+ # "tomatoes".singular #=> tomato
76
+ #
77
+ def singular(word)
78
+ if result = singular_of[word]
79
+ return result.dup
80
+ end
81
+ result = word.dup
82
+ singularization_rules.each do |(match, replacement)|
83
+ break if result.gsub!(match, replacement)
84
+ end
85
+ return result
86
+ end
87
+
88
+ # Convert an English word from singular to plurel.
89
+ #
90
+ # "boy".plural #=> boys
91
+ # "tomato".plural #=> tomatoes
92
+ #
93
+ def plural(word)
94
+ if result = plural_of[word]
95
+ return result.dup
96
+ end
97
+ #return self.dup if /s$/ =~ self # ???
98
+ result = word.dup
99
+ pluralization_rules.each do |(match, replacement)|
100
+ break if result.gsub!(match, replacement)
101
+ end
102
+ return result
103
+ end
104
+ end
105
+
106
+ class English # :nodoc:
107
+ @singular_of = {}
108
+ @plural_of = {}
109
+
110
+ @singular_rules = []
111
+ @plural_rules = []
112
+
113
+ class << self
114
+ include InflectorMethods
115
+ end
116
+
117
+ # One argument means singular and plural are the same.
118
+ word 'equipment'
119
+ word 'information'
120
+ word 'money'
121
+ word 'species'
122
+ word 'series'
123
+ word 'fish'
124
+ word 'sheep'
125
+ word 'moose'
126
+ word 'hovercraft'
127
+
128
+ # Two arguments defines a singular and plural exception.
129
+ word 'Swiss' , 'Swiss'
130
+ word 'life' , 'lives'
131
+ word 'wife' , 'wives'
132
+ word 'virus' , 'viri'
133
+ word 'octopus' , 'octopi'
134
+ word 'cactus' , 'cacti'
135
+ word 'goose' , 'geese'
136
+ word 'criterion' , 'criteria'
137
+ word 'alias' , 'aliases'
138
+ word 'status' , 'statuses'
139
+ word 'axis' , 'axes'
140
+ word 'crisis' , 'crises'
141
+ word 'testis' , 'testes'
142
+ word 'child' , 'children'
143
+ word 'person' , 'people'
144
+ word 'potato' , 'potatoes'
145
+ word 'tomato' , 'tomatoes'
146
+ word 'buffalo' , 'buffaloes'
147
+ word 'torpedo' , 'torpedoes'
148
+ word 'quiz' , 'quizes'
149
+ word 'matrix' , 'matrices'
150
+ word 'vertex' , 'vetices'
151
+ word 'index' , 'indices'
152
+ word 'ox' , 'oxen'
153
+ word 'mouse' , 'mice'
154
+ word 'louse' , 'lice'
155
+ word 'thesis' , 'theses'
156
+ word 'thief' , 'thieves'
157
+ word 'analysis' , 'analyses'
158
+
159
+ # One-way singularization exception (convert plural to singular).
160
+ singular_word 'cactus', 'cacti'
161
+
162
+ # General rules.
163
+ rule 'hive' , 'hives'
164
+ rule 'rf' , 'rves'
165
+ rule 'af' , 'aves'
166
+ rule 'ero' , 'eroes'
167
+ rule 'man' , 'men'
168
+ rule 'ch' , 'ches'
169
+ rule 'sh' , 'shes'
170
+ rule 'ss' , 'sses'
171
+ rule 'ta' , 'tum'
172
+ rule 'ia' , 'ium'
173
+ rule 'ra' , 'rum'
174
+ rule 'ay' , 'ays'
175
+ rule 'ey' , 'eys'
176
+ rule 'oy' , 'oys'
177
+ rule 'uy' , 'uys'
178
+ rule 'y' , 'ies'
179
+ rule 'x' , 'xes'
180
+ rule 'lf' , 'lves'
181
+ rule 'us' , 'uses'
182
+ rule '' , 's'
183
+
184
+ # One-way singular rules.
185
+ singular_rule 'of' , 'ofs' # proof
186
+ singular_rule 'o' , 'oes' # hero, heroes
187
+ singular_rule 'f' , 'ves'
188
+
189
+ # One-way plural rules.
190
+ plural_rule 'fe' , 'ves' # safe, wife
191
+ plural_rule 's' , 'ses'
192
+ end
193
+ end
194
+