dyoder-waves 0.7.7 → 0.8.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 (171) hide show
  1. data/bin/waves +19 -56
  2. data/doc/HISTORY +1 -0
  3. data/doc/LICENSE +22 -0
  4. data/doc/README +1 -0
  5. data/doc/VERSION +1 -0
  6. data/lib/caches/file.rb +48 -0
  7. data/lib/caches/memcached.rb +40 -0
  8. data/lib/caches/simple.rb +25 -0
  9. data/lib/caches/synchronized.rb +25 -0
  10. data/lib/commands/console.rb +35 -0
  11. data/lib/commands/generate.rb +52 -0
  12. data/lib/commands/help.rb +5 -0
  13. data/lib/commands/{waves-server.rb → server.rb} +16 -3
  14. data/lib/dispatchers/base.rb +21 -20
  15. data/lib/dispatchers/default.rb +11 -63
  16. data/lib/ext/float.rb +13 -0
  17. data/lib/{utilities → ext}/hash.rb +2 -2
  18. data/lib/{utilities → ext}/integer.rb +5 -2
  19. data/lib/ext/kernel.rb +20 -0
  20. data/lib/ext/module.rb +20 -0
  21. data/lib/{utilities → ext}/object.rb +3 -5
  22. data/lib/ext/string.rb +20 -0
  23. data/lib/ext/symbol.rb +11 -0
  24. data/lib/ext/tempfile.rb +5 -0
  25. data/lib/foundations/classic.rb +64 -0
  26. data/lib/foundations/compact.rb +50 -0
  27. data/lib/helpers/basic.rb +11 -0
  28. data/lib/helpers/doc_type.rb +34 -0
  29. data/lib/helpers/extended.rb +21 -0
  30. data/lib/helpers/form.rb +3 -1
  31. data/lib/helpers/formatting.rb +3 -3
  32. data/lib/helpers/layouts.rb +37 -0
  33. data/lib/helpers/model.rb +8 -4
  34. data/lib/helpers/view.rb +2 -4
  35. data/lib/layers/inflect/english.rb +67 -0
  36. data/lib/layers/mvc.rb +18 -18
  37. data/lib/layers/mvc/controllers.rb +41 -0
  38. data/lib/layers/mvc/extensions.rb +52 -0
  39. data/lib/layers/orm/{active_record.rb → providers/active_record.rb} +12 -18
  40. data/lib/layers/orm/{active_record → providers/active_record}/migrations/empty.rb.erb +0 -0
  41. data/lib/layers/orm/{active_record → providers/active_record}/tasks/generate.rb +1 -1
  42. data/lib/layers/orm/{active_record → providers/active_record}/tasks/schema.rb +1 -1
  43. data/lib/layers/orm/{data_mapper.rb → providers/data_mapper.rb} +3 -4
  44. data/lib/layers/orm/providers/filebase.rb +25 -0
  45. data/lib/layers/orm/{sequel.rb → providers/sequel.rb} +16 -12
  46. data/lib/layers/orm/{sequel → providers/sequel}/migrations/empty.rb.erb +0 -0
  47. data/lib/layers/orm/{sequel → providers/sequel}/tasks/generate.rb +5 -3
  48. data/lib/layers/orm/{sequel → providers/sequel}/tasks/schema.rb +2 -2
  49. data/lib/{renderers → layers/renderers}/erubis.rb +10 -13
  50. data/lib/layers/renderers/haml.rb +47 -0
  51. data/lib/layers/renderers/markaby.rb +29 -0
  52. data/lib/matchers/accept.rb +21 -0
  53. data/lib/matchers/base.rb +30 -0
  54. data/lib/matchers/content_type.rb +17 -0
  55. data/lib/matchers/path.rb +67 -0
  56. data/lib/matchers/query.rb +21 -0
  57. data/lib/matchers/request.rb +27 -0
  58. data/lib/matchers/resource.rb +19 -0
  59. data/lib/matchers/traits.rb +19 -0
  60. data/lib/matchers/uri.rb +20 -0
  61. data/lib/renderers/mixin.rb +15 -29
  62. data/lib/resources/mixin.rb +132 -0
  63. data/lib/resources/paths.rb +34 -0
  64. data/lib/runtime/configuration.rb +55 -135
  65. data/lib/runtime/console.rb +4 -1
  66. data/lib/runtime/logger.rb +24 -48
  67. data/lib/runtime/mime_types.rb +516 -2
  68. data/lib/runtime/mocks.rb +14 -0
  69. data/lib/runtime/monitor.rb +32 -0
  70. data/lib/runtime/request.rb +107 -39
  71. data/lib/runtime/response.rb +5 -2
  72. data/lib/runtime/response_mixin.rb +43 -22
  73. data/lib/runtime/runtime.rb +67 -0
  74. data/lib/runtime/server.rb +14 -101
  75. data/lib/runtime/session.rb +4 -43
  76. data/lib/runtime/worker.rb +86 -0
  77. data/lib/servers/base.rb +42 -0
  78. data/lib/servers/mongrel.rb +13 -0
  79. data/lib/servers/webrick.rb +13 -0
  80. data/lib/tasks/gem.rb +1 -0
  81. data/lib/tasks/generate.rb +67 -62
  82. data/lib/views/errors.rb +49 -0
  83. data/lib/views/mixin.rb +34 -82
  84. data/lib/waves.rb +36 -55
  85. data/samples/blog/Rakefile +25 -0
  86. data/samples/blog/configurations/default.rb +11 -0
  87. data/samples/blog/configurations/development.rb +29 -0
  88. data/samples/blog/configurations/production.rb +26 -0
  89. data/samples/blog/models/comment.rb +23 -0
  90. data/samples/blog/models/entry.rb +31 -0
  91. data/samples/blog/public/css/site.css +13 -0
  92. data/samples/blog/public/javascript/jquery-1.2.6.min.js +32 -0
  93. data/samples/blog/public/javascript/site.js +13 -0
  94. data/samples/blog/resources/entry.rb +39 -0
  95. data/samples/blog/resources/map.rb +9 -0
  96. data/samples/blog/schema/migrations/001_initial_schema.rb +17 -0
  97. data/samples/blog/schema/migrations/002_add_comments.rb +18 -0
  98. data/samples/blog/schema/migrations/templates/empty.rb.erb +9 -0
  99. data/samples/blog/startup.rb +8 -0
  100. data/samples/blog/templates/comment/add.mab +12 -0
  101. data/samples/blog/templates/comment/list.mab +6 -0
  102. data/samples/blog/templates/entry/edit.mab +14 -0
  103. data/samples/blog/templates/entry/list.mab +16 -0
  104. data/samples/blog/templates/entry/show.mab +18 -0
  105. data/samples/blog/templates/entry/summary.mab +9 -0
  106. data/samples/blog/templates/errors/not_found_404.mab +7 -0
  107. data/{app → samples/blog}/templates/errors/server_error_500.mab +0 -0
  108. data/samples/blog/templates/layouts/default.mab +19 -0
  109. data/samples/blog/templates/waves/status.mab +85 -0
  110. data/templates/classic/Rakefile +130 -0
  111. data/templates/classic/configurations/default.rb.erb +9 -0
  112. data/{app → templates/classic}/configurations/development.rb.erb +3 -7
  113. data/{app → templates/classic}/configurations/production.rb.erb +3 -4
  114. data/templates/classic/resources/map.rb.erb +8 -0
  115. data/templates/classic/startup.rb.erb +11 -0
  116. data/{app → templates/classic}/templates/errors/not_found_404.mab +0 -0
  117. data/templates/classic/templates/errors/server_error_500.mab +2 -0
  118. data/{app → templates/classic}/templates/layouts/default.mab +0 -0
  119. data/templates/compact/startup.rb.erb +11 -0
  120. metadata +967 -144
  121. data/app/Rakefile +0 -14
  122. data/app/bin/waves-console +0 -4
  123. data/app/bin/waves-server +0 -4
  124. data/app/configurations/mapping.rb.erb +0 -13
  125. data/app/controllers/.gitignore +0 -0
  126. data/app/doc/.gitignore +0 -0
  127. data/app/helpers/.gitignore +0 -0
  128. data/app/lib/application.rb.erb +0 -5
  129. data/app/lib/tasks/.gitignore +0 -0
  130. data/app/log/.gitignore +0 -0
  131. data/app/models/.gitignore +0 -0
  132. data/app/public/css/.gitignore +0 -0
  133. data/app/public/flash/.gitignore +0 -0
  134. data/app/public/images/.gitignore +0 -0
  135. data/app/public/javascript/.gitignore +0 -0
  136. data/app/schema/migrations/.gitignore +0 -0
  137. data/app/startup.rb +0 -5
  138. data/app/tmp/sessions/.gitignore +0 -0
  139. data/app/views/.gitignore +0 -0
  140. data/bin/waves-console +0 -4
  141. data/bin/waves-server +0 -4
  142. data/lib/commands/waves-console.rb +0 -21
  143. data/lib/controllers/base.rb +0 -11
  144. data/lib/controllers/mixin.rb +0 -165
  145. data/lib/foundations/default.rb +0 -26
  146. data/lib/foundations/simple.rb +0 -30
  147. data/lib/helpers/asset_helper.rb +0 -67
  148. data/lib/helpers/common.rb +0 -66
  149. data/lib/helpers/default.rb +0 -13
  150. data/lib/helpers/number_helper.rb +0 -25
  151. data/lib/helpers/tag_helper.rb +0 -58
  152. data/lib/helpers/url_helper.rb +0 -77
  153. data/lib/layers/default_errors.rb +0 -26
  154. data/lib/layers/orm/filebase.rb +0 -22
  155. data/lib/layers/simple.rb +0 -35
  156. data/lib/layers/simple_errors.rb +0 -23
  157. data/lib/mapping/mapping.rb +0 -289
  158. data/lib/mapping/pretty_urls.rb +0 -96
  159. data/lib/renderers/markaby.rb +0 -33
  160. data/lib/runtime/application.rb +0 -69
  161. data/lib/runtime/blackboard.rb +0 -57
  162. data/lib/runtime/debugger.rb +0 -9
  163. data/lib/runtime/response_proxy.rb +0 -30
  164. data/lib/tasks/cluster.rb +0 -26
  165. data/lib/utilities/inflect.rb +0 -110
  166. data/lib/utilities/inflect/english.rb +0 -84
  167. data/lib/utilities/module.rb +0 -21
  168. data/lib/utilities/proc.rb +0 -16
  169. data/lib/utilities/string.rb +0 -61
  170. data/lib/utilities/symbol.rb +0 -10
  171. data/lib/views/base.rb +0 -9
