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.
- data/bin/waves +19 -56
- data/doc/HISTORY +1 -0
- data/doc/LICENSE +22 -0
- data/doc/README +1 -0
- data/doc/VERSION +1 -0
- data/lib/caches/file.rb +48 -0
- data/lib/caches/memcached.rb +40 -0
- data/lib/caches/simple.rb +25 -0
- data/lib/caches/synchronized.rb +25 -0
- data/lib/commands/console.rb +35 -0
- data/lib/commands/generate.rb +52 -0
- data/lib/commands/help.rb +5 -0
- data/lib/commands/{waves-server.rb → server.rb} +16 -3
- data/lib/dispatchers/base.rb +21 -20
- data/lib/dispatchers/default.rb +11 -63
- data/lib/ext/float.rb +13 -0
- data/lib/{utilities → ext}/hash.rb +2 -2
- data/lib/{utilities → ext}/integer.rb +5 -2
- data/lib/ext/kernel.rb +20 -0
- data/lib/ext/module.rb +20 -0
- data/lib/{utilities → ext}/object.rb +3 -5
- data/lib/ext/string.rb +20 -0
- data/lib/ext/symbol.rb +11 -0
- data/lib/ext/tempfile.rb +5 -0
- data/lib/foundations/classic.rb +64 -0
- data/lib/foundations/compact.rb +50 -0
- data/lib/helpers/basic.rb +11 -0
- data/lib/helpers/doc_type.rb +34 -0
- data/lib/helpers/extended.rb +21 -0
- data/lib/helpers/form.rb +3 -1
- data/lib/helpers/formatting.rb +3 -3
- data/lib/helpers/layouts.rb +37 -0
- data/lib/helpers/model.rb +8 -4
- data/lib/helpers/view.rb +2 -4
- data/lib/layers/inflect/english.rb +67 -0
- data/lib/layers/mvc.rb +18 -18
- data/lib/layers/mvc/controllers.rb +41 -0
- data/lib/layers/mvc/extensions.rb +52 -0
- data/lib/layers/orm/{active_record.rb → providers/active_record.rb} +12 -18
- data/lib/layers/orm/{active_record → providers/active_record}/migrations/empty.rb.erb +0 -0
- data/lib/layers/orm/{active_record → providers/active_record}/tasks/generate.rb +1 -1
- data/lib/layers/orm/{active_record → providers/active_record}/tasks/schema.rb +1 -1
- data/lib/layers/orm/{data_mapper.rb → providers/data_mapper.rb} +3 -4
- data/lib/layers/orm/providers/filebase.rb +25 -0
- data/lib/layers/orm/{sequel.rb → providers/sequel.rb} +16 -12
- data/lib/layers/orm/{sequel → providers/sequel}/migrations/empty.rb.erb +0 -0
- data/lib/layers/orm/{sequel → providers/sequel}/tasks/generate.rb +5 -3
- data/lib/layers/orm/{sequel → providers/sequel}/tasks/schema.rb +2 -2
- data/lib/{renderers → layers/renderers}/erubis.rb +10 -13
- data/lib/layers/renderers/haml.rb +47 -0
- data/lib/layers/renderers/markaby.rb +29 -0
- data/lib/matchers/accept.rb +21 -0
- data/lib/matchers/base.rb +30 -0
- data/lib/matchers/content_type.rb +17 -0
- data/lib/matchers/path.rb +67 -0
- data/lib/matchers/query.rb +21 -0
- data/lib/matchers/request.rb +27 -0
- data/lib/matchers/resource.rb +19 -0
- data/lib/matchers/traits.rb +19 -0
- data/lib/matchers/uri.rb +20 -0
- data/lib/renderers/mixin.rb +15 -29
- data/lib/resources/mixin.rb +132 -0
- data/lib/resources/paths.rb +34 -0
- data/lib/runtime/configuration.rb +55 -135
- data/lib/runtime/console.rb +4 -1
- data/lib/runtime/logger.rb +24 -48
- data/lib/runtime/mime_types.rb +516 -2
- data/lib/runtime/mocks.rb +14 -0
- data/lib/runtime/monitor.rb +32 -0
- data/lib/runtime/request.rb +107 -39
- data/lib/runtime/response.rb +5 -2
- data/lib/runtime/response_mixin.rb +43 -22
- data/lib/runtime/runtime.rb +67 -0
- data/lib/runtime/server.rb +14 -101
- data/lib/runtime/session.rb +4 -43
- data/lib/runtime/worker.rb +86 -0
- data/lib/servers/base.rb +42 -0
- data/lib/servers/mongrel.rb +13 -0
- data/lib/servers/webrick.rb +13 -0
- data/lib/tasks/gem.rb +1 -0
- data/lib/tasks/generate.rb +67 -62
- data/lib/views/errors.rb +49 -0
- data/lib/views/mixin.rb +34 -82
- data/lib/waves.rb +36 -55
- data/samples/blog/Rakefile +25 -0
- data/samples/blog/configurations/default.rb +11 -0
- data/samples/blog/configurations/development.rb +29 -0
- data/samples/blog/configurations/production.rb +26 -0
- data/samples/blog/models/comment.rb +23 -0
- data/samples/blog/models/entry.rb +31 -0
- data/samples/blog/public/css/site.css +13 -0
- data/samples/blog/public/javascript/jquery-1.2.6.min.js +32 -0
- data/samples/blog/public/javascript/site.js +13 -0
- data/samples/blog/resources/entry.rb +39 -0
- data/samples/blog/resources/map.rb +9 -0
- data/samples/blog/schema/migrations/001_initial_schema.rb +17 -0
- data/samples/blog/schema/migrations/002_add_comments.rb +18 -0
- data/samples/blog/schema/migrations/templates/empty.rb.erb +9 -0
- data/samples/blog/startup.rb +8 -0
- data/samples/blog/templates/comment/add.mab +12 -0
- data/samples/blog/templates/comment/list.mab +6 -0
- data/samples/blog/templates/entry/edit.mab +14 -0
- data/samples/blog/templates/entry/list.mab +16 -0
- data/samples/blog/templates/entry/show.mab +18 -0
- data/samples/blog/templates/entry/summary.mab +9 -0
- data/samples/blog/templates/errors/not_found_404.mab +7 -0
- data/{app → samples/blog}/templates/errors/server_error_500.mab +0 -0
- data/samples/blog/templates/layouts/default.mab +19 -0
- data/samples/blog/templates/waves/status.mab +85 -0
- data/templates/classic/Rakefile +130 -0
- data/templates/classic/configurations/default.rb.erb +9 -0
- data/{app → templates/classic}/configurations/development.rb.erb +3 -7
- data/{app → templates/classic}/configurations/production.rb.erb +3 -4
- data/templates/classic/resources/map.rb.erb +8 -0
- data/templates/classic/startup.rb.erb +11 -0
- data/{app → templates/classic}/templates/errors/not_found_404.mab +0 -0
- data/templates/classic/templates/errors/server_error_500.mab +2 -0
- data/{app → templates/classic}/templates/layouts/default.mab +0 -0
- data/templates/compact/startup.rb.erb +11 -0
- metadata +967 -144
- data/app/Rakefile +0 -14
- data/app/bin/waves-console +0 -4
- data/app/bin/waves-server +0 -4
- data/app/configurations/mapping.rb.erb +0 -13
- data/app/controllers/.gitignore +0 -0
- data/app/doc/.gitignore +0 -0
- data/app/helpers/.gitignore +0 -0
- data/app/lib/application.rb.erb +0 -5
- data/app/lib/tasks/.gitignore +0 -0
- data/app/log/.gitignore +0 -0
- data/app/models/.gitignore +0 -0
- data/app/public/css/.gitignore +0 -0
- data/app/public/flash/.gitignore +0 -0
- data/app/public/images/.gitignore +0 -0
- data/app/public/javascript/.gitignore +0 -0
- data/app/schema/migrations/.gitignore +0 -0
- data/app/startup.rb +0 -5
- data/app/tmp/sessions/.gitignore +0 -0
- data/app/views/.gitignore +0 -0
- data/bin/waves-console +0 -4
- data/bin/waves-server +0 -4
- data/lib/commands/waves-console.rb +0 -21
- data/lib/controllers/base.rb +0 -11
- data/lib/controllers/mixin.rb +0 -165
- data/lib/foundations/default.rb +0 -26
- data/lib/foundations/simple.rb +0 -30
- data/lib/helpers/asset_helper.rb +0 -67
- data/lib/helpers/common.rb +0 -66
- data/lib/helpers/default.rb +0 -13
- data/lib/helpers/number_helper.rb +0 -25
- data/lib/helpers/tag_helper.rb +0 -58
- data/lib/helpers/url_helper.rb +0 -77
- data/lib/layers/default_errors.rb +0 -26
- data/lib/layers/orm/filebase.rb +0 -22
- data/lib/layers/simple.rb +0 -35
- data/lib/layers/simple_errors.rb +0 -23
- data/lib/mapping/mapping.rb +0 -289
- data/lib/mapping/pretty_urls.rb +0 -96
- data/lib/renderers/markaby.rb +0 -33
- data/lib/runtime/application.rb +0 -69
- data/lib/runtime/blackboard.rb +0 -57
- data/lib/runtime/debugger.rb +0 -9
- data/lib/runtime/response_proxy.rb +0 -30
- data/lib/tasks/cluster.rb +0 -26
- data/lib/utilities/inflect.rb +0 -110
- data/lib/utilities/inflect/english.rb +0 -84
- data/lib/utilities/module.rb +0 -21
- data/lib/utilities/proc.rb +0 -16
- data/lib/utilities/string.rb +0 -61
- data/lib/utilities/symbol.rb +0 -10
- data/lib/views/base.rb +0 -9
data/lib/helpers/default.rb
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
module Waves
|
|
2
|
-
module Helpers
|
|
3
|
-
module Default
|
|
4
|
-
attr_reader :request, :content
|
|
5
|
-
include Waves::ResponseMixin
|
|
6
|
-
include Waves::Helpers::Common
|
|
7
|
-
include Waves::Helpers::Formatting
|
|
8
|
-
include Waves::Helpers::Model
|
|
9
|
-
include Waves::Helpers::View
|
|
10
|
-
include Waves::Helpers::Form
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
module Waves
|
|
2
|
-
module Helpers
|
|
3
|
-
module NumberHelper
|
|
4
|
-
|
|
5
|
-
# Formats a +number+ with grouped thousands using +delimiter+. You
|
|
6
|
-
# can customize the format in the +options+ hash.
|
|
7
|
-
# * <tt>:delimiter</tt> - Sets the thousands delimiter, defaults to ","
|
|
8
|
-
# * <tt>:separator</tt> - Sets the separator between the units, defaults to "."
|
|
9
|
-
#
|
|
10
|
-
# number_with_delimiter(12345678) => 12,345,678
|
|
11
|
-
# number_with_delimiter(12345678.05) => 12,345,678.05
|
|
12
|
-
# number_with_delimiter(12345678, :delimiter => ".") => 12.345.678
|
|
13
|
-
def number_with_delimiter(number, delimiter=",", separator=".")
|
|
14
|
-
begin
|
|
15
|
-
parts = number.to_s.split(separator)
|
|
16
|
-
parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
|
|
17
|
-
parts.join separator
|
|
18
|
-
rescue
|
|
19
|
-
number
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
data/lib/helpers/tag_helper.rb
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
module Waves
|
|
2
|
-
module Helpers
|
|
3
|
-
module TagHelper
|
|
4
|
-
|
|
5
|
-
ESCAPE_TABLE = { '&'=>'&', '<'=>'<', '>'=>'>', '"'=>'"', "'"=>''', }
|
|
6
|
-
def h(value)
|
|
7
|
-
value.to_s.gsub(/[&<>"]/) { |s| ESCAPE_TABLE[s] }
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
# Returns an empty HTML tag of type +name+ which by default is XHTML
|
|
11
|
-
# compliant. Setting +open+ to true will create an open tag compatible
|
|
12
|
-
# with HTML 4.0 and below. Add HTML attributes by passing an attributes
|
|
13
|
-
# hash to +options+. For attributes with no value like (disabled and
|
|
14
|
-
# readonly), give it a value of true in the +options+ hash. You can use
|
|
15
|
-
# symbols or strings for the attribute names.
|
|
16
|
-
#
|
|
17
|
-
# tag("br")
|
|
18
|
-
# # => <br />
|
|
19
|
-
# tag("br", nil, true)
|
|
20
|
-
# # => <br>
|
|
21
|
-
# tag("input", { :type => 'text', :disabled => true })
|
|
22
|
-
# # => <input type="text" disabled="disabled" />
|
|
23
|
-
def tag(name, options = nil, open = false)
|
|
24
|
-
"<#{name}#{tag_options(options) if options}" + (open ? ">" : " />")
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# Returns the escaped +html+ without affecting existing escaped entities.
|
|
28
|
-
#
|
|
29
|
-
# escape_once("1 > 2 & 3")
|
|
30
|
-
# # => "1 < 2 & 3"
|
|
31
|
-
def escape_once(html)
|
|
32
|
-
fix_double_escape(h(html.to_s))
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
private
|
|
36
|
-
|
|
37
|
-
def tag_options(options)
|
|
38
|
-
cleaned_options = convert_booleans(options.stringify_keys.reject {|key, value| value.nil?})
|
|
39
|
-
' ' + cleaned_options.map {|key, value| %(#{key}="#{escape_once(value)}")}.sort * ' ' unless cleaned_options.empty?
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def convert_booleans(options)
|
|
43
|
-
%w( disabled readonly multiple ).each { |a| boolean_attribute(options, a) }
|
|
44
|
-
options
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def boolean_attribute(options, attribute)
|
|
48
|
-
options[attribute] ? options[attribute] = attribute : options.delete(attribute)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
# Fix double-escaped entities, such as &amp;, &#123;, etc.
|
|
52
|
-
def fix_double_escape(escaped)
|
|
53
|
-
escaped.gsub(/&([a-z]+|(#\d+));/i) { "&#{$1};" }
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
data/lib/helpers/url_helper.rb
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
module Waves
|
|
2
|
-
module Helpers
|
|
3
|
-
module UrlHelper
|
|
4
|
-
|
|
5
|
-
# Returns the URL for the set of +options+ provided. This takes the
|
|
6
|
-
# same options as url_for in action controller. For a list, see the
|
|
7
|
-
# documentation for ActionController::Base#url_for. Note that it'll
|
|
8
|
-
# set :only_path => true so you'll get the relative /controller/action
|
|
9
|
-
# instead of the fully qualified http://example.com/controller/action.
|
|
10
|
-
#
|
|
11
|
-
# When called from a view, url_for returns an HTML escaped url. If you
|
|
12
|
-
# need an unescaped url, pass :escape => false in the +options+.
|
|
13
|
-
def url_for(options = {}, *parameters_for_method_reference)
|
|
14
|
-
if options.kind_of? Hash
|
|
15
|
-
options = { :only_path => true }.update(options.symbolize_keys)
|
|
16
|
-
escape = options.key?(:escape) ? options.delete(:escape) : true
|
|
17
|
-
else
|
|
18
|
-
escape = true
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
url = options[:url] #@controller.send(:url_for, options, *parameters_for_method_reference)
|
|
22
|
-
escape ? html_escape(url) : url
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
# Creates a link tag of the given +name+ using a URL created by the set
|
|
27
|
-
# of +options+. See the valid options in the documentation for
|
|
28
|
-
# ActionController::Base#url_for. It's also possible to pass a string instead
|
|
29
|
-
# of an options hash to get a link tag that uses the value of the string as the
|
|
30
|
-
# href for the link. If nil is passed as a name, the link itself will become
|
|
31
|
-
# the name.
|
|
32
|
-
#
|
|
33
|
-
# The +html_options+ will accept a hash of html attributes for the link tag.
|
|
34
|
-
# It also accepts 3 modifiers that specialize the link behavior.
|
|
35
|
-
#
|
|
36
|
-
# * <tt>:confirm => 'question?'</tt>: This will add a JavaScript confirm
|
|
37
|
-
# prompt with the question specified. If the user accepts, the link is
|
|
38
|
-
# processed normally, otherwise no action is taken.
|
|
39
|
-
# * <tt>:popup => true || array of window options</tt>: This will force the
|
|
40
|
-
# link to open in a popup window. By passing true, a default browser window
|
|
41
|
-
# will be opened with the URL. You can also specify an array of options
|
|
42
|
-
# that are passed-thru to JavaScripts window.open method.
|
|
43
|
-
# * <tt>:method => symbol of HTTP verb</tt>: This modifier will dynamically
|
|
44
|
-
# create an HTML form and immediately submit the form for processing using
|
|
45
|
-
# the HTTP verb specified. Useful for having links perform a POST operation
|
|
46
|
-
# in dangerous actions like deleting a record (which search bots can follow
|
|
47
|
-
# while spidering your site). Supported verbs are :post, :delete and :put.
|
|
48
|
-
# Note that if the user has JavaScript disabled, the request will fall back
|
|
49
|
-
# to using GET. If you are relying on the POST behavior, your should check
|
|
50
|
-
# for it in your controllers action by using the request objects methods
|
|
51
|
-
# for post?, delete? or put?.
|
|
52
|
-
#
|
|
53
|
-
# You can mix and match the +html_options+ with the exception of
|
|
54
|
-
# :popup and :method which will raise an ActionView::ActionViewError
|
|
55
|
-
# exception.
|
|
56
|
-
#
|
|
57
|
-
# link_to "Visit Other Site", "http://www.rubyonrails.org/", :confirm => "Are you sure?"
|
|
58
|
-
# link_to "Help", { :action => "help" }, :popup => true
|
|
59
|
-
# link_to "View Image", { :action => "view" }, :popup => ['new_window_name', 'height=300,width=600']
|
|
60
|
-
# link_to "Delete Image", { :action => "delete", :id => @image.id }, :confirm => "Are you sure?", :method => :delete
|
|
61
|
-
def link_to(name, options = {}, html_options = nil, *parameters_for_method_reference)
|
|
62
|
-
if html_options
|
|
63
|
-
html_options = html_options.stringify_keys
|
|
64
|
-
# convert_options_to_javascript!(html_options)
|
|
65
|
-
tag_options = tag_options(html_options)
|
|
66
|
-
else
|
|
67
|
-
tag_options = nil
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
url = options.is_a?(String) ? options : self.url_for(options, *parameters_for_method_reference)
|
|
71
|
-
"<a href=\"#{url}\"#{tag_options}>#{name || url}</a>"
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
end
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
module Waves
|
|
2
|
-
module Layers
|
|
3
|
-
|
|
4
|
-
# Configures Waves to use the templates in app/templates/errors for exception handling
|
|
5
|
-
module DefaultErrors
|
|
6
|
-
|
|
7
|
-
def self.included( app )
|
|
8
|
-
|
|
9
|
-
app.auto_eval :Configurations do
|
|
10
|
-
auto_eval :Mapping do
|
|
11
|
-
extend Waves::Mapping
|
|
12
|
-
handle(Waves::Dispatchers::NotFoundError) do
|
|
13
|
-
html = Waves.application.views[:errors].process( request ) do
|
|
14
|
-
not_found_404( :error => Waves::Dispatchers::NotFoundError )
|
|
15
|
-
end
|
|
16
|
-
response.status = '404'
|
|
17
|
-
response.content_type = 'text/html'
|
|
18
|
-
response.body = html
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
data/lib/layers/orm/filebase.rb
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
module Waves
|
|
2
|
-
module Layers
|
|
3
|
-
module ORM
|
|
4
|
-
|
|
5
|
-
# Work in Progress
|
|
6
|
-
module Filebase
|
|
7
|
-
|
|
8
|
-
def self.included(app)
|
|
9
|
-
app.module_eval do
|
|
10
|
-
auto_eval( :Models ) do
|
|
11
|
-
auto_eval( true ) { include Filebase::Model[ :db / self.name.snake_case ] }
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
end
|
data/lib/layers/simple.rb
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
module Waves
|
|
2
|
-
|
|
3
|
-
# Waves uses Layers to provide discrete, stackable, interchangeable bundles of functionality.
|
|
4
|
-
#
|
|
5
|
-
# Developers can make use of Layers by including them directly in a Waves application:
|
|
6
|
-
#
|
|
7
|
-
# module MyApp
|
|
8
|
-
# include SomeLayer
|
|
9
|
-
# end
|
|
10
|
-
module Layers
|
|
11
|
-
|
|
12
|
-
# Creates the Configurations namespace and establishes the standard autoload-or-autocreate
|
|
13
|
-
# rules.
|
|
14
|
-
module Simple
|
|
15
|
-
def self.included( app )
|
|
16
|
-
|
|
17
|
-
def app.config ; Waves.config ; end
|
|
18
|
-
def app.configurations ; self::Configurations ; end
|
|
19
|
-
|
|
20
|
-
app.instance_eval { include AutoCode }
|
|
21
|
-
|
|
22
|
-
app.auto_create_module( :Configurations ) do
|
|
23
|
-
include AutoCode
|
|
24
|
-
auto_create_class true, Waves::Configurations::Default
|
|
25
|
-
auto_load :Mapping, :directories => [:configurations]
|
|
26
|
-
auto_load true, :directories => [:configurations]
|
|
27
|
-
auto_eval :Mapping do
|
|
28
|
-
extend Waves::Mapping
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
data/lib/layers/simple_errors.rb
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
module Waves
|
|
2
|
-
module Layers
|
|
3
|
-
# Configures Waves for minimal exception handling.
|
|
4
|
-
#
|
|
5
|
-
# For example,
|
|
6
|
-
# a NotFoundError results in response status of 404, with body text
|
|
7
|
-
# of "404 Not Found".
|
|
8
|
-
module SimpleErrors
|
|
9
|
-
|
|
10
|
-
def self.included( app )
|
|
11
|
-
|
|
12
|
-
app.auto_eval :Configurations do
|
|
13
|
-
auto_eval :Mapping do
|
|
14
|
-
handle(Waves::Dispatchers::NotFoundError) do
|
|
15
|
-
response.status = 404; response.body = "404 Not Found"
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
data/lib/mapping/mapping.rb
DELETED
|
@@ -1,289 +0,0 @@
|
|
|
1
|
-
module Waves
|
|
2
|
-
|
|
3
|
-
# Mappings in Waves are the interface between the request dispatcher and your
|
|
4
|
-
# application code. The dispatcher matches each request against the mappings
|
|
5
|
-
# to determine a primary action and to collect sets of before, after, wrap,
|
|
6
|
-
# and always actions. The dispatcher also looks for an exception handler
|
|
7
|
-
# registered in the mappings when attempting a rescue.
|
|
8
|
-
#
|
|
9
|
-
# Each mapping associates a block with a set of constraints. Mappings can be
|
|
10
|
-
# one of several types:
|
|
11
|
-
#
|
|
12
|
-
# - action (the actual request processing and response)
|
|
13
|
-
# - handle (exception handling)
|
|
14
|
-
# - before
|
|
15
|
-
# - after
|
|
16
|
-
# - wrap (registers its block as both a before and after action)
|
|
17
|
-
# - always (like an "ensure" clause in a rescue)
|
|
18
|
-
#
|
|
19
|
-
# Actions are registered using path, url, or map. The other types may be
|
|
20
|
-
# registered using methods named after the type.
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
# The available constraints are:
|
|
24
|
-
#
|
|
25
|
-
# - a string or regexp that the path or url must match
|
|
26
|
-
# - parameters to match against the HTTP request headers and the Rack-specific variables (e.g. 'rack.url_scheme')
|
|
27
|
-
# - an additional hash reserved for settings not related to the Rack request (e.g. giving Rack handers special instructions for certain requests. See threaded? )
|
|
28
|
-
#
|
|
29
|
-
# The dispatcher evaluates mapping blocks in an instance of ResponseProxy,
|
|
30
|
-
# which provides access to foundational classes of a Waves application (i.e. controllers and views)
|
|
31
|
-
#
|
|
32
|
-
# == Examples
|
|
33
|
-
#
|
|
34
|
-
# resource = '([\w\-]+)'
|
|
35
|
-
# name = '([\w\-\_\.\+\@]+)'
|
|
36
|
-
#
|
|
37
|
-
# path %r{^/#{resource}/#{name}/?$} do |resource, name|
|
|
38
|
-
# "Hello from a #{resource} named #{name.capitalize}."
|
|
39
|
-
# end
|
|
40
|
-
#
|
|
41
|
-
# In this example, we are using binding regular expressions defined by +resource+
|
|
42
|
-
# and +name+. The matches are passed into the block as parameters. Thus, this
|
|
43
|
-
# rule, given the URL '/person/john' will return:
|
|
44
|
-
#
|
|
45
|
-
# Hello from a person named John.
|
|
46
|
-
#
|
|
47
|
-
# The given block may simple return a string. The content type is inferred from the request
|
|
48
|
-
# if possible, otherwise it defaults to +text+/+html+.
|
|
49
|
-
#
|
|
50
|
-
# path '/critters', :method => :post do
|
|
51
|
-
# request.content_type
|
|
52
|
-
# end
|
|
53
|
-
#
|
|
54
|
-
# /critters # => 'text/html'
|
|
55
|
-
#
|
|
56
|
-
# In this example, we match against a string and check to make sure that the request is a
|
|
57
|
-
# POST. If so, we return the request content_type. The request (and response) objects are
|
|
58
|
-
# available from within the block implicitly.
|
|
59
|
-
#
|
|
60
|
-
# = Invoking Controllers and Views
|
|
61
|
-
#
|
|
62
|
-
# You may invoke a controller or view method for the primary application by using the
|
|
63
|
-
# corresponding methods, preceded by the +use+ directive.
|
|
64
|
-
#
|
|
65
|
-
# == Examples
|
|
66
|
-
#
|
|
67
|
-
# path %r{^/#{resource}/#{name}/?$} do |resource, name|
|
|
68
|
-
# resource( resource ) do
|
|
69
|
-
# controller { find( name ) } | view { | instance | show( resource => instance ) }
|
|
70
|
-
# end
|
|
71
|
-
# end
|
|
72
|
-
#
|
|
73
|
-
# In this example, we take the same rule from above but invoke a controller and view method.
|
|
74
|
-
# We use the +resource+ directive and the resource parameter to set the MVC instances we're going
|
|
75
|
-
# to use. This is necessary to use the +controller+ or +view+ methods. Each of these take
|
|
76
|
-
# a block as arguments which are evaluated in the context of the instance. The +view+ method
|
|
77
|
-
# can further take an argument which is "piped" from the result of the controller block. This
|
|
78
|
-
# isn't required, but helps to clarify the request processing. Within a view block, a hash
|
|
79
|
-
# may also be passed in to the view method, which is converted into instance variables for the
|
|
80
|
-
# view instance. In this example, the +show+ method is assigned to an instance variable with the
|
|
81
|
-
# same name as the resource type.
|
|
82
|
-
#
|
|
83
|
-
# So given the same URL as above - /person/john - what will happen is the +find+ method for
|
|
84
|
-
# the +Person+ controller will be invoked and the result passed to the +Person+ view's +show+
|
|
85
|
-
# method, with +@person+ holding the value returned.
|
|
86
|
-
#
|
|
87
|
-
# Crucially, the controller does not need to know what variables the view depends on. This is
|
|
88
|
-
# the job of the mapping block, to act as the "glue" between the controller and view. The
|
|
89
|
-
# controller and view can thus be completely decoupled and become easier to reuse separately.
|
|
90
|
-
#
|
|
91
|
-
# url 'http://admin.foobar.com:/' do
|
|
92
|
-
# resource( :admin ) { view { console } }
|
|
93
|
-
# end
|
|
94
|
-
#
|
|
95
|
-
# In this example, we are using the +url+ method to map a subdomain of +foobar.com+ to the
|
|
96
|
-
# console method of the Admin view. In this case, we did not need a controller method, so
|
|
97
|
-
# we simply didn't call one.
|
|
98
|
-
#
|
|
99
|
-
# = Mapping Modules
|
|
100
|
-
#
|
|
101
|
-
# You may encapsulate sets of related rules into modules and simply include them into your
|
|
102
|
-
# mapping module. Some rule sets come packaged with Waves, such as PrettyUrls (rules for
|
|
103
|
-
# matching resources using names instead of ids). The simplest way to define such modules for
|
|
104
|
-
# reuse is by defining the +included+ class method for the rules module, and then define
|
|
105
|
-
# the rules using +module_eval+. See the PrettyUrls module for an example of how to do this.
|
|
106
|
-
#
|
|
107
|
-
# *Important:* Using pre-packaged mapping rules does not prevent you from adding to or
|
|
108
|
-
# overriding these rules. However, order does matter, so you should put your own rules
|
|
109
|
-
# ahead of those your may be importing. Also, place rules with constraints (for example,
|
|
110
|
-
# rules that require a POST) ahead of those with no constraints, otherwise the constrainted
|
|
111
|
-
# rules may never be called.
|
|
112
|
-
|
|
113
|
-
module Mapping
|
|
114
|
-
|
|
115
|
-
# If the pattern matches and constraints given by the options hash are satisfied, run the
|
|
116
|
-
# block before running any +path+ or +url+ actions. You can have as many +before+ matches
|
|
117
|
-
# as you want - they will all run, unless one of them calls redirect, generates an
|
|
118
|
-
# unhandled exception, etc.
|
|
119
|
-
def before( path, options = {}, &block )
|
|
120
|
-
if path.is_a? Hash
|
|
121
|
-
options = path
|
|
122
|
-
else
|
|
123
|
-
options[:path] = path
|
|
124
|
-
end
|
|
125
|
-
filters[:before] << [ options, block ]
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
# Similar to before, except it runs its actions after any matching +url+ or +path+ actions.
|
|
129
|
-
# Note that after methods will run even if an exception is thrown during processing.
|
|
130
|
-
def after( path, options = {}, &block )
|
|
131
|
-
if path.is_a? Hash
|
|
132
|
-
options = path
|
|
133
|
-
else
|
|
134
|
-
options[:path] = path
|
|
135
|
-
end
|
|
136
|
-
filters[:after] << [ options, block ]
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
# Run the action before and after the matching +url+ or +path+ action.
|
|
140
|
-
def wrap( path, options = {}, &block )
|
|
141
|
-
if path.is_a? Hash
|
|
142
|
-
options = path
|
|
143
|
-
else
|
|
144
|
-
options[:path] = path
|
|
145
|
-
end
|
|
146
|
-
filters[:before] << [ options, block ]
|
|
147
|
-
filters[:after] << [ options, block ]
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
# Like after, but will run even when an exception is thrown. Exceptions in
|
|
151
|
-
# always mappings are simply logged and ignored.
|
|
152
|
-
def always( path, options = {}, &block )
|
|
153
|
-
if path.is_a? Hash
|
|
154
|
-
options = path
|
|
155
|
-
else
|
|
156
|
-
options[:path] = path
|
|
157
|
-
end
|
|
158
|
-
filters[:always] << [ options, block ]
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
# Maps a request to a block. Don't use this method directly unless you know what
|
|
162
|
-
# you're doing. Use +path+ or +url+ instead.
|
|
163
|
-
def map( path, options = {}, params = {}, &block )
|
|
164
|
-
case path
|
|
165
|
-
when Hash
|
|
166
|
-
params = options; options = path
|
|
167
|
-
when String
|
|
168
|
-
options[:path] = path
|
|
169
|
-
end
|
|
170
|
-
mapping << [ options, params, block ]
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
# Match pattern against the +request.path+, along with satisfying any constraints
|
|
174
|
-
# specified by the options hash. If the pattern matches and the constraints are satisfied,
|
|
175
|
-
# run the block. Only one +path+ or +url+ match will be run (the first one).
|
|
176
|
-
def path( pat, options = {}, params = {}, &block )
|
|
177
|
-
options[:path] = pat; map( options, params, &block )
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
# Match pattern against the +request.url+, along with satisfying any constraints
|
|
181
|
-
# specified by the options hash. If the pattern matches and the constraints are satisfied,
|
|
182
|
-
# run the block. Only one +path+ or +url+ match will be run (the first one).
|
|
183
|
-
def url( pat, options = {}, params = {}, &block )
|
|
184
|
-
options[:url] = pat; map( options, params, &block )
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
# Maps the root of the application to a block. If an options hash is specified it must
|
|
188
|
-
# satisfy those constraints in order to run the block.
|
|
189
|
-
def root( options = {}, params = {}, &block )
|
|
190
|
-
path( %r{^/?$}, options, params, &block )
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
# Maps an exception handler to a block.
|
|
194
|
-
def handle(exception, options = {}, &block )
|
|
195
|
-
handlers << [exception,options, block]
|
|
196
|
-
end
|
|
197
|
-
|
|
198
|
-
# Maps a request to a block that will be executed within it's
|
|
199
|
-
# own thread. This is especially useful when you're running
|
|
200
|
-
# with an event driven server like thin or ebb, and this block
|
|
201
|
-
# is going to take a relatively long time.
|
|
202
|
-
def threaded( pat, options = {}, params = {}, &block)
|
|
203
|
-
params[:threaded] = true
|
|
204
|
-
map( pat, options, params, &block)
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
# Determines whether the request should be handled in a separate thread. This is used
|
|
208
|
-
# by event driven servers like thin and ebb, and is most useful for those methods that
|
|
209
|
-
# take a long time to complete, like for example upload processes. E.g.:
|
|
210
|
-
#
|
|
211
|
-
# threaded("/upload", :method => :post) do
|
|
212
|
-
# handle_upload
|
|
213
|
-
# end
|
|
214
|
-
#
|
|
215
|
-
# You typically wouldn't use this method directly.
|
|
216
|
-
def threaded?( request )
|
|
217
|
-
mapping.find do | options, params, function |
|
|
218
|
-
match = match( request, options, function )
|
|
219
|
-
return params[:threaded] == true if match
|
|
220
|
-
end
|
|
221
|
-
return false
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
# Match the given request against the defined rules. This is typically only called
|
|
225
|
-
# by a dispatcher object, so you shouldn't typically use it directly.
|
|
226
|
-
def []( request )
|
|
227
|
-
|
|
228
|
-
rx = { :before => [], :after => [], :always => [], :action => nil, :handlers => [] }
|
|
229
|
-
|
|
230
|
-
( filters[:before] + filters[:wrap] ).each do | options, function |
|
|
231
|
-
matches = match( request, options, function )
|
|
232
|
-
rx[:before] << matches if matches
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
mapping.find do | options, params, function |
|
|
236
|
-
rx[:action] = match( request, options, function )
|
|
237
|
-
break if rx[:action]
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
( filters[:after] + filters[:wrap] ).each do | options, function |
|
|
241
|
-
matches = match( request, options, function )
|
|
242
|
-
rx[:after] << matches if matches
|
|
243
|
-
end
|
|
244
|
-
|
|
245
|
-
filters[:always].each do | options, function |
|
|
246
|
-
matches = match( request, options, function )
|
|
247
|
-
rx[:always] << matches if matches
|
|
248
|
-
end
|
|
249
|
-
|
|
250
|
-
handlers.each do | exception, options, function |
|
|
251
|
-
matches = match( request, options, function )
|
|
252
|
-
rx[:handlers] << matches.unshift(exception) if matches
|
|
253
|
-
end
|
|
254
|
-
|
|
255
|
-
return rx
|
|
256
|
-
end
|
|
257
|
-
|
|
258
|
-
# Clear all mapping rules
|
|
259
|
-
def clear
|
|
260
|
-
@mapping = @filters = @handlers = nil;
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
private
|
|
264
|
-
|
|
265
|
-
def mapping; @mapping ||= []; end
|
|
266
|
-
|
|
267
|
-
def filters; @filters ||= { :before => [], :after => [], :wrap => [], :always => [] }; end
|
|
268
|
-
|
|
269
|
-
def handlers; @handlers ||= []; end
|
|
270
|
-
|
|
271
|
-
def match ( request, options, function )
|
|
272
|
-
return nil unless satisfy( request, options )
|
|
273
|
-
return [ function, nil ] if ( options[:path] == true or options[:url] == true )
|
|
274
|
-
matches = options[:path].match( request.path ) if options[:path]
|
|
275
|
-
matches = options[:url].match( request.url ) if options[:url]
|
|
276
|
-
return [ function, matches ? matches[1..-1] : nil ]
|
|
277
|
-
end
|
|
278
|
-
|
|
279
|
-
def satisfy( request, options )
|
|
280
|
-
options.nil? or options.all? do |name,wanted|
|
|
281
|
-
return true if wanted == true
|
|
282
|
-
got = request.send( name ) rescue request.env[ ( name =~ /^rack\./ ) ? name.to_s.downcase : name.to_s.upcase ]
|
|
283
|
-
( ( wanted.is_a?(Regexp) and wanted.match( got.to_s ) ) or got.to_s == wanted.to_s ) unless ( wanted.nil? or got.nil? )
|
|
284
|
-
end
|
|
285
|
-
end
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
end
|