waves 0.6.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/app/Rakefile +4 -0
  2. data/app/configurations/default.rb.erb +8 -0
  3. data/app/configurations/development.rb.erb +22 -0
  4. data/app/configurations/mapping.rb.erb +49 -0
  5. data/app/configurations/production.rb.erb +25 -0
  6. data/app/controllers/default.rb.erb +39 -0
  7. data/app/doc/EMTPY +0 -0
  8. data/app/helpers/default.rb.erb +13 -0
  9. data/app/lib/application.rb.erb +52 -0
  10. data/app/lib/startup.rb.erb +2 -0
  11. data/app/lib/tasks/cluster.rb +26 -0
  12. data/app/lib/tasks/schema.rb +28 -0
  13. data/app/models/default.rb.erb +13 -0
  14. data/app/schema/migration/templates/empty.rb.erb +9 -0
  15. data/app/templates/errors/not_found.mab +2 -0
  16. data/app/templates/errors/server_error.mab +2 -0
  17. data/app/templates/layouts/default.mab +14 -0
  18. data/app/views/default.rb.erb +13 -0
  19. data/bin/waves +32 -0
  20. data/bin/waves-console +8 -0
  21. data/bin/waves-server +45 -0
  22. data/lib/controllers/mixin.rb +62 -0
  23. data/lib/dispatchers/base.rb +41 -0
  24. data/lib/dispatchers/default.rb +33 -0
  25. data/lib/helpers/common.rb +22 -0
  26. data/lib/helpers/form.rb +22 -0
  27. data/lib/helpers/formatting.rb +22 -0
  28. data/lib/helpers/model.rb +15 -0
  29. data/lib/helpers/view.rb +14 -0
  30. data/lib/renderers/erubis.rb +38 -0
  31. data/lib/renderers/markaby.rb +31 -0
  32. data/lib/renderers/mixin.rb +41 -0
  33. data/lib/runtime/application.rb +43 -0
  34. data/lib/runtime/configuration.rb +47 -0
  35. data/lib/runtime/console.rb +21 -0
  36. data/lib/runtime/logger.rb +28 -0
  37. data/lib/runtime/mapping.rb +82 -0
  38. data/lib/runtime/mime_types.rb +18 -0
  39. data/lib/runtime/request.rb +43 -0
  40. data/lib/runtime/response.rb +26 -0
  41. data/lib/runtime/response_mixin.rb +53 -0
  42. data/lib/runtime/response_proxy.rb +29 -0
  43. data/lib/runtime/server.rb +58 -0
  44. data/lib/runtime/session.rb +43 -0
  45. data/lib/utilities/integer.rb +8 -0
  46. data/lib/utilities/kernel.rb +8 -0
  47. data/lib/utilities/module.rb +7 -0
  48. data/lib/utilities/object.rb +13 -0
  49. data/lib/utilities/string.rb +36 -0
  50. data/lib/utilities/symbol.rb +5 -0
  51. data/lib/views/mixin.rb +54 -0
  52. data/lib/waves.rb +50 -0
  53. metadata +189 -0