@@ -19,9 +19,9 @@ module Waves
19
19
  # Treat content as Textile.
20
20
  def textile( content )
21
21
  return if content.nil? or content.empty?
22
- ( ::RedCloth::TEXTILE_TAGS << [ 96.chr, '&8216;'] ).each do |pat,ent|
23
- content.gsub!( pat, ent.gsub('&','&#') )
24
- end
22
+ #( ::RedCloth::TEXTILE_TAGS << [ 96.chr, '&8216;'] ).each do |pat,ent|
23
+ # content.gsub!( pat, ent.gsub('&','&#') )
24
+ #end
25
25
  self << ::RedCloth.new( content ).to_html
26
26
  end
27
27
 
@@ -0,0 +1,37 @@
1
+ module Waves
2
+
3
+ module Helpers
4
+
5
+ module Layouts
6
+
7
+ # Invokes a layout view (i.e., a view from the layouts template directory), using
8
+ # the assigns parameter to define instance variables for the view. The block is
9
+ # evaluated and also passed into the view as the +layout_content+ instance variable.
10
+ #
11
+ # You can define a layout just by creating a template and then calling the
12
+ # +layout_content+ accessor when you want to embed the caller's content.
13
+ #
14
+ # == Example
15
+ #
16
+ # doctype :html4_transitional
17
+ # html do
18
+ # title @title # passed as an assigns parameter
19
+ # end
20
+ # body do
21
+ # layout_content
22
+ # end
23
+ #
24
+ def layout( name, assigns = {}, &block )
25
+ assigns[ :layout_content ] = capture(&block)
26
+ self << Waves.main::Views[:layouts].process( request ) do
27
+ send( name, assigns )
28
+ end
29
+ end
30
+
31
+ def layout_content
32
+ self << @layout_content
33
+ end
34
+
35
+ end
36
+ end
37
+ end
data/lib/helpers/model.rb CHANGED
@@ -17,15 +17,19 @@ module Waves
17
17
  # then be called from the template instead of the model helper.
