Class: MsgExtractor::CLI

Inherits:
Object
  • Object
show all
Defined in:
lib/msg_extractor/cli.rb

Class Method Summary collapse

Class Method Details

.json_for(msg, file) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/msg_extractor/cli.rb', line 58

def self.json_for(msg, file)
  {
    file: file,
    message_class: msg.message_class,
    subject: msg.subject,
    date: msg.date&.utc&.iso8601,
    sender: msg.sender && { name: msg.sender.name, email: msg.sender.email },
    to: msg.to.map { |r| { name: r.name, email: r.email } },
    cc: msg.cc.map { |r| { name: r.name, email: r.email } },
    bcc: msg.bcc.map { |r| { name: r.name, email: r.email } },
    body: msg.body,
    html_body: msg.html_body,
    attachments: msg.attachments.map do |a|
      { filename: a.filename, mime_type: a.mime_type, content_id: a.content_id,
        size: a.size, embedded_message: a.embedded_message? }
    end
  }
end

.run(argv, stdout: $stdout, stderr: $stderr) ⇒ Object



8
9
10
11
12
13
14
15
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
48
49
50
51
52
53
54
55
56
# File 'lib/msg_extractor/cli.rb', line 8

def self.run(argv, stdout: $stdout, stderr: $stderr)
  options = { out: ".", json: false, attachments_only: false }
  parser = OptionParser.new do |opts|
    opts.banner = "Usage: msg_extractor FILE... [options]"
    opts.on("--out DIR", "Output directory (default: current directory)") do |dir|
      options[:out] = dir
    end
    opts.on("--json", "Print one JSON object per file to stdout instead of saving") do
      options[:json] = true
    end
    opts.on("--attachments-only", "Save only the attachments, flat into --out") do
      options[:attachments_only] = true
    end
    opts.on("--version", "Print version") do
      stdout.puts MsgExtractor::VERSION
      return 0
    end
  end

  begin
    files = parser.parse(argv)
  rescue OptionParser::ParseError => e
    stderr.puts e.message
    stderr.puts parser.banner
    return 2
  end
  if files.empty?
    stderr.puts parser.banner
    return 2
  end

  status = 0
  files.each do |file|
    msg = MsgExtractor.open(file)
    if options[:json]
      stdout.puts JSON.generate(json_for(msg, file))
    elsif options[:attachments_only]
      FileUtils.mkdir_p(options[:out])
      msg.attachments.reject(&:embedded_message?).each { |a| a.save(dir: options[:out]) }
    else
      FileUtils.mkdir_p(options[:out])
      msg.save(dir: options[:out])
    end
  rescue MsgExtractor::Error, SystemCallError => e
    stderr.puts "#{file}: #{e.message}"
    status = 1
  end
  status
end