X-Git-Url: https://git.notmuchmail.org/git?a=blobdiff_plain;f=lib%2Fsup%2Fmessage.rb;h=f02817a7e4d003263bb4867567f772927648b8ec;hb=8497d187f078a10400079c3d9580d3baa7aece3b;hp=8525fdf067d8d3fd04bd5b349361092f8db6fef8;hpb=14cd17b3a1d4448282dc97c10a0063b575bf2e07;p=sup diff --git a/lib/sup/message.rb b/lib/sup/message.rb index 8525fdf..f02817a 100644 --- a/lib/sup/message.rb +++ b/lib/sup/message.rb @@ -46,7 +46,7 @@ class Message @snippet = opts[:snippet] @snippet_contains_encrypted_content = false @have_snippet = !(opts[:snippet].nil? || opts[:snippet].empty?) - @labels = (opts[:labels] || []).to_set_of_symbols + @labels = Set.new(opts[:labels] || []) @dirty = false @encrypted = false @chunks = nil @@ -73,7 +73,7 @@ class Message else id = "sup-faked-" + Digest::MD5.hexdigest(raw_header) from = header["from"] - #Redwood::log "faking non-existent message-id for message from #{from}: #{id}" + #debug "faking non-existent message-id for message from #{from}: #{id}" id end @@ -81,7 +81,7 @@ class Message header["from"] else name = "Sup Auto-generated Fake Sender " - #Redwood::log "faking non-existent sender for message #@id: #{name}" + #debug "faking non-existent sender for message #@id: #{name}" name end) @@ -92,11 +92,11 @@ class Message begin Time.parse date rescue ArgumentError => e - #Redwood::log "faking mangled date header for #{@id} (orig #{header['date'].inspect} gave error: #{e.message})" + #debug "faking mangled date header for #{@id} (orig #{header['date'].inspect} gave error: #{e.message})" Time.now end else - #Redwood::log "faking non-existent date header for #{@id}" + #debug "faking non-existent date header for #{@id}" Time.now end @@ -127,6 +127,31 @@ class Message @list_unsubscribe = header["list-unsubscribe"] end + ## Expected index entry format: + ## :message_id, :subject => String + ## :date => Time + ## :refs, :replytos => Array of String + ## :from => Person + ## :to, :cc, :bcc => Array of Person + def load_from_index! entry + @id = entry[:message_id] + @from = entry[:from] + @date = entry[:date] + @subj = entry[:subject] + @to = entry[:to] + @cc = entry[:cc] + @bcc = entry[:bcc] + @refs = (@refs + entry[:refs]).uniq + @replytos = entry[:replytos] + + @replyto = nil + @list_address = nil + @recipient_email = nil + @source_marked_read = false + @list_subscribe = nil + @list_unsubscribe = nil + end + def add_ref ref @refs << ref @dirty = true @@ -157,22 +182,22 @@ class Message ## don't tempt me. def sanitize_message_id mid; mid.gsub(/(\s|[^\000-\177])+/, "")[0..254] end - def save index + def save_state index return unless @dirty - index.sync_message self + index.update_message_state self @dirty = false true end def has_label? t; @labels.member? t; end - def add_label t - return if @labels.member? t - @labels = (@labels + [t]).to_set_of_symbols + def add_label l + return if @labels.member? l + @labels << l @dirty = true end - def remove_label t - return unless @labels.member? t - @labels.delete t + def remove_label l + return unless @labels.member? l + @labels.delete l @dirty = true end @@ -181,7 +206,9 @@ class Message end def labels= l - @labels = l.to_set_of_symbols + raise ArgumentError, "not a set" unless l.is_a?(Set) + return if @labels == l + @labels = l @dirty = true end @@ -208,7 +235,7 @@ class Message parse_header @source.load_header(@source_info) message_to_chunks @source.load_message(@source_info) rescue SourceError, SocketError => e - Redwood::log "problem getting messages from #{@source}: #{e.message}" + warn "problem getting messages from #{@source}: #{e.message}" ## we need force_to_top here otherwise this window will cover ## up the error message one @source.error ||= e @@ -242,7 +269,7 @@ EOS begin yield rescue SourceError => e - Redwood::log "problem getting messages from #{@source}: #{e.message}" + warn "problem getting messages from #{@source}: #{e.message}" @source.error ||= e Redwood::report_broken_sources :force_to_top => true error_message e.message @@ -270,11 +297,23 @@ EOS to.map { |p| p.indexable_content }, cc.map { |p| p.indexable_content }, bcc.map { |p| p.indexable_content }, - chunks.select { |c| c.is_a? Chunk::Text }.map { |c| c.lines }, - Message.normalize_subj(subj), + indexable_chunks.map { |c| c.lines }, + indexable_subject, ].flatten.compact.join " " end + def indexable_body + indexable_chunks.map { |c| c.lines }.flatten.compact.join " " + end + + def indexable_chunks + chunks.select { |c| c.is_a? Chunk::Text } + end + + def indexable_subject + Message.normalize_subj(subj) + end + def quotable_body_lines chunks.find_all { |c| c.quotable? }.map { |c| c.lines }.flatten end @@ -288,6 +327,12 @@ EOS "Subject: #{@subj}"] end + def self.build_from_source source, source_info + m = Message.new :source => source, :source_info => source_info + m.load_from_source! + m + end + private ## here's where we handle decoding mime attachments. unfortunately @@ -315,25 +360,25 @@ private def multipart_signed_to_chunks m if m.body.size != 2 - Redwood::log "warning: multipart/signed with #{m.body.size} parts (expecting 2)" + warn "multipart/signed with #{m.body.size} parts (expecting 2)" return end payload, signature = m.body if signature.multipart? - Redwood::log "warning: multipart/signed with payload multipart #{payload.multipart?} and signature multipart #{signature.multipart?}" + warn "multipart/signed with payload multipart #{payload.multipart?} and signature multipart #{signature.multipart?}" return end ## this probably will never happen if payload.header.content_type == "application/pgp-signature" - Redwood::log "warning: multipart/signed with payload content type #{payload.header.content_type}" + warn "multipart/signed with payload content type #{payload.header.content_type}" return end if signature.header.content_type != "application/pgp-signature" ## unknown signature type; just ignore. - #Redwood::log "warning: multipart/signed with signature content type #{signature.header.content_type}" + #warn "multipart/signed with signature content type #{signature.header.content_type}" return end @@ -342,29 +387,33 @@ private def multipart_encrypted_to_chunks m if m.body.size != 2 - Redwood::log "warning: multipart/encrypted with #{m.body.size} parts (expecting 2)" + warn "multipart/encrypted with #{m.body.size} parts (expecting 2)" return end control, payload = m.body if control.multipart? - Redwood::log "warning: multipart/encrypted with control multipart #{control.multipart?} and payload multipart #{payload.multipart?}" + warn "multipart/encrypted with control multipart #{control.multipart?} and payload multipart #{payload.multipart?}" return end if payload.header.content_type != "application/octet-stream" - Redwood::log "warning: multipart/encrypted with payload content type #{payload.header.content_type}" + warn "multipart/encrypted with payload content type #{payload.header.content_type}" return end if control.header.content_type != "application/pgp-encrypted" - Redwood::log "warning: multipart/encrypted with control content type #{signature.header.content_type}" + warn "multipart/encrypted with control content type #{signature.header.content_type}" return end - decryptedm, sig, notice = CryptoManager.decrypt payload - children = message_to_chunks(decryptedm, true) if decryptedm - [notice, sig, children].flatten.compact + notice, sig, decryptedm = CryptoManager.decrypt payload + if decryptedm # managed to decrypt + children = message_to_chunks(decryptedm, true) + [notice, sig, children] + else + [notice] + end end ## takes a RMail::Message, breaks it into Chunk:: classes.