18
18
  #
19
19
  module Model
20
-
20
+
21
+ def model( name )
22
+ Waves.main::Models[ name ][ domain ]
23
+ end
24
+
21
25
  # Just like model.all. Returns all the instances of that model.
22
26
  def all( model )
23
- Waves.application.models[ model ].all( domain )
27
+ model( model ).all
24
28
  end
25
-
29
+
26
30
  # Finds a specific instance using the name field
27
31
  def find( model, name )
28
- Waves.application.models[ model ][ :name => name ] rescue nil
32
+ model( model )[name ] rescue nil
29
33
  end
30
34
 
31
35
  end
data/lib/helpers/view.rb CHANGED
@@ -10,12 +10,10 @@ module Waves
10
10
  # view) and returns the result of evaluating the view as content in the current
11
11
  # template.
12
12
  module View
13
-
13
+
14
14
  # Invokes the view for the given model, passing the assigns as instance variables.
15
15
  def view( model, view, assigns = {} )
16
- self << Waves.application.views[ model ].process( request ) do
17
- send( view, assigns )
18
- end
16
+ self << Waves.main::Views[ model ].new( request ).send( view, assigns )
19
17
  end
20
18
 
21
19
 
@@ -0,0 +1,67 @@
1
+ module Waves
2
+ module Layers
3
+ module Inflect
4
+
5
+ # Adds plural/singular methods for English to String
6
+ module English
7
+
8
+ def self.included(app)
9
+
10
+ require 'english/inflect'
11
+
12
+ Waves::Resources::Mixin::ClassMethods.module_eval do
13
+ def singular ; basename.snake_case.singular ; end
14
+ def plural ; basename.snake_case.plural ; end
15
+ end
16
+
17
+ Waves::Resources::Mixin.module_eval do
18
+ def singular ; self.class.singular ; end
19
+ def plural ; self.class.plural ; end
20
+ end
21
+
22
+ Waves::Resources::Paths.module_eval do
23
+ def resource ; self.class.resource.singular ; end
24
+ def resources ; self.class.resource.plural ; end
25
+
26
+ # TODO: be nice to DRY this up ... basically the same code
27
+ # as the mixin except with the singular / plural stuff
28
+ # mixed in ...
29
+ def generate( template, args )
30
+ return "/#{ args * '/' }" unless template.is_a?( Array ) and not template.empty?
31
+ path = []
32
+ ( "/#{ path * '/' }" ) if template.all? do | want |
33
+ case want
34
+ when true then path += args
35
+ when String then path << want
36
+ when Symbol
37
+ case want
38
+ when :resource then path << resource
39
+ when :resources then path << resources
40
+ else path << args.shift
41
+ end
42
+ when Regexp then path << args.shift
43
+ when Hash
44
+ key, value = want.to_a.first
45
+ case key
46
+ when :resource then path << resource
47
+ when :resources then path << resources
48
+ else
49
+ case value
50
+ when true then path += args
51
+ when String, Symbol, RegExp then path << args.unshift
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+
67
+
data/lib/layers/mvc.rb CHANGED
@@ -1,22 +1,16 @@
1
1
  module Waves
