imap-backup 3.4.0 → 4.0.0.rc3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: ")