tuktuk 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,7 +10,7 @@ module Package
10
10
 
11
11
  mail['In-Reply-To'] = message[:in_reply_to] if message[:in_reply_to]
12
12
  mail['List-Archive'] = message[:list_archive] if message[:list_archive] # https://github.com/tomas/prey
13
- mail['List-Id'] = message[:list_id] if message[:list_id] # <prey.tomas.github.com>
13
+ mail['List-Id'] = message[:list_id] if message[:list_id] # <prey.tomas.github.com>
14
14
 
15
15
  if message[:return_path]
16
16
  mail['Return-Path'] = message[:return_path]
@@ -29,7 +29,7 @@ module Package
29
29
  # sender message[:sender] if message[:sender]
30
30
  subject message[:subject]
31
31
  message_id message[:message_id] if message[:message_id]
32
- body message[:attachments] ? link_plain_attachments(message[:attachments], message[:body]) : message[:body]
32
+ body message[:body]
33
33
  end
34
34
  end
35
35
 
@@ -42,31 +42,15 @@ module Package
42
42
  subject message[:subject]
43
43
  message_id message[:message_id] if message[:message_id]
44
44
  text_part do
45
- body message[:attachments] ? link_plain_attachments(message[:attachments], message[:body]) : message[:body]
45
+ body message[:body]
46
46
  end
47
47
  html_part do
48
48
  content_type 'text/html; charset=UTF-8'
49
- body message[:attachments] ? link_html_attachments(message[:attachments], message[:html_body]) : message[:html_body]
49
+ body message[:html_body]
50
50
  end
51
51
  end
52
52
  end
53
53
 
54
- def link_plain_attachments(attachments, body)
55
- text = "\n\nAttachments\n==========\n"
56
- attachments.each_with_index do |att, i|
57
- text += "[#{att[:name]}] #{att[:link]} \n"
58
- end
59
- body + text
60
- end
61
-
62
- def link_html_attachments(attachments, body)
63
- text = "\n\n<h4>Attachments</h4>\n<ul>\n"
64
- attachments.each_with_index do |att, i|
65
- text += "<li>[<a href='#{att[:link]}' target='_blank'>#{att[:name]}</a>] <a href='#{att[:link]}' target='_blank'>#{att[:link]}</a></li>\n"
66
- end
67
- body + text + "</ul>"
68
- end
69
-
70
54
  end
71
55
 
72
56
  end
data/lib/tuktuk/tuktuk.rb CHANGED
@@ -5,114 +5,114 @@ require 'logger'
5
5
  require 'tuktuk/package'
6
6
 
7
7
  DEFAULTS = {
8
- :retry_sleep => 10,
9
- :max_attempts => 3
8
+ :retry_sleep => 10,
9
+ :max_attempts => 3
10
10
  }
11
11
 
12
12
  module Tuktuk
13
13
 
