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



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

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

#extract_headers(mail = @mail) ⇒ Object



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

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



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

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



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

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



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

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



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

def format_text_body(part)
  text = part.body.decoded.gsub("\r", '')
  charset = part.content_type_parameters && part.content_type_parameters['charset']
  if charset && charset != '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
# File 'lib/vmail/message_formatter.rb', line 28

def process_body(target = @mail)
  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
end

#utf8(string) ⇒ Object



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

def utf8(string)
  return '' unless string
  return string unless encoding
  if encoding && encoding != 'UTF-8'
    Iconv.conv('UTF-8//TRANSLIT/IGNORE', encoding, string)
  else
    string
  end
rescue
  puts $!
  string
end