X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=lib%2Fsup%2Fmessage.rb;h=c69b9e30327ff6e51d70b8b2395f47107c0dc68e;hb=d4c1bd840f55a07fd5aeb4d08a1f43c3f7c1850e;hp=29999863ebbfa8bf73eb2ce1e26a6a7e838ce99d;hpb=8ee91effe23a42d483fa6c0d2106ff328d3ba686;p=sup diff --git a/lib/sup/message.rb b/lib/sup/message.rb index 2999986..c69b9e3 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 @@ -333,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 @@ -360,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. @@ -403,20 +434,24 @@ private chunks elsif m.header.content_type == "message/rfc822" - payload = RMail::Parser.read(m.body) - from = payload.header.from.first ? payload.header.from.first.format : "" - to = payload.header.to.map { |p| p.format }.join(", ") - cc = payload.header.cc.map { |p| p.format }.join(", ") - subj = payload.header.subject - subj = subj ? Message.normalize_subj(payload.header.subject.gsub(/\s+/, " ").gsub(/\s+$/, "")) : subj - if Rfc2047.is_encoded? subj - subj = Rfc2047.decode_to $encoding, subj + if m.body + payload = RMail::Parser.read(m.body) + from = payload.header.from.first ? payload.header.from.first.format : "" + to = payload.header.to.map { |p| p.format }.join(", ") + cc = payload.header.cc.map { |p| p.format }.join(", ") + subj = payload.header.subject + subj = subj ? Message.normalize_subj(payload.header.subject.gsub(/\s+/, " ").gsub(/\s+$/, "")) : subj + if Rfc2047.is_encoded? subj + subj = Rfc2047.decode_to $encoding, subj + end + msgdate = payload.header.date + from_person = from ? Person.from_address(from) : nil + to_people = to ? Person.from_address_list(to) : nil + cc_people = cc ? Person.from_address_list(cc) : nil + [Chunk::EnclosedMessage.new(from_person, to_people, cc_people, msgdate, subj)] + message_to_chunks(payload, encrypted) + else + [Chunk::EnclosedMessage.new(nil, "")] end - msgdate = payload.header.date - from_person = from ? Person.from_address(from) : nil - to_people = to ? Person.from_address_list(to) : nil - cc_people = cc ? Person.from_address_list(cc) : nil - [Chunk::EnclosedMessage.new(from_person, to_people, cc_people, msgdate, subj)] + message_to_chunks(payload, encrypted) else filename = ## first, paw through the headers looking for a filename