Class: GitCommitNotifier::Emailer
- Inherits:
-
Object
- Object
- GitCommitNotifier::Emailer
- Defined in:
- lib/git_commit_notifier/emailer.rb
Overview
Represents email sender.
Constant Summary collapse
- DEFAULT_STYLESHEET_PATH =
Default CSS stylesheet file path
File.join(File.dirname(__FILE__), *'../../template/styles.css'.split('/')).freeze
- TEMPLATE =
Default ERB template file path
File.join(File.dirname(__FILE__), *'../../template/email.html.erb'.split('/')).freeze
- PARAMETERS =
Instance variable names
%w[ project_path recipient from_address from_alias reply_to_address commit_date current_date offset_date subject text_message html_message repo_name ref_name old_rev new_rev message_link ].freeze
- CHARS_NEEDING_QUOTING =
A quick-and-dirty regexp for determining whether a string contains any characters that need escaping.
/[^\x0a\x0d\x20-\x7e]/
Class Attribute Summary collapse
-
.config ⇒ Object
[Hash] Gets or sets config.
Class Method Summary collapse
-
.reset_stylesheet ⇒ NilClass
Resets CSS stylesheet source.
-
.reset_template ⇒ NilClass
Resets compiled template.
-
.stylesheet ⇒ String
Gets or reads CSS stylesheet.
-
.stylesheet_source ⇒ String
Reads CSS stylesheet source code.
-
.template ⇒ Object
Gets or reads compiled template.
-
.template_source ⇒ String
Reads template source code from file system.
Instance Method Summary collapse
-
#boundary ⇒ String
Gets or creates email part boundary.
-
#config ⇒ Hash
Gets config.
-
#encode_quoted_printable_message(text) ⇒ Object
Convert a message into quoted printable encoding, limiting line length to 76 characters per spec.
-
#initialize(config, options = {}) ⇒ Emailer
constructor
A new instance of Emailer.
-
#mail_html_message ⇒ String
Gets HTML-formatted message.
-
#perform_delivery_debug(content) ⇒ NilClass
Performs email delivery in debug mode (to STDOUT).
-
#perform_delivery_nntp(content, nntp_settings) ⇒ NilClass
Performs email delivery through NNTP.
-
#perform_delivery_sendmail(content, options = nil) ⇒ NilClass
Performs email delivery through Sendmail.
-
#perform_delivery_smtp(content, smtp_settings) ⇒ NilClass
Performs email delivery through SMTP.
-
#quote_if_necessary(text, charset) ⇒ Object
Quote the given text if it contains any "illegal" characters.
-
#quoted_printable(text, charset) ⇒ Object
Convert the given text into quoted printable format, with an instruction that the text be eventually interpreted in the given charset.
-
#quoted_printable_encode(character) ⇒ Object
Convert the given character to quoted printable format, taking into account multi-byte characters (if executing with $KCODE="u", for instance).
-
#send ⇒ NilClass
Creates email message and sends it using configured delivery method.
-
#stylesheet_string ⇒ String
Gets stylesheet string.
Constructor Details
#initialize(config, options = {}) ⇒ Emailer
Returns a new instance of Emailer.
39 40 41 42 43 44 |
# File 'lib/git_commit_notifier/emailer.rb', line 39 def initialize(config, = {}) GitCommitNotifier::Emailer.config = config || {} PARAMETERS.each do |name| instance_variable_set("@#{name}".to_sym, [name.to_sym]) end end |
Class Attribute Details
.config ⇒ Object
[Hash] Gets or sets config.
48 49 50 |
# File 'lib/git_commit_notifier/emailer.rb', line 48 def config @config end |
Class Method Details
.reset_stylesheet ⇒ NilClass
Useful for tests.
Resets CSS stylesheet source.
84 85 86 |
# File 'lib/git_commit_notifier/emailer.rb', line 84 def reset_stylesheet @stylesheet = nil end |
.reset_template ⇒ NilClass
Useful for tests.
Resets compiled template.
53 54 55 |
# File 'lib/git_commit_notifier/emailer.rb', line 53 def reset_template @template = nil end |
.stylesheet ⇒ String
Gets or reads CSS stylesheet.
97 98 99 |
# File 'lib/git_commit_notifier/emailer.rb', line 97 def stylesheet @stylesheet ||= stylesheet_source end |
.stylesheet_source ⇒ String
Reads CSS stylesheet source code.
90 91 92 93 |
# File 'lib/git_commit_notifier/emailer.rb', line 90 def stylesheet_source stylesheet = config['stylesheet'] || DEFAULT_STYLESHEET_PATH IO.read(stylesheet) end |
.template ⇒ Object
Erubis used as template engine if present; ERB otherwise.
Gets or reads compiled template.
67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/git_commit_notifier/emailer.rb', line 67 def template unless @template source = template_source begin require 'erubis' @template = Erubis::Eruby.new(source) rescue LoadError require 'erb' @template = ERB.new(source) end end @template end |
.template_source ⇒ String
Reads template source code from file system.
59 60 61 62 |
# File 'lib/git_commit_notifier/emailer.rb', line 59 def template_source template_file = config['custom_template'] || TEMPLATE IO.read(template_file) end |
Instance Method Details
#boundary ⇒ String
Gets or creates email part boundary
123 124 125 126 127 128 |
# File 'lib/git_commit_notifier/emailer.rb', line 123 def boundary return @boundary if @boundary srand seed = "#{rand(10000)}#{Time.now}" @boundary = Digest::SHA1.hexdigest(seed) end |
#config ⇒ Hash
Helper that represents class method in instance scope.
Gets config.
35 36 37 |
# File 'lib/git_commit_notifier/emailer.rb', line 35 def config GitCommitNotifier::Emailer.config end |
#encode_quoted_printable_message(text) ⇒ Object
Convert a message into quoted printable encoding, limiting line length to 76 characters per spec. Encoding messages in this way ensures that they won't violate rules for maximum line length, which can result in the MTA breaking lines at inconvenient points, such as in the middle of UTF8 characters.
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 |
# File 'lib/git_commit_notifier/emailer.rb', line 271 def (text) str = '' # Character encoding of output string can be plain US-ASCII since quoted-printable is plain ASCII str.force_encoding("US-ASCII") if str.respond_to?(:force_encoding) StringIO.open(str, "w") do |output| line_max = 76 line_len = 0 input = StringIO.new(text, "r") input.each_byte do |b| case (b) when 9, 32..60, 62..126 if line_len >= line_max - 1 output << "=\r\n" line_len = 0 end output << b.chr line_len += 1 else if line_len >= line_max - 3 output << "=\r\n" line_len = 0 end output << "=%02X" % b line_len += 3 end end output << "=\r\n" if line_len > 0 output.string end end |
#mail_html_message ⇒ String
Gets HTML-formatted message.
104 105 106 107 108 109 110 111 |
# File 'lib/git_commit_notifier/emailer.rb', line 104 def html = GitCommitNotifier::Emailer.template.result(binding) if config['expand_css'].nil? || config['expand_css'] premailer = Premailer.new(html, :with_html_string => true, :adapter => :nokogiri) html = premailer.to_inline_css end html end |
#perform_delivery_debug(content) ⇒ NilClass
Performs email delivery in debug mode (to STDOUT).
132 133 134 135 136 137 |
# File 'lib/git_commit_notifier/emailer.rb', line 132 def perform_delivery_debug(content) content.each do |line| puts line end nil end |
#perform_delivery_nntp(content, nntp_settings) ⇒ NilClass
Performs email delivery through NNTP.
187 188 189 190 191 192 193 |
# File 'lib/git_commit_notifier/emailer.rb', line 187 def perform_delivery_nntp(content, nntp_settings) require 'nntp' Net::NNTP.start(nntp_settings['address'], nntp_settings['port']) do |nntp| nntp.post content end nil end |
#perform_delivery_sendmail(content, options = nil) ⇒ NilClass
Performs email delivery through Sendmail.
170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/git_commit_notifier/emailer.rb', line 170 def perform_delivery_sendmail(content, = nil) sendmail_settings = { 'location' => "/usr/sbin/sendmail", 'arguments' => "-i -t" }.merge( || {}) command = "#{sendmail_settings['location']} #{sendmail_settings['arguments']}" IO.popen(command, "w+") do |f| content.each do |line| f.print(line, "\r\n") end f.flush end nil end |
#perform_delivery_smtp(content, smtp_settings) ⇒ NilClass
Performs email delivery through SMTP.
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/git_commit_notifier/emailer.rb', line 141 def perform_delivery_smtp(content, smtp_settings) settings = { } %w(address port domain user_name password authentication enable_tls).each do |key| val = smtp_settings[key].to_s.empty? ? nil : smtp_settings[key] settings.merge!({ key => val}) end main_smtp = Net::SMTP.new settings['address'], settings['port'] main_smtp.enable_starttls if settings['enable_tls'] main_smtp.start( settings['domain'], settings['user_name'], settings['password'], settings['authentication']) do |smtp| recipients = @recipient.dup recipients.force_encoding('ASCII-8BIT') if recipients.respond_to?(:force_encoding) recipients = recipients.split(",").map(&:strip) smtp.(@from_address, recipients) do |f| content.each do |line| line.force_encoding('ASCII-8BIT') if line.respond_to?(:force_encoding) f.print(line) f.print("\r\n") end end end nil end |
#quote_if_necessary(text, charset) ⇒ Object
Quote the given text if it contains any "illegal" characters
325 326 327 328 329 330 331 |
# File 'lib/git_commit_notifier/emailer.rb', line 325 def quote_if_necessary(text, charset) text = text.dup.force_encoding(Encoding::ASCII_8BIT) if text.respond_to?(:force_encoding) (text =~ CHARS_NEEDING_QUOTING) ? quoted_printable(text, charset) : text end |
#quoted_printable(text, charset) ⇒ Object
Convert the given text into quoted printable format, with an instruction that the text be eventually interpreted in the given charset.
306 307 308 309 310 |
# File 'lib/git_commit_notifier/emailer.rb', line 306 def quoted_printable(text, charset) text = text.gsub( /[^a-z ]/i ) { quoted_printable_encode($&) }. gsub( / /, "_" ) "=?#{charset}?Q?#{text}?=" end |
#quoted_printable_encode(character) ⇒ Object
Convert the given character to quoted printable format, taking into account multi-byte characters (if executing with $KCODE="u", for instance)
314 315 316 317 318 |
# File 'lib/git_commit_notifier/emailer.rb', line 314 def quoted_printable_encode(character) result = "" character.each_byte { |b| result << "=%02X" % b } result end |
#send ⇒ NilClass
Creates email message and sends it using configured delivery method.
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'lib/git_commit_notifier/emailer.rb', line 197 def send to_tag = config['delivery_method'] == 'nntp' ? 'Newsgroups' : 'To' quoted_from_alias = !@from_alias.nil? ? quote_if_necessary("#{@from_alias}",'utf-8') : nil from = (@from_alias.nil? || @from_alias.empty?) ? @from_address : "#{quoted_from_alias} <#{@from_address}>" reply_to = (@from_alias.nil? || !config['reply_to_author']) ? @reply_to_address : "#{@from_alias} <#{@reply_to_address}>" plaintext = if config['add_plaintext'].nil? || config['add_plaintext'] else "Plain text part omitted. Consider setting add_plaintext in configuration." end content = [] content << "From: #{from}" unless from.nil? content << "Reply-To: #{reply_to}" unless reply_to.nil? # Setting the email date from the commit date is undesired by those # who sort their email by send date instead of receive date. # We currently use @offset_date, which starts with the time the notifier was started, # and adds a second of time per commit. This should result in the commits arriving # in order by their processing sequence, even when they are all processed within the # same second #date = @commit_date # Date of the commit #date = @current_date # Date we processed this commit date = @offset_date # Date notifier started, plus 1 second per commit processed date = Time.new.rfc2822 if date.nil? # Fallback to current date if date is nil content.concat [ "#{to_tag}: #{quote_if_necessary(@recipient, 'utf-8')}", "Date: #{date}", "Subject: #{quote_if_necessary(@subject, 'utf-8')}", "X-Mailer: git-commit-notifier", "X-Git-Repository: #{@repo_name}", "X-Git-Refname: #{@ref_name}", "X-Git-Oldrev: #{@old_rev}", "X-Git-Newrev: #{@new_rev}", "Mime-Version: 1.0", "Content-Type: multipart/alternative; boundary=#{boundary}", "", "--#{boundary}", "Content-Type: text/plain; charset=utf-8", "Content-Transfer-Encoding: quoted-printable", "Content-Disposition: inline", "", (plaintext), "--#{boundary}", "Content-Type: text/html; charset=utf-8", "Content-Transfer-Encoding: quoted-printable", "Content-Disposition: inline", "", (), "--#{boundary}--"] if @recipient.empty? puts content.join("\n") return end case config['delivery_method'].to_sym when :smtp then perform_delivery_smtp(content, config['smtp_server']) when :nntp then perform_delivery_nntp(content, config['nntp_settings']) when :debug then perform_delivery_debug(content) else # sendmail perform_delivery_sendmail(content, config['sendmail_options']) end nil end |
#stylesheet_string ⇒ String
This is helper to provide data from class context.
Gets stylesheet string.
117 118 119 |
# File 'lib/git_commit_notifier/emailer.rb', line 117 def stylesheet_string GitCommitNotifier::Emailer.stylesheet end |