- ## Syncs the message to the index, replacing any previous version. adding
- ## either way. Index state will be determined by the message's #labels
- ## accessor.
- ##
- ## if need_load is false, docid and entry are assumed to be set to the
- ## result of load_entry_for_id (which can be nil).
- def sync_message m, need_load=true, docid=nil, entry=nil, opts={}
- docid, entry = load_entry_for_id m.id if need_load
-
- raise "no source info for message #{m.id}" unless m.source && m.source_info
- @index_mutex.synchronize do
- raise "trying to delete non-corresponding entry #{docid} with index message-id #{@index[docid][:message_id].inspect} and parameter message id #{m.id.inspect}" if docid && @index[docid][:message_id] != m.id
- end
-
- source_id = if m.source.is_a? Integer
- m.source
- else
- m.source.id or raise "unregistered source #{m.source} (id #{m.source.id.inspect})"
- end
-
- snippet = if m.snippet_contains_encrypted_content? && $config[:discard_snippets_from_encrypted_messages]
- ""
- else
- m.snippet
- end
-
- ## write the new document to the index. if the entry already exists in the
- ## index, reuse it (which avoids having to reload the entry from the source,
- ## which can be quite expensive for e.g. large threads of IMAP actions.)
- ##
- ## exception: if the index entry belongs to an earlier version of the
- ## message, use everything from the new message instead, but union the
- ## flags. this allows messages sent to mailing lists to have their header
- ## updated and to have flags set properly.
- ##
- ## minor hack: messages in sources with lower ids have priority over
- ## messages in sources with higher ids. so messages in the inbox will
- ## override everyone, and messages in the sent box will be overridden
- ## by everyone else.
- ##
- ## written in this manner to support previous versions of the index which
- ## did not keep around the entry body. upgrading is thus seamless.
- entry ||= {}
- labels = m.labels.uniq # override because this is the new state, unless...
-
- ## if we are a later version of a message, ignore what's in the index,
- ## but merge in the labels.
- if entry[:source_id] && entry[:source_info] && entry[:label] &&
- ((entry[:source_id].to_i > source_id) || (entry[:source_info].to_i < m.source_info))
- labels = (entry[:label].symbolistize + m.labels).uniq
- #Redwood::log "found updated version of message #{m.id}: #{m.subj}"
- #Redwood::log "previous version was at #{entry[:source_id].inspect}:#{entry[:source_info].inspect}, this version at #{source_id.inspect}:#{m.source_info.inspect}"
- #Redwood::log "merged labels are #{labels.inspect} (index #{entry[:label].inspect}, message #{m.labels.inspect})"
- entry = {}
- end
-
- ## if force_overwite is true, ignore what's in the index. this is used
- ## primarily by sup-sync to force index updates.
- entry = {} if opts[:force_overwrite]
-
- d = {
- :message_id => m.id,
- :source_id => source_id,
- :source_info => m.source_info,
- :date => (entry[:date] || m.date.to_indexable_s),
- :body => (entry[:body] || m.indexable_content),
- :snippet => snippet, # always override
- :label => labels.uniq.join(" "),
- :attachments => (entry[:attachments] || m.attachments.uniq.join(" ")),
-
- ## always override :from and :to.
- ## older versions of Sup would often store the wrong thing in the index
- ## (because they were canonicalizing email addresses, resulting in the
- ## wrong name associated with each.) the correct address is read from
- ## the original header when these messages are opened in thread-view-mode,
- ## so this allows people to forcibly update the address in the index by
- ## marking those threads for saving.
- :from => (m.from ? m.from.indexable_content : ""),
- :to => (m.to + m.cc + m.bcc).map { |x| x.indexable_content }.join(" "),
-
- :subject => (entry[:subject] || wrap_subj(Message.normalize_subj(m.subj))),
- :refs => (entry[:refs] || (m.refs + m.replytos).uniq.join(" ")),
- }
-
- @index_mutex.synchronize do
- @index.delete docid if docid
- @index.add_document d
- end
-
- ## this hasn't been triggered in a long time.
- ## docid, entry = load_entry_for_id m.id
- ## raise "just added message #{m.id.inspect} but couldn't find it in a search" unless docid