imap-backup 3.4.0 → 4.0.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +2 -2
  3. data/.rubocop_todo.yml +1 -1
  4. data/CHANGELOG.md +19 -0
  5. data/README.md +22 -8
  6. data/bin/imap-backup +3 -93
  7. data/imap-backup +9 -0
  8. data/imap-backup.gemspec +2 -3
  9. data/lib/email/mboxrd/message.rb +2 -2
  10. data/lib/imap/backup/account/connection.rb +16 -33
  11. data/lib/imap/backup/cli/backup.rb +21 -0
  12. data/lib/imap/backup/cli/folders.rb +27 -0
  13. data/lib/imap/backup/cli/helpers.rb +20 -0
  14. data/lib/imap/backup/cli/local.rb +70 -0
  15. data/lib/imap/backup/cli/restore.rb +19 -0
  16. data/lib/imap/backup/cli/setup.rb +13 -0
  17. data/lib/imap/backup/cli/status.rb +26 -0
  18. data/lib/imap/backup/cli.rb +89 -0
  19. data/lib/imap/backup/configuration/account.rb +1 -11
  20. data/lib/imap/backup/configuration/list.rb +13 -12
  21. data/lib/imap/backup/version.rb +3 -3
  22. data/lib/imap/backup.rb +0 -1
  23. data/spec/unit/imap/backup/account/connection_spec.rb +31 -51
  24. data/spec/unit/imap/backup/configuration/account_spec.rb +0 -43
  25. data/spec/unit/imap/backup/configuration/list_spec.rb +1 -0
  26. metadata +23 -62
  27. data/docs/01-credentials-screen.png +0 -0
  28. data/docs/02-new-project.png +0 -0
  29. data/docs/03-initial-credentials-for-project.png +0 -0
  30. data/docs/04-credential-type-selection.png +0 -0
  31. data/docs/05-cant-create-without-consent-setup.png +0 -0
  32. data/docs/06-user-type-selection.png +0 -0
  33. data/docs/07-consent-screen-form.png +0 -0
  34. data/docs/08-app-scopes.png +0 -0
  35. data/docs/09-scope-selection.png +0 -0
  36. data/docs/10-updated-app-scopes.png +0 -0
  37. data/docs/11-test-users.png +0 -0
  38. data/docs/12-add-users.png +0 -0
  39. data/docs/13-create-oauth-client.png +0 -0
  40. data/docs/14-application-details.png +0 -0
  41. data/docs/16-initial-menu.png +0 -0
  42. data/docs/17-inputting-the-email-address.png +0 -0
  43. data/docs/18-choose-password.png +0 -0
  44. data/docs/19-supply-client-info.png +0 -0
  45. data/docs/20-choose-gmail-account.png +0 -0
  46. data/docs/21-accept-warnings.png +0 -0
  47. data/docs/22-grant-access.png +0 -0
  48. data/docs/24-confirm-choices.png +0 -0
  49. data/docs/25-success-code.png +0 -0
  50. data/docs/26-type-code-into-imap-backup.png +0 -0
  51. data/docs/27-success.png +0 -0
  52. data/docs/setting-up-gmail-with-oauth2.md +0 -166
  53. data/lib/gmail/authenticator.rb +0 -160
  54. data/lib/google/auth/stores/in_memory_token_store.rb +0 -9
  55. data/lib/imap/backup/configuration/gmail_oauth2.rb +0 -102
  56. data/spec/unit/gmail/authenticator_spec.rb +0 -138
  57. data/spec/unit/google/auth/stores/in_memory_token_store_spec.rb +0 -15
  58. data/spec/unit/imap/backup/configuration/gmail_oauth2_spec.rb +0 -121
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 44a7f8e8754461ed51afdbd5711ba809ad6b0ed68c0f40ff95a42688d85881b9
4
- data.tar.gz: a70019109a179506f520b969bb03de78fa67fca66001b182af99427b7a02ecdd
3
+ metadata.gz: 956fde3bc96dc3acd872d51905a88fa9478d9b5cd7022cf55f8e73db769d8ef7
4
+ data.tar.gz: 28d653dc4e1cfebaed0a730c0231ec13a3c3c04e1a8514352183b11f152db065
5
5
  SHA512:
