dyoder-waves 0.7.3 → 0.7.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. data/app/bin/waves-console +1 -0
  2. data/app/bin/waves-server +1 -0
  3. data/app/configurations/development.rb.erb +5 -6
  4. data/app/configurations/mapping.rb.erb +1 -2
  5. data/app/configurations/production.rb.erb +2 -2
  6. data/app/controllers/.gitignore +0 -0
  7. data/app/doc/.gitignore +0 -0
  8. data/app/helpers/.gitignore +0 -0
  9. data/app/lib/application.rb.erb +4 -2
  10. data/app/lib/tasks/.gitignore +0 -0
  11. data/app/log/.gitignore +0 -0
  12. data/app/models/.gitignore +0 -0
  13. data/app/public/css/.gitignore +0 -0
  14. data/app/public/flash/.gitignore +0 -0
  15. data/app/public/images/.gitignore +0 -0
  16. data/app/public/javascript/.gitignore +0 -0
  17. data/app/schema/migrations/.gitignore +0 -0
  18. data/app/tmp/sessions/.gitignore +0 -0
  19. data/app/views/.gitignore +0 -0
  20. data/bin/waves +29 -46
  21. data/bin/waves-console +1 -1
  22. data/bin/waves-server +1 -1
  23. data/lib/commands/waves-console.rb +0 -3
  24. data/lib/controllers/base.rb +11 -0
  25. data/lib/controllers/mixin.rb +39 -32
  26. data/lib/dispatchers/base.rb +37 -22
  27. data/lib/dispatchers/default.rb +25 -11
  28. data/lib/foundations/default.rb +6 -8
  29. data/lib/foundations/simple.rb +13 -0
  30. data/lib/helpers/asset_helper.rb +67 -0
  31. data/lib/helpers/common.rb +4 -0
  32. data/lib/helpers/default.rb +13 -0
  33. data/lib/helpers/form.rb +1 -0
  34. data/lib/helpers/number_helper.rb +25 -0
  35. data/lib/helpers/tag_helper.rb +58 -0
  36. data/lib/helpers/url_helper.rb +77 -0
  37. data/lib/layers/default_errors.rb +7 -5
  38. data/lib/layers/mvc.rb +54 -0
  39. data/lib/layers/orm/active_record.rb +93 -0
  40. data/lib/layers/orm/active_record/migrations/empty.rb.erb +9 -0
  41. data/lib/layers/orm/active_record/tasks/generate.rb +28 -0
  42. data/lib/layers/orm/active_record/tasks/schema.rb +22 -0
  43. data/lib/layers/orm/data_mapper.rb +38 -0
  44. data/lib/layers/orm/filebase.rb +22 -0
  45. data/lib/layers/orm/migration.rb +79 -0
  46. data/lib/layers/orm/sequel.rb +86 -0
  47. data/lib/layers/orm/sequel/migrations/empty.rb.erb +9 -0
  48. data/lib/layers/orm/sequel/tasks/generate.rb +28 -0
  49. data/lib/layers/orm/sequel/tasks/schema.rb +16 -0
  50. data/lib/layers/simple.rb +35 -0
  51. data/lib/layers/simple_errors.rb +11 -5
  52. data/lib/mapping/mapping.rb +61 -24
  53. data/lib/mapping/pretty_urls.rb +5 -3
  54. data/lib/renderers/erubis.rb +3 -1
  55. data/lib/renderers/mixin.rb +1 -4
  56. data/lib/runtime/application.rb +12 -8
  57. data/lib/runtime/blackboard.rb +57 -0
  58. data/lib/runtime/configuration.rb +60 -55
  59. data/lib/runtime/logger.rb +8 -1
  60. data/lib/runtime/request.rb +5 -4
  61. data/lib/runtime/response.rb +3 -3
  62. data/lib/runtime/response_mixin.rb +3 -0
  63. data/lib/runtime/response_proxy.rb +4 -1
  64. data/lib/runtime/server.rb +18 -5
  65. data/lib/runtime/session.rb +20 -10
  66. data/lib/tasks/cluster.rb +2 -1
  67. data/lib/tasks/generate.rb +76 -11
  68. data/lib/utilities/hash.rb +31 -0
  69. data/lib/utilities/inflect.rb +86 -170
  70. data/lib/utilities/inflect/english.rb +84 -0
  71. data/lib/utilities/integer.rb +23 -16
  72. data/lib/utilities/module.rb +19 -15
  73. data/lib/utilities/object.rb +22 -14
  74. data/lib/utilities/proc.rb +13 -6
  75. data/lib/utilities/string.rb +58 -44
  76. data/lib/utilities/symbol.rb +4 -1
  77. data/lib/views/base.rb +9 -0
  78. data/lib/views/mixin.rb +3 -1
  79. data/lib/waves.rb +15 -13
  80. metadata +50 -25
  81. data/lib/utilities/kernel.rb +0 -34
  82. data/lib/verify/mapping.rb +0 -29
  83. data/lib/verify/request.rb +0 -40
