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