6
- metadata.gz: 5055eea6a69b674f02f2b50c0423df197a4c312171aa04a19b183ce784047699815ac603d8550d28f78ada6f2aa4a904d74d5b7bef8f6ea10633de68752f7a65
7
- data.tar.gz: 7849285c5b94136b7d5f620eac770630ea4e7cf988b42cc7079021dac95163c271f5fd68d5b620ac9d36326be142557c617459ba890755920c181110cf99531a
6
+ metadata.gz: 75643fb06176ab9017d0a7673bb428df4907e1350075cf4e3429702b42f03f8a6ef8a2be1095af3b6f4032ebd682d165e05d94b2e3930397ecb31ad95b2be665
7
+ data.tar.gz: e703041a7ed4e38ced9ef1b762fb3f2ebaf178cd7beb88a204624f6dd7fc53c8f9b9635942018c0f02abfa664db90e52c17eccf3278251e23395072153fe99da
data/.circleci/config.yml CHANGED
@@ -27,7 +27,7 @@ jobs:
27
27
  type: string
28
28
  environment:
29
29
  BUNDLE_PATH: ./vendor/bundle
30
- DOCKER_IMAP_PORT: 993
30
+ DOCKER_IMAP_SERVER: 993
31
31
  docker:
32
32
  - image: "cimg/ruby:<< parameters.ruby_version >>"
33
33
  - image: antespi/docker-imap-devel:latest
@@ -48,4 +48,4 @@ workflows:
48
48
  - test:
49
49
  matrix:
50
50
  parameters:
51
- ruby_version: ["2.4", "2.5", "2.6", "2.7"]
51
+ ruby_version: ["2.5", "2.6", "2.7"]
data/.rubocop_todo.yml CHANGED
@@ -63,7 +63,7 @@ Metrics/AbcSize:
63
63
  # Offense count: 3
64
64
  # Configuration parameters: CountComments, CountAsOne.
65
65
  Metrics/ClassLength:
66
- Max: 171
66
+ Max: 172
67
67
 
68
68
  # Offense count: 19
69
69
  # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
