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



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

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

Instance Method Details

#encodingObject



130
131
132
# File 'lib/vmail/message_formatter.rb', line 130

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

#extract_headers(mail = @mail) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/vmail/message_formatter.rb', line 113

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),
    'subject' => utf8(mail.subject)
  }
  if !mail.cc.nil?
    headers['cc'] = utf8(mail['cc'].decoded.to_s)
  end
  if !mail.reply_to.nil?
    headers['reply_to'] = utf8(mail['reply_to'].decoded)
  end
  headers
rescue
  {'error' => $!}
end

#find_text_or_html_part(parts = @mail.parts) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/vmail/message_formatter.rb', line 68

def find_text_or_html_part(parts = @mail.parts)
  if parts.empty?
    return @mail
  end
  part = parts.detect {|part| part.multipart?}
  if part
    find_text_or_html_part(part.parts)
  else
    # no multipart part
    part = parts.detect {|part| (part.header["Content-Type"].to_s =~ /text\/plain/) }
    if part
      return part
    else
      parts.first
    end
  end
end

#format_html_body(part) ⇒ Object

depend on lynx or whatever is set by the VMAIL_HTML_PART_READER variable



98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/vmail/message_formatter.rb', line 98

def format_html_body(part)
  html_tool = ENV['VMAIL_HTML_PART_READER'] || 'lynx -stdin -dump'
  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'
    Iconv.conv('UTF-8//TRANSLIT//IGNORE', charset, output) 
  else
    output
  end
end

#format_part(part) ⇒ Object



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

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)
      process_body(m)
    else # just format_text on it anyway
      format_text_body(part) 
    end
  else 
    "[NO BODY]" 
  end
rescue
  puts $!
  "[error:] #{$!}"
end

#format_text_body(part) ⇒ Object



86
87
88
89
90
91
92
93
94
# File 'lib/vmail/message_formatter.rb', line 86

def format_text_body(part)
  text = part.body.decoded.gsub("\r", '')
  charset = (part.content_type_parameters && part.content_type_parameters['charset']) || encoding
  if (charset && charset != 'UTF-8') || (text.encoding != 'UTF-8')
    Iconv.conv('UTF-8//TRANSLIT//IGNORE', charset, text)
  else
    text
  end
end

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



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

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

#process_body(target = @mail) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/vmail/message_formatter.rb', line 28

def process_body(target = @mail)
  out = if target.header['Content-Type'].to_s =~ /multipart\/mixed/
    target.parts.map {|part| 
      if part.multipart?
        part = find_text_or_html_part(target.parts)
        format_part(part) 
      else
        format_part(part) 
      end
    }.join("\n#{'-' * 39}\n")
  elsif target.header['Content-Type'].to_s =~ /multipart\/alternative/
    part = find_text_or_html_part(target.parts)
    format_part(part) 
  else
    format_part(target)
  end
  out
end

#utf8(string, this_encoding = encoding) ⇒ Object



134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/vmail/message_formatter.rb', line 134

def utf8(string, this_encoding = encoding)
  return '' unless string
  out = if this_encoding && this_encoding.upcase != 'UTF-8' 
          Iconv.conv('UTF-8//TRANSLIT/IGNORE', this_encoding, string)
        elsif this_encoding.upcase == 'UTF-8' 
          string 
        else
          # assume UTF-8
          Iconv.conv('US-ASCII//TRANSLIT/IGNORE', 'UTF-8', string)
        end
  out
rescue
  "[error: #$!]"
end