DEFAULT_SENDER = "(missing sender)"
attr_reader :id, :date, :from, :subj, :refs, :replytos, :to, :source,
- :cc, :bcc, :labels, :list_address, :recipient_email, :replyto,
+ :cc, :bcc, :labels, :attachments, :list_address, :recipient_email, :replyto,
:source_info, :list_subscribe, :list_unsubscribe
bool_reader :dirty, :source_marked_read, :snippet_contains_encrypted_content
@dirty = false
@encrypted = false
@chunks = nil
+ @attachments = []
## we need to initialize this. see comments in parse_header as to
## why.
begin
Time.parse date
rescue ArgumentError => e
- raise MessageFormatError, "unparsable date #{header['date']}: #{e.message}"
+ Redwood::log "faking date header for #{@id} due to error parsing date #{header['date'].inspect}: #{e.message}"
+ Time.now
end
else
Redwood::log "faking date header for #{@id}"
@dirty = true
end
+ def remove_ref ref
+ @dirty = true if @refs.delete ref
+ end
+
def snippet; @snippet || (chunks && @snippet); end
def is_list_message?; !@list_address.nil?; end
def is_draft?; @source.is_a? DraftLoader; end
@source.fn_for_offset @source_info
end
- def sanitize_message_id mid; mid.gsub(/\s/, "") end
+ ## sanitize message ids by removing spaces and non-ascii characters.
+ ## also, truncate to 255 characters. all these steps are necessary
+ ## to make ferret happy. of course, we probably fuck up a couple
+ ## valid message ids as well. as long as we're consistent, this
+ ## should be fine, though.
+ ##
+ ## also, mostly the message ids that are changed by this belong to
+ ## spam email.
+ ##
+ ## an alternative would be to SHA1 or MD5 all message ids on a regular basis.
+ ## don't tempt me.
+ def sanitize_message_id mid; mid.gsub(/(\s|[^\000-\177])+/, "")[0..254] end
def save index
- index.sync_message self if @dirty
+ return unless @dirty
+ index.sync_message self
@dirty = false
+ true
end
def has_label? t; @labels.member? t; end
payload = RMail::Parser.read(m.body)
from = payload.header.from.first
from_person = from ? PersonManager.person_for(from.format) : nil
- [Chunk::EnclosedMessage.new(from_person, payload.to_s)]
+ [Chunk::EnclosedMessage.new(from_person, payload.to_s)] +
+ message_to_chunks(payload, encrypted)
else
filename =
## first, paw through the headers looking for a filename
## if there's a filename, we'll treat it as an attachment.
if filename
+ # add this to the attachments list if its not a generated html
+ # attachment (should we allow images with generated names?).
+ # Lowercase the filename because searches are easier that way
+ @attachments.push filename.downcase unless filename =~ /^sup-attachment-/
+ add_label :attachment unless filename =~ /^sup-attachment-/
[Chunk::Attachment.new(m.header.content_type, filename, m, sibling_types)]
## otherwise, it's body text
Iconv.iconv($encoding + "//IGNORE", charset, body + " ").join[0 .. -2]
rescue Errno::EINVAL, Iconv::InvalidEncoding, Iconv::IllegalSequence, MessageFormatError => e
Redwood::log "warning: error (#{e.class.name}) decoding message body from #{charset}: #{e.message}"
- File.open("sup-unable-to-decode.txt", "w") { |f| f.write body }
+ File.open(File.join(BASE_DIR,"unable-to-decode.txt"), "w") { |f| f.write body }
body
end
end