data/CHANGELOG.md ADDED
@@ -0,0 +1,19 @@
1
+ # Change Log
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
+ and this project adheres to [Semantic Versioning](http://semver.org/).
6
+
7
+ ## [4.0.0.rc2] - 2021-11-18
8
+
9
+ ### Removed
10
+
11
+ * GMail OAuth2 support. Tokens only last a few days, so this authentication
12
+ method is not usable for automated backups.
13
+
14
+ ## [4.0.0.rc1] - 2021-11-17
15
+
16
+ ### Added
17
+
18
+ * `local` commands to list accounts, folders and emails and to view single
19
+ emails.
data/README.md CHANGED
@@ -20,20 +20,24 @@
20
20
 
21
21
  To use imap-backup with GMail, you will need to enable 'App passwords' on your account.
22
22
 
23
- ## GMail OAuth2
23
+ # Installation
24
+
25
+ ```shell
26
+ $ gem install 'imap-backup'
27
+ ```
24
28
 
25
- GMail OAuth2 authentication is supported, but as GMail's policy requires
26
- users to set up an application specific to their account, the feature
27
- is disabled by default.
29
+ # Commands
28
30
 
29
- You will need to set the environment variable IMAP_BACKUP_ENABLE_GMAIL_OAUTH2.
31
+ For a full list, run
30
32
 
31
- To set it up, [follow the HOWTO](docs/setting-up-gmail-with-oauth2.md).
33
+ ```
34
+ $ imap-backup help
35
+ ```
32
36
 
33
- # Installation
37
+ For more information about a command, run
34
38
 
35
39
  ```shell
36
- $ gem install 'imap-backup'
40
+ $ imap-backup help COMMAND
37
41
  ```
38
42
 
39
43
  # Setup
@@ -148,6 +152,16 @@ Each folder is saved to an mbox file.
148
152
  Alongside each mbox is a file with extension '.imap', which lists the source IMAP
149
153
  UIDs to allow a full restore.
150
154
 
155
+ # Local commands
156
+
157
+ There a various commands for viewing local backup status.
158
+
159
+ To view the list, use
160
+
161
+ ```shell
162
+ $ imap_backup help local
163
+ ```
164
+
151
165
  # Troubleshooting
152
166
 
153
167
  If you have problems:
data/bin/imap-backup CHANGED
@@ -1,98 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
- require "optparse"
3
2
 
4
3
  $LOAD_PATH.unshift(File.expand_path("../lib/", __dir__))
5
- require "imap/backup"
4
+ require "imap/backup/cli"
6
5
 
7
- KNOWN_COMMANDS = [
8
- {name: "setup", help: "Create/edit the configuration file"},
9
- {name: "backup", help: "Do the backup (default)"},
10
- {name: "folders", help: "List folders for all (or selected) accounts"},
11
- {name: "restore", help: "Restore emails to server"},
12
- {name: "status", help: "List count of non backed-up emails per folder"},
13
- {name: "help", help: "Show usage"}
14
- ].freeze
6
+ Imap::Backup::Configuration::List.new.setup_logging
15
7
 
16
- options = {command: "backup"}
17
- parser = OptionParser.new do |opts|
18
- opts.banner = "Usage: #{$PROGRAM_NAME} [options] COMMAND"
19
-
20
- opts.separator ""
21
- opts.separator "Commands:"
22
- KNOWN_COMMANDS.each do |command|
23
- opts.separator format("\t%- 20<name>s %<help>s", command)
24
- end
25
- opts.separator ""
26
- opts.separator "Common options:"
27
-
28
- opts.on(
29
- "-a",
30
- "--accounts ACCOUNT1[,ACCOUNT2,...]",
31
- Array,
32
- "only these accounts"
33
- ) do |account|
34
- options[:accounts] = account
35
- end
36
-
37
- opts.on_tail("-h", "--help", "Show usage") do
38
- puts opts
39
- exit
40
- end
41
-
42
- opts.on_tail("--version", "Show version") do
43
- puts Imap::Backup::VERSION
44
- exit
45
- end
46
- end
47
- parser.parse!
48
-
49
- options[:command] = ARGV.shift if !ARGV.empty?
50
-
51
- # rubocop:disable Style/IfUnlessModifier
52
- if KNOWN_COMMANDS.find { |c| c[:name] == options[:command] }.nil?
53
- raise "Unknown command '#{options[:command]}'"
54
- end
55
-
56
- # rubocop:enable Style/IfUnlessModifier
57
-
58
- if options[:command] == "help"
59
- puts parser
60
- exit
61
- end
62
-
63
- begin
64
- configuration = Imap::Backup::Configuration::List.new(options[:accounts])
65
- rescue Imap::Backup::ConfigurationNotFound
66
- Imap::Backup::Configuration::Setup.new.run
67
- exit
68
- end
69
-
70
- configuration.setup_logging
71
-
72
- case options[:command]
73
- when "setup"
74
- Imap::Backup::Configuration::Setup.new.run
75
- when "backup"
76
- configuration.each_connection(&:run_backup)
77
- when "folders"
78
- configuration.each_connection do |connection|
79
- puts connection.username
80
- folders = connection.folders
81
- if folders.nil?
82
- warn "Unable to list account folders"
83
- exit 1
84
- end
85
- folders.each { |f| puts "\t#{f}" }
86
- end
87
- when "restore"
88
- configuration.each_connection(&:restore)
89
- when "status"
90
- configuration.each_connection do |connection|
91
- puts connection.username
92
- folders = connection.status
93
- folders.each do |f|
94
- missing_locally = f[:remote] - f[:local]
95
- puts "#{f[:name]}: #{missing_locally.size}"
96
- end
97
- end
98
- end
8
+ Imap::Backup::CLI.start(ARGV)
data/imap-backup ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift(File.expand_path("../lib/", __dir__))
4
+ require "imap/backup/cli"
5
+
6
+ Imap::Backup::CLI.start(ARGV)
7
+
8
+ __END__
9
+
data/imap-backup.gemspec CHANGED
@@ -13,14 +13,13 @@ Gem::Specification.new do |gem|
13
13
  gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
14
14
  gem.test_files = gem.files.grep(%r{^spec/})
15
15
  gem.require_paths = ["lib"]
16
- gem.required_ruby_version = [">= 2.4.0"]
16
+ gem.required_ruby_version = ">= 2.5"
17
17
  gem.version = Imap::Backup::VERSION
18
18
 
19
- gem.add_runtime_dependency "gmail_xoauth"
20
- gem.add_runtime_dependency "googleauth"
21
19
  gem.add_runtime_dependency "highline"
22
20
  gem.add_runtime_dependency "mail"
23
21
  gem.add_runtime_dependency "rake"
22
+ gem.add_runtime_dependency "thor", "~> 1.1"
24
23
 
25
24
  gem.add_development_dependency "codeclimate-test-reporter", "~> 0.4.8"
26
25
  if RUBY_ENGINE == "jruby"
@@ -36,12 +36,12 @@ module Email::Mboxrd
36
36
  supplied_body.gsub(/(?<!\r)\n/, "\r\n")
37
37
  end
38
38
 
39
- private
40
-
41
39
  def parsed
42
40
  @parsed ||= Mail.new(supplied_body)
43
41
  end
44
42
 
43
+ private
44
+
45
45
  def from
46
46
  @from ||=
47
47
  begin
@@ -1,15 +1,11 @@
1
1
  require "net/imap"
2
- require "gmail_xoauth"
3
2
 
4
- require "gmail/authenticator"
5
3
  require "retry_on_error"
6
4
 
7
5
  module Imap::Backup
8
6
  module Account; end
9
7
 
10
8
  class Account::Connection
11
- class InvalidGmailOauth2RefreshToken < StandardError; end
12
-
13
9
  include RetryOnError
14
10
 
15
11
  LOGIN_RETRY_CLASSES = [EOFError, Errno::ECONNRESET, SocketError].freeze
@@ -73,6 +69,19 @@ module Imap::Backup
73
69
  end
74
70
  end
75
71
 
72
+ def local_folders
73
+ return enum_for(:local_folders) if !block_given?
74
+
75
+ glob = File.join(local_path, "**", "*.imap")
76
+ base = Pathname.new(local_path)
77
+ Pathname.glob(glob) do |path|
78
+ name = path.relative_path_from(base).to_s[0..-6]
79
+ serializer = Serializer::Mbox.new(local_path, name)
80
+ folder = Account::Folder.new(self, name)
81
+ yield serializer, folder
82
+ end
83
+ end
84
+
76
85
  def restore
77
86
  local_folders do |serializer, folder|
78
87
  restore_folder serializer, folder
@@ -80,7 +89,7 @@ module Imap::Backup
80
89
  end
81
90
 
82
91
  def disconnect
83
- imap.disconnect
92
+ imap.disconnect if @imap
84
93
  end
85
94
 
86
95
  def reconnect
@@ -96,17 +105,8 @@ module Imap::Backup
96
105
  "Creating IMAP instance: #{server}, options: #{options.inspect}"
97
106
  )
