From: wmorgan Date: Fri, 1 Dec 2006 19:39:28 +0000 (+0000) Subject: added saving of message and attachments to disk (and some bugfixes in buffer X-Git-Url: https://git.notmuchmail.org/git?a=commitdiff_plain;h=973d04f29b429bb81e3d9107f89311adf2d3fffd;p=sup added saving of message and attachments to disk (and some bugfixes in buffer in support of this). git-svn-id: svn://rubyforge.org/var/svn/sup/trunk@56 5c8cc53c-5e98-4d25-b20a-d8db53a31250 --- diff --git a/lib/sup/buffer.rb b/lib/sup/buffer.rb index b3dd60a..03aead6 100644 --- a/lib/sup/buffer.rb +++ b/lib/sup/buffer.rb @@ -352,7 +352,7 @@ class BufferManager id ||= @minibuf_stack.length @minibuf_stack[id] = s unless @freeze - draw_minibuf + draw_screen Ncurses.refresh end id @@ -363,7 +363,7 @@ class BufferManager def flash s @flash = s unless @freeze - draw_minibuf + draw_screen Ncurses.refresh end end @@ -377,7 +377,7 @@ class BufferManager end end unless @freeze - draw_minibuf + draw_screen Ncurses.refresh end end diff --git a/lib/sup/draft.rb b/lib/sup/draft.rb index 12233f3..9847bae 100644 --- a/lib/sup/draft.rb +++ b/lib/sup/draft.rb @@ -77,8 +77,7 @@ class DraftLoader end end - ## load the full header text - def load_header_text offset + def raw_header offset ret = "" File.open fn_for_offset(offset) do |f| until f.eof? || (l = f.gets) =~ /^$/ @@ -88,6 +87,14 @@ class DraftLoader ret end + def raw_full_message offset + ret = "" + File.open fn_for_offset(offset) do |f| + ret += l until f.eof? + end + ret + end + def each while File.exists?(fn = File.join(@dir, @end_offset.to_s)) yield @end_offset, [:draft, :inbox] diff --git a/lib/sup/mbox/loader.rb b/lib/sup/mbox/loader.rb index 51af5f2..f4cbe80 100644 --- a/lib/sup/mbox/loader.rb +++ b/lib/sup/mbox/loader.rb @@ -34,7 +34,11 @@ class Loader end).compact end - def reset!; @end_offset = 0; @dirty = true; end + def seek_to! offset + @end_offset = [offset, File.size(@f) - 1].min; + @dirty = true + end + def reset!; seek_to! 0; end def == o; o.is_a?(Loader) && o.filename == filename; end def to_s; "mbox://#{@filename}"; end @@ -61,8 +65,7 @@ class Loader end end - ## load the full header text - def load_header_text offset + def raw_header offset ret = "" @mutex.synchronize do @f.seek offset @@ -73,6 +76,18 @@ class Loader ret end + def raw_full_message offset + ret = "" + @mutex.synchronize do + @f.seek offset + @f.gets # skip mbox header + until @f.eof? || (l = @f.gets) =~ BREAK_RE + ret += l + end + end + ret + end + def next return nil if done? @dirty = true diff --git a/lib/sup/message.rb b/lib/sup/message.rb index 69f4f02..9afde3f 100644 --- a/lib/sup/message.rb +++ b/lib/sup/message.rb @@ -27,24 +27,27 @@ class Message end class Attachment - attr_reader :content_type, :desc + attr_reader :content_type, :desc, :filename def initialize content_type, desc, part @content_type = content_type @desc = desc @part = part @file = nil + desc =~ /filename="(.*?)"/ && @filename = $1 end def view! unless @file @file = Tempfile.new "redwood.attachment" - @file.print @part.decode + @file.print self @file.close end ## TODO: handle unknown mime-types system "/usr/bin/run-mailcap --action=view #{@content_type}:#{@file.path}" end + + def to_s; @part.decode; end end class Text @@ -171,8 +174,12 @@ class Message message_to_chunks m end - def header_text - @source.load_header_text @source_info + def raw_header + @source.raw_header @source_info + end + + def raw_full_message + @source.raw_full_message @source_info end def content diff --git a/lib/sup/modes/thread-view-mode.rb b/lib/sup/modes/thread-view-mode.rb index 0ce591d..7a590c8 100644 --- a/lib/sup/modes/thread-view-mode.rb +++ b/lib/sup/modes/thread-view-mode.rb @@ -16,6 +16,7 @@ class ThreadViewMode < LineCursorMode k.add :collapse_non_new_messages, "Collapse all but new messages", 'N' k.add :reply, "Reply to a message", 'r' k.add :forward, "Forward a message", 'f' + k.add :save_to_disk, "Save message/attachment to disk", 's' end def initialize thread, hidden_labels=[] @@ -62,7 +63,7 @@ class ThreadViewMode < LineCursorMode def show_header return unless(m = @message_lines[curpos]) BufferManager.spawn_unless_exists("Full header") do - TextMode.new m.header_text + TextMode.new m.raw_header end end @@ -109,6 +110,32 @@ class ThreadViewMode < LineCursorMode update end + def save fn + if File.exists? fn + return unless BufferManager.ask_yes_or_no "File exists. Overwrite?" + end + begin + File.open(fn, "w") { |f| yield f } + BufferManager.flash "Successfully wrote #{fn}." + rescue SystemCallError => e + BufferManager.flash "Error writing to file: #{e.message}" + end + end + private :save + + def save_to_disk + return unless(chunk = @chunk_lines[curpos]) + case chunk + when Message::Attachment + fn = BufferManager.ask :filename, "save attachment to file: ", chunk.filename + save(fn) { |f| f.print chunk } if fn + else + m = @message_lines[curpos] + fn = BufferManager.ask :filename, "save message to file: " + save(fn) { |f| f.print m.raw_full_message } if fn + end + end + def edit_message return unless(m = @message_lines[curpos]) if m.is_draft? diff --git a/lib/sup/thread.rb b/lib/sup/thread.rb index 688a033..c7e36b3 100644 --- a/lib/sup/thread.rb +++ b/lib/sup/thread.rb @@ -321,6 +321,7 @@ class ThreadSet else ## to disable subject grouping, use the next line instead ## (and the same for below) + Redwood::log "[1] normalized subject for #{id} is #{Message.normalize_subj(root.subj)}" thread = (@subj_thread[Message.normalize_subj(root.subj)] ||= Thread.new) #thread = (@subj_thread[root.id] ||= Thread.new) @@ -341,6 +342,7 @@ class ThreadSet else ## to disable subject grouping, use the next line instead ## (and the same above) + Redwood::log "[2] normalized subject for #{id} is #{Message.normalize_subj(root.subj)}" thread = (@subj_thread[Message.normalize_subj(root.subj)] ||= Thread.new) #thread = (@subj_thread[root.id] ||= Thread.new)