From 03763d91b333dbcdd36c2fe4557684c8f06e86cb Mon Sep 17 00:00:00 2001 From: wmorgan Date: Mon, 10 Dec 2007 05:56:50 +0000 Subject: [PATCH] forward individual attachments from thread-view-mode, and forward messages now forwards all attachments by default git-svn-id: svn://rubyforge.org/var/svn/sup/trunk@762 5c8cc53c-5e98-4d25-b20a-d8db53a31250 --- lib/sup/modes/edit-message-mode.rb | 22 +++++++---- lib/sup/modes/forward-mode.rb | 51 ++++++++++++++++++++++---- lib/sup/modes/thread-index-mode.rb | 2 +- lib/sup/modes/thread-view-mode.rb | 7 +++- lib/sup/util.rb | 59 ++++++++++++++++-------------- 5 files changed, 96 insertions(+), 45 deletions(-) diff --git a/lib/sup/modes/edit-message-mode.rb b/lib/sup/modes/edit-message-mode.rb index 43bf9f0..78e8896 100644 --- a/lib/sup/modes/edit-message-mode.rb +++ b/lib/sup/modes/edit-message-mode.rb @@ -61,10 +61,16 @@ EOS @body = opts.delete(:body) || [] @body += sig_lines if $config[:edit_signature] - @attachments = [] + if opts[:attachments] + @attachments = opts[:attachments].values + @attachment_names = opts[:attachments].keys + else + @attachments = [] + @attachment_names = [] + end + @message_id = "<#{Time.now.to_i}-sup-#{rand 10000}@#{Socket.gethostname}>" @edited = false - @reserve_top_rows = opts[:reserve_top_rows] || 0 @selectors = [] @selector_label_width = 0 @@ -140,14 +146,16 @@ EOS def attach_file fn = BufferManager.ask_for_filename :attachment, "File name (enter for browser): " return unless fn - @attachments << Pathname.new(fn) + @attachments << RMail::Message.make_file_attachment(fn) + @attachment_names << fn update end def delete_attachment - i = (curpos - @reserve_top_rows) - @attachment_lines_offset - if i >= 0 && i < @attachments.size && BufferManager.ask_yes_or_no("Delete attachment #{@attachments[i]}?") + i = curpos - @attachment_lines_offset - DECORATION_LINES - 1 + if i >= 0 && i < @attachments.size && BufferManager.ask_yes_or_no("Delete attachment #{@attachment_names[i]}?") @attachments.delete_at i + @attachment_names.delete_at i update end end @@ -186,7 +194,7 @@ protected unless @attachments.empty? @text += [""] @attachment_lines_offset = @text.length - @text += @attachments.map { |f| [[:attachment_color, "+ Attachment: #{f} (#{f.human_size})"]] } + @text += (0 ... @attachments.size).map { |i| [[:attachment_color, "+ Attachment: #{@attachment_names[i]} (#{@attachments[i].body.size.to_human_size})"]] } end end @@ -311,7 +319,7 @@ protected body_m.header["Content-Disposition"] = "inline" m.add_part body_m - @attachments.each { |fn| m.add_file_attachment fn.to_s } + @attachments.each { |a| m.add_part a } end f.puts m.to_s end diff --git a/lib/sup/modes/forward-mode.rb b/lib/sup/modes/forward-mode.rb index 7e830d3..147efb6 100644 --- a/lib/sup/modes/forward-mode.rb +++ b/lib/sup/modes/forward-mode.rb @@ -1,28 +1,63 @@ module Redwood class ForwardMode < EditMessageMode - - ## todo: share some of this with reply-mode - def initialize m, opts={} + ## TODO: share some of this with reply-mode + def initialize opts={} header = { "From" => AccountManager.default_account.full_address, - "Subject" => "Fwd: #{m.subj}", } + header["Subject"] = + if opts[:message] + "Fwd: " + opts[:message].subj + elsif opts[:attachments] + "Fwd: " + opts[:attachments].keys.join(", ") + end + header["To"] = opts[:to].map { |p| p.full_address }.join(", ") if opts[:to] header["Cc"] = opts[:cc].map { |p| p.full_address }.join(", ") if opts[:cc] header["Bcc"] = opts[:bcc].map { |p| p.full_address }.join(", ") if opts[:bcc] - super :header => header, :body => forward_body_lines(m) + body = + if opts[:message] + forward_body_lines(opts[:message]) + elsif opts[:attachments] + ["Note: #{opts[:attachments].size.pluralize 'attachment'}."] + end + + super :header => header, :body => body, :attachments => opts[:attachments] end - def self.spawn_nicely m, opts={} + def self.spawn_nicely opts={} to = opts[:to] || BufferManager.ask_for_contacts(:people, "To: ") or return cc = opts[:cc] || BufferManager.ask_for_contacts(:people, "Cc: ") or return if $config[:ask_for_cc] bcc = opts[:bcc] || BufferManager.ask_for_contacts(:people, "Bcc: ") or return if $config[:ask_for_bcc] - mode = ForwardMode.new m, :to => to, :cc => cc, :bcc => bcc - BufferManager.spawn "Forwarding #{m.subj}", mode + attachment_hash = {} + attachments = opts[:attachments] || [] + + if(m = opts[:message]) + m.load_from_source! # read the full message in. you know, maybe i should just make Message#chunks do this.... + attachments += m.chunks.select { |c| c.is_a?(Chunk::Attachment) && !c.quotable? } + end + + attachments.each do |c| + mime_type = MIME::Types[c.content_type].first || MIME::Types["application/octet-stream"] + attachment_hash[c.filename] = RMail::Message.make_attachment c.raw_content, mime_type.content_type, mime_type.encoding, c.filename + end + + mode = ForwardMode.new :message => opts[:message], :to => to, :cc => cc, :bcc => bcc, :attachments => attachment_hash + + title = "Forwarding " + + if opts[:message] + opts[:message].subj + elsif attachments + attachment_hash.keys.join(", ") + else + "something" + end + + BufferManager.spawn title, mode mode.edit_message end diff --git a/lib/sup/modes/thread-index-mode.rb b/lib/sup/modes/thread-index-mode.rb index 1307284..dbb3f19 100644 --- a/lib/sup/modes/thread-index-mode.rb +++ b/lib/sup/modes/thread-index-mode.rb @@ -407,7 +407,7 @@ EOS m = t.latest_message return if m.nil? # probably won't happen m.load_from_source! - ForwardMode.spawn_nicely m + ForwardMode.spawn_nicely :message => m end def load_n_threads_background n=LOAD_MORE_THREAD_NUM, opts={} diff --git a/lib/sup/modes/thread-view-mode.rb b/lib/sup/modes/thread-view-mode.rb index 1f00783..e974964 100644 --- a/lib/sup/modes/thread-view-mode.rb +++ b/lib/sup/modes/thread-view-mode.rb @@ -136,8 +136,11 @@ EOS end def forward - m = @message_lines[curpos] or return - ForwardMode.spawn_nicely m + if(chunk = @chunk_lines[curpos]) && chunk.is_a?(Chunk::Attachment) + ForwardMode.spawn_nicely :attachments => [chunk] + elsif(m = @message_lines[curpos]) + ForwardMode.spawn_nicely :message => m + end end include CanAliasContacts diff --git a/lib/sup/util.rb b/lib/sup/util.rb index e023917..bd150b4 100644 --- a/lib/sup/util.rb +++ b/lib/sup/util.rb @@ -37,16 +37,7 @@ class Pathname rescue SystemCallError return "?" end - - if s < 1024 - s.to_s + "b" - elsif s < (1024 * 1024) - (s / 1024).to_s + "k" - elsif s < (1024 * 1024 * 1024) - (s / 1024 / 1024).to_s + "m" - else - (s / 1024 / 1024 / 1024).to_s + "g" - end + s.to_human_size end def human_time @@ -63,33 +54,35 @@ module RMail class EncodingUnsupportedError < StandardError; end class Message - def add_file_attachment fn + def self.make_file_attachment fn bfn = File.basename fn - a = Message.new t = MIME::Types.type_for(bfn).first || MIME::Types.type_for("exe").first + make_attachment IO.read(fn), t.content_type, t.encoding, bfn.to_s + end + + def charset + if header.field?("content-type") && header.fetch("content-type") =~ /charset="?(.*?)"?(;|$)/ + $1 + end + end - a.header.add "Content-Disposition", "attachment; filename=#{bfn.to_s.inspect}" - a.header.add "Content-Type", "#{t.content_type}; name=#{bfn.to_s.inspect}" - a.header.add "Content-Transfer-Encoding", t.encoding + def self.make_attachment payload, mime_type, encoding, filename + a = Message.new + a.header.add "Content-Disposition", "attachment; filename=#{filename.inspect}" + a.header.add "Content-Type", "#{mime_type}; name=#{filename.inspect}" + a.header.add "Content-Transfer-Encoding", encoding a.body = - case t.encoding + case encoding when "base64" - [IO.read(fn)].pack "m" + [payload].pack "m" when "quoted-printable" - [IO.read(fn)].pack "M" + [payload].pack "M" when "7bit", "8bit" - IO.read(fn) + payload else raise EncodingUnsupportedError, t.encoding end - - add_part a - end - - def charset - if header.field?("content-type") && header.fetch("content-type") =~ /charset="?(.*?)"?(;|$)/ - $1 - end + a end end end @@ -294,6 +287,18 @@ class Numeric end def in? range; range.member? self; end + + def to_human_size + if self < 1024 + to_s + "b" + elsif self < (1024 * 1024) + (self / 1024).to_s + "k" + elsif self < (1024 * 1024 * 1024) + (self / 1024 / 1024).to_s + "m" + else + (self / 1024 / 1024 / 1024).to_s + "g" + end + end end class Fixnum -- 2.45.2