98
107
  imap = Net::IMAP.new(server, options)
99
- if use_gmail_oauth2? && Gmail::Authenticator.refresh_token?(password)
100
- authenticator = Gmail::Authenticator.new(email: username, token: password)
101
- credentials = authenticator.credentials
102
- raise InvalidGmailOauth2RefreshToken if !credentials
103
-
104
- Imap::Backup.logger.debug "Logging in with OAuth2 token: #{username}"
105
- imap.authenticate("XOAUTH2", username, credentials.access_token)
106
- else
107
- Imap::Backup.logger.debug "Logging in: #{username}/#{masked_password}"
108
- imap.login(username, password)
109
- end
108
+ Imap::Backup.logger.debug "Logging in: #{username}/#{masked_password}"
109
+ imap.login(username, password)
110
110
  Imap::Backup.logger.debug "Login complete"
111
111
  imap
112
112
  end
@@ -168,23 +168,6 @@ module Imap::Backup
168
168
  password.gsub(/./, "x")
169
169
  end
170
170
 
171
- def use_gmail_oauth2?
172
- # TODO: test use of ENV
173
- server == Email::Provider::GMAIL_IMAP_SERVER &&
174
- ENV["IMAP_BACKUP_ENABLE_GMAIL_OAUTH2"]
175
- end
176
-
177
- def local_folders
178
- glob = File.join(local_path, "**", "*.imap")
179
- base = Pathname.new(local_path)
180
- Pathname.glob(glob) do |path|
181
- name = path.relative_path_from(base).to_s[0..-6]
182
- serializer = Serializer::Mbox.new(local_path, name)
183
- folder = Account::Folder.new(self, name)
184
- yield serializer, folder
185
- end
186
- end
187
-
188
171
  def backup_folders
