mack-notifier 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +34 -0
- data/lib/mack-notifier/adapters/base.rb +24 -0
- data/lib/mack-notifier/adapters/tmail.rb +69 -0
- data/lib/mack-notifier/attachment.rb +38 -0
- data/lib/mack-notifier/configs/sendmail_settings.yml +3 -0
- data/lib/mack-notifier/configs/smtp_settings.yml +7 -0
- data/lib/mack-notifier/delivery_handlers/sendmail.rb +21 -0
- data/lib/mack-notifier/delivery_handlers/smtp.rb +21 -0
- data/lib/mack-notifier/delivery_handlers/test.rb +17 -0
- data/lib/mack-notifier/errors.rb +11 -0
- data/lib/mack-notifier/loader.rb +7 -0
- data/lib/mack-notifier/notifier.rb +164 -0
- data/lib/mack-notifier/notifier_generator/manifest.yml +23 -0
- data/lib/mack-notifier/notifier_generator/notifier_generator.rb +23 -0
- data/lib/mack-notifier/notifier_generator/templates/app/notifiers/html.erb.template +2 -0
- data/lib/mack-notifier/notifier_generator/templates/app/notifiers/notifier.rb.template +3 -0
- data/lib/mack-notifier/notifier_generator/templates/app/notifiers/plain.erb.template +2 -0
- data/lib/mack-notifier/notifier_generator/templates/test/notifiers/rspec.rb.template +7 -0
- data/lib/mack-notifier/notifier_generator/templates/test/notifiers/test_case.rb.template +9 -0
- data/lib/mack-notifier/paths.rb +20 -0
- data/lib/mack-notifier/rendering/type/mailer.rb +16 -0
- data/lib/mack-notifier/settings.rb +15 -0
- data/lib/mack-notifier/testing.rb +47 -0
- data/lib/mack-notifier/validations.rb +104 -0
- data/lib/mack-notifier.rb +25 -0
- metadata +97 -0
data/README
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
This gem provides a simple API for creating emails within a Mack application.
|
2
|
+
|
3
|
+
A simple Mack::Notifier model would look like this:
|
4
|
+
|
5
|
+
class WelcomeEmail
|
6
|
+
include Mack::Notifier
|
7
|
+
end
|
8
|
+
|
9
|
+
To use this in your application you would do something like the following:
|
10
|
+
|
11
|
+
mail = WelcomeEmail.new
|
12
|
+
mail.to = "foo@example.com"
|
13
|
+
mail.from = "me@example.com"
|
14
|
+
mail.subject = "Hello"
|
15
|
+
mail.body(:plain, "This is my plain text body")
|
16
|
+
mail.body(:html, "This is my <b>HTML</b> body")
|
17
|
+
mail.attach(Mack::Notifier::Attachment.new("/path/to/my/image_file.png"))
|
18
|
+
mail.attach(Mack::Notifier::Attachment.new("/path/to/my/pdf_file.pdf"))
|
19
|
+
mail.deliver
|
20
|
+
|
21
|
+
This gem currently has an adapter for TMail, but it can support any mailing
|
22
|
+
framework under the covers with the creation of a simple adapter class.
|
23
|
+
|
24
|
+
Currently implemented delivery handlers are: SMTP (default), sendmail, and test.
|
25
|
+
|
26
|
+
== Testing
|
27
|
+
|
28
|
+
When testing you can get access to delivered emails with the delivered_emails
|
29
|
+
method. After each tests these emails will be flushed our of the test handler.
|
30
|
+
|
31
|
+
== Rake tasks
|
32
|
+
|
33
|
+
# Generates a notifier model, a test, and text and html template files.
|
34
|
+
rake generate:notifier
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Mack
|
2
|
+
module Notifier
|
3
|
+
module Adapters # :nodoc:
|
4
|
+
# All mail adapters need to extend this class.
|
5
|
+
class Base
|
6
|
+
|
7
|
+
# The origina Mack::Notifier object passed in.
|
8
|
+
attr_accessor :mack_notifier
|
9
|
+
|
10
|
+
def initialize(mail) # :nodoc:
|
11
|
+
self.mack_notifier = mail
|
12
|
+
end
|
13
|
+
|
14
|
+
# The transformed (ie, converted, object)
|
15
|
+
needs_method :transformed
|
16
|
+
# Convert the Mack::Notifier object to the adapted object.
|
17
|
+
needs_method :convert
|
18
|
+
# The RAW encoded String ready for delivery via SMTP, Sendmail, etc...
|
19
|
+
needs_method :deliverable
|
20
|
+
|
21
|
+
end # Base
|
22
|
+
end # Adapters
|
23
|
+
end # Notifier
|
24
|
+
end # Mack
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "base")
|
2
|
+
require 'base64'
|
3
|
+
module Mack
|
4
|
+
module Notifier
|
5
|
+
module Adapters # :nodoc:
|
6
|
+
# Converts a Mack::Notifier object into a TMail object.
|
7
|
+
class Tmail < Mack::Notifier::Adapters::Base
|
8
|
+
|
9
|
+
# Returns the underlying TMail object.
|
10
|
+
# Raises Mack::Errors::UnconvertedNotifier if the convert method hasn't
|
11
|
+
# been called first.
|
12
|
+
def transformed
|
13
|
+
raise Mack::Errors::UnconvertedNotifier.new if @tmail.nil?
|
14
|
+
@tmail
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns the ready to be delivered encoded String
|
18
|
+
def deliverable
|
19
|
+
transformed.encoded
|
20
|
+
end
|
21
|
+
|
22
|
+
# Converts the Mack::Notifier object to a TMail object.
|
23
|
+
def convert
|
24
|
+
@tmail = TMail::Mail.new
|
25
|
+
@tmail.to = mack_notifier.to
|
26
|
+
@tmail.cc = mack_notifier.cc
|
27
|
+
@tmail.bcc = mack_notifier.bcc
|
28
|
+
@tmail.reply_to = mack_notifier.reply_to
|
29
|
+
@tmail.from = mack_notifier.from
|
30
|
+
@tmail.subject = mack_notifier.subject
|
31
|
+
@tmail.date = mack_notifier.date_sent
|
32
|
+
@tmail.mime_version = mack_notifier.mime_version
|
33
|
+
|
34
|
+
# set text and html bodies
|
35
|
+
main_body = TMail::Mail.new
|
36
|
+
unless mack_notifier.body(:plain).blank?
|
37
|
+
text = TMail::Mail.new
|
38
|
+
text.content_type = "text/plain"
|
39
|
+
text.body = mack_notifier.body(:plain)
|
40
|
+
main_body.parts << text
|
41
|
+
end
|
42
|
+
unless mack_notifier.body(:html).blank?
|
43
|
+
html = TMail::Mail.new
|
44
|
+
html.content_type = "text/html"
|
45
|
+
html.body = mack_notifier.body(:html)
|
46
|
+
main_body.parts << html
|
47
|
+
end
|
48
|
+
unless main_body.parts.empty?
|
49
|
+
main_body.content_type = "multipart/alternative"
|
50
|
+
@tmail.parts << main_body
|
51
|
+
end
|
52
|
+
|
53
|
+
# set attachments, if any.
|
54
|
+
mack_notifier.attachments.each do |at|
|
55
|
+
attachment = TMail::Mail.new
|
56
|
+
attachment.body = Base64.encode64(at.body)
|
57
|
+
attachment.transfer_encoding = "Base64"
|
58
|
+
attachment.content_type = "application/octet-stream"
|
59
|
+
attachment['Content-Disposition'] = "attachment; filename=#{at.file_name}"
|
60
|
+
@tmail.parts << attachment
|
61
|
+
end
|
62
|
+
|
63
|
+
@tmail.content_type = mack_notifier.content_type
|
64
|
+
end
|
65
|
+
|
66
|
+
end # Tmail
|
67
|
+
end # Adapters
|
68
|
+
end # Notifier
|
69
|
+
end # Mack
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Mack
|
2
|
+
module Notifier
|
3
|
+
# Creates an attachment for a Mack::Notifier object.
|
4
|
+
class Attachment
|
5
|
+
|
6
|
+
# Returns a String representing the body of the attachment. This String is NOT encoded in anyway!
|
7
|
+
attr_accessor :body
|
8
|
+
# Returns the name of the attached file.
|
9
|
+
attr_accessor :file_name
|
10
|
+
|
11
|
+
def initialize(body = nil)
|
12
|
+
unless body.nil?
|
13
|
+
self.add_file(body) if body.is_a?(String)
|
14
|
+
self.add_io(body) if body.is_a?(IO)
|
15
|
+
self.add_uploaded_file(body) if body.is_a?(Mack::Request::UploadedFile)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Takes an IO object and sets the body. You'll need to explicity set the file_name afterwards.
|
20
|
+
def add_io(io)
|
21
|
+
self.body = io.read
|
22
|
+
end
|
23
|
+
|
24
|
+
# Takes a path to a file, reads it in, and sets the file_name based on the path.
|
25
|
+
def add_file(file)
|
26
|
+
self.file_name = File.basename(file)
|
27
|
+
self.body = File.read(file)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Takes a Mack::Request::UploadedFile file object, reads it in, and sets the file name.
|
31
|
+
def add_uploaded_file(file)
|
32
|
+
self.body = File.read(file.temp_file.path)
|
33
|
+
self.file_name = file.file_name
|
34
|
+
end
|
35
|
+
|
36
|
+
end # Attachment
|
37
|
+
end # Notifier
|
38
|
+
end # Mack
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Mack
|
2
|
+
module Notifier
|
3
|
+
module DeliveryHandlers # :nodoc:
|
4
|
+
# Delivers Mack::Notifier objects using sendmail.
|
5
|
+
module SendMail
|
6
|
+
|
7
|
+
def self.deliver(mail)
|
8
|
+
sendmail_settings = app_config.notifier.sendmail_settings
|
9
|
+
sendmail_settings.symbolize_keys!
|
10
|
+
sendmail_args = sendmail_settings[:arguments]
|
11
|
+
sendmail_args += " -f \"#{mail.reply_to}\"" if mail.reply_to
|
12
|
+
IO.popen("#{sendmail_settings[:location]} #{sendmail_args}","w+") do |sm|
|
13
|
+
sm.print(mail.deliverable.gsub(/\r/, ''))
|
14
|
+
sm.flush
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end # SendMail
|
19
|
+
end # DeliveryHandlers
|
20
|
+
end # Notifier
|
21
|
+
end # Mack
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'net/smtp'
|
2
|
+
module Mack
|
3
|
+
module Notifier
|
4
|
+
module DeliveryHandlers # :nodoc:
|
5
|
+
# Delivers Mack::Notifier objects using Net::SMTP.
|
6
|
+
module Smtp
|
7
|
+
|
8
|
+
def self.deliver(mail)
|
9
|
+
smtp_settings = app_config.notifier.smtp_settings
|
10
|
+
smtp_settings.symbolize_keys!
|
11
|
+
Net::SMTP.start(smtp_settings[:address], smtp_settings[:port],
|
12
|
+
smtp_settings[:domain], smtp_settings[:user_name],
|
13
|
+
smtp_settings[:password], smtp_settings[:authentication]) do |smtp|
|
14
|
+
smtp.sendmail(mail.deliverable, mail.reply_to, mail.recipients)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end # Smtp
|
19
|
+
end # DeliveryHandlers
|
20
|
+
end # Notifier
|
21
|
+
end # Mack
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Mack
|
2
|
+
module Notifier
|
3
|
+
module DeliveryHandlers # :nodoc:
|
4
|
+
# Delivers Mack::Notifier objects to an Array.
|
5
|
+
module Test
|
6
|
+
|
7
|
+
def self.deliver(mail)
|
8
|
+
EmailRegistry.add(mail)
|
9
|
+
end
|
10
|
+
|
11
|
+
class EmailRegistry < Mack::Utils::RegistryList # :nodoc:
|
12
|
+
end
|
13
|
+
|
14
|
+
end # Test
|
15
|
+
end # DeliveryHandlers
|
16
|
+
end # Notifier
|
17
|
+
end # Mack
|
@@ -0,0 +1,164 @@
|
|
1
|
+
module Mack # :nodoc:
|
2
|
+
# The heart and soul of the mack-notifier package.
|
3
|
+
module Notifier
|
4
|
+
|
5
|
+
attr_accessor :to
|
6
|
+
attr_accessor :cc
|
7
|
+
attr_accessor :bcc
|
8
|
+
attr_accessor :from
|
9
|
+
attr_accessor :reply_to
|
10
|
+
attr_accessor :subject
|
11
|
+
attr_accessor :date_sent
|
12
|
+
attr_accessor :mime_version
|
13
|
+
attr_accessor :content_type
|
14
|
+
|
15
|
+
# A helper method that takes a Hash and will populate the notification with the key/value pairs of that Hash.
|
16
|
+
# Use body_* to set a body part.
|
17
|
+
def build(options = {})
|
18
|
+
options.each do |k,v|
|
19
|
+
k = k.to_s
|
20
|
+
unless k.match(/^body_/)
|
21
|
+
self.send("#{k}=", v)
|
22
|
+
else
|
23
|
+
k.gsub!("body_", "")
|
24
|
+
self.body(k, v)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# If called with two parameters it will set the value of the body type to the second parameter.
|
30
|
+
#
|
31
|
+
# Example:
|
32
|
+
# body(:plain, "hello") # => sets the 'plain' body to "hello"
|
33
|
+
#
|
34
|
+
# If called with just one parameter it will return the value of that body type. If the value is nil
|
35
|
+
# the template for that body type will be rendered.
|
36
|
+
#
|
37
|
+
# Example:
|
38
|
+
# body(:plain) # => "hello"
|
39
|
+
# body(:html) # => will call the html.erb template for this notifier.
|
40
|
+
def body(part, value = nil)
|
41
|
+
part = part.to_sym
|
42
|
+
if value.nil?
|
43
|
+
body = bodies[part]
|
44
|
+
if body.blank?
|
45
|
+
bodies[part] = build_template(part)
|
46
|
+
return bodies[part]
|
47
|
+
else
|
48
|
+
return body
|
49
|
+
end
|
50
|
+
else
|
51
|
+
bodies[part] = value
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns the mime_version of the notification, defaults to "1.0"
|
56
|
+
def mime_version
|
57
|
+
(@mime_version ||= "1.0")
|
58
|
+
end
|
59
|
+
|
60
|
+
# This will attempt to determine the content type of the notification, unless one is already specified.
|
61
|
+
def content_type
|
62
|
+
return @content_type unless @content_type.blank?
|
63
|
+
if has_attachments?
|
64
|
+
return "multipart/mixed"
|
65
|
+
elsif !body(:plain).blank? && !body(:html).blank?
|
66
|
+
return "multipart/alternative"
|
67
|
+
elsif body(:html)
|
68
|
+
return "text/html"
|
69
|
+
else
|
70
|
+
return "text/plain"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Returns the date sent, defaults to Time.now
|
75
|
+
def date_sent
|
76
|
+
(@date_sent ||= Time.now)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Returns the reply to address, defaults to the from address.
|
80
|
+
def reply_to
|
81
|
+
(@reply_to || self.from)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Adds a Mack::Notifier::Attachment to the notifier.
|
85
|
+
# Raise ArgumentError if the parameter is not a Mack::Notifier::Attachment
|
86
|
+
def attach(file)
|
87
|
+
raise ArgumentError.new unless file.is_a?(Mack::Notifier::Attachment)
|
88
|
+
attachments << file
|
89
|
+
end
|
90
|
+
|
91
|
+
# Returns true if there are attachments.
|
92
|
+
def has_attachments?
|
93
|
+
!attachments.empty?
|
94
|
+
end
|
95
|
+
|
96
|
+
# Returns the attachments Array.
|
97
|
+
def attachments
|
98
|
+
@attachments ||= []
|
99
|
+
end
|
100
|
+
|
101
|
+
# Delivers the notification with the configured Mack::Notifier::DeliveryHandlers class.
|
102
|
+
# Returns false if there are any errors.
|
103
|
+
def deliver(handler = deliver_with)
|
104
|
+
begin
|
105
|
+
deliver!(handler)
|
106
|
+
rescue Exception => e
|
107
|
+
return false
|
108
|
+
end
|
109
|
+
return true
|
110
|
+
end
|
111
|
+
|
112
|
+
# Delivers the email with the configured Mack::Notifier::DeliveryHandlers class.
|
113
|
+
def deliver!(handler = deliver_with)
|
114
|
+
"Mack::Notifier::DeliveryHandlers::#{handler.to_s.camelcase}".constantize.deliver(self)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Returns all the recipients of this notifier.
|
118
|
+
def recipients
|
119
|
+
[self.to, self.cc, self.bcc].flatten.compact
|
120
|
+
end
|
121
|
+
|
122
|
+
# Returns a ready to be delivered, encoded, version of the notification.
|
123
|
+
def deliverable(adap = adapter)
|
124
|
+
adap = "Mack::Notifier::Adapters::#{adap.to_s.camelcase}".constantize.new(self)
|
125
|
+
adap.convert
|
126
|
+
adap.deliverable
|
127
|
+
end
|
128
|
+
|
129
|
+
# This method returns the adapter that will transform the Mack::Notifier object
|
130
|
+
# and prepare it for delivery. This method returns the app_config.notifier.adapter
|
131
|
+
# parameter. Override this in your Mack::Notifier class to specify a different adapter
|
132
|
+
# or change the app_config parameter to globally affect all your Notifiers.
|
133
|
+
#
|
134
|
+
# Default: :tmail
|
135
|
+
def adapter
|
136
|
+
app_config.notifier.adapter
|
137
|
+
end
|
138
|
+
|
139
|
+
# This method returns the delivery handler that will delivers the Mack::Notifier object.
|
140
|
+
# This method returns the app_config.notifier.deliver_with parameter. Override this in
|
141
|
+
# your Mack::Notifier class to specify a different handler or change the app_config
|
142
|
+
# parameter to globally affect all your Notifiers.
|
143
|
+
#
|
144
|
+
# Default: :sendmail
|
145
|
+
def deliver_with
|
146
|
+
app_config.notifier.deliver_with
|
147
|
+
end
|
148
|
+
|
149
|
+
private
|
150
|
+
def bodies
|
151
|
+
@bodies ||= {}
|
152
|
+
end
|
153
|
+
|
154
|
+
def build_template(format)
|
155
|
+
begin
|
156
|
+
vt = Mack::Rendering::ViewTemplate.new(:notifier, self.class.to_s.underscore, {:locals => {:notifier => self}, :format => format.to_s})
|
157
|
+
return vt.compile_and_render
|
158
|
+
rescue Mack::Errors::ResourceNotFound => e
|
159
|
+
end
|
160
|
+
return nil
|
161
|
+
end
|
162
|
+
|
163
|
+
end # Notifier
|
164
|
+
end # Mack
|
@@ -0,0 +1,23 @@
|
|
1
|
+
notifier_template:
|
2
|
+
type: file
|
3
|
+
template_path: <%= File.join(templates_directory_path, "app", "notifiers", "notifier.rb.template") %>
|
4
|
+
output_path: <%= File.join("app", "notifiers", "#{file_name}.rb") %>
|
5
|
+
text_template:
|
6
|
+
type: file
|
7
|
+
template_path: <%= File.join(templates_directory_path, "app", "notifiers", "plain.erb.template") %>
|
8
|
+
output_path: <%= File.join("app", "notifiers", "templates", file_name, "plain.erb") %>
|
9
|
+
html_template:
|
10
|
+
type: file
|
11
|
+
template_path: <%= File.join(templates_directory_path, "app", "notifiers", "html.erb.template") %>
|
12
|
+
output_path: <%= File.join("app", "notifiers", "templates", file_name, "html.erb") %>
|
13
|
+
<% if app_config.mack.testing_framework == "test_case" -%>
|
14
|
+
test_template:
|
15
|
+
type: file
|
16
|
+
template_path: <%= File.join(templates_directory_path, "test", "notifiers", "test_case.rb.template") %>
|
17
|
+
output_path: <%= File.join("test", "notifiers", "#{file_name}_test.rb") %>
|
18
|
+
<% elsif app_config.mack.testing_framework == "rspec" -%>
|
19
|
+
test_template:
|
20
|
+
type: file
|
21
|
+
template_path: <%= File.join(templates_directory_path, "test", "notifiers", "rspec.rb.template") %>
|
22
|
+
output_path: <%= File.join("test", "notifiers", "#{file_name}_spec.rb") %>
|
23
|
+
<% end -%>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Generates the necessary files for a basic notifier.
|
2
|
+
#
|
3
|
+
# Example:
|
4
|
+
# rake generate:notifier name=welcome_email
|
5
|
+
# generates the following files:
|
6
|
+
# app/notifiers/welcome_email.rb
|
7
|
+
# app/notifiers/templates/welcome_email/text.erb
|
8
|
+
# app/notifiers/templates/welcome_email/html.erb
|
9
|
+
# test/unit/welcome_email_spec.rb # => if using RSpec
|
10
|
+
# test/unit/welcome_email_test.rb # => if using Test::Unit::TestCase
|
11
|
+
class NotifierGenerator < Genosaurus
|
12
|
+
|
13
|
+
require_param :name
|
14
|
+
|
15
|
+
def file_name # :nodoc:
|
16
|
+
param(:name).underscore.downcase
|
17
|
+
end
|
18
|
+
|
19
|
+
def class_name # :nodoc:
|
20
|
+
param(:name).camelcase
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Mack # :nodoc:
|
2
|
+
module Paths
|
3
|
+
|
4
|
+
# The path to the app/notifiers directory.
|
5
|
+
def self.notifiers(*args)
|
6
|
+
File.join(Mack.root, "app", "notifiers", args)
|
7
|
+
end
|
8
|
+
|
9
|
+
# The path to the app/notifiers/templates directory.
|
10
|
+
def self.notifier_templates(*args)
|
11
|
+
Mack::Paths.notifiers("templates", args)
|
12
|
+
end
|
13
|
+
|
14
|
+
# The path the test/notifiers directory
|
15
|
+
def self.notifier_tests(*args)
|
16
|
+
File.join(Mack.root, "test", "notifiers", args)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Mack
|
2
|
+
module Rendering # :nodoc:
|
3
|
+
module Type # :nodoc:
|
4
|
+
class Notifier < Mack::Rendering::Type::FileBase # :nodoc:
|
5
|
+
|
6
|
+
def render
|
7
|
+
x_file = Mack::Paths.notifier_templates(self.render_value, self.options[:format])
|
8
|
+
render_file(x_file)
|
9
|
+
end
|
10
|
+
|
11
|
+
end # Notifier
|
12
|
+
end # Type
|
13
|
+
end # Rendering
|
14
|
+
end # Mack
|
15
|
+
|
16
|
+
Mack::Rendering::Engine::Registry.instance.register(:notifier, :erb)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
if app_config.notifier.nil? || app_config.notifier.smtp_settings.nil?
|
2
|
+
app_config.load_file(File.join(File.dirname(__FILE__), "configs", "smtp_settings.yml"))
|
3
|
+
end
|
4
|
+
|
5
|
+
if app_config.notifier.nil? || app_config.notifier.sendmail_settings.nil?
|
6
|
+
app_config.load_file(File.join(File.dirname(__FILE__), "configs", "sendmail_settings.yml"))
|
7
|
+
end
|
8
|
+
|
9
|
+
if app_config.notifier.nil? || app_config.notifier.deliver_with.nil?
|
10
|
+
app_config.load_hash({"notifier::deliver_with" => (Mack.env == "test" ? "test" : "smtp")}, String.randomize)
|
11
|
+
end
|
12
|
+
|
13
|
+
if app_config.notifier.nil? || app_config.notifier.adapter.nil?
|
14
|
+
app_config.load_hash({"notifier::adapter" => "tmail"}, String.randomize)
|
15
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
if Mack.env == "test"
|
2
|
+
|
3
|
+
# Used for testing this method will return any emails that have been 'sent' using Mack::Notifier::DeliveryHandlers::Test.
|
4
|
+
# These emails will get 'flushed' after each test.
|
5
|
+
def delivered_emails
|
6
|
+
Mack::Notifier::DeliveryHandlers::Test::EmailRegistry.registered_items
|
7
|
+
end
|
8
|
+
|
9
|
+
module Spec # :nodoc:
|
10
|
+
module Example # :nodoc:
|
11
|
+
module ExampleMethods # :nodoc:
|
12
|
+
include Mack::Routes::Urls
|
13
|
+
include Mack::Testing::Helpers
|
14
|
+
|
15
|
+
alias_method :email_spec_execute, :execute
|
16
|
+
|
17
|
+
def execute(options, instance_variables)
|
18
|
+
@__res = email_spec_execute(options, instance_variables)
|
19
|
+
Mack::Notifier::DeliveryHandlers::Test::EmailRegistry.reset!
|
20
|
+
@__res
|
21
|
+
end
|
22
|
+
|
23
|
+
end # ExampleMethods
|
24
|
+
end # Example
|
25
|
+
end # Spec
|
26
|
+
|
27
|
+
module Test # :nodoc:
|
28
|
+
module Unit # :nodoc:
|
29
|
+
class TestCase # :nodoc:
|
30
|
+
|
31
|
+
# Let's alias the run method in the class above us so we can create a new one here
|
32
|
+
# but still reference it.
|
33
|
+
alias_method :super_run, :run # :nodoc:
|
34
|
+
|
35
|
+
# We need to wrap the run method so we can do things like
|
36
|
+
# run a cleanup method if it exists
|
37
|
+
def run(result, &progress_block) # :nodoc:
|
38
|
+
@__res = super_run(result)
|
39
|
+
Mack::Notifier::DeliveryHandlers::Test::EmailRegistry.reset!
|
40
|
+
@__res
|
41
|
+
end
|
42
|
+
|
43
|
+
end # TestCase
|
44
|
+
end # Unit
|
45
|
+
end # Test
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module Mack
|
2
|
+
module Notifier
|
3
|
+
# Includes the validatable gem into your Notifier.
|
4
|
+
# http://validatable.rubyforge.org
|
5
|
+
module Validatable
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
base.instance_eval do
|
9
|
+
include ::Validatable
|
10
|
+
alias_method "unvalidated_deliver!", "deliver!"
|
11
|
+
end
|
12
|
+
|
13
|
+
base.class_eval do
|
14
|
+
|
15
|
+
class << self
|
16
|
+
|
17
|
+
# Alias the Validatable methods to look like DataMapper methods,
|
18
|
+
# if that's the kind of thing you're used to. :)
|
19
|
+
alias_method :validates_is_accepted, :validates_acceptance_of
|
20
|
+
alias_method :validates_is_confirmed, :validates_confirmation_of
|
21
|
+
alias_method :validates_format, :validates_format_of
|
22
|
+
alias_method :validates_length, :validates_length_of
|
23
|
+
alias_method :validates_is_number, :validates_numericality_of
|
24
|
+
alias_method :validates_present, :validates_presence_of
|
25
|
+
|
26
|
+
# Adds common validations to your Mack::Notifier class.
|
27
|
+
# These include:
|
28
|
+
# validates_presence_of :to
|
29
|
+
# validates_presence_of :from
|
30
|
+
# validates_presence_of :subject
|
31
|
+
# validates_email_format_of :to
|
32
|
+
# validates_email_format_of :from
|
33
|
+
def common_notifier_validations
|
34
|
+
validates_presence_of :to
|
35
|
+
validates_presence_of :from
|
36
|
+
validates_presence_of :subject
|
37
|
+
validates_email_format_of :to
|
38
|
+
validates_email_format_of :from
|
39
|
+
end
|
40
|
+
|
41
|
+
# Validates the email format of the column specified against the email_validation_regex method.
|
42
|
+
# This will drill into arrays as well, if that's what your column is.
|
43
|
+
def validates_email_format_of(column, options = {})
|
44
|
+
options = {:logic => lambda{
|
45
|
+
[send(column)].flatten.each_with_index do |addr, i|
|
46
|
+
errors.add(column, "[#{addr}] is not valid") unless addr.to_s.downcase.match(self.class.email_validation_regex)
|
47
|
+
end
|
48
|
+
}}.merge(options)
|
49
|
+
validates_each :to, options
|
50
|
+
end
|
51
|
+
|
52
|
+
def email_validation_regex
|
53
|
+
regex = <<-EOF
|
54
|
+
[a-z0-9!#$\%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$\%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?
|
55
|
+
EOF
|
56
|
+
/#{regex.strip}/
|
57
|
+
end
|
58
|
+
|
59
|
+
end # class << self
|
60
|
+
end # class_eval
|
61
|
+
end # included
|
62
|
+
|
63
|
+
# Raises a RuntimeError if the email you are trying to deliver is not valid.
|
64
|
+
def deliver!(handler = deliver_with)
|
65
|
+
raise 'Notification is Invalid!' unless self.valid?
|
66
|
+
unvalidated_deliver!(handler)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Returns false if the email is not valid.
|
70
|
+
# If the email is valid and an exception is raised when trying to deliver it
|
71
|
+
# false is returned and the exception is added to the errors array, with the
|
72
|
+
# key :deliver.
|
73
|
+
def deliver(handler = deliver_with)
|
74
|
+
return false unless self.valid?
|
75
|
+
begin
|
76
|
+
"Mack::Notifier::DeliveryHandlers::#{handler.to_s.camelcase}".constantize.deliver(self)
|
77
|
+
rescue Exception => e
|
78
|
+
self.errors.add(:deliver, e.message)
|
79
|
+
return false
|
80
|
+
end
|
81
|
+
return true
|
82
|
+
end
|
83
|
+
|
84
|
+
end # Validatable
|
85
|
+
end # Notifier
|
86
|
+
end # Mack
|
87
|
+
|
88
|
+
module Validatable # :nodoc:
|
89
|
+
class ValidationBase #:nodoc:
|
90
|
+
|
91
|
+
# This fixes a bug with reloading of Validatable classes.
|
92
|
+
def raise_error_if_key_is_dup(klass) # :nodoc:
|
93
|
+
vals = {}
|
94
|
+
klass.validations.each do |v|
|
95
|
+
vals[v.key] = v
|
96
|
+
end
|
97
|
+
klass.validations.clear
|
98
|
+
vals.each do |k,v|
|
99
|
+
klass.validations << v
|
100
|
+
end
|
101
|
+
end # raise_error_if_key_is_dup
|
102
|
+
|
103
|
+
end # ValidationBase
|
104
|
+
end # Validatable
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'validatable'
|
3
|
+
require 'tmail'
|
4
|
+
|
5
|
+
fl = File.join(File.dirname(__FILE__), "mack-notifier")
|
6
|
+
|
7
|
+
require File.join(fl, "paths")
|
8
|
+
require File.join(fl, "settings")
|
9
|
+
require File.join(fl, "errors")
|
10
|
+
require File.join(fl, "attachment")
|
11
|
+
require File.join(fl, "notifier_generator", "notifier_generator")
|
12
|
+
|
13
|
+
[:delivery_handlers, :adapters, :rendering].each do |dir|
|
14
|
+
Dir.glob(File.join(fl, dir.to_s, "**/*.rb")).each do |h|
|
15
|
+
require h
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
require File.join(fl, "notifier")
|
20
|
+
|
21
|
+
require File.join(fl, "validations")
|
22
|
+
|
23
|
+
require File.join(fl, "testing")
|
24
|
+
|
25
|
+
require File.join(fl, "loader")
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mack-notifier
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.6.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mark Bates
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-08-04 00:00:00 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: tmail
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - "="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.2.3.1
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: validatable
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.6.7
|
34
|
+
version:
|
35
|
+
description: Notifier functionality for Mack applications.
|
36
|
+
email: mark@mackframework.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
files:
|
44
|
+
- lib/mack-notifier/adapters/base.rb
|
45
|
+
- lib/mack-notifier/adapters/tmail.rb
|
46
|
+
- lib/mack-notifier/attachment.rb
|
47
|
+
- lib/mack-notifier/configs/sendmail_settings.yml
|
48
|
+
- lib/mack-notifier/configs/smtp_settings.yml
|
49
|
+
- lib/mack-notifier/delivery_handlers/sendmail.rb
|
50
|
+
- lib/mack-notifier/delivery_handlers/smtp.rb
|
51
|
+
- lib/mack-notifier/delivery_handlers/test.rb
|
52
|
+
- lib/mack-notifier/errors.rb
|
53
|
+
- lib/mack-notifier/loader.rb
|
54
|
+
- lib/mack-notifier/notifier.rb
|
55
|
+
- lib/mack-notifier/notifier_generator/manifest.yml
|
56
|
+
- lib/mack-notifier/notifier_generator/notifier_generator.rb
|
57
|
+
- lib/mack-notifier/notifier_generator/templates/app/notifiers/html.erb.template
|
58
|
+
- lib/mack-notifier/notifier_generator/templates/app/notifiers/notifier.rb.template
|
59
|
+
- lib/mack-notifier/notifier_generator/templates/app/notifiers/plain.erb.template
|
60
|
+
- lib/mack-notifier/notifier_generator/templates/test/notifiers/rspec.rb.template
|
61
|
+
- lib/mack-notifier/notifier_generator/templates/test/notifiers/test_case.rb.template
|
62
|
+
- lib/mack-notifier/paths.rb
|
63
|
+
- lib/mack-notifier/rendering/type/mailer.rb
|
64
|
+
- lib/mack-notifier/settings.rb
|
65
|
+
- lib/mack-notifier/testing.rb
|
66
|
+
- lib/mack-notifier/validations.rb
|
67
|
+
- lib/mack-notifier.rb
|
68
|
+
- README
|
69
|
+
has_rdoc: true
|
70
|
+
homepage: http://www.mackframework.com
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
- lib
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: "0"
|
82
|
+
version:
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: "0"
|
88
|
+
version:
|
89
|
+
requirements: []
|
90
|
+
|
91
|
+
rubyforge_project: magrathea
|
92
|
+
rubygems_version: 1.2.0
|
93
|
+
signing_key:
|
94
|
+
specification_version: 2
|
95
|
+
summary: Notifier functionality for Mack applications.
|
96
|
+
test_files: []
|
97
|
+
|