Skip to content

Commit 5b10b87

Browse files
committed
Add an example script for email extraction
1 parent a1e55d1 commit 5b10b87

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed

contrib/extract-email

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
#!/usr/bin/env ruby
2+
# frozen_string_literal: true
3+
4+
# This script is an example of how to extract email text from a backup.
5+
# In order to just get the email text, pass the `--quiet` option.
6+
# Please adapt it to your specific needs.
7+
8+
require "bundler/inline"
9+
10+
gemfile do
11+
source "https://rubygems.org"
12+
13+
gem "imap-backup", ">= 14.0.0"
14+
gem "optparse"
15+
gem "pry-byebug"
16+
end
17+
18+
class Options
19+
attr_reader :config_path
20+
attr_reader :account
21+
attr_reader :folder
22+
attr_reader :uid
23+
attr_reader :verbose
24+
attr_reader :quiet
25+
26+
def initialize
27+
parser.parse!
28+
29+
fail("Please supply a --config PATH option") if !config_path
30+
fail("Please supply a --account EMAIL option") if !account
31+
fail("Please supply a --folder FOLDER option") if !folder
32+
fail("Please supply a --uid UID option") if !uid
33+
34+
raise "The configuration file '#{config_path}' does not exist" if !File.exist?(config_path)
35+
end
36+
37+
def for_logging
38+
{verbose: [verbose], quiet: quiet}
39+
end
40+
41+
private
42+
43+
USAGE = "Usage: #{$PROGRAM_NAME} --config my-config.json --account me@example.com --folder INBOX --uid 12345 --quiet"
44+
45+
def parser
46+
@parser ||= OptionParser.new do |opts|
47+
opts.banner = <<~BANNER
48+
Extract email text from an imap-backup backup file.#{' '}
49+
50+
#{USAGE}
51+
52+
Configuration:
53+
BANNER
54+
55+
opts.on("--config=CONFIG", "The path to an existing (or new) imap-backup config file") do |v|
56+
@config_path = v
57+
end
58+
opts.on("--account=EMAIL", "The email address of the account") do |v|
59+
@account = v
60+
end
61+
opts.on("--folder=FOLDER", "The folder to extract from") do |v|
62+
@folder = v
63+
end
64+
opts.on("--uid=UID", "The UID of the email to extract") do |v|
65+
@uid = v
66+
end
67+
opts.on("-q", "--quiet", "Do not print any output") do
68+
@quiet = true
69+
end
70+
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
71+
@verbose = v
72+
end
73+
end
74+
end
75+
76+
def fail(message)
77+
$stderr.puts message
78+
$stderr.puts
79+
$stderr.puts USAGE
80+
exit 1
81+
end
82+
end
83+
84+
options = Options.new
85+
86+
require "imap/backup/logger"
87+
require "imap/backup/configuration"
88+
require "imap/backup/account/serialized_folders"
89+
90+
Imap::Backup::Logger.setup_logging(options.for_logging)
91+
92+
Imap::Backup::Logger.logger.info(
93+
"Extract #{options.account}, folder '#{options.folder}' message '#{options.uid}'"
94+
)
95+
96+
Imap::Backup::Logger.logger.info("Loading imap-backup configuration '#{options.config_path}'")
97+
98+
config = Imap::Backup::Configuration.new(path: options.config_path)
99+
account = config.accounts.find { |a| a.username == options.account }
100+
101+
raise "Account '#{options.account}' not found in the configuration" if !account
102+
103+
serialized_folders = Imap::Backup::Account::SerializedFolders.new(account: account)
104+
serializer, _folder = serialized_folders.find do |_s, f|
105+
f.name == options.folder
106+
end
107+
raise "Folder '#{folder_name}' not found" if !serializer
108+
109+
message = serializer.each_message([options.uid]).first
110+
raise "Message '#{options.uid}' not found in folder '#{options.folder}'" if !message
111+
112+
puts message.body

0 commit comments

Comments
 (0)