189
172
  @backup_folders ||=
190
173
  begin
@@ -0,0 +1,21 @@
1
+ module Imap::Backup
2
+ class CLI::Backup < Thor
3
+ include Thor::Actions
4
+ include CLI::Helpers
5
+
6
+ attr_reader :account_names
7
+
8
+ def initialize(options)
9
+ super([])
10
+ @account_names = (options[:accounts] || "").split(",")
11
+ end
12
+
13
+ no_commands do
14
+ def run
15
+ each_connection(account_names) do |connection|
16
+ connection.run_backup
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,27 @@
1
+ module Imap::Backup
2
+ class CLI::Folders < Thor
3
+ include Thor::Actions
4
+ include CLI::Helpers
5
+
6
+ attr_reader :account_names
7
+
8
+ def initialize(options)
9
+ super([])
10
+ @account_names = (options[:accounts] || "").split(",")
11
+ end
12
+
13
+ no_commands do
14
+ def run
15
+ each_connection(account_names) do |connection|
16
+ puts connection.username
17
+ folders = connection.folders
18
+ if folders.nil?
19
+ warn "Unable to list account folders"
20
+ return false
21
+ end
22
+ folders.each { |f| puts "\t#{f}" }
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,20 @@
1
+ require "imap/backup"
2
+
3
+ module Imap::Backup::CLI::Helpers
4
+ def symbolized(options)
5
+ options.each.with_object({}) { |(k, v), acc| acc[k.intern] = v }
6
+ end
7
+
8
+ def each_connection(names)
9
+ begin
10
+ connections = Imap::Backup::Configuration::List.new(names)
11
+ rescue Imap::Backup::ConfigurationNotFound
12
+ raise "imap-backup is not configured. Run `imap-backup setup`"
13
+ return
14
+ end
15
+
16
+ connections.each_connection do |connection|
17
+ yield connection
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,70 @@
1
+ module Imap::Backup
2
+ class CLI::Local < Thor
3
+ include Thor::Actions
4
+ include CLI::Helpers
5
+
6
+ desc "accounts", "List locally backed-up accounts"
7
+ def accounts
8
+ connections = Imap::Backup::Configuration::List.new
9
+ connections.accounts.each { |a| puts a[:username] }
10
+ end
11
+
12
+ desc "folders EMAIL", "List account folders"
13
+ def folders(email)
14
+ connections = Imap::Backup::Configuration::List.new
15
+ account = connections.accounts.find { |a| a[:username] == email }
16
+ raise "#{email} is not a configured account" if !account
17
+
18
+ account_connection = Imap::Backup::Account::Connection.new(account)
19
+ account_connection.local_folders.each do |_s, f|
20
+ puts %("#{f.name}")
21
+ end
22
+ end
23
+
24
+ desc "emails EMAIL FOLDER", "List emails in a folder"
25
+ def emails(email, folder_name)
26
+ connections = Imap::Backup::Configuration::List.new
27
+ account = connections.accounts.find { |a| a[:username] == email }
28
+ raise "#{email} is not a configured account" if !account
29
+
30
+ account_connection = Imap::Backup::Account::Connection.new(account)
31
+ folder_serializer, folder = account_connection.local_folders.find do |(_s, f)|
32
+ f.name == folder_name
33
+ end
34
+ raise "Folder '#{folder_name}' not found" if !folder_serializer
35
+
36
+ max_subject = 60
37
+ puts format("%-10<uid>s %-#{max_subject}<subject>s - %<date>s", {uid: "UID", subject: "Subject", date: "Date"})
38
+ puts "-" * (12 + max_subject + 28)
39
+
40
+ uids = folder_serializer.uids
41
+
42
+ folder_serializer.each_message(uids).map do |uid, message|
43
+ m = {uid: uid, date: message.parsed.date.to_s, subject: message.parsed.subject}
44
+ if m[:subject].length > max_subject
45
+ puts format("% 10<uid>u: %.#{max_subject - 3}<subject>s... - %<date>s", m)
46
+ else
47
+ puts format("% 10<uid>u: %-#{max_subject}<subject>s - %<date>s", m)
48
+ end
49
+ end
50
+ end
51
+
52
+ desc "email EMAIL FOLDER UID", "Show an email"
53
+ def email(email, folder_name, uid)
54
+ connections = Imap::Backup::Configuration::List.new
55
+ account = connections.accounts.find { |a| a[:username] == email }
56
+ raise "#{email} is not a configured account" if !account
57
+
58
+ account_connection = Imap::Backup::Account::Connection.new(account)
59
+ folder_serializer, _folder = account_connection.local_folders.find do |(_s, f)|
60
+ f.name == folder_name
61
+ end
62
+ raise "Folder '#{folder_name}' not found" if !folder_serializer
63
+
64
+ loaded_message = folder_serializer.load(uid)
65
+ raise "Message #{uid} not found in folder '#{folder_name}'" if !loaded_message
66
+
67
+ puts loaded_message.supplied_body
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,19 @@
1
+ module Imap::Backup
2
+ class CLI::Restore < Thor
3
+ include Thor::Actions
4
+ include CLI::Helpers
5
+
6
+ attr_reader :account_names
7
+
8
+ def initialize(options)
9
+ super([])
10
+ @account_names = (options[:accounts] || "").split(",")
11
+ end
12
+
13
+ no_commands do
14
+ def run
15
+ each_connection(account_names) { |connection| connection.restore }
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ class Imap::Backup::CLI::Setup < Thor
2
+ include Thor::Actions
3
+
4
+ def initialize()
5
+ super([])
6
+ end
7
+
8
+ no_commands do
9
+ def run
10
+ Imap::Backup::Configuration::Setup.new.run
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,26 @@
1
+ module Imap::Backup
2
+ class CLI::Status < Thor
3
+ include Thor::Actions
4
+ include CLI::Helpers
5
+
6
+ attr_reader :account_names
7
+
8
+ def initialize(options)
9
+ super([])
10
+ @account_names = (options[:accounts] || "").split(",")
11
+ end
12
+
13
+ no_commands do
14
+ def run
15
+ each_connection(account_names) do |connection|
16
+ puts connection.username
17
+ folders = connection.status
18
+ folders.each do |f|
19
+ missing_locally = f[:remote] - f[:local]
20
+ puts "#{f[:name]}: #{missing_locally.size}"
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,89 @@
1
+ require "thor"
2
+
3
+ module Imap::Backup
4
+ class CLI < Thor
5
+ require "imap/backup/cli/helpers"
6
+
7
+ autoload :Backup, "imap/backup/cli/backup"
8
+ autoload :Folders, "imap/backup/cli/folders"
9
+ autoload :Local, "imap/backup/cli/local"
10
+ autoload :Remote, "imap/backup/cli/remote"
11
+ autoload :Restore, "imap/backup/cli/restore"
12
+ autoload :Setup, "imap/backup/cli/setup"
13
+ autoload :Status, "imap/backup/cli/status"
14
+
15
+ include Helpers
16
+
17
+ default_task :backup
18
+
19
+ def self.exit_on_failure?
20
+ true
21
+ end
22
+
23
+ def self.accounts_option
24
+ method_option(
25
+ "accounts",
26
+ type: :string,
27
+ banner: "a comma-separated list of accounts (defaults to all configured accounts)",
28
+ aliases: ["-a"]
29
+ )
30
+ end
31
+
32
+ desc "backup [OPTIONS]", "Run the backup"
33
+ long_desc <<~DESC
34
+ Downloads any emails not yet present locally.
35
+ Runs the backup for each configured account,
36
+ or for those requested via the --accounts option.
37
+ By default all folders, are backed up.
38
+ The setup tool can be used to choose a specific list of folders to back up.
39
+ DESC
40
+ accounts_option
41
+ def backup
42
+ Backup.new(symbolized(options)).run
43
+ end
44
+
45
+ desc "folders [OPTIONS]", "This command is deprecated, use `imap-backup remote folders ACCOUNT`"
46
+ long_desc <<~DESC
47
+ Lists all folders of all configured accounts.
48
+ This command is deprecated.
49
+ Instead, use a combination of `imap-backup local accounts` to get the list of accounts,
50
+ and `imap-backup remote folders ACCOUNT` to get the folder list.
51
+ DESC
52
+ accounts_option
53
+ def folders
54
+ Folders.new(symbolized(options)).run
55
+ end
56
+
57
+ desc "restore [OPTIONS]", "This command is deprecated, use `imap-backup restore ACCOUNT`"
58
+ long_desc <<~DESC
59
+ By default, restores all local emails to their respective servers.
60
+ This command is deprecated.
61
+ Instead, use `imap-backup restore ACCOUNT` to restore a single account.
62
+ DESC
63
+ accounts_option
64
+ def restore
65
+ Restore.new(symbolized(options)).run
66
+ end
67
+
68
+ desc "setup", "Configure imap-backup"
69
+ long_desc <<~DESC
70
+ A menu-driven command-line application used to configure imap-backup.
71
+ Configure email accounts to back up.
72
+ DESC
73
+ def setup
74
+ Setup.new().run
75
+ end
76
+
77
+ desc "status", "Show backup status"
78
+ long_desc <<~DESC
79
+ For each configured account and folder, lists the number of emails yet to be downloaded.
80
+ DESC
81
+ accounts_option
82
+ def status
83
+ Status.new(symbolized(options)).run
84
+ end
85
+
86
+ desc "local SUBCOMMAND [OPTIONS]", "View local info"
87
+ subcommand "local", Local
88
+ end
89
+ end
@@ -68,12 +68,7 @@ module Imap::Backup
68
68
 
69
69
  def modify_password(menu)
70
70
  menu.choice("modify password") do
71
- password =
72
- if use_gmail_oauth2?(account)
73
- Configuration::GmailOauth2.new(account).run
74
- else
75
- Configuration::Asker.password
76
- end
71
+ password = Configuration::Asker.password
77
72
 
78
73
  if !password.nil?
79
74
  account[:password] = password
@@ -82,11 +77,6 @@ module Imap::Backup
82
77
  end
83
78
  end
84
79
 
85
- def use_gmail_oauth2?(account)
86
- account[:server] == Email::Provider::GMAIL_IMAP_SERVER &&
87
- ENV["IMAP_BACKUP_ENABLE_GMAIL_OAUTH2"]
88
- end
89
-
90
80
  def modify_server(menu)
91
81
  menu.choice("modify server") do
92
82
  server = highline.ask("server: ")