waw 0.2.2
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/LICENCE.rdoc +25 -0
- data/README.rdoc +32 -0
- data/bin/waw +32 -0
- data/bin/waw-profile +26 -0
- data/bin/waw-start +26 -0
- data/bin/wspec +33 -0
- data/layouts/empty/Rakefile +14 -0
- data/layouts/empty/config.ru +5 -0
- data/layouts/empty/config/commons.cfg +31 -0
- data/layouts/empty/config/devel.cfg +21 -0
- data/layouts/empty/ignore +7 -0
- data/layouts/empty/logs/dontforgetme +0 -0
- data/layouts/empty/resources/messages.rs +1 -0
- data/layouts/empty/test/wspec/site_respond.wspec +3 -0
- data/layouts/empty/test/wspec/test_all.rb +13 -0
- data/layouts/empty/waw.deploy +1 -0
- data/layouts/empty/waw.routing +6 -0
- data/layouts/static/dependencies +1 -0
- data/layouts/static/public/.wawaccess +18 -0
- data/layouts/static/public/css/style.css +0 -0
- data/layouts/static/public/images/dontforgetme +0 -0
- data/layouts/static/public/js/project.js +0 -0
- data/layouts/static/public/pages/.wawaccess +30 -0
- data/layouts/static/public/pages/404.wtpl +1 -0
- data/layouts/static/public/pages/index.wtpl +5 -0
- data/layouts/static/public/templates/.wawaccess +9 -0
- data/layouts/static/public/templates/layout.wtpl +17 -0
- data/layouts/static/test/wspec/static_pages_are_served.wspec +21 -0
- data/layouts/static/waw.routing +8 -0
- data/lib/waw.rb +99 -0
- data/lib/waw/commands/command.rb +115 -0
- data/lib/waw/commands/profile_command.rb +66 -0
- data/lib/waw/commands/start_command.rb +59 -0
- data/lib/waw/config.rb +110 -0
- data/lib/waw/controller.rb +25 -0
- data/lib/waw/controllers/action/action.rb +91 -0
- data/lib/waw/controllers/action/action_utils.rb +30 -0
- data/lib/waw/controllers/action/js_generation.rb +116 -0
- data/lib/waw/controllers/action_controller.rb +133 -0
- data/lib/waw/controllers/error/backtrace.rb +54 -0
- data/lib/waw/controllers/error_handler.rb +62 -0
- data/lib/waw/controllers/json_controller.rb +31 -0
- data/lib/waw/controllers/no_cache.rb +22 -0
- data/lib/waw/controllers/static/match.rb +80 -0
- data/lib/waw/controllers/static/waw_access.rb +235 -0
- data/lib/waw/controllers/static/waw_access_dsl.rb +48 -0
- data/lib/waw/controllers/static_controller.rb +37 -0
- data/lib/waw/default_config.cfg +14 -0
- data/lib/waw/environment_utils.rb +57 -0
- data/lib/waw/errors.rb +4 -0
- data/lib/waw/ext.rb +3 -0
- data/lib/waw/ext/core.rb +4 -0
- data/lib/waw/ext/core/hash.rb +47 -0
- data/lib/waw/ext/core/logger.rb +10 -0
- data/lib/waw/ext/core/module.rb +20 -0
- data/lib/waw/ext/core/object.rb +29 -0
- data/lib/waw/ext/rack.rb +19 -0
- data/lib/waw/ext/rack/builder.rb +43 -0
- data/lib/waw/ext/rack/delegator.rb +51 -0
- data/lib/waw/ext/rack/urlmap.rb +55 -0
- data/lib/waw/ext/wlang.rb +1 -0
- data/lib/waw/ext/wlang/hosted_language.rb +21 -0
- data/lib/waw/fullstate.rb +8 -0
- data/lib/waw/fullstate/on_class.rb +37 -0
- data/lib/waw/fullstate/on_instance.rb +27 -0
- data/lib/waw/fullstate/variable.rb +36 -0
- data/lib/waw/kern.rb +6 -0
- data/lib/waw/kern/app.rb +48 -0
- data/lib/waw/kern/empty/waw.deploy +0 -0
- data/lib/waw/kern/empty/waw.routing +1 -0
- data/lib/waw/kern/freezed_state.rb +32 -0
- data/lib/waw/kern/hooks.rb +53 -0
- data/lib/waw/kern/lifecycle.rb +248 -0
- data/lib/waw/kern/living_state.rb +87 -0
- data/lib/waw/kern/utils.rb +27 -0
- data/lib/waw/resource_collection.rb +100 -0
- data/lib/waw/restart.rb +32 -0
- data/lib/waw/routing.rb +43 -0
- data/lib/waw/routing/action_routing.rb +78 -0
- data/lib/waw/routing/dsl.rb +45 -0
- data/lib/waw/routing/feedback.rb +23 -0
- data/lib/waw/routing/form_validation_feedback.rb +36 -0
- data/lib/waw/routing/javascript.rb +17 -0
- data/lib/waw/routing/redirect.rb +26 -0
- data/lib/waw/routing/refresh.rb +17 -0
- data/lib/waw/routing/routing_rule.rb +16 -0
- data/lib/waw/scope_utils.rb +69 -0
- data/lib/waw/session.rb +51 -0
- data/lib/waw/testing.rb +1 -0
- data/lib/waw/tools/mail.rb +4 -0
- data/lib/waw/tools/mail/mail.rb +119 -0
- data/lib/waw/tools/mail/mail_agent.rb +123 -0
- data/lib/waw/tools/mail/mailbox.rb +62 -0
- data/lib/waw/tools/mail/template.rb +38 -0
- data/lib/waw/utils/dsl_helper.rb +116 -0
- data/lib/waw/validation.rb +175 -0
- data/lib/waw/validation/and_validator.rb +27 -0
- data/lib/waw/validation/array_validations.rb +38 -0
- data/lib/waw/validation/boolean_validator.rb +32 -0
- data/lib/waw/validation/comparison_validations.rb +45 -0
- data/lib/waw/validation/date_validator.rb +31 -0
- data/lib/waw/validation/default_validator.rb +30 -0
- data/lib/waw/validation/dsl_ruby_extensions.rb +11 -0
- data/lib/waw/validation/errors.rb +17 -0
- data/lib/waw/validation/ext.rb +3 -0
- data/lib/waw/validation/file_validator.rb +30 -0
- data/lib/waw/validation/float_validator.rb +19 -0
- data/lib/waw/validation/helpers.rb +67 -0
- data/lib/waw/validation/integer_validator.rb +16 -0
- data/lib/waw/validation/isin_validator.rb +24 -0
- data/lib/waw/validation/mandatory_validator.rb +17 -0
- data/lib/waw/validation/missing_validator.rb +17 -0
- data/lib/waw/validation/not_validator.rb +20 -0
- data/lib/waw/validation/or_validator.rb +34 -0
- data/lib/waw/validation/regexp_validator.rb +29 -0
- data/lib/waw/validation/same_validator.rb +16 -0
- data/lib/waw/validation/signature.rb +157 -0
- data/lib/waw/validation/size_validations.rb +44 -0
- data/lib/waw/validation/string_validator.rb +15 -0
- data/lib/waw/validation/validator.rb +48 -0
- data/lib/waw/wawgen.rb +2 -0
- data/lib/waw/wawgen/create.rb +166 -0
- data/lib/waw/wawgen/project.rb +25 -0
- data/lib/waw/wspec.rb +5 -0
- data/lib/waw/wspec/browser.rb +240 -0
- data/lib/waw/wspec/dsl.rb +201 -0
- data/lib/waw/wspec/html_analysis.rb +136 -0
- data/lib/waw/wspec/html_analysis/tag.rb +56 -0
- data/lib/waw/wspec/runner.rb +70 -0
- data/lib/waw/wspec/scenario.rb +35 -0
- data/lib/waw/wspec/suite.rb +54 -0
- data/test/bricks/error_handler/config/test.cfg +2 -0
- data/test/bricks/error_handler/logs/webapp.log +1411 -0
- data/test/bricks/error_handler/test/error_handler.wspec +16 -0
- data/test/bricks/error_handler/waw.deploy +1 -0
- data/test/bricks/error_handler/waw.routing +27 -0
- data/test/integration/waw_create_integration_test.rb +24 -0
- data/test/spec/assumptions_spec.rb +30 -0
- data/test/spec/controllers/action_controller_spec.rb +14 -0
- data/test/spec/controllers/static/waw_access_spec.rb +112 -0
- data/test/spec/environment_utils_spec.rb +15 -0
- data/test/spec/ext/core/hash_spec.rb +58 -0
- data/test/spec/fixtures.rb +41 -0
- data/test/spec/fixtures/action/config/default.cfg +2 -0
- data/test/spec/fixtures/action/lib/action_controller_test.rb +12 -0
- data/test/spec/fixtures/action/waw.deploy +1 -0
- data/test/spec/fixtures/action/waw.routing +6 -0
- data/test/spec/fixtures/empty/waw.deploy +0 -0
- data/test/spec/fixtures/empty/waw.routing +0 -0
- data/test/spec/fullstate/on_class_spec.rb +59 -0
- data/test/spec/fullstate/on_instance_spec.rb +59 -0
- data/test/spec/fullstate/session_spec.rb +43 -0
- data/test/spec/fullstate/variable_spec.rb +55 -0
- data/test/spec/resource_collection_spec.rb +50 -0
- data/test/spec/test_all.rb +9 -0
- data/test/spec/tools/mail/mail_agent_spec.rb +116 -0
- data/test/spec/tools/mail/mail_spec.rb +56 -0
- data/test/spec/tools/mail/mailbox_spec.rb +57 -0
- data/test/spec/tools/mail/template_spec.rb +47 -0
- data/test/spec/validation/array_validation_spec.rb +63 -0
- data/test/spec/validation/array_validator_spec.rb +17 -0
- data/test/spec/validation/date_validation_spec.rb +35 -0
- data/test/spec/validation/default_validation_spec.rb +37 -0
- data/test/spec/validation/disjuctive_validation_spec.rb +33 -0
- data/test/spec/validation/errors_spec.rb +37 -0
- data/test/spec/validation/file_validator_spec.rb +34 -0
- data/test/spec/validation/mail_validation_spec.rb +51 -0
- data/test/spec/validation/missing_validation_spec.rb +43 -0
- data/test/spec/validation/same_validation_spec.rb +24 -0
- data/test/spec/validation/signature_intuition_spec.rb +37 -0
- data/test/spec/validation/signature_spec.rb +164 -0
- data/test/spec/validation/validation_spec.rb +28 -0
- data/test/spec/wspec/html_analysis/tag_spec.rb +38 -0
- data/test/spec/wspec/html_analysis_spec.rb +170 -0
- data/test/unit/test_all.rb +8 -0
- data/test/unit/waw/app_test.rb +126 -0
- data/test/unit/waw/app_test/config/commons.cfg +2 -0
- data/test/unit/waw/app_test/config/devel.cfg +1 -0
- data/test/unit/waw/config_test.rb +54 -0
- data/test/unit/waw/controllers/action_controller_test.rb +76 -0
- data/test/unit/waw/controllers/action_test.rb +35 -0
- data/test/unit/waw/controllers/example_action_controller_test.rb +24 -0
- data/test/unit/waw/controllers/multiple_action_controller_test.rb +78 -0
- data/test/unit/waw/controllers/static/example/css/example.css +1 -0
- data/test/unit/waw/controllers/static/example/index.html +1 -0
- data/test/unit/waw/controllers/static/example/js/example.js +1 -0
- data/test/unit/waw/controllers/static/example/pages/hello.wtpl +1 -0
- data/test/unit/waw/controllers/static/waw_access_test.rb +76 -0
- data/test/unit/waw/ext/rack_test.rb +74 -0
- data/test/unit/waw/resource_collection_test.rb +49 -0
- data/test/unit/waw/resources.txt +4 -0
- data/test/unit/waw/routing/routing_test.rb +26 -0
- data/test/unit/waw/utils/dsl_helper_test.rb +79 -0
- data/test/unit/waw/utils/dsl_helper_test_extensions1.rb +4 -0
- data/test/unit/waw/validation/signature_test.rb +193 -0
- data/test/unit/waw/validation_test.rb +319 -0
- data/test/unit/waw/wspec/html_analysis_test.html +81 -0
- data/test/unit/waw/wspec/html_analysis_test.rb +26 -0
- metadata +272 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Waw
|
|
2
|
+
module Routing
|
|
3
|
+
class RoutingRule
|
|
4
|
+
|
|
5
|
+
# Applies this routing rule on a Waw::WSpec::Browser instance.
|
|
6
|
+
# By default, does nothing at all.
|
|
7
|
+
def apply_on_browser(result, browser)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def generate_js_code(result, align=0)
|
|
11
|
+
raise "RoutingRule #{self.class} does not support javascript code generation"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end # RoutingRule
|
|
15
|
+
end # module Routing
|
|
16
|
+
end # module Waw
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
module Waw
|
|
2
|
+
module ScopeUtils
|
|
3
|
+
|
|
4
|
+
# Find the kernel context whose call must be delegated to.
|
|
5
|
+
def find_kernel_context
|
|
6
|
+
return self.waw_kernel if self.respond_to?(:waw_kernel)
|
|
7
|
+
return Waw.kernel if Waw.kernel
|
|
8
|
+
Waw.logger.warn("Using a empty kernel because no one has been found")
|
|
9
|
+
Waw::Kern::App.new("Empty autoloaded kernel").autoload(File.join(File.dirname(__FILE__), 'kern', 'empty'))
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
################################################################# About waw application
|
|
13
|
+
|
|
14
|
+
# Returns the root folder
|
|
15
|
+
def root_folder
|
|
16
|
+
find_kernel_context.root_folder
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Returns waw resources
|
|
20
|
+
def config
|
|
21
|
+
find_kernel_context.config
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Logger to use
|
|
25
|
+
def logger
|
|
26
|
+
find_kernel_context.logger
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Returns waw resources
|
|
30
|
+
def resources
|
|
31
|
+
find_kernel_context.resources
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
################################################################# About current request
|
|
35
|
+
|
|
36
|
+
# Returns the current Rack env instance
|
|
37
|
+
def rack_env
|
|
38
|
+
find_kernel_context.rack_env
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Returns the current Rack request instance
|
|
42
|
+
def request
|
|
43
|
+
find_kernel_context.request
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Returns the current Rack request instance
|
|
47
|
+
def response
|
|
48
|
+
find_kernel_context.response
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Request parameters
|
|
52
|
+
def params
|
|
53
|
+
find_kernel_context.params
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
################################################################# About current session
|
|
57
|
+
|
|
58
|
+
# Returns the current Rack session
|
|
59
|
+
def real_session
|
|
60
|
+
find_kernel_context.real_session
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Returns the waw session decorator
|
|
64
|
+
def session
|
|
65
|
+
find_kernel_context.session
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end # module ScopeUtils
|
|
69
|
+
end # module Waw
|
data/lib/waw/session.rb
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'singleton'
|
|
2
|
+
module Waw
|
|
3
|
+
class Session
|
|
4
|
+
extend FullState::OnInstance
|
|
5
|
+
|
|
6
|
+
# Creates a session instance
|
|
7
|
+
def initialize(rack_session)
|
|
8
|
+
@rack_session = rack_session
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Returns Rack's underlying session Hash
|
|
12
|
+
def rack_session
|
|
13
|
+
@rack_session
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Clears the session
|
|
17
|
+
def clear
|
|
18
|
+
rack_session.clear
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Checks if a given key exists in the session
|
|
22
|
+
def has_key?(name)
|
|
23
|
+
rack_session.has_key?(name)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Returns the value of a given variable
|
|
27
|
+
def [](name)
|
|
28
|
+
rack_session[name]
|
|
29
|
+
end
|
|
30
|
+
alias :get :[]
|
|
31
|
+
|
|
32
|
+
# Returns the value of a given variable
|
|
33
|
+
def []=(name, value)
|
|
34
|
+
rack_session[name] = value
|
|
35
|
+
end
|
|
36
|
+
alias :set :[]=
|
|
37
|
+
|
|
38
|
+
# Resets a given variable whose name is provided
|
|
39
|
+
def reset(name)
|
|
40
|
+
rack_session.delete(name)
|
|
41
|
+
end
|
|
42
|
+
alias :delete :reset
|
|
43
|
+
alias :unset :reset
|
|
44
|
+
|
|
45
|
+
# Inspects the session
|
|
46
|
+
def inspect
|
|
47
|
+
rack_session.inspect
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
end
|
data/lib/waw/testing.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require 'waw/wspec'
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
module Waw
|
|
2
|
+
module Tools
|
|
3
|
+
class MailAgent
|
|
4
|
+
# A helper to respect the mail protocol
|
|
5
|
+
class Mail
|
|
6
|
+
|
|
7
|
+
# Source address
|
|
8
|
+
attr_accessor :from
|
|
9
|
+
|
|
10
|
+
# Target addresses
|
|
11
|
+
attr_accessor :to
|
|
12
|
+
|
|
13
|
+
# Target carbon copy addresses
|
|
14
|
+
attr_accessor :cc
|
|
15
|
+
|
|
16
|
+
# Target b carbon copy addresses
|
|
17
|
+
attr_accessor :bcc
|
|
18
|
+
|
|
19
|
+
# Mail subject
|
|
20
|
+
attr_accessor :subject
|
|
21
|
+
|
|
22
|
+
# Mail date
|
|
23
|
+
attr_accessor :date
|
|
24
|
+
|
|
25
|
+
# MIME version
|
|
26
|
+
attr_accessor :mime_version
|
|
27
|
+
|
|
28
|
+
# Content-type
|
|
29
|
+
attr_accessor :content_type
|
|
30
|
+
|
|
31
|
+
# Content-type
|
|
32
|
+
attr_accessor :charset
|
|
33
|
+
|
|
34
|
+
# Mail body
|
|
35
|
+
attr_accessor :body
|
|
36
|
+
|
|
37
|
+
# Creates an empty mail
|
|
38
|
+
def initialize(subject = nil, body = nil, from = nil, *to)
|
|
39
|
+
@from = from
|
|
40
|
+
@to = to.empty? ? [] : to
|
|
41
|
+
@cc, @bcc = [], []
|
|
42
|
+
@subject = subject
|
|
43
|
+
@date = Time.now
|
|
44
|
+
@mime_version = "1.0"
|
|
45
|
+
@content_type = "text/plain"
|
|
46
|
+
@charset = "UTF-8"
|
|
47
|
+
@body = body
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Class methods
|
|
51
|
+
class << self
|
|
52
|
+
|
|
53
|
+
# Decodes a mail from a given string
|
|
54
|
+
def decode(str)
|
|
55
|
+
mail = Mail.new
|
|
56
|
+
lines = str.split("\n")
|
|
57
|
+
until false
|
|
58
|
+
case line = lines.shift.strip
|
|
59
|
+
when /^From: (.*)$/
|
|
60
|
+
mail.from = $1
|
|
61
|
+
when /^To: (.*)$/
|
|
62
|
+
mail.to = $1.split(',').collect{|s| s.strip}
|
|
63
|
+
when /^Cc: (.*)$/
|
|
64
|
+
mail.cc = $1.split(',').collect{|s| s.strip}
|
|
65
|
+
when /^Bcc: (.*)$/
|
|
66
|
+
mail.bcc = $1.split(',').collect{|s| s.strip}
|
|
67
|
+
when /^Subject: (.*)$/
|
|
68
|
+
mail.subject = $1
|
|
69
|
+
when /^Date: (.*)$/
|
|
70
|
+
mail.date = Time.rfc2822($1)
|
|
71
|
+
when /^MIME-Version: (.*)$/
|
|
72
|
+
mail.mime_version = $1
|
|
73
|
+
when /^Content-type: (.*); charset=(.*)$/
|
|
74
|
+
mail.content_type = $1
|
|
75
|
+
mail.charset = $2
|
|
76
|
+
when /^$/
|
|
77
|
+
break
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
mail.body = lines.join("\n")
|
|
81
|
+
mail
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
alias :parse :decode
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Returns a valid mail string instantiation
|
|
88
|
+
def to_s
|
|
89
|
+
str = <<-MAIL_END
|
|
90
|
+
From: #{from}
|
|
91
|
+
To: #{to.nil? ? '' : to.join(", ")}
|
|
92
|
+
Cc: #{cc.nil? ? '' : cc.join(", ")}
|
|
93
|
+
Bcc: #{bcc.nil? ? '' : bcc.join(", ")}
|
|
94
|
+
Subject: #{subject}
|
|
95
|
+
Date: #{date.rfc2822}
|
|
96
|
+
MIME-Version: #{mime_version}
|
|
97
|
+
Content-type: #{content_type}; charset=#{charset}
|
|
98
|
+
|
|
99
|
+
#{body}
|
|
100
|
+
MAIL_END
|
|
101
|
+
str.gsub(/^[ \t]*/, '')
|
|
102
|
+
end
|
|
103
|
+
alias :encode :to_s
|
|
104
|
+
alias :dump :to_s
|
|
105
|
+
|
|
106
|
+
# Makes a deep copy of this mail. Changing the list of receivers
|
|
107
|
+
# in particular does not affect the original mail
|
|
108
|
+
def dup
|
|
109
|
+
mail = super
|
|
110
|
+
mail.to = to.nil? ? nil : to.dup
|
|
111
|
+
mail.cc = cc.nil? ? nil : cc.dup
|
|
112
|
+
mail.bcc = bcc.nil? ? nil : bcc.dup
|
|
113
|
+
mail
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
end # class Mail
|
|
117
|
+
end # class MailAgent
|
|
118
|
+
end # module Tools
|
|
119
|
+
end # module Waw
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
module Waw
|
|
2
|
+
module Tools
|
|
3
|
+
# Provides a tool to send mails simply
|
|
4
|
+
class MailAgent
|
|
5
|
+
|
|
6
|
+
# Creates a default mail agent
|
|
7
|
+
def initialize(opts = {}, force_real = false)
|
|
8
|
+
@force_real = force_real
|
|
9
|
+
if do_it_really?
|
|
10
|
+
@smtp_host = opts[:host]
|
|
11
|
+
@smtp_port = opts[:port]
|
|
12
|
+
@smtp_timeout = opts[:timeout]
|
|
13
|
+
raise ArgumentError, "Opts should include :host, :port and :timeout parameters\n#{opts.inspect} received"\
|
|
14
|
+
if @smtp_host.nil? or @smtp_port.nil? or @smtp_timeout.nil?
|
|
15
|
+
end
|
|
16
|
+
@templates = {}
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Builds a mail instance. This method should always be used preferably
|
|
20
|
+
# to an explicit Mail.new invocation.
|
|
21
|
+
def mail(*args)
|
|
22
|
+
Mail.new(*args)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Builds a template instance. This method should always be used preferably
|
|
26
|
+
# to an explicit Template.new invocation.
|
|
27
|
+
def template(*args)
|
|
28
|
+
Template.new(*args)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Adds a mail template under a given name
|
|
32
|
+
def add_template(name, *args)
|
|
33
|
+
if args.size == 1 and Template===args[0]
|
|
34
|
+
@templates[name] = args[0]
|
|
35
|
+
else
|
|
36
|
+
@templates[name] = template(*args)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Converts a named template to a mail
|
|
41
|
+
def to_mail(template_name, wlang_context)
|
|
42
|
+
raise ArgumentError, "No such template #{template_name}" unless @templates.has_key?(template_name)
|
|
43
|
+
@templates[template_name].to_mail(wlang_context)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Send mails, really?
|
|
47
|
+
def do_it_really?
|
|
48
|
+
@force_real or (Waw.config and ['production', 'acceptation'].include?(Waw.config.deploy_mode))
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Returns installed mailboxes
|
|
52
|
+
def mailboxes
|
|
53
|
+
@mailboxes ||= Hash.new{|h, k| h[k] = Mailbox.new(k)}
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Returns the mailbox of a given receiver, creating
|
|
57
|
+
# a new one if it cannot be found
|
|
58
|
+
def mailbox(receiver)
|
|
59
|
+
mailboxes[receiver]
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
#
|
|
63
|
+
# Sends an email. If Waw.config.deploy_mode is set to 'production'
|
|
64
|
+
# or 'acceptation', the mail is really sent. Otherwise it is pushed
|
|
65
|
+
# in the receiver mailbox.
|
|
66
|
+
#
|
|
67
|
+
# This method accepts the following invocation signatures:
|
|
68
|
+
#
|
|
69
|
+
# # sending a real Mail instance (and only one)
|
|
70
|
+
# agent.send_mail(mail)
|
|
71
|
+
#
|
|
72
|
+
# # sending from a template for which receivers have been already set
|
|
73
|
+
# agent.send_mail(:my_template, {:title => "Hello"})
|
|
74
|
+
#
|
|
75
|
+
# # sending from a template, with explicit receivers as varargs
|
|
76
|
+
# agent.send_mail(:my_template, {:title => "Hello"}, "receiver@example.com", ..., "receiver_N@example.com")
|
|
77
|
+
#
|
|
78
|
+
# # sending from a template, with explicit receivers as an array
|
|
79
|
+
# agent.send_mail(:my_template, {:title => "Hello"}, [...])
|
|
80
|
+
#
|
|
81
|
+
def send_mail(*args)
|
|
82
|
+
# Let try to match the signature
|
|
83
|
+
if args.size == 1 and Mail===args[0]
|
|
84
|
+
# first one
|
|
85
|
+
mail = args[0]
|
|
86
|
+
elsif Symbol===args[0] and Hash===args[1]
|
|
87
|
+
# the others
|
|
88
|
+
mail = to_mail(args.shift, args.shift)
|
|
89
|
+
unless args.empty?
|
|
90
|
+
if args.size == 1 and Array===args[0]
|
|
91
|
+
# third one
|
|
92
|
+
mail.to = args[0]
|
|
93
|
+
else
|
|
94
|
+
# fourth one
|
|
95
|
+
mail.to = args
|
|
96
|
+
end
|
|
97
|
+
else
|
|
98
|
+
# second one
|
|
99
|
+
end
|
|
100
|
+
else
|
|
101
|
+
raise ArgumentError, "Unable to find the send_mail sigature you want with #{args.inspect}"
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
if do_it_really?
|
|
105
|
+
require 'net/smtp'
|
|
106
|
+
smtp_conn = Net::SMTP.new(@smtp_host, @smtp_port)
|
|
107
|
+
smtp_conn.open_timeout = @smtp_timeout
|
|
108
|
+
smtp_conn.start
|
|
109
|
+
smtp_conn.send_message(mail.dump, mail.from, *mail.to)
|
|
110
|
+
smtp_conn.finish
|
|
111
|
+
else
|
|
112
|
+
Waw.logger.debug mail.dump
|
|
113
|
+
sent = Mail.parse(mail.dump)
|
|
114
|
+
mail.to.each {|who| mailbox(who) << sent.dup}
|
|
115
|
+
mail.cc.each {|who| mailbox(who) << sent.dup}
|
|
116
|
+
mail.bcc.each {|who| mailbox(who) << sent.dup}
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
alias :<< :send_mail
|
|
120
|
+
|
|
121
|
+
end # class MailAgent
|
|
122
|
+
end # module Tools
|
|
123
|
+
end # module Waw
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
module Waw
|
|
2
|
+
module Tools
|
|
3
|
+
class MailAgent
|
|
4
|
+
# Helper for testing purposes only.
|
|
5
|
+
class Mailbox
|
|
6
|
+
|
|
7
|
+
# Creates an empty mailbox for a given adress
|
|
8
|
+
def initialize(mail_address)
|
|
9
|
+
@mail_address = mail_address
|
|
10
|
+
@mails = []
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Returns the number of mails in this mailbox
|
|
14
|
+
def size
|
|
15
|
+
@mails.size
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Checks if the mailbox is empty or not
|
|
19
|
+
def empty?
|
|
20
|
+
@mails.empty?
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Pushes a mail inside the mailbox, returns an id
|
|
24
|
+
def push(mail)
|
|
25
|
+
@mails << [mail, false]
|
|
26
|
+
@mails.size-1
|
|
27
|
+
end
|
|
28
|
+
alias :<< :push
|
|
29
|
+
|
|
30
|
+
# Returns the id-th mail in the mailbox. Returns nil
|
|
31
|
+
# if no such mail can be found
|
|
32
|
+
def [](id)
|
|
33
|
+
mail = @mails[id]
|
|
34
|
+
return nil unless mail
|
|
35
|
+
mail[0]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Checks if a mail is marked as read. Returns nil
|
|
39
|
+
# if no such mail can be found
|
|
40
|
+
def is_read?(id)
|
|
41
|
+
mail = @mails[id]
|
|
42
|
+
return nil unless mail
|
|
43
|
+
mail[1]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Marks a mail as read and returns it
|
|
47
|
+
def read(id)
|
|
48
|
+
mail = @mails[id]
|
|
49
|
+
return nil unless mail
|
|
50
|
+
mail[1] = true
|
|
51
|
+
mail[0]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Removes all mails
|
|
55
|
+
def clear
|
|
56
|
+
@mails.clear
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end # class Mailbox
|
|
60
|
+
end # class MailAgent
|
|
61
|
+
end # module Tools
|
|
62
|
+
end # module Waw
|