@@ -66,14 +66,16 @@ module Waves
66
66
  # create a new resource for the given model
67
67
  path %r{^/#{model}/?$}, :method => :post do | model |
68
68
  resource( model.singular ) do
69
- instance = controller { create }
70
- redirect( "/#{model.singular}/#{instance.name}/editor" )
69
+ controller do
70
+ instance = create
71
+ redirect( "/#{model_name}/#{instance.name}/editor" )
72
+ end
71
73
  end
72
74
  end
73
75
 
74
76
  # update the given resource for the given model
75
77
  path %r{^/#{model}/#{name}/?$}, :method => :put do | model, name |
76
- resource( model ) { controller { update( name ) }; redirect( url ) }
78
+ resource( model ) { controller { update( name ); redirect( url ) } }
77
79
  end
78
80
 
79
81
  # delete the given resource for the given model
@@ -1,12 +1,14 @@
1
1
  require 'erubis'
2
2
 
3
- module Erubis
3
+ module Erubis # :nodoc:
4
4
 
5
5
  # This is added to the Erubis Content class to allow the same helper methods
6
6
  # to be used with both Markaby and Erubis.
7
7
  class Context
8
8
  include Waves::Helpers::UrlHelper
9
9
  include Waves::Helpers::TagHelper
10
+ include Waves::Helpers::AssetHelper
11
+ include Waves::Helpers::NumberHelper
10
12
 
11
13
  def <<(s)
12
14
  eval("_buf", @binding).concat s # add to rendered output
@@ -1,9 +1,6 @@
1
1
  module Waves
2
2
 
3
- module Renderers
4
-
5
- extend Autocode
6
- # autoload :renderers, Class
3
+ module Renderers # :nodoc:
7
4
 
8
5
  # The renderers mixin provides a number of methods to simplify writing new renderers.
9
6
  # Just include this in your Renderer class and write your render method.
@@ -7,10 +7,8 @@ module Waves
7
7
  attr_reader :application
8
8
 
9
9
  # Register a module as a Waves application.
10
- # Also, initialize the database connection if necessary.
11
10
  def << ( app )
12
11
  @application = app if Module === app
13
- app.database if app.respond_to? 'database'
14
12
  end
15
13
 
16
14
  def instance ; Waves::Application.instance ; end
@@ -28,9 +26,9 @@ module Waves
28
26
  # main Waves application, you can use +Waves+.+application+.
29
27
  class Application
30
28
 
31
- class << self; attr_accessor :instance; end
29
+ class << self; attr_accessor :instance; end
32
30
 
33
- # Accessor for options passed to the application. Valid options include
31
+ # Accessor for options passed to the application.
34
32
  attr_reader :options
35
33
 
36
34
  # Create a new Waves application instance.
@@ -41,16 +39,22 @@ module Waves
41
39
  Kernel.load( :lib / 'application.rb' ) if Waves.application.nil?
42
40
  end
43
41
 
44
- def synchronize( &block ) ; ( @mutex ||= Mutex.new ).synchronize( &block ) ; end
42
+ def synchronize( &block )
43
+ ( @mutex ||= Mutex.new ).synchronize( &block )
44
+ end
45
45
 
46
46
  # The 'mode' of the application determines which configuration it will run under.
47
- def mode ; @mode ||= @options[:mode]||:development ; end
48
-
47
+ def mode
48
+ @mode ||= @options[:mode]||:development
49
+ end
50
+
49
51
  # Debug is true if debug is set to true in the current configuration.
50
52
  def debug? ; config.debug ; end
51
53
 
52
54
  # Access the current configuration. *Example:* +Waves::Server.config+
53
- def config ; Waves.application.configurations[ mode ] ; end
55
+ def config
56
+ Waves.application.configurations[ mode ]
57
+ end
54
58
 
55
59
  # Access the mappings for the application.
56
60
  def mapping ; Waves.application.configurations[ :mapping ] ; end
@@ -0,0 +1,57 @@
1
+ module Waves
2
+
3
+ # Encapsulates the blackboard associated with a given request. The scope of the blackboard is
4
+ # the same as the request object it gets attached to.
5
+ #
6
+ # The Waves blackboard is a very simple shared storaged usable during the request processing.
7
+ # It is available within:
8
+ # - mappings
9
+ # - controllers
10
+ # - helpers
11
+ #
12
+ # Adding a value:
13
+ # blackboard.value1 = 1
14
+ # blackboard[:value2] = 2
15
+ #
16
+ # Retrieving values
17
+ # blackboard.value1
18
+ # blackboard[:value2]
19
+ #
20
+ # see also blackboard_verify.rb
21
+
22
+ class Blackboard
23
+
24
+ # Create a new blackboard object using the given request.
25
+ def initialize( request )
26
+ @request = request
27
+ @data = {}
28
+ end
29
+
30
+ # Access a given data element of the blackboard using the given key.
31
+ def [](key)
32
+ @data[key]
33
+ end
34
+
35
+ # Set the given data element of the blackboard using the given key and value.
36
+ def []=(key,val)
37
+ @data[key] = val
38
+ end
39
+
40
+ def each(&block)
41
+ @data.each(&block)
42
+ end
43
+
44
+ # also allow things like
45
+ # blackboard.test1 instead of blackboard[:test1]
46
+ # blackboard.test1 = 2 instead of blackboard[:test1] = 2
47
+ def method_missing(name,*args)
48
+ if (name.to_s =~ /=$/)
49
+ self[name.to_s.gsub('=', '')] = args[0]
50
+ else
51
+ self[name.to_s]
52
+ end
53
+ end
54
+
55
+ end
56
+
57
+ end
@@ -1,12 +1,11 @@
1
1
  module Waves
2
2
 
3
- # Waves configurations are simply Ruby code, meaning you can use an Ruby expression as
4
- # a value for a configuration parameter, extend and inherit your configurations, and
5
- # add your own configuration attributes. You can even use it as a configuration repository
6
- # for your applications.
3
+ # Waves configurations are Ruby code. This means you can use a Ruby expression as
4
+ # the value of a configuration attribute, extend and inherit your configurations, and
5
+ # add your own attributes. You can even use it as a repository
6
+ # for your application configuration.
7
7
  #
8
- # The form for configuration parameters to use the parameter name as a method name. Passing
9
- # in a parameter sets the value.
8
+ # You can access configuration attributes using the attribute name as a method, with the value as the argument.
10
9
  #
11
10
  # == Example
12
11
  #
@@ -25,28 +24,27 @@ module Waves
25
24
  # end
26
25
  # end
27
26
  #
28
- # There are three forms for accessing parameters:
27
+ # There are three forms for accessing attributes:
29
28
  #
30
- # Waves.config.port # generic form - gets current config
31
- # Blog.configurations[:development] # gets a value for a specific config
32
- # Blog::Configurations::Development.port # Access config constant directly
29
+ # Waves.config.port # generic form - gets the value for current config
30
+ # Blog.configurations[:development].port # gets the value for a specified config
31
+ # Blog::Configurations::Development.port # Access a specific config constant directly
33
32
  #
34
- # You can inherit configurations, as is shown in the example above. Typically, you
35
- # can use the application's "default" configuration to set shared configurations,
36
- # and then inherit from it for specific variations.
33
+ # Configuration data is inheritable, as shown in the example above. Typically, you
34
+ # would set data common to all configurations in the Default class, from which
35
+ # your variations inherit.
37
36
  #
38
- # To define your own attributes, and still make them inheritable, you should use
39
- # the +attribute+ class method, like this:
37
+ # You may define your own heritable attributes using the +attribute+ class method:
40
38
  #
41
39
  # class Default < Waves::Configurations::Default
42
- # attribute 'theme' # define a theme attribute
43
- # theme 'ultra' # give it a default
40
+ # attribute 'theme' # define an attribute named "theme"
41
+ # theme 'ultra' # set an inheritable default
44
42
  # end
45
43
  #
46
- # There are a number of reserved or built-in attributes. These are:
44
+ # Certain attributes are reserved for internal use by Waves:
47
45
  #
48
46
  # - application: configure the application for use with Rack
49
- # - database: takes a hash of parameters used to initalize the database; see below
47
+ # - database: initialization parameters needed by the ORM layer
50
48
  # - reloadable: an array of module names to reload; see below for more
51
49
  # - log: takes a hash of parameters; see below for more
52
50
  # - host: the host to bind the server to (string)
@@ -58,7 +56,7 @@ module Waves
58
56
  #
59
57
  # One of the really nice features of Rack is the ability to install "middleware"
60
58
  # components to optimize the way you handle requests. Waves exposes this ability
61
- # directly to the application developer via the +application+ configuration parameter.
59
+ # directly to the application developer via the +application+ configuration method.
62
60
  #
63
61
  # *Example*
64
62
  #
@@ -70,51 +68,50 @@ module Waves
70
68
  #
71
69
  # == Configuring Database Access
72
70
  #
73
- # The database parameter takes a hash with the following elements:
74
- #
75
- # - host: which host the database is running on
76
- # - adapter: which adapter is being used to access the database (mysql, postgres, etc.)
77
- # - database: the name of the database the application is connecting to
78
- # - user: the user for authentication
79
- # - password: password for authentication
80
- #
81
- # *Example*
71
+ # The ORM layers provided with Waves use the +database+ attribute for connection initialization.
72
+ # Most ORMs take a hash for this purpose, with keys that may vary depending on the ORM and backend.
82
73
  #
74
+ # # Sequel with a MySQL db
83
75
  # database :host => 'localhost', :adapter => 'mysql', :database => 'blog',
84
76
  # :user => 'root', :password => 'guess'
85
77
  #
78
+ # # Sequel with an SQLite db
79
+ # database :adapter => 'sqlite', :database => 'blog'
80
+ #
81
+ # See the documentation for each ORM layer for details.
86
82
  #
87
83
  # == Configuring Code Reloading
88
84
  #
89
- # You can specify a list of modules to reload on each request using the +reloadable+
90
- # configuration parameter. The Waves server will call +reload+ on each module to trigger
91
- # the reloading. Typically, your modules will use the Autocode gem to set parameters for
92
- # reloading. This is done for you when you generate an application using the +waves+
93
- # command, but you can change the default settings. See the documentation for Autocode
94
- # for more information. Typically, you will set this parameter to just include your
95
- # main application:
85
+ # The +reloadable+ attribute takes an array of modules. Before every request, the default Waves
86
+ # dispatcher calls +reload+ on each listed module. The module should remove any reloadable constants
87
+ # currently defined in its namespace.
88
+ #
89
+ # In a Waves application built on the Default foundation, +reload+ functionality is provided
90
+ # by AutoCode for the Configurations, Controllers, Helpers, Models, and Views modules.
91
+ #
92
+ # Listing only your application module will work in most cases:
96
93
  #
97
94
  # reloadable [ Blog ]
98
95
  #
99
- # although you could do this with several modules just as easily (say, your primary
100
- # application and several helper applications).
96
+ # As an alternative, you could reload only some of the modules within your application:
97
+ #
98
+ # reloadable [ Blog::Models, Blog::Controllers ]
101
99
  #
102
100
  # == Configuring Logging
103
101
  #
104
- # The +log+ configuration parameter takes the following options (as a hash):
105
- # - level: The level to filter logging at. Uses Ruby's built in Logger class.
106
- # - output: A filename or IO object. Should be a filename if running as a daemon.
102
+ # The +log+ configuration attribute takes hash with these keys:
103
+ # - :level - The log filter level. Uses Ruby's built in Logger class.
104
+ # - :output - A filename or IO object. Should be a filename if running as a daemon.
107
105
  #
108
106
  # *Examples*
109
107
  #
110
- # log :level => :info, :output => $stderr
111
- # log :level => :error, :output => 'log/blog.log'
108
+ # log :level => :info, :output => $stderr
109
+ # log :level => :error, :output => 'log/blog.log'
112
110
  #
113
111
 
114
112
  module Configurations
115
113
 
116
114
  class Base
117
-
118
115
  # Set the given attribute with the given value. Typically, you wouldn't
119
116
  # use this directly.
120
117
  def self.[]=( name, val )
@@ -125,7 +122,8 @@ module Waves
125
122
  # use this directly.
126
123
  def self.[]( name ) ; send "_#{name}" ; end
127
124
 
128
- # Define a new attribute. After calling this, you can get and set the value.
125
+ # Define a new attribute. After calling this, you can get and set the value
126
+ # using the attribute name as the method
129
127
  def self.attribute( name )
130
128
  meta_def(name) do |*args|
131
129
  raise ArgumentError.new('Too many arguments.') if args.length > 1
@@ -136,16 +134,22 @@ module Waves
136
134
 
137
135
  end
138
136
 
139
- # The Default configuration provides a good starting point for your applications,
140
- # defining a number of attributes that are required by Waves.
137
+ # The Default configuration defines sensible defaults for attributes required by Waves.
138
+ # debug true
139
+ # synchronize? true
140
+ # session :duration => 30.minutes, :path => '/tmp/sessions'
141
+ # log :level => :info, :output => $stderr
142
+ # reloadable []
141
143
  class Default < Base
142
144
 
143
- %w( host port ports log reloadable database session debug root ).
145
+ %w( host port ports log reloadable database session debug root synchronize? ).
144
146
  each { |name| attribute(name) }
145
147
 
146
- # Set the handler for use with Rack, along with any handler-specific options
147
- # that will be passed to the handler's #run method. When accessing the value
148
- # (calling with no arguments) returns an array of the handler and options.
148
+ # Set the Rack handler, along with any specific options
149
+ # that need to be passed to the handler's #run method.
150
+ #
151
+ # When accessing the value
152
+ # (calling with no arguments), returns an array of the handler and options.
149
153
  def self.handler(*args)
150
154
  if args.length > 0
151
155
  @rack_handler, @rack_handler_options = args
@@ -154,13 +158,14 @@ module Waves
154
158
  end
155
159
  end
156
160
 
157
- # Provide access to the Waves::MimeTypes class via the configuration. You
158
- # could potentially point this to your own MIME types repository class.
161
+ # Provides access to the Waves::MimeTypes class via the configuration. You
162
+ # can override #mime_types to return your own MIME types repository class.
159
163
  def self.mime_types
160
164
  Waves::MimeTypes
161
165
  end
162
166
 
163
- # Defines the application for use with Rack.
167
+ # Defines the application for use with Rack. Treat this method like an
168
+ # instance of Rack::Builder
164
169
  def self.application( &block )
165
170
  if block_given?
166
171
  self['application'] = Rack::Builder.new( &block )
@@ -169,7 +174,7 @@ module Waves
169
174
  end
170
175
  end
171
176
 
172
- debug true
177
+ debug true ; synchronize? true
173
178
  session :duration => 30.minutes, :path => '/tmp/sessions'
174
179
  log :level => :info, :output => $stderr
175
180
  reloadable []
@@ -27,18 +27,25 @@ module Waves
27
27
  def output
28
28
  @output ||= ( config[:output] ? File.expand_path( config[:output] ) : $stderr )
29
29
  end
30
+
30
31
  # Returns the active configuration for the logger.
31
- def config ; @config ||= Waves::Server.config.log ; end
32
+ def config
33
+ @config ||= Waves::Server.config.log
34
+ end
35
+
32
36
  # Returns the logging level used to filter logging events.
33
37
  def level ; @level ||= ::Logger.const_get( config[:level].to_s.upcase || 'INFO' ) ; end
38
+
34
39
  # Starts the logger, using the active configuration to initialize it.
35
40
  def start
36
41
  @log = config[:rotation] ?
37
42
  ::Logger.new( output, config[:rotation].intern ) :
38
43
  ::Logger.new( output )
39
44
  @log.level = level
45
+ @log.datetime_format = "%Y-%m-%d %H:%M:%S "
40
46
  self
41
47
  end
48
+
42
49
  # Forwards logging methods to the logger.
43
50
  def method_missing(name,*args,&block)
44
51
  @log.send name,*args, &block if @log
@@ -1,12 +1,10 @@
1
1
  module Waves
2
- # Waves::Request represents an HTTP request and has methods for accessing anything
3
- # relating to the request. See Rack::Request for more information, since many methods
4
- # are actually delegated to Rack::Request.
2
+ # Waves::Request represents an HTTP request and provides convenient methods for accessing request attributes. See Rack::Request for documentation of any method not defined here.
5
3
  class Request
6
4
 
7
5
  class ParseError < Exception ; end
8
6
 
9
- attr_reader :response, :session
7
+ attr_reader :response, :session, :blackboard
10
8
 
11
9
  # Create a new request. Takes a env parameter representing the request passed in from Rack.
12
10
  # You shouldn't need to call this directly.
@@ -14,7 +12,10 @@ module Waves
14
12
  @request = Rack::Request.new( env )
15
13
  @response = Waves::Response.new( self )
16
14
  @session = Waves::Session.new( self )
15
+ @blackboard = Waves::Blackboard.new( self )
17
16
  end
17
+
18
+ def rack_request; @request; end
18
19
 
19
20
  # Accessor not explicitly defined by Waves::Request are delegated to Rack::Request.
20
21
  # Check the Rack documentation for more information.
@@ -1,9 +1,7 @@
1
1
  module Waves
2
2
  # Waves::Response represents an HTTP response and has methods for constructing a response.
3
3
  # These include setters for +content_type+, +content_length+, +location+, and +expires+
4
- # headers. You may also set the headers directly using the [] operator. If you don't find
5
- # what you are looking for here, check the documentation for Rack::Response since many
6
- # methods for this class are delegated to Rack::Response.
4
+ # headers. You may also set the headers directly using the [] operator. See Rack::Response for documentation of any method not defined here.
7
5
  class Response
8
6
 
9
7
  attr_reader :request
@@ -13,6 +11,8 @@ module Waves
13
11
  @request = request
14
12
  @response = Rack::Response.new
15
13
  end
14
+
15
+ def rack_response; @response; end
16
16
 
17
17
  %w( Content-Type Content-Length Location Expires ).each do |header|
18
18
  define_method( header.downcase.gsub('-','_')+ '=' ) do | val |
@@ -30,6 +30,9 @@ module Waves
30
30
  def not_found; request.not_found; end
31
31
  # Access the Waves::Logger.
32
32
  def log; Waves::Logger; end
33
+ # Access the Blackboard
34
+ def blackboard; request.blackboard; end
35
+
33
36
  end
34
37
 
35
38
  end