scambra-ar_mailer 2.1.6

Sign up to get free protection for your applications and to get access to all the features.
data/lib/smtp_tls.rb ADDED
@@ -0,0 +1,105 @@
1
+ # Original code believed public domain from ruby-talk or ruby-core email.
2
+ # Modifications by Kyle Maxwell <kyle@kylemaxwell.com> used under MIT license.
3
+
4
+ require "openssl"
5
+ require "net/smtp"
6
+
7
+ # :stopdoc:
8
+
9
+ class Net::SMTP
10
+
11
+ class << self
12
+ send :remove_method, :start
13
+ end
14
+
15
+ def self.start( address, port = nil,
16
+ helo = 'localhost.localdomain',
17
+ user = nil, secret = nil, authtype = nil, use_tls = false,
18
+ &block) # :yield: smtp
19
+ new(address, port).start(helo, user, secret, authtype, use_tls, &block)
20
+ end
21
+
22
+ alias tls_old_start start
23
+
24
+ def start( helo = 'localhost.localdomain',
25
+ user = nil, secret = nil, authtype = nil, use_tls = false ) # :yield: smtp
26
+ start_method = use_tls ? :do_tls_start : :do_start
27
+ if block_given?
28
+ begin
29
+ send start_method, helo, user, secret, authtype
30
+ return yield(self)
31
+ ensure
32
+ do_finish
33
+ end
34
+ else
35
+ send start_method, helo, user, secret, authtype
36
+ return self
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def do_tls_start(helodomain, user, secret, authtype)
43
+ raise IOError, 'SMTP session already started' if @started
44
+ check_auth_args user, secret, authtype if user or secret
45
+
46
+ sock = timeout(@open_timeout) { TCPSocket.open(@address, @port) }
47
+ @socket = Net::InternetMessageIO.new(sock)
48
+ @socket.read_timeout = 60 #@read_timeout
49
+ @socket.debug_output = STDERR #@debug_output
50
+
51
+ check_response(critical { recv_response() })
52
+ do_helo(helodomain)
53
+
54
+ raise 'openssl library not installed' unless defined?(OpenSSL)
55
+ starttls
56
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
57
+ ssl.sync_close = true
58
+ ssl.connect
59
+ @socket = Net::InternetMessageIO.new(ssl)
60
+ @socket.read_timeout = 60 #@read_timeout
61
+ @socket.debug_output = STDERR #@debug_output
62
+ do_helo(helodomain)
63
+
64
+ authenticate user, secret, authtype if user
65
+ @started = true
66
+ ensure
67
+ unless @started
68
+ # authentication failed, cancel connection.
69
+ @socket.close if not @started and @socket and not @socket.closed?
70
+ @socket = nil
71
+ end
72
+ end
73
+
74
+ def do_helo(helodomain)
75
+ begin
76
+ if @esmtp
77
+ ehlo helodomain
78
+ else
79
+ helo helodomain
80
+ end
81
+ rescue Net::ProtocolError
82
+ if @esmtp
83
+ @esmtp = false
84
+ @error_occured = false
85
+ retry
86
+ end
87
+ raise
88
+ end
89
+ end
90
+
91
+ def starttls
92
+ getok('STARTTLS')
93
+ end
94
+
95
+ alias tls_old_quit quit
96
+
97
+ def quit
98
+ begin
99
+ getok('QUIT')
100
+ rescue EOFError
101
+ end
102
+ end
103
+
104
+ end unless Net::SMTP.private_method_defined? :do_tls_start or
105
+ Net::SMTP.method_defined? :tls?
@@ -0,0 +1,30 @@
1
+ #!/bin/sh
2
+ # PROVIDE: ar_sendmail
3
+ # REQUIRE: DAEMON
4
+ # BEFORE: LOGIN
5
+ # KEYWORD: FreeBSD shutdown
6
+
7
+ #
8
+ # Add the following lines to /etc/rc.conf to enable ar_sendmail:
9
+ #
10
+ #ar_sendmail_enable="YES"
11
+
12
+ . /etc/rc.subr
13
+
14
+ name="ar_sendmail"
15
+ rcvar=`set_rcvar`
16
+
17
+ command="/usr/local/bin/ar_sendmail"
18
+ command_interpreter="/usr/local/bin/ruby18"
19
+
20
+ # set defaults
21
+
22
+ ar_sendmail_rails_env=${ar_sendmail_rails_env:-"production"}
23
+ ar_sendmail_chdir=${ar_sendmail_chdir:-"/"}
24
+ ar_sendmail_enable=${ar_sendmail_enable:-"NO"}
25
+ ar_sendmail_flags=${ar_sendmail_flags:-"-d"}
26
+
27
+ load_rc_config $name
28
+ export RAILS_ENV=$ar_sendmail_rails_env
29
+ run_rc_command "$1"
30
+
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # ar_sendmail Startup script for ar_mailer by Adam Meehan
4
+ #
5
+ # chkconfig: - 85 15
6
+ # description: ar_sendmail manages sending emails for Rails apps.
7
+ #
8
+ require 'yaml'
9
+
10
+ # Config file app mailers
11
+ config_file = '/etc/ar_sendmail.conf'
12
+
13
+ begin
14
+ config = YAML::load(IO.read(config_file)) || {}
15
+ if config.empty? || (config.has_key?('defaults') && config.size == 1)
16
+ puts "No mailers defined. Exiting."
17
+ exit
18
+ end
19
+ rescue Errno::ENOENT
20
+ puts "Config file not found at '#{config_file}'!"
21
+ exit
22
+ end
23
+
24
+ default_options = {'pidfile' => './log/ar_sendmail.pid'}.merge(config.delete('defaults') || {})
25
+
26
+ command, app_name = *ARGV
27
+
28
+ def start(app, options)
29
+ switches = ""
30
+ options.each {|k, v| switches << " --#{k} #{v}"}
31
+ STDOUT.write "Starting mailer for #{app} in #{options['environment']} mode ... "
32
+ status = system("ar_sendmail -d #{switches}") ? "started" : "failed"
33
+ puts status
34
+ end
35
+
36
+ def stop(app, options)
37
+ pid_file = File.expand_path(options['pidfile'], options['chdir'])
38
+ if File.exist? pid_file
39
+ begin
40
+ pid = open(pid_file).read.to_i
41
+ STDOUT.write "Stopping mailer for #{app}... "
42
+ Process.kill('TERM', pid)
43
+ puts "stopped"
44
+ rescue Errno::ESRCH
45
+ puts "Mailer process does not exist. Is not running."
46
+ end
47
+ else
48
+ puts "Skipping mailer for #{app}, no pid file."
49
+ end
50
+ end
51
+
52
+ def restart(app, options)
53
+ puts "Restarting mailer for #{app} ..."
54
+ stop app, options
55
+ start app, options
56
+ end
57
+
58
+ def command_error(msg)
59
+ puts msg
60
+ exit
61
+ end
62
+
63
+ if ['start', 'stop', 'restart'].include?(command)
64
+ apps = config
65
+ if app_name
66
+ command_error "No such app defined in ar_sendmail config" unless config.include?(app_name)
67
+ app_options = config[app_name]
68
+ command_error "Must specify chdir for app in ar_sendmail config" if app_options['chdir'].nil?
69
+ apps = {app_name => app_options}
70
+ end
71
+
72
+ apps.each do |app, options|
73
+ options = default_options.merge(options)
74
+ send(command, app, options)
75
+ end
76
+ else
77
+ command_error "Usage: ar_sendmail {start|stop|restart} [optional app_name]"
78
+ end
@@ -0,0 +1,30 @@
1
+ # This is a configuration file for ar_sendmail daemon init.d script
2
+ #
3
+ # Define the settings for each app which has a mailer that you want start
4
+ # automatically on startup.
5
+ #
6
+ # You can define an optional defaults section which will apply to all
7
+ # applications unless the setting is specified under the applications specific
8
+ # config.
9
+ #
10
+ # Settings not specified in either the defaults or app config section will
11
+ # be implied by the gem binary defaults. The option names are the same as the
12
+ # long format binary option switches. Run 'ar_sendmail -h' to see option switches
13
+ # and default values.
14
+ #
15
+ # Copy this file to /etc/ar_sendmail.conf and it will be read by the init.d
16
+ # script.
17
+ #
18
+
19
+ ## Demo app config
20
+ #
21
+ #defaults:
22
+ # batch-size: 10
23
+ # max-age: 0
24
+ # delay: 60
25
+ #
26
+ #app_name:
27
+ # chdir: /var/www/apps/app_name
28
+ # environment: production
29
+ # pidfile: ./log/ar_sendmail.pid
30
+
@@ -0,0 +1,197 @@
1
+ require 'net/smtp'
2
+ require 'smtp_tls' unless Net::SMTP.instance_methods.include?("enable_starttls_auto")
3
+ require 'time'
4
+
5
+ class Net::SMTP
6
+
7
+ @reset_called = 0
8
+
9
+ @deliveries = []
10
+
11
+ @send_message_block = nil
12
+
13
+ @start_block = nil
14
+
15
+ class << self
16
+
17
+ attr_reader :deliveries
18
+ attr_reader :send_message_block
19
+ attr_accessor :reset_called
20
+
21
+ # send :remove_method, :start
22
+ end
23
+
24
+ def self.on_send_message(&block)
25
+ @send_message_block = block
26
+ end
27
+
28
+ def self.on_start(&block)
29
+ if block_given?
30
+ @start_block = block
31
+ else
32
+ @start_block
33
+ end
34
+ end
35
+
36
+ def self.clear_on_start
37
+ @start_block = nil
38
+ end
39
+
40
+ def self.reset
41
+ deliveries.clear
42
+ on_start
43
+ on_send_message
44
+ @reset_called = 0
45
+ end
46
+
47
+ def start(*args)
48
+ self.class.on_start.call if self.class.on_start
49
+ yield self
50
+ end
51
+
52
+ alias test_old_reset reset if instance_methods.include? 'reset'
53
+
54
+ def reset
55
+ self.class.reset_called += 1
56
+ end
57
+
58
+ alias test_old_send_message send_message
59
+
60
+ def send_message(mail, to, from)
61
+ return self.class.send_message_block.call(mail, to, from) unless
62
+ self.class.send_message_block.nil?
63
+ self.class.deliveries << [mail, to, from]
64
+ return "queued"
65
+ end
66
+
67
+ end
68
+
69
+ ##
70
+ # Stub for ActionMailer::Base
71
+
72
+ module ActionMailer; end
73
+
74
+ class ActionMailer::Base
75
+
76
+ @server_settings = {}
77
+
78
+ class << self
79
+ cattr_accessor :email_class
80
+ attr_accessor :delivery_method
81
+ end
82
+
83
+ def self.logger
84
+ o = Object.new
85
+ def o.info(arg) end
86
+ return o
87
+ end
88
+
89
+ def self.method_missing(meth, *args)
90
+ meth.to_s =~ /deliver_(.*)/
91
+ super unless $1
92
+ new($1, *args).deliver!
93
+ end
94
+
95
+ def self.reset
96
+ server_settings.clear
97
+ self.email_class = Email
98
+ end
99
+
100
+ def self.server_settings
101
+ @server_settings
102
+ end
103
+
104
+ def initialize(meth = nil)
105
+ send meth if meth
106
+ end
107
+
108
+ def deliver!
109
+ perform_delivery_activerecord @mail
110
+ end
111
+
112
+ end
113
+
114
+ ##
115
+ # Stub for an ActiveRecord model
116
+
117
+ class Email
118
+
119
+ START = Time.parse 'Thu Aug 10 2006 11:19:48'
120
+
121
+ attr_accessor :from, :to, :mail, :last_send_attempt, :created_on, :id
122
+
123
+ @records = []
124
+ @id = 0
125
+
126
+ class << self; attr_accessor :records, :id; end
127
+
128
+ def self.create(record)
129
+ record = new record[:from], record[:to], record[:mail],
130
+ record[:last_send_attempt]
131
+ records << record
132
+ return record
133
+ end
134
+
135
+ def self.destroy_all(conditions)
136
+ timeout = conditions.last
137
+ found = []
138
+
139
+ records.each do |record|
140
+ next if record.last_send_attempt == 0
141
+ next if record.created_on == 0
142
+ next unless record.created_on < timeout
143
+ record.destroy
144
+ found << record
145
+ end
146
+
147
+ found
148
+ end
149
+
150
+ def self.find(_, conditions = nil)
151
+ return records if conditions.nil?
152
+ now = Time.now.to_i - 300
153
+ return records.select do |r|
154
+ r.last_send_attempt < now
155
+ end
156
+ end
157
+
158
+ def self.reset
159
+ @id = 0
160
+ records.clear
161
+ end
162
+
163
+ def initialize(from, to, mail, last_send_attempt = nil)
164
+ @from = from
165
+ @to = to
166
+ @mail = mail
167
+ @id = self.class.id += 1
168
+ @created_on = START + @id
169
+ @last_send_attempt = last_send_attempt || 0
170
+ end
171
+
172
+ def destroy
173
+ self.class.records.delete self
174
+ self.freeze
175
+ end
176
+
177
+ def ==(other)
178
+ other.id == id
179
+ end
180
+
181
+ def save
182
+ end
183
+
184
+ end
185
+
186
+ Newsletter = Email
187
+
188
+ class String
189
+ def classify
190
+ self
191
+ end
192
+
193
+ def tableize
194
+ self.downcase
195
+ end
196
+
197
+ end
@@ -0,0 +1,46 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper')
2
+
3
+ class Mailer < ActionMailer::Base
4
+ self.delivery_method = :activerecord
5
+
6
+ def mail
7
+ @mail = Object.new
8
+ def @mail.encoded() 'email' end
9
+ def @mail.from() ['nobody@example.com'] end
10
+ def @mail.destinations() %w[user1@example.com user2@example.com] end
11
+ end
12
+
13
+ end
14
+
15
+ class TestARMailer < Test::Unit::TestCase
16
+
17
+ def setup
18
+ Mailer.email_class = Email
19
+
20
+ Email.records.clear
21
+ Newsletter.records.clear
22
+ end
23
+
24
+ def test_self_email_class_equals
25
+ Mailer.email_class = Newsletter
26
+
27
+ Mailer.deliver_mail
28
+
29
+ assert_equal 2, Newsletter.records.length
30
+ end
31
+
32
+ def test_perform_delivery_activerecord
33
+ Mailer.deliver_mail
34
+
35
+ assert_equal 2, Email.records.length
36
+
37
+ record = Email.records.first
38
+ assert_equal 'email', record.mail
39
+ assert_equal 'user1@example.com', record.to
40
+ assert_equal 'nobody@example.com', record.from
41
+
42
+ assert_equal 'user2@example.com', Email.records.last.to
43
+ end
44
+
45
+ end
46
+