waves-stable 0.7.7

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 (185) hide show
  1. data/app/Rakefile +72 -0
  2. data/app/bin/waves-console +4 -0
  3. data/app/bin/waves-server +4 -0
  4. data/app/configurations/development.rb.erb +31 -0
  5. data/app/configurations/mapping.rb.erb +14 -0
  6. data/app/configurations/production.rb.erb +31 -0
  7. data/app/controllers/.gitignore +0 -0
  8. data/app/doc/.gitignore +0 -0
  9. data/app/helpers/.gitignore +0 -0
  10. data/app/lib/application.rb.erb +5 -0
  11. data/app/lib/tasks/.gitignore +0 -0
  12. data/app/log/.gitignore +0 -0
  13. data/app/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/errors/not_found_404.mab +2 -0
  21. data/app/templates/errors/server_error_500.mab +2 -0
  22. data/app/templates/layouts/default.mab +14 -0
  23. data/app/tmp/sessions/.gitignore +0 -0
  24. data/app/views/.gitignore +0 -0
  25. data/bin/waves +84 -0
  26. data/bin/waves-console +4 -0
  27. data/bin/waves-server +4 -0
  28. data/doc/HISTORY +44 -0
  29. data/doc/LICENSE +22 -0
  30. data/lib/commands/waves-console.rb +21 -0
  31. data/lib/commands/waves-server.rb +55 -0
  32. data/lib/controllers/base.rb +11 -0
  33. data/lib/controllers/mixin.rb +165 -0
  34. data/lib/dispatchers/base.rb +67 -0
  35. data/lib/dispatchers/default.rb +81 -0
  36. data/lib/foundations/default.rb +27 -0
  37. data/lib/foundations/simple.rb +30 -0
  38. data/lib/helpers/asset_helper.rb +67 -0
  39. data/lib/helpers/common.rb +66 -0
  40. data/lib/helpers/default.rb +13 -0
  41. data/lib/helpers/form.rb +40 -0
  42. data/lib/helpers/formatting.rb +30 -0
  43. data/lib/helpers/model.rb +33 -0
  44. data/lib/helpers/number_helper.rb +25 -0
  45. data/lib/helpers/tag_helper.rb +58 -0
  46. data/lib/helpers/url_helper.rb +77 -0
  47. data/lib/helpers/view.rb +24 -0
  48. data/lib/layers/default_errors.rb +26 -0
  49. data/lib/layers/inflect/english.rb +24 -0
  50. data/lib/layers/inflect/english/rules.rb +88 -0
  51. data/lib/layers/inflect/english/string.rb +24 -0
  52. data/lib/layers/mvc.rb +54 -0
  53. data/lib/layers/orm/active_record.rb +92 -0
  54. data/lib/layers/orm/active_record/migrations/empty.rb.erb +9 -0
  55. data/lib/layers/orm/active_record/tasks/generate.rb +28 -0
  56. data/lib/layers/orm/active_record/tasks/schema.rb +22 -0
  57. data/lib/layers/orm/data_mapper.rb +38 -0
  58. data/lib/layers/orm/filebase.rb +22 -0
  59. data/lib/layers/orm/migration.rb +79 -0
  60. data/lib/layers/orm/sequel.rb +86 -0
  61. data/lib/layers/orm/sequel/migrations/empty.rb.erb +9 -0
  62. data/lib/layers/orm/sequel/tasks/generate.rb +28 -0
  63. data/lib/layers/orm/sequel/tasks/schema.rb +16 -0
  64. data/lib/layers/simple.rb +32 -0
  65. data/lib/layers/simple_errors.rb +23 -0
  66. data/lib/mapping/mapping.rb +289 -0
  67. data/lib/mapping/pretty_urls.rb +96 -0
  68. data/lib/renderers/erubis.rb +63 -0
  69. data/lib/renderers/haml.rb +45 -0
  70. data/lib/renderers/markaby.rb +33 -0
  71. data/lib/renderers/mixin.rb +50 -0
  72. data/lib/runtime/application.rb +69 -0
  73. data/lib/runtime/blackboard.rb +57 -0
  74. data/lib/runtime/configuration.rb +185 -0
  75. data/lib/runtime/console.rb +20 -0
  76. data/lib/runtime/debugger.rb +9 -0
  77. data/lib/runtime/logger.rb +59 -0
  78. data/lib/runtime/mime_types.rb +22 -0
  79. data/lib/runtime/request.rb +78 -0
  80. data/lib/runtime/response.rb +40 -0
  81. data/lib/runtime/response_mixin.rb +38 -0
  82. data/lib/runtime/response_proxy.rb +30 -0
  83. data/lib/runtime/server.rb +107 -0
  84. data/lib/runtime/session.rb +66 -0
  85. data/lib/tasks/cluster.rb +26 -0
  86. data/lib/tasks/gem.rb +31 -0
  87. data/lib/tasks/generate.rb +80 -0
  88. data/lib/utilities/hash.rb +31 -0
  89. data/lib/utilities/inflect.rb +110 -0
  90. data/lib/utilities/integer.rb +24 -0
  91. data/lib/utilities/module.rb +21 -0
  92. data/lib/utilities/object.rb +25 -0
  93. data/lib/utilities/proc.rb +16 -0
  94. data/lib/utilities/string.rb +49 -0
  95. data/lib/utilities/symbol.rb +10 -0
  96. data/lib/utilities/tempfile.rb +9 -0
  97. data/lib/views/base.rb +9 -0
  98. data/lib/views/mixin.rb +110 -0
  99. data/lib/waves.rb +84 -0
  100. data/samples/blog/Rakefile +14 -0
  101. data/samples/blog/bin/waves-console +3 -0
  102. data/samples/blog/bin/waves-server +3 -0
  103. data/samples/blog/configurations/development.rb +31 -0
  104. data/samples/blog/configurations/mapping.rb +23 -0
  105. data/samples/blog/configurations/production.rb +30 -0
  106. data/samples/blog/doc/EMTPY +0 -0
  107. data/samples/blog/lib/application.rb +5 -0
  108. data/samples/blog/models/comment.rb +14 -0
  109. data/samples/blog/models/entry.rb +14 -0
  110. data/samples/blog/public/css/site.css +2 -0
  111. data/samples/blog/public/javascript/site.js +13 -0
  112. data/samples/blog/schema/migrations/001_initial_schema.rb +17 -0
  113. data/samples/blog/schema/migrations/002_add_comments.rb +18 -0
  114. data/samples/blog/schema/migrations/templates/empty.rb.erb +9 -0
  115. data/samples/blog/startup.rb +6 -0
  116. data/samples/blog/templates/comment/add.mab +10 -0
  117. data/samples/blog/templates/comment/list.mab +6 -0
  118. data/samples/blog/templates/entry/editor.mab +13 -0
  119. data/samples/blog/templates/entry/list.mab +11 -0
  120. data/samples/blog/templates/entry/show.mab +9 -0
  121. data/samples/blog/templates/entry/summary.mab +5 -0
  122. data/samples/blog/templates/errors/not_found_404.mab +2 -0
  123. data/samples/blog/templates/errors/server_error_500.mab +2 -0
  124. data/samples/blog/templates/layouts/default.mab +17 -0
  125. data/verify/app_generation/helpers.rb +24 -0
  126. data/verify/app_generation/startup.rb +39 -0
  127. data/verify/blackboard/blackboard_verify.rb +92 -0
  128. data/verify/blackboard/helpers.rb +5 -0
  129. data/verify/configurations/attributes.rb +37 -0
  130. data/verify/configurations/helpers.rb +1 -0
  131. data/verify/configurations/rack_integration.rb +29 -0
  132. data/verify/controllers/base.rb +37 -0
  133. data/verify/controllers/helpers.rb +13 -0
  134. data/verify/controllers/interface.rb +51 -0
  135. data/verify/core/helpers.rb +3 -0
  136. data/verify/core/utilities.rb +177 -0
  137. data/verify/foundations/default.rb +86 -0
  138. data/verify/foundations/default_application/Rakefile +14 -0
  139. data/verify/foundations/default_application/bin/waves-console +3 -0
  140. data/verify/foundations/default_application/bin/waves-server +3 -0
  141. data/verify/foundations/default_application/configurations/development.rb +26 -0
  142. data/verify/foundations/default_application/configurations/mapping.rb +14 -0
  143. data/verify/foundations/default_application/configurations/production.rb +30 -0
  144. data/verify/foundations/default_application/controllers/default.rb +15 -0
  145. data/verify/foundations/default_application/controllers/loaded.rb +15 -0
  146. data/verify/foundations/default_application/defaultapplication.db +0 -0
  147. data/verify/foundations/default_application/helpers/loaded.rb +10 -0
  148. data/verify/foundations/default_application/lib/application.rb +5 -0
  149. data/verify/foundations/default_application/models/default.rb +13 -0
  150. data/verify/foundations/default_application/models/loaded.rb +13 -0
  151. data/verify/foundations/default_application/schema/migrations/templates/empty.rb.erb +9 -0
  152. data/verify/foundations/default_application/startup.rb +7 -0
  153. data/verify/foundations/default_application/templates/errors/not_found_404.mab +2 -0
  154. data/verify/foundations/default_application/templates/errors/server_error_500.mab +2 -0
  155. data/verify/foundations/default_application/templates/layouts/default.mab +14 -0
  156. data/verify/foundations/default_application/views/default.rb +7 -0
  157. data/verify/foundations/default_application/views/loaded.rb +15 -0
  158. data/verify/foundations/helpers.rb +1 -0
  159. data/verify/foundations/simple.rb +25 -0
  160. data/verify/helpers.rb +76 -0
  161. data/verify/layers/data_mapper/association_verify.rb +87 -0
  162. data/verify/layers/default_errors.rb +29 -0
  163. data/verify/layers/helpers.rb +1 -0
  164. data/verify/layers/migration.rb +33 -0
  165. data/verify/layers/sequel/model.rb +41 -0
  166. data/verify/mapping/always.rb +19 -0
  167. data/verify/mapping/filters.rb +65 -0
  168. data/verify/mapping/handle.rb +24 -0
  169. data/verify/mapping/helpers.rb +7 -0
  170. data/verify/mapping/matches.rb +27 -0
  171. data/verify/mapping/named.rb +29 -0
  172. data/verify/mapping/options.rb +17 -0
  173. data/verify/mapping/path.rb +40 -0
  174. data/verify/mapping/response_proxy.rb +50 -0
  175. data/verify/mapping/threaded.rb +25 -0
  176. data/verify/requests/helpers.rb +16 -0
  177. data/verify/requests/request.rb +73 -0
  178. data/verify/requests/response.rb +59 -0
  179. data/verify/requests/session.rb +54 -0
  180. data/verify/views/helpers.rb +1 -0
  181. data/verify/views/rendering.rb +34 -0
  182. data/verify/views/templates/foo.erb +0 -0
  183. data/verify/views/templates/moo.erb +0 -0
  184. data/verify/views/templates/moo.mab +0 -0
  185. metadata +439 -0
