Module: Mailmate::CLI::Message Private

Extended by:
Message
Included in:
Message
Defined in:
lib/mailmate/cli/message.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

‘mmmessage` — print a decoded MailMate message by its eml-id. Ports the standalone mailmate-message script. Headers + plain-text body by default; `–raw` for the original .eml bytes; `–text-only` for just the body.

Instance Method Summary collapse

Instance Method Details

#parse_options(argv) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/mailmate/cli/message.rb', line 49

def parse_options(argv)
  opts = { raw: false, text_only: false }
  OptionParser.new do |o|
    o.banner = "Usage: mmmessage <id> [--raw|--text-only]"
    o.separator ""
    o.separator "<id> can be either a local eml-id (e.g. 183715) or an RFC"
    o.separator "Message-ID (with or without angle brackets, e.g."
    o.separator "<abc@example.com>). Message-IDs are portable across machines"
    o.separator "and survive copy/paste between desktop/laptop/iPad."
    o.on("--raw", "Output raw .eml bytes") { opts[:raw] = true }
    o.on("--text-only", "Output decoded body only (no headers block)") { opts[:text_only] = true }
  end.parse!(argv)
  opts
end

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



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
# File 'lib/mailmate/cli/message.rb', line 71

def print_headers(mail, eml_id, path)
  imap_root = Mailmate.config.imap_root
  mailbox = path.sub("#{imap_root}/", "").sub(%r{/Messages/[^/]+\.eml\z}, "")
  $stdout.puts "eml-id:     #{eml_id}"
  $stdout.puts "path:       #{path}"
  $stdout.puts "mailbox:    #{mailbox}"
  $stdout.puts "from:       #{Array(mail.from).join(", ")}" if mail.from
  $stdout.puts "to:         #{Array(mail.to).join(", ")}"   if mail.to
  $stdout.puts "cc:         #{Array(mail.cc).join(", ")}"   if mail.cc
  $stdout.puts "subject:    #{mail.subject}"
  $stdout.puts "date:       #{Mailmate.localize(mail.date)&.iso8601}"
  $stdout.puts "message-id: #{mail.message_id}"
  if mail.attachments.any?
    $stdout.puts "attachments:"
    mail.attachments.each do |a|
      sz = begin
        a.body.decoded.bytesize
      rescue StandardError
        0
      end
      $stdout.puts "  - #{a.filename || "(no name)"}  #{a.mime_type}  #{sz}b"
    end
  end
  $stdout.puts
end

#run(argv) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/mailmate/cli/message.rb', line 16

def run(argv)
  opts = parse_options(argv)
  input = argv.first

  return usage_error("missing <id>") if input.nil? || input.empty?

  # Accept either eml-id (all digits) or RFC Message-ID (with or without
  # angle brackets). Lets you copy/paste from any machine without caring
  # whether the local eml-id matches.
  eml_id = Mailmate::EmlLookup.resolve_id(input)
  if eml_id.nil? || eml_id.zero?
    warn "Not found: #{input.inspect} (couldn't resolve as eml-id or Message-ID)"
    return 1
  end

  path = Mailmate::EmlLookup.path_for(eml_id)
  unless path
    warn "Not found: #{eml_id}.eml"
    return 1
  end

  if opts[:raw]
    $stdout.binmode
    $stdout.write(File.binread(path))
    return 0
  end

  mail = Mail.read(path)
  print_headers(mail, eml_id, path) unless opts[:text_only]
  $stdout.puts text_body(mail)
  0
end

#text_body(mail) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



97
98
99
100
101
102
103
104
105
106
# File 'lib/mailmate/cli/message.rb', line 97

def text_body(mail)
  if mail.text_part
    mail.text_part.decoded.force_encoding("UTF-8").scrub
  elsif mail.html_part
    "[no text/plain part — HTML rendered below; use --raw for original]\n\n" +
      mail.html_part.decoded.force_encoding("UTF-8").scrub
  else
    mail.body.decoded.to_s.force_encoding("UTF-8").scrub
  end
end

#usage_error(msg) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



64
65
66
67
68
69
# File 'lib/mailmate/cli/message.rb', line 64

def usage_error(msg)
  warn "mmmessage: #{msg}"
  warn "Usage: mmmessage <id> [--raw|--text-only]"
  warn "  <id> is either an eml-id (digits) or an RFC Message-ID."
  2
end