mack-notifier 0.6.1
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/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
|
+
|