@@ -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,31 @@
1
+ module Waves
2
+ module Utilities # :nodoc:
3
+
4
+ # Utility methods mixed into Hash.
5
+ module Hash
6
+
7
+ # Return a copy of the hash where all keys have been converted to strings.
8
+ def stringify_keys
9
+ inject({}) do |options, (key, value)|
10
+ options[key.to_s] = value
11
+ options
12
+ end
13
+ end
14
+
15
+ # Destructively convert all keys to symbols.
16
+ def symbolize_keys!
17
+ keys.each do |key|
18
+ unless key.is_a?(Symbol)
19
+ self[key.to_sym] = self[key]
20
+ delete(key)
21
+ end
22
+ end
23
+ self
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ class Hash # :nodoc:
30
+ include Waves::Utilities::Hash
31
+ end
@@ -0,0 +1,110 @@
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
+ module Waves
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 ||= {}
21
+ @singular_of[plural] = singular
22
+ end
23
+
24
+ # Define a pluralization exception.
25
+ def plural_word(singular, plural)
26
+ @plural_of ||= {}
27
+ @plural_of[singular] = plural
28
+ end
29
+
30
+ # Define a general rule.
31
+ def rule(singular, plural)
32
+ singular_rule(singular, plural)
33
+ plural_rule(singular, plural)
34
+ end
35
+
36
+ # Define a singularization rule.
37
+ def singular_rule(singular, plural)
38
+ (@singular_rules ||= []) << [singular, plural]
39
+ end
40
+
41
+ # Define a plurualization rule.
42
+ def plural_rule(singular, plural)
43
+ (@plural_rules ||= []) << [singular, plural]
44
+ end
45
+
46
+ # Read prepared singularization rules.
47
+ def singularization_rules
48
+ @singular_rules ||= []
49
+ return @singularization_rules if @singularization_rules
50
+ sorted = @singular_rules.sort_by{ |s, p| "#{p}".size }.reverse
51
+ @singularization_rules = sorted.collect do |s, p|
52
+ [ /#{p}$/, "#{s}" ]
53
+ end
54
+ end
55
+
56
+ # Read prepared pluralization rules.
57
+ def pluralization_rules
58
+ @plural_rules ||= []
59
+ return @pluralization_rules if @pluralization_rules
60
+ sorted = @plural_rules.sort_by{ |s, p| "#{s}".size }.reverse
61
+ @pluralization_rules = sorted.collect do |s, p|
62
+ [ /#{s}$/, "#{p}" ]
63
+ end
64
+ end
65
+
66
+ #
67
+ def plural_of
68
+ @plural_of ||= {}
69
+ end
70
+
71
+ #
72
+ def singular_of
73
+ @singular_of ||= {}
74
+ end
75
+
76
+ # Convert an English word from plural to singular.
77
+ #
78
+ # "boys".singular #=> boy
79
+ # "tomatoes".singular #=> tomato
80
+ #
81
+ def singular(word)
82
+ if result = singular_of[word]
83
+ return result.dup
84
+ end
85
+ result = word.dup
86
+ singularization_rules.each do |(match, replacement)|
87
+ break if result.gsub!(match, replacement)
88
+ end
89
+ return result
90
+ end
91
+
92
+ # Convert an English word from singular to plurel.
93
+ #
94
+ # "boy".plural #=> boys
95
+ # "tomato".plural #=> tomatoes
96
+ #
97
+ def plural(word)
98
+ if result = plural_of[word]
99
+ return result.dup
100
+ end
101
+ #return self.dup if /s$/ =~ self # ???
102
+ result = word.dup
103
+ pluralization_rules.each do |(match, replacement)|
104
+ break if result.gsub!(match, replacement)
105
+ end
106
+ return result
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,24 @@
1
+ module Waves
2
+ module Utilities
3
+ module Integer
4
+ def seconds ; self ; end
5
+ def minutes ; self * 60 ; end
6
+ def hours ; self * 60.minutes ; end
7
+ def days ; self * 24.hours ; end
8
+ def weeks ; self * 7.days ; end
9
+ def bytes ; self ; end
10
+ def kilobytes ; self * 1024 ; end
11
+ def megabytes ; self * 1024.kilobytes ; end
12
+ def gigabytes ; self * 1024.megabytes ; end
13
+ def terabytes ; self * 1024.gigabytes ; end
14
+ def petabytes ; self * 1024.terabytes ; end
15
+ def exabytes ; self * 1024.petabytes ; end
16
+ def zettabytes ; self * 1024.exabytes ; end
17
+ def yottabytes ; self * 1024.zettabytes ; end
18
+ end
19
+ end
20
+ end
21
+
22
+ class Integer # :nodoc:
23
+ include Waves::Utilities::Integer
24
+ end
@@ -0,0 +1,21 @@
1
+ module Waves
2
+ module Utilities
3
+ module Module
4
+ # This comes in handy when you are trying to do meta-programming with modules / classes
5
+ # that may be nested within other modules / classes. I think I've seen it defined in
6
+ # facets, but I'm not relying on facets just for this one method.
7
+ def basename
8
+ self.name.split('::').last || ''
9
+ end
10
+
11
+ # Just a convenience method for accessing a const within a Module
12
+ def []( cname )
13
+ const_get( cname.to_s.camel_case )
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ class Module # :nodoc:
20
+ include Waves::Utilities::Module
21
+ end
@@ -0,0 +1,25 @@
1
+ module Waves
2
+ module Utilities
3
+ module Object
4
+ # This is an extremely powerful little function that will be built-in to Ruby 1.9.
5
+ # This version is from Mauricio Fernandez via ruby-talk. Works like instance_eval
6
+ # except that you can pass parameters to the block. This means you can define a block
7
+ # intended for use with instance_eval, pass it to another method, which can then
8
+ # invoke with parameters. This is used quite a bit by the Waves::Mapping code.
9
+ def instance_exec(*args, &block)
10
+ mname = "__instance_exec_#{Thread.current.object_id.abs}"
11
+ class << self; self end.class_eval{ define_method(mname, &block) }
12
+ begin
13
+ ret = send(mname, *args)
14
+ ensure
15
+ class << self; self end.class_eval{ undef_method(mname) } rescue nil
16
+ end
17
+ ret
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ class Object # :nodoc:
24
+ include Waves::Utilities::Object
25
+ end
@@ -0,0 +1,16 @@
1
+ module Waves
2
+ module Utilities
3
+ module Proc
4
+ # calls the given lambda with the receiver as its argument
5
+ def |(lambda)
6
+ lambda do
7
+ lambda.call( self.call )
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
13
+
14
+ class Proc # :nodoc:
15
+ include Waves::Utilities::Proc
16
+ end
@@ -0,0 +1,49 @@
1
+ module Waves
2
+ module Utilities
3
+
4
+ # Utility methods mixed into String.
5
+
6
+ module String
7
+
8
+ # Syntactic sugar for using File.join to concatenate the argument to the receiver.
9
+ #
10
+ # require "lib" / "utilities" / "string"
11
+ #
12
+ # The idea is not original, but we can't remember where we first saw it.
13
+ #
14
+ # Waves::Utilities::Symbol defines the same method, allowing for :files / 'afilename.txt'
15
+
16
+ def / ( string )
17
+ File.join(self,string.to_s)
18
+ end
19
+
20
+ # produces stringsLikeThis
21
+ def lower_camel_case
22
+ gsub(/(_)(\w)/) { $2.upcase }
23
+ end
24
+
25
+ # produces StringsLikeThis
26
+ def camel_case
27
+ lower_camel_case.gsub(/^([a-z])/) { $1.upcase }
28
+ end
29
+
30
+ # produces strings_like_this
31
+ def snake_case
32
+ gsub(/\s+/,'').gsub(/([a-z\d])([A-Z])/){ "#{$1}_#{$2}"}.tr("-", "_").downcase
33
+ end
34
+
35
+ def title_case
36
+ gsub(/(^|\s)\s*([a-z])/) { $1 + $2.upcase }
37
+ end
38
+
39
+ def text
40
+ gsub(/[\_\-\.\:]/,' ')
41
+ end
42
+
43
+ end
44
+ end
45
+ end
46
+
47
+ class ::String # :nodoc:
48
+ include Waves::Utilities::String
49
+ end
@@ -0,0 +1,10 @@
1
+ class Symbol
2
+ # Does File.join on self and string, converting self to string before invocation.
3
+ # See String#/ for more.
4
+ #
5
+ # Note: This overrides any definitions done politely in modules, such as
6
+ # {Sequel::SQL::ComplexExpressionMethods}[http://sequel.rubyforge.org/classes/Sequel/SQL/ComplexExpressionMethods.html]
7
+ def / ( string )
8
+ self.to_s / string
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ # Patch Ruby's Tempfile class to work around a problem uploading files with Rack.
2
+ #
3
+ # The fix came from here: http://sinatra.lighthouseapp.com/projects/9779/tickets/1
4
+ #
5
+ # This is fixed in Rack already, but it hasn't made it into a gem.
6
+ class Tempfile
7
+ # Make == act like eql?
8
+ def ==(other) ; eql?(other) || super ; end
9
+ end