imap-backup 15.0.3.rc1 → 16.0.0
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.
- checksums.yaml +4 -4
- data/docs/performance.md +5 -7
- data/imap-backup.gemspec +2 -0
- data/lib/imap/backup/account/folder.rb +5 -1
- data/lib/imap/backup/cli/helpers.rb +22 -0
- data/lib/imap/backup/cli/migrate.rb +79 -0
- data/lib/imap/backup/cli/mirror.rb +79 -0
- data/lib/imap/backup/cli/single.rb +2 -2
- data/lib/imap/backup/cli/transfer.rb +7 -6
- data/lib/imap/backup/cli.rb +20 -94
- data/lib/imap/backup/mirror.rb +5 -3
- data/lib/imap/backup/version.rb +3 -3
- metadata +33 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ac22de1cd99aab34b9d478d2ad8727faf67bbac635cf6ef80335d27012328a29
|
4
|
+
data.tar.gz: 7b74833c6e1752c1a25a201d3e3f40a05f8b966bebe38796843ee4f133191aff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0147bfef559ef12c9f6b3e41eced66cade0de85fa418bafb81eed6cfa06bd6e751d818cb8d058768a8259e69526c2a90aa504389a188146722f66f2d2671b2c
|
7
|
+
data.tar.gz: 6b48724665aa1383094053164de511e2bcfd1b3bf2b32d28bf659740e96e1e5f32a9dc37af32ec6cb0fd23fb06bd863d567ca78135bac27bb2662d6b6b6f5118
|
data/docs/performance.md
CHANGED
@@ -1,14 +1,12 @@
|
|
1
|
-
#
|
1
|
+
# Performance
|
2
2
|
|
3
|
-
The two performance-related settings are "Download strategy",
|
4
|
-
which is a global setting,
|
5
|
-
and "Multi-fetch size", which is an Account-level setting.
|
3
|
+
The two performance-related settings are "Download strategy", which is a global setting, and "Multi-fetch size", which is an Account-level setting.
|
6
4
|
|
7
5
|
As with all performance tweaks, there are trade-offs.
|
8
6
|
|
9
7
|
# Overview
|
10
8
|
|
11
|
-
The defaults, which suit most machines and
|
9
|
+
The defaults, which suit most machines and play nice with servers are:
|
12
10
|
|
13
11
|
* Download strategy: "delay writing metadata",
|
14
12
|
* Multi-fetch size: 1.
|
@@ -18,7 +16,7 @@ a small virtual server or Raspberry Pi
|
|
18
16
|
to run your backups, you can change "Download strategy".
|
19
17
|
|
20
18
|
If your email provider supports it,
|
21
|
-
and you don't have tight
|
19
|
+
and you don't have tight memory limits,
|
22
20
|
increase "Multi-fetch size" for faster backups.
|
23
21
|
|
24
22
|
# Delay download writes
|
@@ -45,7 +43,7 @@ By default, during backup, each message is downloaded one-by-one.
|
|
45
43
|
Using this setting, you can download chunks of emails at a time,
|
46
44
|
potentially speeding up the process.
|
47
45
|
|
48
|
-
Using multi-fetch
|
46
|
+
Using multi-fetch mean that the backup process *will* use
|
49
47
|
more memory - equivalent to the size of the groups of messages
|
50
48
|
that are downloaded.
|
51
49
|
|
data/imap-backup.gemspec
CHANGED
@@ -21,10 +21,12 @@ Gem::Specification.new do |gem|
|
|
21
21
|
gem.required_ruby_version = ">= 3.0"
|
22
22
|
|
23
23
|
gem.add_runtime_dependency "highline"
|
24
|
+
gem.add_runtime_dependency "logger"
|
24
25
|
gem.add_runtime_dependency "mail", "2.7.1"
|
25
26
|
gem.add_runtime_dependency "net-imap", ">= 0.3.2"
|
26
27
|
gem.add_runtime_dependency "net-smtp"
|
27
28
|
gem.add_runtime_dependency "os"
|
29
|
+
gem.add_runtime_dependency "ostruct"
|
28
30
|
gem.add_runtime_dependency "rake"
|
29
31
|
gem.add_runtime_dependency "thor", "~> 1.1"
|
30
32
|
gem.add_runtime_dependency "thunderbird", "0.3.0"
|
@@ -67,7 +67,10 @@ module Imap::Backup
|
|
67
67
|
def uids
|
68
68
|
Logger.logger.debug "Fetching UIDs for folder '#{name}'"
|
69
69
|
examine
|
70
|
-
result =
|
70
|
+
result =
|
71
|
+
retry_on_error(errors: UID_SEARCH_RETRY_CLASSES) do
|
72
|
+
client.uid_search(["ALL"]).sort
|
73
|
+
end
|
71
74
|
Logger.logger.debug "#{result.count} UIDs found for folder '#{name}'"
|
72
75
|
result
|
73
76
|
rescue FolderNotFound
|
@@ -177,6 +180,7 @@ module Imap::Backup
|
|
177
180
|
|
178
181
|
BODY_ATTRIBUTE = "BODY[]".freeze
|
179
182
|
UID_FETCH_RETRY_CLASSES = [::EOFError, ::Errno::ECONNRESET, ::IOError].freeze
|
183
|
+
UID_SEARCH_RETRY_CLASSES = [::EOFError, ::Errno::ECONNRESET, ::IOError].freeze
|
180
184
|
APPEND_RETRY_CLASSES = [::Net::IMAP::BadResponseError].freeze
|
181
185
|
CREATE_RETRY_CLASSES = [::Net::IMAP::BadResponseError].freeze
|
182
186
|
EXAMINE_RETRY_CLASSES = [::Net::IMAP::BadResponseError].freeze
|
@@ -16,6 +16,28 @@ module Imap::Backup
|
|
16
16
|
options.define_options
|
17
17
|
end
|
18
18
|
|
19
|
+
# @return [String] a description of the namespace configuration
|
20
|
+
NAMESPACE_CONFIGURATION_DESCRIPTION = <<~DESC.freeze
|
21
|
+
Some IMAP servers use namespaces (i.e. prefixes like "INBOX"),
|
22
|
+
while others, while others concatenate the names of subfolders
|
23
|
+
with a charater ("delimiter") other than "/".
|
24
|
+
|
25
|
+
In these cases there are two choices.
|
26
|
+
|
27
|
+
You can use the `--automatic-namespaces` option.
|
28
|
+
This will query the source and detination servers for their
|
29
|
+
namespace configuration and will adapt paths accordingly.
|
30
|
+
This option requires that both the source and destination
|
31
|
+
servers are available and work with the provided parameters
|
32
|
+
and authentication.
|
33
|
+
|
34
|
+
If automatic configuration does not work as desired, there are the
|
35
|
+
`--source-prefix=`, `--source-delimiter=`,
|
36
|
+
`--destination-prefix=` and `--destination-delimiter=` parameters.
|
37
|
+
To check what values you should use, check the output of the
|
38
|
+
`imap-backup remote namespaces EMAIL` command.
|
39
|
+
DESC
|
40
|
+
|
19
41
|
# Processes command-line parameters
|
20
42
|
# @return [Hash] the supplied command-line parameters with
|
21
43
|
# with hyphens in keys replaced by underscores
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Imap; end
|
2
|
+
|
3
|
+
module Imap::Backup
|
4
|
+
# Processes parameters to run the `migrate` command via command-line parameters
|
5
|
+
module CLI::Migrate
|
6
|
+
include Thor::Actions
|
7
|
+
include CLI::Helpers
|
8
|
+
|
9
|
+
LONG_DESCRIPTION = <<~DESC.freeze
|
10
|
+
This command is deprecated and will be removed in a future version.
|
11
|
+
Use 'copy' instead.
|
12
|
+
|
13
|
+
All emails which have been backed up for the "source account" (SOURCE_EMAIL) are
|
14
|
+
uploaded to the "destination account" (DESTINATION_EMAIL).
|
15
|
+
|
16
|
+
Some configuration may be necessary, as follows:
|
17
|
+
|
18
|
+
#{CLI::Helpers::NAMESPACE_CONFIGURATION_DESCRIPTION}
|
19
|
+
|
20
|
+
Finally, if you want to delete existing emails in destination folders,
|
21
|
+
use the `--reset` option. In this case, all existing emails are
|
22
|
+
deleted before uploading the migrated emails.
|
23
|
+
DESC
|
24
|
+
|
25
|
+
def self.included(base)
|
26
|
+
base.class_eval do
|
27
|
+
desc(
|
28
|
+
"migrate SOURCE_EMAIL DESTINATION_EMAIL [OPTIONS]",
|
29
|
+
"(Deprecated) Uploads backed-up emails from account SOURCE_EMAIL " \
|
30
|
+
"to account DESTINATION_EMAIL"
|
31
|
+
)
|
32
|
+
long_desc LONG_DESCRIPTION
|
33
|
+
config_option
|
34
|
+
quiet_option
|
35
|
+
verbose_option
|
36
|
+
method_option(
|
37
|
+
"automatic-namespaces",
|
38
|
+
type: :boolean,
|
39
|
+
desc: "automatically choose delimiters and prefixes"
|
40
|
+
)
|
41
|
+
method_option(
|
42
|
+
"destination-delimiter",
|
43
|
+
type: :string,
|
44
|
+
desc: "the delimiter for destination folder names"
|
45
|
+
)
|
46
|
+
method_option(
|
47
|
+
"destination-prefix",
|
48
|
+
type: :string,
|
49
|
+
desc: "the prefix (namespace) to add to destination folder names",
|
50
|
+
aliases: ["-d"]
|
51
|
+
)
|
52
|
+
method_option(
|
53
|
+
"reset",
|
54
|
+
type: :boolean,
|
55
|
+
desc: "DANGER! This option deletes all messages from destination " \
|
56
|
+
"folders before uploading",
|
57
|
+
aliases: ["-r"]
|
58
|
+
)
|
59
|
+
method_option(
|
60
|
+
"source-delimiter",
|
61
|
+
type: :string,
|
62
|
+
desc: "the delimiter for source folder names"
|
63
|
+
)
|
64
|
+
method_option(
|
65
|
+
"source-prefix",
|
66
|
+
type: :string,
|
67
|
+
desc: "the prefix (namespace) to strip from source folder names",
|
68
|
+
aliases: ["-s"]
|
69
|
+
)
|
70
|
+
# Migrates emails from one account to another
|
71
|
+
# @return [void]
|
72
|
+
def migrate(source_email, destination_email)
|
73
|
+
non_logging_options = Imap::Backup::Logger.setup_logging(options)
|
74
|
+
CLI::Transfer.new(:migrate, source_email, destination_email, non_logging_options).run
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Imap; end
|
2
|
+
|
3
|
+
module Imap::Backup
|
4
|
+
# Processes parameters to run the `mirror` command via command-line parameters
|
5
|
+
module CLI::Mirror
|
6
|
+
include Thor::Actions
|
7
|
+
include CLI::Helpers
|
8
|
+
|
9
|
+
LONG_DESCRIPTION = <<~DESC.freeze
|
10
|
+
This command is deprecated and will be removed in a future version.
|
11
|
+
Use 'copy' instead.
|
12
|
+
|
13
|
+
This command updates the DESTINATION_EMAIL account's folders to have the same contents
|
14
|
+
as those on the SOURCE_EMAIL account.
|
15
|
+
|
16
|
+
If a folder list is configured for the SOURCE_EMAIL account,
|
17
|
+
only the folders indicated by the setting are copied.
|
18
|
+
|
19
|
+
First, it runs the download of the SOURCE_EMAIL account.
|
20
|
+
If the SOURCE_EMAIL account is **not** configured to be in 'mirror' mode,
|
21
|
+
a warning is printed.
|
22
|
+
|
23
|
+
When the mirror command is used, for each folder that is processed,
|
24
|
+
a new file is created alongside the normal backup files (.imap and .mbox)
|
25
|
+
This file has a '.mirror' extension. This file contains a mapping of
|
26
|
+
the known UIDs on the source account to those on the destination account.
|
27
|
+
|
28
|
+
Some configuration may be necessary, as follows:
|
29
|
+
|
30
|
+
#{CLI::Helpers::NAMESPACE_CONFIGURATION_DESCRIPTION}
|
31
|
+
DESC
|
32
|
+
|
33
|
+
def self.included(base)
|
34
|
+
base.class_eval do
|
35
|
+
desc(
|
36
|
+
"mirror SOURCE_EMAIL DESTINATION_EMAIL [OPTIONS]",
|
37
|
+
"(Deprecated) Keeps the DESTINATION_EMAIL account aligned with the SOURCE_EMAIL account"
|
38
|
+
)
|
39
|
+
long_desc LONG_DESCRIPTION
|
40
|
+
config_option
|
41
|
+
quiet_option
|
42
|
+
verbose_option
|
43
|
+
method_option(
|
44
|
+
"automatic-namespaces",
|
45
|
+
type: :boolean,
|
46
|
+
desc: "automatically choose delimiters and prefixes"
|
47
|
+
)
|
48
|
+
method_option(
|
49
|
+
"destination-delimiter",
|
50
|
+
type: :string,
|
51
|
+
desc: "the delimiter for destination folder names"
|
52
|
+
)
|
53
|
+
method_option(
|
54
|
+
"destination-prefix",
|
55
|
+
type: :string,
|
56
|
+
desc: "the prefix (namespace) to add to destination folder names",
|
57
|
+
aliases: ["-d"]
|
58
|
+
)
|
59
|
+
method_option(
|
60
|
+
"source-delimiter",
|
61
|
+
type: :string,
|
62
|
+
desc: "the delimiter for source folder names"
|
63
|
+
)
|
64
|
+
method_option(
|
65
|
+
"source-prefix",
|
66
|
+
type: :string,
|
67
|
+
desc: "the prefix (namespace) to strip from source folder names",
|
68
|
+
aliases: ["-s"]
|
69
|
+
)
|
70
|
+
# Keeps one email account in line with another
|
71
|
+
# @return [void]
|
72
|
+
def mirror(source_email, destination_email)
|
73
|
+
non_logging_options = Imap::Backup::Logger.setup_logging(options)
|
74
|
+
CLI::Transfer.new(:mirror, source_email, destination_email, non_logging_options).run
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -88,7 +88,7 @@ module Imap::Backup
|
|
88
88
|
"password-environment-variable",
|
89
89
|
type: :string,
|
90
90
|
desc: "an environment variable that is set to your password",
|
91
|
-
aliases: ["-
|
91
|
+
aliases: ["-w"]
|
92
92
|
)
|
93
93
|
method_option(
|
94
94
|
"password-file",
|
@@ -137,7 +137,7 @@ module Imap::Backup
|
|
137
137
|
"mirror",
|
138
138
|
type: :boolean,
|
139
139
|
desc: "if this option is given, " \
|
140
|
-
"emails that are
|
140
|
+
"existing backed-up emails that are no longer on the server " \
|
141
141
|
"will be removed from the local backup.",
|
142
142
|
aliases: ["-m"]
|
143
143
|
)
|
@@ -13,7 +13,7 @@ module Imap::Backup
|
|
13
13
|
include CLI::Helpers
|
14
14
|
|
15
15
|
# The possible values for the action parameter
|
16
|
-
ACTIONS = %i(migrate mirror).freeze
|
16
|
+
ACTIONS = %i(copy migrate mirror).freeze
|
17
17
|
|
18
18
|
def initialize(action, source_email, destination_email, options)
|
19
19
|
@action = action
|
@@ -39,14 +39,17 @@ module Imap::Backup
|
|
39
39
|
raise "Unknown action '#{action}'" if !ACTIONS.include?(action)
|
40
40
|
|
41
41
|
process_options!
|
42
|
-
|
42
|
+
warn_if_source_account_is_not_in_mirror_mode if action == :mirror
|
43
|
+
run_backup if %i(copy mirror).include?(action)
|
43
44
|
|
44
45
|
folders.each do |serializer, folder|
|
45
46
|
case action
|
47
|
+
when :copy
|
48
|
+
Mirror.new(serializer, folder, reset: false).run
|
46
49
|
when :migrate
|
47
50
|
Migrator.new(serializer, folder, reset: reset).run
|
48
51
|
when :mirror
|
49
|
-
Mirror.new(serializer, folder).run
|
52
|
+
Mirror.new(serializer, folder, reset: true).run
|
50
53
|
end
|
51
54
|
end
|
52
55
|
end
|
@@ -123,9 +126,7 @@ module Imap::Backup
|
|
123
126
|
self.source_prefix ||= ""
|
124
127
|
end
|
125
128
|
|
126
|
-
def
|
127
|
-
warn_if_source_account_is_not_in_mirror_mode
|
128
|
-
|
129
|
+
def run_backup
|
129
130
|
CLI::Backup.new(config: config_path, accounts: source_email).run
|
130
131
|
end
|
131
132
|
|
data/lib/imap/backup/cli.rb
CHANGED
@@ -12,6 +12,8 @@ module Imap::Backup
|
|
12
12
|
|
13
13
|
autoload :Backup, "imap/backup/cli/backup"
|
14
14
|
autoload :Local, "imap/backup/cli/local"
|
15
|
+
autoload :Migrate, "imap/backup/cli/migrate"
|
16
|
+
autoload :Mirror, "imap/backup/cli/mirror"
|
15
17
|
autoload :Remote, "imap/backup/cli/remote"
|
16
18
|
autoload :Restore, "imap/backup/cli/restore"
|
17
19
|
autoload :Setup, "imap/backup/cli/setup"
|
@@ -22,28 +24,6 @@ module Imap::Backup
|
|
22
24
|
|
23
25
|
include Helpers
|
24
26
|
|
25
|
-
NAMESPACE_CONFIGURATION_DESCRIPTION = <<~DESC.freeze
|
26
|
-
Some IMAP servers use namespaces (i.e. prefixes like "INBOX"),
|
27
|
-
while others, while others concatenate the names of subfolders
|
28
|
-
with a charater ("delimiter") other than "/".
|
29
|
-
|
30
|
-
In these cases there are two choices.
|
31
|
-
|
32
|
-
You can use the `--automatic-namespaces` option.
|
33
|
-
This will query the source and detination servers for their
|
34
|
-
namespace configuration and will adapt paths accordingly.
|
35
|
-
This option requires that both the source and destination
|
36
|
-
servers are available and work with the provided parameters
|
37
|
-
and authentication.
|
38
|
-
|
39
|
-
If automatic configuration does not work as desired, there are the
|
40
|
-
`--source-prefix=`, `--source-delimiter=`,
|
41
|
-
`--destination-prefix=` and `--destination-delimiter=` parameters.
|
42
|
-
To check what values you should use, check the output of the
|
43
|
-
`imap-backup remote namespaces EMAIL` command.
|
44
|
-
DESC
|
45
|
-
private_constant :NAMESPACE_CONFIGURATION_DESCRIPTION
|
46
|
-
|
47
27
|
default_task :backup
|
48
28
|
|
49
29
|
# Overrides {https://www.rubydoc.info/gems/thor/Thor%2FBase%2FClassMethods:start Thor's method}
|
@@ -94,91 +74,31 @@ module Imap::Backup
|
|
94
74
|
Backup.new(non_logging_options).run
|
95
75
|
end
|
96
76
|
|
97
|
-
desc "local SUBCOMMAND [OPTIONS]", "View local info"
|
98
|
-
subcommand "local", Local
|
99
|
-
|
100
77
|
desc(
|
101
|
-
"
|
102
|
-
"
|
78
|
+
"copy SOURCE_EMAIL DESTINATION_EMAIL [OPTIONS]",
|
79
|
+
"Copies emails from the SOURCE account to the DESTINATION account, avoiding duplicates"
|
103
80
|
)
|
104
81
|
long_desc <<~DESC
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
Some configuration may be necessary, as follows:
|
109
|
-
|
110
|
-
#{NAMESPACE_CONFIGURATION_DESCRIPTION}
|
111
|
-
|
112
|
-
Finally, if you want to delete existing emails in destination folders,
|
113
|
-
use the `--reset` option. In this case, all existing emails are
|
114
|
-
deleted before uploading the migrated emails.
|
115
|
-
DESC
|
116
|
-
config_option
|
117
|
-
quiet_option
|
118
|
-
verbose_option
|
119
|
-
method_option(
|
120
|
-
"automatic-namespaces",
|
121
|
-
type: :boolean,
|
122
|
-
desc: "automatically choose delimiters and prefixes"
|
123
|
-
)
|
124
|
-
method_option(
|
125
|
-
"destination-delimiter",
|
126
|
-
type: :string,
|
127
|
-
desc: "the delimiter for destination folder names"
|
128
|
-
)
|
129
|
-
method_option(
|
130
|
-
"destination-prefix",
|
131
|
-
type: :string,
|
132
|
-
desc: "the prefix (namespace) to add to destination folder names",
|
133
|
-
aliases: ["-d"]
|
134
|
-
)
|
135
|
-
method_option(
|
136
|
-
"reset",
|
137
|
-
type: :boolean,
|
138
|
-
desc: "DANGER! This option deletes all messages from destination folders before uploading",
|
139
|
-
aliases: ["-r"]
|
140
|
-
)
|
141
|
-
method_option(
|
142
|
-
"source-delimiter",
|
143
|
-
type: :string,
|
144
|
-
desc: "the delimiter for source folder names"
|
145
|
-
)
|
146
|
-
method_option(
|
147
|
-
"source-prefix",
|
148
|
-
type: :string,
|
149
|
-
desc: "the prefix (namespace) to strip from source folder names",
|
150
|
-
aliases: ["-s"]
|
151
|
-
)
|
152
|
-
# Migrates emails from one account to another
|
153
|
-
# @return [void]
|
154
|
-
def migrate(source_email, destination_email)
|
155
|
-
non_logging_options = Imap::Backup::Logger.setup_logging(options)
|
156
|
-
Transfer.new(:migrate, source_email, destination_email, non_logging_options).run
|
157
|
-
end
|
82
|
+
This command copies messages from the SOURCE_EMAIL account
|
83
|
+
to the DESTINATION_EMAIL account. It keeps track of copied
|
84
|
+
messages and avoids duplicate copies.
|
158
85
|
|
159
|
-
|
160
|
-
|
161
|
-
"Keeps the DESTINATION_EMAIL account aligned with the SOURCE_EMAIL account"
|
162
|
-
)
|
163
|
-
long_desc <<~DESC
|
164
|
-
This command updates the DESTINATION_EMAIL account's folders to have the same contents
|
165
|
-
as those on the SOURCE_EMAIL account.
|
86
|
+
Any other messages that are present on the DESTINATION_EMAIL account
|
87
|
+
are not affected.
|
166
88
|
|
167
89
|
If a folder list is configured for the SOURCE_EMAIL account,
|
168
90
|
only the folders indicated by the setting are copied.
|
169
91
|
|
170
92
|
First, it runs the download of the SOURCE_EMAIL account.
|
171
|
-
If the SOURCE_EMAIL account is **not** configured to be in 'mirror' mode,
|
172
|
-
a warning is printed.
|
173
93
|
|
174
|
-
When the
|
94
|
+
When the copy command is used, for each folder that is processed,
|
175
95
|
a new file is created alongside the normal backup files (.imap and .mbox)
|
176
96
|
This file has a '.mirror' extension. This file contains a mapping of
|
177
97
|
the known UIDs on the source account to those on the destination account.
|
178
98
|
|
179
99
|
Some configuration may be necessary, as follows:
|
180
100
|
|
181
|
-
#{NAMESPACE_CONFIGURATION_DESCRIPTION}
|
101
|
+
#{Helpers::NAMESPACE_CONFIGURATION_DESCRIPTION}
|
182
102
|
DESC
|
183
103
|
config_option
|
184
104
|
quiet_option
|
@@ -210,13 +130,19 @@ module Imap::Backup
|
|
210
130
|
desc: "the prefix (namespace) to strip from source folder names",
|
211
131
|
aliases: ["-s"]
|
212
132
|
)
|
213
|
-
#
|
133
|
+
# Copies messages from one email account to another
|
214
134
|
# @return [void]
|
215
|
-
def
|
135
|
+
def copy(source_email, destination_email)
|
216
136
|
non_logging_options = Imap::Backup::Logger.setup_logging(options)
|
217
|
-
Transfer.new(:
|
137
|
+
Transfer.new(:copy, source_email, destination_email, non_logging_options).run
|
218
138
|
end
|
219
139
|
|
140
|
+
desc "local SUBCOMMAND [OPTIONS]", "View local info"
|
141
|
+
subcommand "local", Local
|
142
|
+
|
143
|
+
include Migrate
|
144
|
+
include Mirror
|
145
|
+
|
220
146
|
desc "remote SUBCOMMAND [OPTIONS]", "View info about online accounts"
|
221
147
|
subcommand "remote", Remote
|
222
148
|
|
data/lib/imap/backup/mirror.rb
CHANGED
@@ -5,9 +5,10 @@ module Imap; end
|
|
5
5
|
module Imap::Backup
|
6
6
|
# Synchronises a folder between a source and destination
|
7
7
|
class Mirror
|
8
|
-
def initialize(serializer, folder)
|
8
|
+
def initialize(serializer, folder, reset: false)
|
9
9
|
@serializer = serializer
|
10
10
|
@folder = folder
|
11
|
+
@reset = reset
|
11
12
|
end
|
12
13
|
|
13
14
|
# If necessary, reates the destination folder,
|
@@ -19,7 +20,7 @@ module Imap::Backup
|
|
19
20
|
# @return [void]
|
20
21
|
def run
|
21
22
|
ensure_destination_folder
|
22
|
-
delete_destination_only_emails
|
23
|
+
delete_destination_only_emails if reset
|
23
24
|
update_flags
|
24
25
|
append_emails
|
25
26
|
map.save
|
@@ -31,6 +32,7 @@ module Imap::Backup
|
|
31
32
|
|
32
33
|
attr_reader :serializer
|
33
34
|
attr_reader :folder
|
35
|
+
attr_reader :reset
|
34
36
|
|
35
37
|
def ensure_destination_folder
|
36
38
|
return if folder.exist?
|
@@ -90,7 +92,7 @@ module Imap::Backup
|
|
90
92
|
destination: folder.uid_validity
|
91
93
|
)
|
92
94
|
if !map_ok
|
93
|
-
folder.clear
|
95
|
+
folder.clear if reset
|
94
96
|
map.reset(
|
95
97
|
source_uid_validity: serializer.uid_validity,
|
96
98
|
destination_uid_validity: folder.uid_validity
|
data/lib/imap/backup/version.rb
CHANGED
@@ -2,13 +2,13 @@ module Imap; end
|
|
2
2
|
|
3
3
|
module Imap::Backup
|
4
4
|
# @private
|
5
|
-
MAJOR =
|
5
|
+
MAJOR = 16
|
6
6
|
# @private
|
7
7
|
MINOR = 0
|
8
8
|
# @private
|
9
|
-
REVISION =
|
9
|
+
REVISION = 0
|
10
10
|
# @private
|
11
|
-
PRE =
|
11
|
+
PRE = nil
|
12
12
|
# The application version
|
13
13
|
VERSION = [MAJOR, MINOR, REVISION, PRE].compact.map(&:to_s).join(".")
|
14
14
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: imap-backup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 16.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joe Yates
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-06-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: highline
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: logger
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: mail
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +94,20 @@ dependencies:
|
|
80
94
|
- - ">="
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: ostruct
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
83
111
|
- !ruby/object:Gem::Dependency
|
84
112
|
name: rake
|
85
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -153,6 +181,8 @@ files:
|
|
153
181
|
- lib/imap/backup/cli/helpers.rb
|
154
182
|
- lib/imap/backup/cli/local.rb
|
155
183
|
- lib/imap/backup/cli/local/check.rb
|
184
|
+
- lib/imap/backup/cli/migrate.rb
|
185
|
+
- lib/imap/backup/cli/mirror.rb
|
156
186
|
- lib/imap/backup/cli/options.rb
|
157
187
|
- lib/imap/backup/cli/remote.rb
|
158
188
|
- lib/imap/backup/cli/restore.rb
|
@@ -234,7 +264,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
234
264
|
- !ruby/object:Gem::Version
|
235
265
|
version: '0'
|
236
266
|
requirements: []
|
237
|
-
rubygems_version: 3.
|
267
|
+
rubygems_version: 3.2.33
|
238
268
|
signing_key:
|
239
269
|
specification_version: 4
|
240
270
|
summary: Backup GMail (or other IMAP) accounts to disk
|