Module: Vmail::ShowingMessage

Included in:
ImapClient
Defined in:
lib/vmail/showing_message.rb

Instance Method Summary collapse

Instance Method Details

#cached_full_message?(message_id) ⇒ Boolean

Returns:

  • (Boolean)


15
16
17
18
19
20
21
22
23
24
# File 'lib/vmail/showing_message.rb', line 15

def cached_full_message?(message_id)
  m = Message[message_id]
  if m
    log "- found message #{ message_id }"
    log "- message has plaintext? #{!m.plaintext.nil?}"
  else
    log "- could not find message #{ message_id.inspect }"
  end
  m && !m.plaintext.nil? && m
end

#current_mailObject



11
12
13
# File 'lib/vmail/showing_message.rb', line 11

def current_mail
  (c = current_message) && Mail.new(c.rfc822)
end

#current_messageObject



6
7
8
9
# File 'lib/vmail/showing_message.rb', line 6

def current_message
  return unless @cur_message_id
  Message[@cur_message_id]
end

#fetch_and_cache(message_id) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/vmail/showing_message.rb', line 36

def fetch_and_cache(message_id)
  if message = cached_full_message?(message_id)
    log "- full message cache hit"
    return message.plaintext
  end
  log "- full message cache miss"
  params = { message_id: message_id, label_id: @label.label_id }
  labeling = Labeling[params] || Labeling.create(params)
  unless (labeling && labeling.uid)
    log "- Labeling not found for #{ params.inspect }"
    # break out early
    return "\nUnable to get message for #{ labeling.values }"
  end
  uid = labeling.uid

  log "- fetching message uid #{ uid }"
  fetch_data = reconnect_if_necessary do
    res = retry_if_needed do
      @imap.uid_fetch(uid, ["FLAGS", "RFC822", "RFC822.SIZE"])
    end
    raise "Message uid #{ uid } could not be fetched from server" if res.nil?
    res[0]
  end
  seqno = fetch_data.seqno
  rfc822 = Mail.new(fetch_data.attr['RFC822'])
  formatter = Vmail::MessageFormatter.new rfc822

  message = Message[message_id]
  parts_list = format_parts_info(formatter.list_parts)
  headers_hash = formatter.extract_headers
  headers_hash['date']
  headers = format_headers headers_hash
  # replace the date value with the one derived from the envelope
  body = formatter.plaintext_part
  # [\w-]+ matches charsets like ISO-8851
  if /charset=([\w-]+)/.match(parts_list)
    conv_from = /charset=([\w-]+)/.match(parts_list)[1].strip
    body = body.encode!('utf-8', conv_from, undef: :replace, invalid: :replace)
  else
    body = body.encode!('us-ascii', 'utf-8', undef: :replace, invalid: :replace)
  end
  message_text = <<-EOF
#{ message_id } #{ number_to_human_size message.size } #{ message.flags } #{ parts_list }
#{ divider '-' }
#{ headers }

#{ body }
EOF
  # 2 calls so we can see more fine grained exceptions
  message.update(:rfc822 => rfc822)
  if !message_text.valid_encoding?
    message_text.encode!('utf-8', undef: :replace, invalid: :replace)
  end

  begin
    message.update(:plaintext => message_text)
  rescue
    log message_text.encoding
    #log message_text
    raise
  end
  message_text
rescue
  msg = "Error encountered in fetch_and_cache(), message_id #{ message_id } [#@mailbox]:\n#{$!}\n#{$!.backtrace.join("\n")}"
  log msg
  msg
end

#format_parts_info(parts) ⇒ Object



104
105
106
107
108
109
# File 'lib/vmail/showing_message.rb', line 104

def format_parts_info(parts)
  lines = parts #.select {|part| part !~ %r{text/plain}}
  if lines.size > 0
    "\n#{ lines.join("\n") }"
  end
end

#show_message(message_id, raw = false) ⇒ Object



26
27
28
29
30
31
32
33
34
# File 'lib/vmail/showing_message.rb', line 26

def show_message(message_id, raw=false)
  message_id = message_id.strip.gsub('\\', '')
  log "Show message: #{ message_id.inspect }"
  return current_message.rfc822 if raw
  res = retry_if_needed { fetch_and_cache(message_id) }
  log "Showing message message_id: #{ message_id }"
  @cur_message_id = message_id
  res
end