dyoder-waves 0.7.3

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 (61) hide show
  1. data/app/Rakefile +14 -0
  2. data/app/bin/waves-console +3 -0
  3. data/app/bin/waves-server +3 -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 +30 -0
  7. data/app/lib/application.rb.erb +3 -0
  8. data/app/startup.rb +5 -0
  9. data/app/templates/errors/not_found_404.mab +2 -0
  10. data/app/templates/errors/server_error_500.mab +2 -0
  11. data/app/templates/layouts/default.mab +14 -0
  12. data/bin/waves +66 -0
  13. data/bin/waves-console +4 -0
  14. data/bin/waves-server +4 -0
  15. data/lib/commands/waves-console.rb +24 -0
  16. data/lib/commands/waves-server.rb +55 -0
  17. data/lib/controllers/mixin.rb +158 -0
  18. data/lib/dispatchers/base.rb +52 -0
  19. data/lib/dispatchers/default.rb +67 -0
  20. data/lib/foundations/default.rb +28 -0
  21. data/lib/foundations/simple.rb +17 -0
  22. data/lib/helpers/common.rb +62 -0
  23. data/lib/helpers/form.rb +39 -0
  24. data/lib/helpers/formatting.rb +30 -0
  25. data/lib/helpers/model.rb +33 -0
  26. data/lib/helpers/view.rb +24 -0
  27. data/lib/layers/default_errors.rb +24 -0
  28. data/lib/layers/simple_errors.rb +17 -0
  29. data/lib/mapping/mapping.rb +252 -0
  30. data/lib/mapping/pretty_urls.rb +94 -0
  31. data/lib/renderers/erubis.rb +61 -0
  32. data/lib/renderers/markaby.rb +33 -0
  33. data/lib/renderers/mixin.rb +53 -0
  34. data/lib/runtime/application.rb +65 -0
  35. data/lib/runtime/configuration.rb +180 -0
  36. data/lib/runtime/console.rb +20 -0
  37. data/lib/runtime/debugger.rb +9 -0
  38. data/lib/runtime/logger.rb +52 -0
  39. data/lib/runtime/mime_types.rb +22 -0
  40. data/lib/runtime/request.rb +77 -0
  41. data/lib/runtime/response.rb +40 -0
  42. data/lib/runtime/response_mixin.rb +35 -0
  43. data/lib/runtime/response_proxy.rb +27 -0
  44. data/lib/runtime/server.rb +94 -0
  45. data/lib/runtime/session.rb +56 -0
  46. data/lib/tasks/cluster.rb +25 -0
  47. data/lib/tasks/gem.rb +31 -0
  48. data/lib/tasks/generate.rb +15 -0
  49. data/lib/utilities/inflect.rb +194 -0
  50. data/lib/utilities/integer.rb +17 -0
  51. data/lib/utilities/kernel.rb +34 -0
  52. data/lib/utilities/module.rb +17 -0
  53. data/lib/utilities/object.rb +17 -0
  54. data/lib/utilities/proc.rb +9 -0
  55. data/lib/utilities/string.rb +47 -0
  56. data/lib/utilities/symbol.rb +7 -0
  57. data/lib/verify/mapping.rb +29 -0
  58. data/lib/verify/request.rb +40 -0
  59. data/lib/views/mixin.rb +108 -0
  60. data/lib/waves.rb +80 -0
  61. metadata +260 -0
