commit 03763d91b333dbcdd36c2fe4557684c8f06e86cb
parent 17fd0c9bf15e8c114fc05c11a6ba5346154d1730
Author: wmorgan <wmorgan@5c8cc53c-5e98-4d25-b20a-d8db53a31250>
Date: Mon, 10 Dec 2007 05:56:50 +0000
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
Diffstat:
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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