14
- class << self
15
-
16
- def deliver(message, opts = {})
17
- config.merge(opts)
18
- mail = Package.new(message)
19
- mail['X-Mailer'] = opts[:smtp_server_name] || "Tuktuk SMTP #{VERSION}"
20
- lookup_and_deliver(mail)
21
- mail
22
- end
23
-
24
- def dkim=(dkim_opts)
25
- Dkim::domain = dkim_opts[:domain]
26
- Dkim::selector = dkim_opts[:selector]
27
- Dkim::private_key = dkim_opts[:private_key]
28
- end
29
-
30
- private
31
-
32
- def config
33
- @config ||= DEFAULTS
34
- end
35
-
36
- def use_dkim?
37
- !Dkim::domain.nil?
38
- end
39
-
40
- def logger
41
- @logger ||= Logger.new(config[:logfile])
42
- end
43
-
44
- def get_domain(email_address)
45
- email_address[/@([a-z0-9\._-]+)/i, 1]
46
- end
47
-
48
- def success(destination)
49
- logger.info("#{destination} - Successfully sent mail!")
50
- end
51
-
52
- def error(mail, destination, error, attempt = 1)
53
- if attempt <= config[:max_attempts] && (error.is_a?(Net::SMTPServerBusy) or error.is_a?(EOFError))
54
- logger.info "#{destination} - Got #{error.class.name} error. Retrying after #{config[:retry_sleep]} secs..."
55
- sleep config[:retry_sleep]
56
- lookup_and_deliver(mail, attempt+1)
57
- else
58
- error_message = error.respond_to?(:message) ? "#{error.message} [#{error.class.name}]" : error
59
- logger.error("#{destination} - Unable to send: #{error_message}")
60
- raise "Unable to send to #{destination}: #{error_message}"
61
- end
62
- end
63
-
64
- def smtp_servers_for_domain(domain)
65
- res = Net::DNS::Resolver.new
66
- if mx = res.mx(domain)
67
- mx.sort {|x,y| x.preference <=> y.preference}.map {|rr| rr.exchange}
68
- else
69
- raise RuntimeError, "Could not locate MX records for domain #{domain}."
70
- end
71
- end
72
-
73
- def lookup_and_deliver(mail, attempt = 1)
74
- raise "No destinations found! Forgot to pass the to: field?" if mail.destinations.empty?
75
-
76
- mail.destinations.each do |destination|
77
-
78
- domain = get_domain(destination)
79
- servers = smtp_servers_for_domain(domain)
80
- error(mail, destination, "Unknown host: #{domain}") && next if servers.empty?
81
-
82
- last_error = nil
83
- servers.each do |server|
84
- begin
85
- send_now(mail, server, destination)
86
- break
87
- rescue => e
88
- last_error = e
89
- end
90
- end
91
- error(mail, destination, last_error, attempt) if last_error
92
- end
93
- end
94
-
95
- def send_now(mail, server, to)
96
- raw_mail = use_dkim? ? Dkim.sign(mail.to_s).to_s : mail.to_s
97
-
98
- from = mail.return_path || mail.sender || mail.from_addrs.first
99
- logger.info "#{to} - Delivering email at #{server}..."
100
-
101
- context = OpenSSL::SSL::SSLContext.new
102
- context.verify_mode = OpenSSL::SSL::VERIFY_NONE # OpenSSL::SSL::VERIFY_PEER
103
-
104
- domain = config[:domain] || get_domain(to)
105
-
106
- smtp = Net::SMTP.new(server, nil)
107
- smtp.enable_starttls_auto(context)
108
- smtp.start(domain, nil, nil, nil) do |smtp|
109
- result = smtp.send_message(raw_mail, from, to)
110
- logger.info res.string
111
- end
112
-
113
- success(to)
114
- end
115
-
116
- end
14
+ class << self
15
+
16
+ def deliver(message, opts = {})
17
+ config.merge(opts)
18
+ mail = Package.new(message)
19
+ mail['X-Mailer'] = opts[:smtp_server_name] || "Tuktuk SMTP #{VERSION}"
20
+ lookup_and_deliver(mail)
21
+ mail
22
+ end
23
+
24
+ def dkim=(dkim_opts)
25
+ Dkim::domain = dkim_opts[:domain]
26
+ Dkim::selector = dkim_opts[:selector]
27
+ Dkim::private_key = dkim_opts[:private_key]
28
+ end
29
+
30
+ private
31
+
32
+ def config
33
+ @config ||= DEFAULTS
34
+ end
35
+
36
+ def use_dkim?
37
+ !Dkim::domain.nil?
38
+ end
39
+
40
+ def logger
41
+ @logger ||= Logger.new(config[:logfile])
42
+ end
43
+
44
+ def get_domain(email_address)
45
+ email_address[/@([a-z0-9\._-]+)/i, 1]
46
+ end
47
+
48
+ def success(destination)
49
+ logger.info("#{destination} - Successfully sent mail!")
50
+ end
51
+
52
+ def error(mail, destination, error, attempt = 1)
53
+ if attempt <= config[:max_attempts] && (error.is_a?(Net::SMTPServerBusy) or error.is_a?(EOFError))
54
+ logger.info "#{destination} - Got #{error.class.name} error. Retrying after #{config[:retry_sleep]} secs..."
55
+ sleep config[:retry_sleep]
56
+ lookup_and_deliver(mail, attempt+1)
57
+ else
58
+ error_message = error.respond_to?(:message) ? "#{error.message} [#{error.class.name}]" : error
59
+ logger.error("#{destination} - Unable to send: #{error_message}")
60
+ raise "Unable to send to #{destination}: #{error_message}"
61
+ end
62
+ end
63
+
64
+ def smtp_servers_for_domain(domain)
65
+ res = Net::DNS::Resolver.new
66
+ if mx = res.mx(domain)
67
+ mx.sort {|x,y| x.preference <=> y.preference}.map {|rr| rr.exchange}
68
+ else
69
+ raise RuntimeError, "Could not locate MX records for domain #{domain}."
70
+ end
71
+ end
72
+
73
+ def lookup_and_deliver(mail, attempt = 1)
74
+ raise "No destinations found! Forgot to pass the to: field?" if mail.destinations.empty?
75
+
76
+ mail.destinations.each do |destination|
77
+
78
+ domain = get_domain(destination)
79
+ servers = smtp_servers_for_domain(domain)
80
+ error(mail, destination, "Unknown host: #{domain}") && next if servers.empty?
81
+
82
+ last_error = nil
83
+ servers.each do |server|
84
+ begin
85
+ send_now(mail, server, destination)
86
+ break
87
+ rescue => e
88
+ last_error = e
89
+ end
90
+ end
91
+ error(mail, destination, last_error, attempt) if last_error
92
+ end
93
+ end
94
+
95
+ def send_now(mail, server, to)
96
+ raw_mail = use_dkim? ? Dkim.sign(mail.to_s).to_s : mail.to_s
97
+
98
+ from = mail.return_path || mail.sender || mail.from_addrs.first
99
+ logger.info "#{to} - Delivering email at #{server}..."
100
+
101
+ context = OpenSSL::SSL::SSLContext.new
102
+ context.verify_mode = OpenSSL::SSL::VERIFY_NONE # OpenSSL::SSL::VERIFY_PEER
103
+
104
+ domain = config[:domain] || get_domain(to)
105
+
106
+ smtp = Net::SMTP.new(server, nil)
107
+ smtp.enable_starttls_auto(context)
108
+ smtp.start(domain, nil, nil, nil) do |smtp|
109
+ result = smtp.send_message(raw_mail, from, to)
110
+ logger.info res.string
111
+ end
112
+
113
+ success(to)
114
+ end
115
+
116
+ end
117
117
 
118
118
  end
@@ -1,7 +1,7 @@
1
1
  module Tuktuk
2
2
  MAJOR = 0
3
3
  MINOR = 1
4
- PATCH = 0
4
+ PATCH = 1
5
5
 
6
6
  VERSION = [MAJOR, MINOR, PATCH].join('.')
7
7
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tuktuk
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 0
10
- version: 0.1.0
9
+ - 1
10
+ version: 0.1.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - "Tom\xC3\xA1s Pollak"