sup

A curses threads-with-tags style email client

sup.git

git clone https://supmua.dev/git/sup/
commit 4ad7b53ff6588410449f789146d250d20919cef8
parent 9cc396845f569245104d9dd514a187cfebcfb3ec
Author: Rich Lane <rlane@club.cc.cmu.edu>
Date:   Mon, 18 Jan 2010 22:25:13 -0800

change index format to store multiple message locations

Diffstat:
M lib/sup/index.rb | 27 ++++++++++++++++++++-------
M lib/sup/message.rb | 19 ++++++++++++++-----
2 files changed, 34 insertions(+), 12 deletions(-)
diff --git a/lib/sup/index.rb b/lib/sup/index.rb
@@ -193,11 +193,15 @@ EOS
     entry = synchronize { get_entry id }
     return unless entry
 
-    source = SourceManager[entry[:source_id]]
-    raise "invalid source #{entry[:source_id]}" unless source
+    locations = entry[:locations].map do |source_id,source_info|
+      source = SourceManager[source_id]
+      raise "invalid source #{source_id}" unless source
+      [source, source_info]
+    end
 
-    m = Message.new :source => source, :source_info => entry[:source_info],
-                    :labels => entry[:labels], :snippet => entry[:snippet]
+    m = Message.new :locations => locations,
+                    :labels => entry[:labels],
+                    :snippet => entry[:snippet]
 
     mk_person = lambda { |x| Person.new(*x.reverse!) }
     entry[:from] = mk_person[entry[:from]]
@@ -453,6 +457,7 @@ EOS
     'id' => 'Q',
     'thread' => 'H',
     'ref' => 'R',
+    'location' => 'J',
   }
 
   PREFIX = NORMAL_PREFIX.merge BOOLEAN_PREFIX
@@ -575,8 +580,7 @@ EOS
 
     entry = {
       :message_id => m.id,
-      :source_id => m.source.id,
-      :source_info => m.source_info,
+      :locations => m.locations.map { |source,source_info| [source.id, source_info] },
       :date => truncate_date(m.date),
       :snippet => snippet,
       :labels => m.labels.to_a,
@@ -595,6 +599,7 @@ EOS
       index_message_static m, doc, entry
     end
 
+    index_message_locations doc, entry, old_entry
     index_message_threading doc, entry, old_entry
     index_message_labels doc, entry[:labels], (do_index_static ? [] : old_entry[:labels])
     doc.entry = entry
@@ -637,7 +642,6 @@ EOS
     doc.add_term mkterm(:date, m.date) if m.date
     doc.add_term mkterm(:type, 'mail')
     doc.add_term mkterm(:msgid, m.id)
-    doc.add_term mkterm(:source_id, m.source.id)
     m.attachments.each do |a|
       a =~ /\.(\w+)$/ or next
       doc.add_term mkterm(:attachment_extension, $1)
@@ -654,6 +658,13 @@ EOS
     doc.add_value DATE_VALUENO, date_value
   end
 
+  def index_message_locations doc, entry, old_entry
+    old_entry[:locations].map { |x| x[0] }.uniq.each { |x| doc.remove_term mkterm(:source_id, x) } if old_entry
+    entry[:locations].map { |x| x[0] }.uniq.each { |x| doc.add_term mkterm(:source_id, x) }
+    old_entry[:locations].each { |x| doc.remove_term mkterm(:location, *x) } if old_entry
+    entry[:locations].each { |x| doc.add_term mkterm(:location, *x) }
+  end
+
   def index_message_labels doc, new_labels, old_labels
     return if new_labels == old_labels
     added = new_labels.to_a - old_labels.to_a
@@ -716,6 +727,8 @@ EOS
       end + args[1].to_s.downcase
     when :source_id
       PREFIX['source_id'] + args[0].to_s.downcase
+    when :location
+      PREFIX['location'] + [args[0]].pack('n') + args[1].to_s
     when :attachment_extension
       PREFIX['attachment_extension'] + args[0].to_s.downcase
     when :msgid, :ref, :thread
diff --git a/lib/sup/message.rb b/lib/sup/message.rb
@@ -33,17 +33,16 @@ class Message
   DEFAULT_SENDER = "(missing sender)"
   MAX_HEADER_VALUE_SIZE = 4096
 
-  attr_reader :id, :date, :from, :subj, :refs, :replytos, :to, :source,
+  attr_reader :id, :date, :from, :subj, :refs, :replytos, :to, :locations,
               :cc, :bcc, :labels, :attachments, :list_address, :recipient_email, :replyto,
-              :source_info, :list_subscribe, :list_unsubscribe
+              :list_subscribe, :list_unsubscribe
 
   bool_reader :dirty, :source_marked_read, :snippet_contains_encrypted_content
 
   ## if you specify a :header, will use values from that. otherwise,
   ## will try and load the header from the source.
   def initialize opts
-    @source = opts[:source] or raise ArgumentError, "source can't be nil"
-    @source_info = opts[:source_info] or raise ArgumentError, "source_info can't be nil"
+    @locations = opts[:locations] or raise ArgumentError, "locations can't be nil"
     @snippet = opts[:snippet]
     @snippet_contains_encrypted_content = false
     @have_snippet = !(opts[:snippet].nil? || opts[:snippet].empty?)
@@ -224,6 +223,16 @@ class Message
     @chunks
   end
 
+  def source
+    fail if @locations.empty?
+    @locations.last[0]
+  end
+
+  def source_info
+    fail if @locations.empty?
+    @locations.last[1]
+  end
+
   ## this is called when the message body needs to actually be loaded.
   def load_from_source!
     @chunks ||=
@@ -336,7 +345,7 @@ EOS
   end
 
   def self.build_from_source source, source_info
-    m = Message.new :source => source, :source_info => source_info
+    m = Message.new :locations => [[source, source_info]]
     m.load_from_source!
     m
   end