@@ -0,0 +1,62 @@
1
+ module Waves
2
+
3
+ module Controllers
4
+
5
+ module Mixin
6
+
7
+ attr_reader :request
8
+
9
+ include Waves::ResponseMixin
10
+
11
+ def self.included( c )
12
+ def c.process( request, &block )
13
+ self.new( request ).instance_eval( &block )
14
+ end
15
+ end
16
+
17
+ def initialize( request )
18
+ @request = request
19
+ end
20
+
21
+
22
+ # override to convert 'foo.bar' to 'foo' => 'bar' => value
23
+ def params
24
+ @params ||= destructure(request.params)
25
+ end
26
+
27
+ def model_name
28
+ self.class.basename.snake_case
29
+ end
30
+
31
+ def model
32
+ Waves.application.models[ model_name.intern ]
33
+ end
34
+
35
+ private
36
+
37
+ def destructure(hash)
38
+ rval = {}
39
+ hash.keys.map{ |key|key.split('.') }.each do |keys|
40
+ destructure_with_array_keys(hash,'',keys,rval)
41
+ end
42
+ rval
43
+ end
44
+
45
+ def destructure_with_array_keys(hash,prefix,keys,rval)
46
+ if keys.length == 1
47
+ val = hash[prefix+keys.first]
48
+ rval[keys.first.intern] = case val
49
+ when String then val.strip
50
+ when Hash then val
51
+ end
52
+ else
53
+ rval = ( rval[keys.first.intern] ||= {} )
54
+ destructure_with_array_keys(hash,(keys.shift<<'.'),keys,rval)
55
+ end
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+
62
+ end
@@ -0,0 +1,41 @@
1
+ module Waves
2
+
3
+ module Dispatchers
4
+
5
+ class NotFoundError < Exception ; end
6
+
7
+ class Redirect < Exception
8
+ attr_reader :path
9
+ def initialize( path )
10
+ @path = path
11
+ end
12
+ end
13
+
14
+ class Base
15
+
16
+ def call( env )
17
+ Waves::Server.synchronize do
18
+ request = Waves::Request.new( env )
19
+ response = request.response
20
+ begin
21
+ safe( request )
22
+ rescue Dispatchers::Redirect => redirect
23
+ response.status = '302'
24
+ response.location = redirect.path
25
+ rescue Dispatchers::NotFoundError => e
26
+ html = Waves.application.views[:errors].process( request ) do
27
+ not_found_404( :error => e )
28
+ end
29
+ response.status = '404'
30
+ response.content_type = 'text/html'
31
+ response.write( html )
32
+ end
33
+ response.finish
34
+ end
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,33 @@
1
+ module Waves
2
+
3
+ module Dispatchers
4
+
5
+ class Default < Base
6
+
7
+ def safe( request )
8
+
9
+ response = request.response
10
+
11
+ Waves::Server.reset if Waves::Server.debug?
12
+ response.content_type = Waves::Server.config.mime_types[ request.path ] || 'text/html'
13
+
14
+ mapping = Waves::Server.mapping[ request ]
15
+
16
+ mapping[:before].each do | block, args |
17
+ ResponseProxy.new(request).instance_exec(*args,&block)
18
+ end
19
+
20
+ block, args = mapping[:action]
21
+ response.write( ResponseProxy.new(request).instance_exec(*args, &block) )
22
+
23
+ mapping[:after].each do | block, args |
24
+ ResponseProxy.new(request).instance_exec(*args,&block)
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,22 @@
1
+ module Waves
2
+ module Helpers
3
+ module Common
4
+
5
+ def layout( name, assigns = {}, &block )
6
+ assigns[ :content ] = yield
7
+ Blog::Views::Layouts.process( request ) do
8
+ send( name, assigns )
9
+ end
10
+ end
11
+
12
+ def doctype(type)
13
+ case type
14
+ when :html4_strict
15
+ '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" ' <<
16
+ '"http://www.w3.org/TR/html4/strict.dtd">'
17
+ end
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ module Waves
2
+
3
+ module Helpers
4
+
5
+ module Form
6
+
7
+ def properties(&block)
8
+ div.properties do
9
+ yield
10
+ end
11
+ end
12
+
13
+ def property( options )
14
+ self << view( :form, options[:type], options )
15
+ end
16
+
17
+
18
+ end
19
+
20
+ end
21
+
22
+ end
@@ -0,0 +1,22 @@
1
+ require 'redcloth'
2
+ module Waves
3
+ module Helpers
4
+ module Formatting
5
+
6
+ # TODO: this won't work inside a erb template!
7
+ # but i hate to do a whole new Builder when I'm
8
+ # already inside one! test self === Builder?
9
+ def mab( content )
10
+ eval content
11
+ end
12
+
13
+ def textile( content )
14
+ ( ::RedCloth::TEXTILE_TAGS << [ 96.chr, '&8216;'] ).each do |pat,ent|
15
+ content.gsub!( pat, ent.gsub('&','&#') )
16
+ end
17
+ ::RedCloth.new( content ).to_html
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ module Waves
2
+ module Helpers
3
+ module Model
4
+
5
+ def all( model )
6
+ Application.models[ model ].all( domain )
7
+ end
8
+
9
+ def find( model, name )
10
+ Application.models[ model ].find( domain, name ) rescue nil
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ module Waves
2
+ module Helpers
3
+ module View
4
+
5
+ def view( model, view, assigns = {} )
6
+ self << Application.views[ model ].process( request ) do
7
+ send view, assigns
8
+ end
9
+ end
10
+
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,38 @@
1
+ require 'erubis'
2
+
3
+ module Erubis
4
+
5
+ class Context
6
+ def <<(s) ; s ; end
7
+ end
8
+
9
+ end
10
+
11
+ module Waves
12
+
13
+ module Renderers
14
+
15
+ class Erubis
16
+
17
+ include Renderers::Mixin
18
+
19
+ extension :erb
20
+
21
+ def self.render( path, assigns )
22
+ eruby = ::Erubis::Eruby.new( template( path ) )
23
+ helper = helper( path )
24
+ context = ::Erubis::Context.new
25
+ context.meta_eval { include( helper ) ; }
26
+ context.instance_eval do
27
+ assigns.each do |key,val|
28
+ instance_variable_set("@#{key}",val)
29
+ end
30
+ end
31
+ eruby.evaluate( context )
32
+ end
33
+
34
+ end
35
+
36
+ end
37
+
38
+ end
@@ -0,0 +1,31 @@
1
+ require 'markaby'
2
+
3
+ ::Markaby::Builder.set( :indent, 2 )
4
+
5
+ module Waves
6
+
7
+ module Renderers
8
+
9
+ class Markaby
10
+
11
+ include Renderers::Mixin
12
+
13
+ extension :mab
14
+ # capture needed here for content fragments, otherwise
15
+ # you'll just get the last tag's output ...
16
+ def self.capture( template )
17
+ "capture { #{template} }"
18
+ end
19
+
20
+ def self.render( path, assigns )
21
+ builder = ::Markaby::Builder.new( assigns )
22
+ helper = helper( path )
23
+ builder.meta_eval { include( helper ) }
24
+ builder.instance_eval( capture( template( path ) ) ).to_s
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,41 @@
1
+ module Waves
2
+
3
+ module Renderers
4
+
5
+ extend Autoload
6
+ autoload :renderers
7
+
8
+ module Mixin
9
+
10
+ def self.included(target)
11
+ class << target
12
+
13
+ def extension(*args)
14
+ return @extension if args.length == 0
15
+ @extension = args.first
16
+ end
17
+
18
+ def filename(path)
19
+ :templates / "#{path}.#{self.extension}"
20
+ end
21
+
22
+ def render(path,args=nil)
23
+ end
24
+
25
+ def template( path )
26
+ File.read( filename( path ) )
27
+ end
28
+
29
+ def helper( path )
30
+ Waves.application.helpers[
31
+ File.basename( File.dirname( path ) ).camel_case ]
32
+ end
33
+ end
34
+ end
35
+
36
+
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,43 @@
1
+ module Waves
2
+
3
+ class << self
4
+
5
+ attr_reader :application
6
+
7
+ # give us the root namespace for the application
8
+ def << ( app )
9
+ @application = app if Module === app
10
+ end
11
+
12
+ end
13
+
14
+ class Application
15
+
16
+ def initialize( mode = :development )
17
+ @mode = mode
18
+ end
19
+
20
+ def debug? ; @mode == :development ; end
21
+
22
+ # now we can get the configuration, based on the mode
23
+ # we must specify global scope to avoid picking up Waves::Configurations::*
24
+ # and / or Waves::Application::* ... because the configuration may be
25
+ # loaded via autoload ....
26
+ def config
27
+ Waves.application.configurations[ @mode ]
28
+ end
29
+
30
+ # and, similarly, the url mapping ...
31
+ def mapping
32
+ Waves.application.configurations[ :mapping ]
33
+ end
34
+
35
+ # the config then tells us whether to unload any namespaces
36
+ # after each request ...
37
+ def reset
38
+ config.reloadable.each { |mod| mod.reload }
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,47 @@
1
+ module Waves
2
+
3
+ module Configurations
4
+
5
+ class Base
6
+
7
+ def self.[]=( name, val )
8
+ meta_def("_#{name}") { val }
9
+ end
10
+
11
+ def self.[]( name ) ; send "_#{name}" ; end
12
+
13
+ def self.attribute( name )
14
+ meta_def(name) do |*args|
15
+ raise ArgumentError.new('Too many arguments.') if args.length > 1
16
+ args.length == 1 ? self[ name ] = args.first : self[ name ]
17
+ end
18
+ self[ name ] = nil
19
+ end
20
+
21
+ def self.mime_types
22
+ Waves::MimeTypes
23
+ end
24
+
25
+ end
26
+
27
+ class Default < Base
28
+
29
+ %w( host port ports log reloadable server database session ).
30
+ each { |name| attribute(name) }
31
+
32
+ def self.application( &block )
33
+ if block_given?
34
+ self['application'] = Rack::Builder.new( &block )
35
+ else
36
+ self['application']
37
+ end
38
+ end
39
+
40
+ session :duration => 30.minutes,
41
+ :path => :tmp / :sessions
42
+
43
+ end
44
+ end
45
+ end
46
+
47
+