Class: Vmail::MessageFormatter

Inherits:
Object
  • Object
show all
Defined in:
lib/vmail/message_formatter.rb

Instance Method Summary collapse

Constructor Details

#initialize(mail, uid = nil) ⇒ MessageFormatter

initialize with a Mail object



7
8
9
10
# File 'lib/vmail/message_formatter.rb', line 7

def initialize(mail, uid = nil)
  @mail = mail
  @uid = uid
end

Instance Method Details

#encodingObject



104
105
106
# File 'lib/vmail/message_formatter.rb', line 104

def encoding
  @encoding ||= @mail.header.charset || 'UTF-8'
end

#extract_headers(mail = @mail) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/vmail/message_formatter.rb', line 90

def extract_headers(mail = @mail)
  headers = {
    'from' => utf8(mail['from'].decoded),
    'date' => (mail.date.strftime('%a, %b %d %I:%M %p %Z %Y') rescue mail.date),
    'to' => mail['to'].nil? ? nil : utf8(mail['to'].decoded),
    'cc' => (mail.cc && utf8(mail['cc'].decoded.to_s)),
    'reply_to' => (mail.reply_to && utf8(mail['reply_to'].decoded)),
    'subject' => utf8(mail.subject)
  }
  headers
rescue
  {'error' => $!}
end

#find_text_part2(part, content_type) ⇒ Object

helper method



34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/vmail/message_formatter.rb', line 34

def find_text_part2(part, content_type)
  if part.multipart?
    part.parts.
      map {|p| find_text_part2(p, p.content_type)}.
      compact.
      select {|p| !p.attachment?}.
      first
  elsif content_type =~ %r[^text/plain] ||
    content_type =~ %r[text/plain] ||
    content_type =~ %r[message/rfc]
    part
  end
end

#format_html_body(part) ⇒ Object

depend on VMAIL_HTML_PART_READER variable



75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/vmail/message_formatter.rb', line 75

def format_html_body(part)
  html_tool = ENV['VMAIL_HTML_PART_READER']
  html = part.body.decoded.gsub("\r", '')
  stdin, stdout, stderr = Open3.popen3(html_tool)
  stdin.puts html
  stdin.close
  output = "[vmail: html part translated into plaintext by '#{ html_tool }']\n\n" + stdout.read
  charset = part.content_type_parameters && part.content_type_parameters['charset']
  if charset && charset != 'UTF-8'
    output.encode!('utf-8', charset, undef: :replace, invalid: :replace)
  else
    output
  end
end

#format_part(part) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/vmail/message_formatter.rb', line 48

def format_part(part)
  if part && part.respond_to?(:header)
    case part.header["Content-Type"].to_s
    when /text\/html/
      format_html_body(part)
    when /text\/plain/
      format_text_body(part)
    when /message\/rfc/
      m = Mail.new(part.body.decoded)
      plaintext_part(m)
    else # just format_text on it anyway
      format_text_body(part)
    end
  else
    part.decoded.gsub("\r", '')
  end
rescue
  puts $!
  "[error:] #{$!}"
end

#format_text_body(part) ⇒ Object



69
70
71
# File 'lib/vmail/message_formatter.rb', line 69

def format_text_body(part)
  part.body.decoded.gsub("\r", '')
end

#list_parts(parts = (@mail.parts.empty? ? [@mail] : @mail.parts)) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
# File 'lib/vmail/message_formatter.rb', line 12

def list_parts(parts = (@mail.parts.empty? ? [@mail] : @mail.parts))
  lines = parts.map do |part|
    if part.multipart?
      list_parts(part.parts)
    else
      # part.charset could be used
      "- #{ part.content_type } #{ part.attachment? ? part.filename : '' }"
    end
  end
  lines.flatten
end

#plaintext_part(mail = @mail) ⇒ Object



24
25
26
27
28
29
30
31
# File 'lib/vmail/message_formatter.rb', line 24

def plaintext_part(mail=@mail)
  part = find_text_part2(mail.body, mail.content_type)
  if part.nil?
    format_part(@mail || '')
  else
    format_part part
  end
end

#utf8(string, this_encoding = encoding) ⇒ Object



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/vmail/message_formatter.rb', line 108

def utf8(string, this_encoding = encoding)
  return '' unless string
  out = if this_encoding && this_encoding.upcase != 'UTF-8'
          string.encode!('utf-8', this_encoding, undef: :replace, invalid: :replace)
        elsif this_encoding.upcase == 'UTF-8'
          string
        else
          # assume UTF-8 and convert to ascii
          string.encode!('us-ascii', 'utf-8', undef: :replace, invalid: :replace)
        end
  out
rescue
  $logger.debug $!
  "[error: #$!]"
end