lib/sup/modes/edit-message-mode.rb in sup-0.11 vs lib/sup/modes/edit-message-mode.rb in sup-0.12
- old
+ new
@@ -1,9 +1,8 @@
require 'tempfile'
require 'socket' # just for gethostname!
require 'pathname'
-require 'rmail'
module Redwood
class SendmailCommandFailed < StandardError; end
@@ -56,10 +55,22 @@
crypto_selector: the UI element that controls the current cryptography setting.
Return value:
none
EOS
+ HookManager.register "sendmail", <<EOS
+Sends the given mail. If this hook doesn't exist, the sendmail command
+configured for the account is used.
+The message will be saved after this hook is run, so any modification to it
+will be recorded.
+Variables:
+ message: RMail::Message instance of the mail to send
+ account: Account instance matching the From address
+Return value:
+ True if mail has been sent successfully, false otherwise.
+EOS
+
attr_reader :status
attr_accessor :body, :header
bool_reader :edited
register_keymap do |k|
@@ -205,11 +216,11 @@
protected
def mime_encode string
string = [string].pack('M') # basic quoted-printable
string.gsub!(/=\n/,'') # .. remove trailing newline
- string.gsub!(/_/,'=96') # .. encode underscores
+ string.gsub!(/_/,'=5F') # .. encode underscores
string.gsub!(/\?/,'=3F') # .. encode question marks
string.gsub!(/ /,'_') # .. translate space to underscores
"=?utf-8?q?#{string}?="
end
@@ -339,12 +350,21 @@
BufferManager.flash "Sending..."
begin
date = Time.now
m = build_message date
- IO.popen(acct.sendmail, "w") { |p| p.puts m }
- raise SendmailCommandFailed, "Couldn't execute #{acct.sendmail}" unless $? == 0
+
+ if HookManager.enabled? "sendmail"
+ if not HookManager.run "sendmail", :message => m, :account => acct
+ warn "Sendmail hook was not successful"
+ return false
+ end
+ else
+ IO.popen(acct.sendmail, "w") { |p| p.puts m }
+ raise SendmailCommandFailed, "Couldn't execute #{acct.sendmail}" unless $? == 0
+ end
+
SentManager.write_sent_message(date, from_email) { |f| f.puts sanitize_body(m.to_s) }
BufferManager.kill_buffer buffer
BufferManager.flash "Message sent!"
true
rescue SystemCallError, SendmailCommandFailed, CryptoManager::Error => e
@@ -380,10 +400,15 @@
## do whatever crypto transformation is necessary
if @crypto_selector && @crypto_selector.val != :none
from_email = Person.from_address(@header["From"]).email
to_email = [@header["To"], @header["Cc"], @header["Bcc"]].flatten.compact.map { |p| Person.from_address(p).email }
+ if m.multipart?
+ m.each_part {|p| p = transfer_encode p}
+ else
+ m = transfer_encode m
+ end
m = CryptoManager.send @crypto_selector.val, from_email, to_email, m
end
## finally, set the top-level headers
@@ -399,11 +424,12 @@
end
m.header["Date"] = date.rfc2822
m.header["Message-Id"] = @message_id
m.header["User-Agent"] = "Sup/#{Redwood::VERSION}"
- m.header["Content-Transfer-Encoding"] = '8bit'
+ m.header["Content-Transfer-Encoding"] ||= '8bit'
+ m.header["MIME-Version"] = "1.0" if m.multipart?
m
end
## TODO: remove this. redundant with write_full_message_to.
##
@@ -494,9 +520,28 @@
if sigfn && File.exists?(sigfn)
["", "-- "] + File.readlines(sigfn).map { |l| l.chomp }
else
[]
end
+ end
+
+ def transfer_encode msg_part
+ ## return the message unchanged if it's already encoded
+ if (msg_part.header["Content-Transfer-Encoding"] == "base64" ||
+ msg_part.header["Content-Transfer-Encoding"] == "quoted-printable")
+ return msg_part
+ end
+
+ ## encode to quoted-printable for all text/* MIME types,
+ ## use base64 otherwise
+ if msg_part.header["Content-Type"] =~ /text\/.*/
+ msg_part.header["Content-Transfer-Encoding"] = 'quoted-printable'
+ msg_part.body = [msg_part.body].pack('M')
+ else
+ msg_part.header["Content-Transfer-Encoding"] = 'base64'
+ msg_part.body = [msg_part.body].pack('m')
+ end
+ msg_part
end
end
end