2
2
  module Layers
3
- # The MVC layer establishes the Models, Views, Controllers, and Helpers namespaces inside
4
- # a Waves application. In each namespace, undefined constants are handled by AutoCode, which
5
- # loads the constant from the correct file in the appropriate directory if it exists, or creates
6
- # from default otherwise.
7
3
  module MVC
8
4
 
9
5
  def self.included( app )
10
6
 
11
- def app.models ; self::Models ; end
12
- def app.views ; self::Views ; end
13
- def app.controllers ; self::Controllers ; end
14
- def app.helpers ; self::Helpers ; end
7
+ require 'layers/mvc/extensions'
8
+ require 'layers/mvc/controllers'
15
9
 
16
10
  app.auto_create_module( :Models ) do
17
11
  include AutoCode
18
12
  auto_create_class :Default
19
- auto_load :Default, :directories => [:models]
13
+ auto_load :Default, :directories => [ :models ]
20
14
  end
21
15
 
22
16
  app.auto_eval( :Models ) do
@@ -24,30 +18,36 @@ module Waves
24
18
  auto_load true, :directories => [ :models ]
25
19
  end
26
20
 
27
- app.auto_create_module( :Views ) { include AutoCode }
21
+ app.auto_create_module( :Views ) do
22
+ include AutoCode
23
+ auto_create_class :Default, Waves::Views::Base
24
+ auto_load :Default, :directories => [ :views ]
25
+ end
28
26
 