data/app/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Warning: This file is clobbered when you update your
4
+ # application with the waves script. Accordingly, you may
5
+ # wish to keep your tasks in .rb or .rake files in lib/tasks
6
+ require 'startup'
7
+ Waves::Console.load(:mode => ENV['mode'])
8
+
9
+ # load tasks from waves framework
10
+ %w( cluster generate gem ).each { |task| require "tasks/#{task}.rb" }
11
+
12
+ # load tasks from this app's lib/tasks
13
+ Dir["lib/tasks/*.{rb,rake}"].each { |task| require task }
14
+
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'startup'
3
+ require 'commands/waves-console'
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'startup'
3
+ require 'commands/waves-server'
@@ -0,0 +1,31 @@
1
+ module <%= name %>
2
+
3
+ module Configurations
4
+
5
+ class Development
6
+
7
+ database :host => 'localhost', :adapter => 'sqlite', :database => '<%= name.downcase %>',
8
+ :user => 'root', :password => ''
9
+
10
+ reloadable [ <%= name %> ]
11
+
12
+ log :level => :debug
13
+
14
+ host '127.0.0.1'
15
+
16
+ port 3000
17
+
18
+ handler ::Rack::Handler::Mongrel, :Host => host, :Port => port
19
+ # handler ::Rack::Handler::WEBrick, :BindAddress => host, :Port => port
20
+ # handler ::Rack::Handler::Thin, :Host => host, :Port => port
21
+
22
+ application do
23
+ use ::Rack::ShowExceptions
24
+ run ::Waves::Dispatchers::Default.new
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,14 @@
1
+ module <%= name %>
2
+
3
+ module Configurations
4
+
5
+ module Mapping
6
+ extend Waves::Mapping
7
+ # your custom rules go here
8
+ include Waves::Mapping::PrettyUrls::RestRules
9
+ include Waves::Mapping::PrettyUrls::GetRules
10
+ end
11
+
12
+ end
13
+
14
+ end
@@ -0,0 +1,30 @@
1
+ module <%= name %>
2
+
3
+ module Configurations
4
+
5
+ class Production < Default
6
+
7
+ database :host => 'localhost', :adapter => 'mysql', :database => '<%= name.downcase %>',
8
+ :user => 'root', :password => ''
9
+
10
+ reloadable []
11
+
12
+ log :level => :error,
13
+ :output => ( :log / "waves.#{$$}" ),
14
+ :rotation => :weekly
15
+
16
+ host '0.0.0.0'
17
+
18
+ port 80
19
+
20
+ handler ::Rack::Handler::Mongrel, :Host => host, :Port => port
21
+ # handler ::Rack::Handler::WEBrick, :BindAddress => host, :Port => port
22
+ # handler ::Rack::Handler::Thin, :Host => host, :Port => port
23
+
24
+ application do
25
+ run ::Waves::Dispatchers::Default.new
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,3 @@
1
+ module <%= name %>
2
+ include Waves::Foundations::Default
3
+ end
data/app/startup.rb ADDED
@@ -0,0 +1,5 @@
1
+ lambda {
2
+ waves = ( ( WAVES if defined? WAVES ) || ENV['WAVES'] || File.join(File.dirname(__FILE__), 'waves') )
3
+ $:.unshift(File.join( waves, "lib" )) if File.exist? waves
4
+ }.call
5
+ require 'waves'
@@ -0,0 +1,2 @@
1
+ h1 '404'
2
+ p %q( That URL does not exist on this server. )
@@ -0,0 +1,2 @@
1
+ h1 '500'
2
+ p %q( Internal server error. Sorry, but your request could not be processed. )
@@ -0,0 +1,14 @@
1
+ doctype :html4_strict
2
+
3
+ html do
4
+
5
+ head do
6
+ title @title
7
+ end
8
+
9
+ body do
10
+ layout_content
11
+ end
12
+
13
+ end
14
+
data/bin/waves ADDED
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # rudimentary argument checks
4
+ if ARGV.length != 1 || ARGV[0] == '--help'
5
+ $stderr.puts "Usage: waves {app_name}"
6
+ $stderr.puts "app_name may contain only letters, numbers, and underscores."
7
+ exit 1
8
+ end
9
+
10
+ app_path = ARGV[0]
11
+ app_name = File.basename(app_path)
12
+ if app_name =~ /[^\w\d_]/
13
+ raise ArgumentError, <<-TEXT
14
+ Unusable name: \"#{app_name}\"
15
+ Application names may contain only letters, numbers, and underscores."
16
+ TEXT
17
+ end
18
+
19
+
20
+ require 'rubygems'
21
+ require 'erubis'
22
+ require 'extensions/all'
23
+ begin
24
+ require 'utilities/string'
25
+ rescue LoadError
26
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'utilities', 'string')
27
+ end
28
+
29
+ require 'fileutils'
30
+ include FileUtils
31
+
32
+ # are we calling this script from within the waves framework source?
33
+ script_path = File.expand_path(__FILE__)
34
+ WAVES_SRC = File.dirname(File.dirname(script_path))
35
+ IN_WAVES_SRC = Dir.pwd.match(WAVES_SRC) ? true : false
36
+
37
+
38
+ puts "** Creating new Waves application ..."
39
+ template = begin
40
+ File.join File.dirname(File.readlink(__FILE__)), '..', 'app'
41
+ rescue Exception
42
+ File.join( File.dirname(__FILE__),'..','app')
43
+ end
44
+ mkdir(app_path)
45
+ cp_r Dir["#{template}/*"], app_path
46
+
47
+ # get rid of placeholder files left over from gem install
48
+ Dir["#{app_path}/**/EMPTY"].each { |path| rm path }
49
+ # Dir["#{app_path}/**/EMPTY"].each { |path| system "rm #{path}" }
50
+
51
+ # next, process all template files ...
52
+ Dir["#{app_path}/**/*.erb"].each do |path|
53
+ unless path =~ %r{^#{app_path}/(schema/migrations/templates|templates)}
54
+ name = app_name.camel_case
55
+ File.write( path.gsub(/\.erb$/,''),
56
+ Erubis::Eruby.new( File.read( path ) ).result( binding ) )
57
+ rm path
58
+ end
59
+ end
60
+
61
+ unless RUBY_PLATFORM =~ /mswin32/
62
+ # make the scripts executable
63
+ system "chmod ug+x #{app_path}/bin/waves-*"
64
+ end
65
+
66
+ puts "** Application created!"
data/bin/waves-console ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'startup'
3
+
4
+ require 'commands/waves-console'
data/bin/waves-server ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'startup'
3
+
4
+ require 'commands/waves-server'
@@ -0,0 +1,24 @@
1
+ require 'choice'
2
+
3
+ Choice.options do
4
+ header 'Run waves in console mode.'
5
+ header ''
6
+ option :mode do
7
+ short '-c'
8
+ long '--config=CONFIG'
9
+ desc 'Configuration to use.'
10
+ desc 'Defaults to development.'
11
+ cast Symbol
12
+ end
13
+ separator ''
14
+ end
15
+
16
+ console = Waves::Console.load( Choice.choices )
17
+ Object.send(:define_method, :waves) { console }
18
+ Object.instance_eval do
19
+ include Waves::Verify::Helpers::Request
20
+ end
21
+ require 'irb'
22
+ require 'irb/completion'
23
+ ARGV.clear
24
+ IRB.start
@@ -0,0 +1,55 @@
1
+ require 'choice'
2
+
3
+ Choice.options do
4
+ header 'Run a waves application server.'
5
+ header ''
6
+ option :port do
7
+ short '-p'
8
+ long '--port=PORT'
9
+ desc 'Port to listen on.'
10
+ desc 'Defaults to value given in configuration.'
11
+ cast Integer
12
+ end
13
+ separator ''
14
+ option :host do
15
+ short '-h'
16
+ long '--host=HOST'
17
+ desc 'Host or IP address of the host to bind.'
18
+ desc 'Defaults to value given in configuration.'
19
+ end
20
+ separator ''
21
+ option :mode do
22
+ short '-c'
23
+ long '--config=CONFIG'
24
+ desc 'Configuration to use.'
25
+ desc 'Defaults to development.'
26
+ cast Symbol
27
+ end
28
+ separator ''
29
+ option :directory do
30
+ short '-D'
31
+ long '--dir=DIR'
32
+ desc 'Directory containing the application.'
33
+ desc 'Defaults to the current directory.'
34
+ end
35
+ separator ''
36
+ option :daemon do
37
+ short '-d'
38
+ long '--daemon'
39
+ desc 'Run as a daemon.'
40
+ end
41
+ separator ''
42
+ option :debugger do
43
+ short '-u'
44
+ long '--debugger'
45
+ desc 'Enable ruby-debug.'
46
+ end
47
+ separator ''
48
+ option :startup do
49
+ short '-s'
50
+ long '--startup'
51
+ desc 'Startup file to load.'
52
+ desc 'Defaults to "lib/startup.rb"'
53
+ end
54
+ end
55
+ Waves::Server.run( Choice.choices )
@@ -0,0 +1,158 @@
1
+ module Waves
2
+
3
+ #
4
+ # Controllers in Waves are simply classes that provide a request / response
5
+ # context for operating on a model. While models are essentially just a way
6
+ # to manage data in an application, controllers manage data in response to
7
+ # a request. For example, a controller updates a model instance using
8
+ # parameters from the request.
9
+ #
10
+ # Controller methods simply return data (a resource), if necessary, that
11
+ # can be then used by views to determine how to render that data.
12
+ # Controllers do not determine which view will be invoked. They are
13
+ # independent of the view; one controller method might be suitable for
14
+ # several different views. In some cases, controllers can choose to
15
+ # directly modify the response and possibly even short-circuit the view
16
+ # entirely. A good example of this is a redirect.
17
+ #
18
+ # Controllers, like Views and Mappings, use the Waves::ResponseMixin to
19
+ # provide a rich context for working with the request and response objects.
20
+ # They can even call other controllers or views using the controllers method.
21
+ # In addition, they provide some basic reflection (access to the model and
22
+ # model_name that corresponds to the class name for the given model) and
23
+ # automatic parameter destructuring. This allows controller methods to access
24
+ # the request parameters as a hash, so that a POST variable named
25
+ # <tt>entry.title</tt> is accessed as <tt>params[:entry][:title]</tt>.
26
+ #
27
+ # Controllers often do not have to be explicitly defined. Instead, one or more
28
+ # default controllers can be defined that are used as exemplars for a given
29
+ # model. By default, the +waves+ command generates a single default, placed in
30
+ # the application's <tt>controllers/default.rb</tt> file. This can be modified
31
+ # to change the default behavior for all controllers. Alternatively, the
32
+ # <tt>rake generate:controller</tt> command can be used to explicitly define a
33
+ # controller.
34
+ #
35
+ # As an example, the code for the default controller is below for the Blog application.
36
+ #
37
+ # module Blog
38
+ # module Controllers
39
+ # class Default
40
+ #
41
+ # # Pick up the default controller methods, like param, url, etc.
42
+ # include Waves::Controllers::Mixin
43
+ #
44
+ # # This gets me the parameters associated with this model
45
+ # def attributes; params[model_name.singular.intern]; end
46
+ #
47
+ # # A simple generic delegator to the model
48
+ # def all; model.all; end
49
+ #
50
+ # # Find a specific instance based on a name or raise a 404
51
+ # def find( name ); model[ :name => name ] or not_found; end
52
+ #
53
+ # # Create a new instance based on the request params
54
+ # def create; model.create( attributes ); end
55
+ #
56
+ # # Update an existing record. find will raise a 404 if not found.
57
+ # def update( name )
58
+ # instance = find( name )
59
+ # instance.set( attributes )
60
+ # instance.save_changes
61
+ # end
62
+ #
63
+ # # Find and delete - or will raise a 404 if it doesn't exist
64
+ # def delete( name ); find( name ).destroy; end
65
+ #
66
+ # end
67
+ # end
68
+ # end
69
+ #
70
+ # Since the mapping file handles "glueing" controllers to views, controllers
71
+ # don't have to be at all concerned with views. They don't have to set
72
+ # instance variables, layouts, or contain logic to select the appropriate
73
+ # view based on the request. All they do is worry about updating the model
74
+ # when necessary based on the request.
75
+
76
+ module Controllers
77
+
78
+ #
79
+ # This mixin provides some handy methods for Waves controllers. You will probably
80
+ # want to include it in any controllers you define for your application. The default
81
+ # controllers generated using the +wave+ command already do this.
82
+ #
83
+ # Basically, what the mixin does is adapt the class so that it can be used within
84
+ # mappings (see Waves::Mapping); add some simple reflection to allow controller methods
85
+ # to be written generically (i.e., without reference to a specific model); and provide
86
+ # parameter destructuring for the request parameters.
87
+ #
88
+
89
+ module Mixin
90
+
91
+ attr_reader :request
92
+
93
+ include Waves::ResponseMixin
94
+
95
+ # When you include this Mixin, a +process+ class method is added to your class,
96
+ # which accepts a request object and a block. The request object is used to initialize
97
+ # the controller and the block is evaluated using +instance_eval+. This allows the
98
+ # controller to be used within a mapping file.
99
+
100
+ def self.included( c )
101
+ def c.process( request, &block )
102
+ self.new( request ).instance_eval( &block )
103
+ end
104
+ end
105
+
106
+ def initialize( request ); @request = request; end
107
+
108
+ # The params variable is taken from the request object and "destructured", so that
109
+ # a parameter named 'blog.title' becomes:
110
+ #
111
+ # params['blog']['title']
112
+ #
113
+ # If you want to access the original parameters object, you can still do so using
114
+ # +request.parameters+ instead of simply +params+.
115
+ def params; @params ||= destructure(request.params); end
116
+
117
+ # You can access the name of the model related to this controller using this method.
118
+ # It simply takes the basename of the module and converts it to snake case, so if the
119
+ # model uses a different plurality, this won't, in fact, be the model name.
120
+ def model_name; self.class.basename.snake_case; end
121
+
122
+ # This uses the model_name method to attempt to identify the model corresponding to this
123
+ # controller. This allows you to write generic controller methods such as:
124
+ #
125
+ # model.find( name )
126
+ #
127
+ # to find an instance of a given model. Again, the plurality of the controller and
128
+ # model must be the same for this to work.
129
+ def model; Waves.application.models[ model_name.intern ]; end
130
+
131
+ private
132
+
133
+ def destructure(hash)
134
+ rval = {}
135
+ hash.keys.map{ |key|key.split('.') }.each do |keys|
136
+ destructure_with_array_keys(hash,'',keys,rval)
137
+ end
138
+ rval
139
+ end
140
+
141
+ def destructure_with_array_keys(hash,prefix,keys,rval)
142
+ if keys.length == 1
143
+ val = hash[prefix+keys.first]
144
+ rval[keys.first.intern] = case val
145
+ when String then val.strip
146
+ when Hash then val
147
+ end
148
+ else
149
+ rval = ( rval[keys.first.intern] ||= {} )
150
+ destructure_with_array_keys(hash,(keys.shift<<'.'),keys,rval)
151
+ end
152
+ end
153
+
154
+ end
155
+
156
+ end
157
+
158
+ end