29
27
  app.auto_eval( :Views ) do
30
- auto_create_class :Default, Waves::Views::Base
31
- auto_load :Default, :directories => [:views]
32
28
  auto_create_class true, app::Views::Default
33
29
  auto_load true, :directories => [ :views ]
34
30
  end
35
31
 
36
- app.auto_create_module( :Controllers ) { include AutoCode }
32
+ app.auto_create_module( :Controllers ) do
33
+ include AutoCode
34
+ auto_create_class :Default, Waves::Controllers::Base
35
+ auto_load :Default, :directories => [ :controllers ]
36
+ end
37
37
 
38
38
  app.auto_eval( :Controllers ) do
39
- auto_create_class :Default, Waves::Controllers::Base
40
- auto_load :Default, :directories => [:controllers]
41
39
  auto_create_class true, app::Controllers::Default
42
40
  auto_load true, :directories => [ :controllers ]
43
41
  end
44
42
 
45
43
  app.auto_create_module( :Helpers ) do
46
44
  include AutoCode
47
- auto_create_module { include Waves::Helpers::Default }
45
+ auto_create_module( :Default ) { include Waves::Helpers::Extended }
46
+ auto_load :Default, :directories => [ :helpers ]
47
+ auto_create_module( true ) { include app::Helpers::Default }
48
48
  auto_load true, :directories => [ :helpers ]
49
- end
50
-
49
+ end
50
+
51
51
  end
52
52
  end
53
53
  end
@@ -0,0 +1,41 @@
1
+ module Waves
2
+
3
+ module Controllers
4
+
5
+ module Mixin
6
+
7
+ attr_reader :request
8
+
9
+ include Waves::ResponseMixin
10
+
11
+ def initialize( request )
12
+ @request = request
13
+ end
14
+
15
+ def find( name )
16
+ model.find( name )
17
+ end
18
+
19
+ def create( attributes )
20
+ model.create( attributes )
21
+ end
22
+
23
+ def update( name, attributes )
24
+ find( name ).attributes = attributes
25
+ end
26
+
27
+ def delete( name )
28
+ model.delete( name )
29
+ end
30
+
31
+ def list
32
+ model.all
33
+ end
34
+
35
+ end
36
+
37
+ class Base ; include Mixin ; end
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,52 @@
1
+ module Waves
2
+
3
+ module Resources
4
+
5
+ module Mixin
6
+
7
+ def controller( resource = nil )
8
+ resource ||= self.class.basename
9
+ @controller ||= app::Controllers[ resource ].new( @request )
10
+ end
11
+
12
+ def view( resource = nil )
13
+ resource ||= self.class.basename
14
+ @view ||= app::Views[ resource ].new( @request )
15
+ end
16
+
17
+ end
18
+
19
+ end
20
+
21
+ module ResponseMixin
22
+
23
+ # Returns the name of the model corresponding to this controller by taking the basename
24
+ # of the module and converting it to snake case. If the model plurality is different than
25
+ # the controller, this will not, in fact, be the model name.
26
+ def model_name; self.class.basename.snake_case; end
27
+
28
+ # Returns the model corresponding to this controller by naively assuming that
29
+ # +model_name+ must be correct. This allows you to write generic controller methods such as:
30
+ #
31
+ # model.find( name )
32
+ #
33
+ # to find an instance of a given model. Again, the plurality of the controller and
34
+ # model must be the same for this to work.
35
+ def model; app::Models[ model_name.intern ]; end
36
+
37
+ # MVC Params get automatically destructured with the keys as accessors methods.
38
+ # You can still access the original query by calling request.query
39
+ def query
40
+ @query ||= Waves::Request::Query.new(
41
+ Waves::Request::Utilities.destructure( request.query ) )
42
+ end
43
+
44
+ # Attributes are just the query elements specific to the model associated with
45
+ # the current resource.
46
+ def attributes
47
+ query[ model_name ]
48
+ end
49
+
50
+ end
51
+
52
+ end
@@ -1,14 +1,3 @@
1
- class Symbol
2
- # Protect ActiveRecord from itself by undefining the to_proc method.
3
- # Don't worry, AR will redefine it.
4
- alias :extensions_to_proc :to_proc
5
- remove_method :to_proc
6
- end
7
- require 'active_record'
8
- require "#{File.dirname(__FILE__)}/active_record/tasks/schema" if defined?(Rake)
9
- require "#{File.dirname(__FILE__)}/active_record/tasks/generate" if defined?(Rake)
10
-
11
-
12
1
  module Waves
13
2
  module Layers
14
3
  module ORM
@@ -28,8 +17,13 @@ module Waves
28
17
  # - create
29
18
  # - delete(name)
30
19
  # - update(name)
31
-
20
+
21
+
32
22
  def self.included(app)
23
+
24
+ require 'active_record'
25
+ require "#{File.dirname(__FILE__)}/active_record/tasks/schema" if defined?(Rake)
26
+ require "#{File.dirname(__FILE__)}/active_record/tasks/generate" if defined?(Rake)
33
27
 
34
28
  def app.database
35
29
  unless @database
@@ -67,20 +61,20 @@ module Waves
67
61
  model.find(:all)
68
62
  end
69
63
 
70
- def find( id )
71
- model.find(id) or not_found
64
+ def find( name )
65
+ model.find_by_name(name) or not_found
72
66
  end
73
67
 
74
68
  def create
75
69
  model.create( attributes )
76
70
  end
77
71
 
78
- def delete( id )
79
- find( id ).destroy
72
+ def delete( name )
73
+ find( name ).destroy
80
74
  end
81
75
 
82
- def update( id )
83
- instance = find( id )
76
+ def update( name )
77
+ instance = find( name )
84
78
  instance.update_attributes( attributes )
85
79
  instance
86
80
  end
@@ -13,7 +13,7 @@ namespace :generate do
13
13
  end
14
14
 
15
15
  model = <<TEXT
16
- module #{Waves.application.name}
16
+ module #{app_name}
17
17
  module Models
18
18
  class #{model_name} < Default
19
19
 
@@ -14,7 +14,7 @@ namespace :schema do
14
14
  end
15
15
 
16
16
  task :connect do
17
- Waves.application.database
17
+ Waves.main.database
18
18
  ActiveRecord::Base.logger = Logger.new($stdout)
19
19
  end
20
20
 
@@ -1,7 +1,3 @@
1
- gem 'dm-core', '=0.9.0'
2
-
3
- require 'data_mapper'
4
-
5
1
  module Waves
6
2
  module Layers
7
3
  module ORM
@@ -10,6 +6,9 @@ module Waves
10
6
  module DataMapper
11
7
 
12
8
  def self.included(app)
9
+ gem 'dm-core', '=0.9.0'
10
+
11
+ require 'data_mapper'
13
12
 
14
13
  def app.database
15
14
  @adapter ||= ::DataMapper.setup(:main_repository, config.database[:database])
@@ -0,0 +1,25 @@
1
+ module Waves
2
+ module Layers
3
+ module ORM
4
+
5
+ # The Filebase ORM layer configures model classes to use Filebase with a datastore located in
6
+ # <tt>db/model_name</tt>, where @model_name@ is the snakecased version of the class name.
7
+ #
8
+ # The Filebase store for Blog::Models::Entry would be located in <tt>db/entry</tt>, for example.
9
+ module Filebase
10
+
11
+ def self.included(app)
12
+ app.module_eval do
13
+ auto_eval( :Models ) do
14
+ auto_eval( true ) { include ::Filebase::Model[ :db / self.basename.snake_case ] }
15
+ end
16
+ end
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+
25
+ end