imap-backup 4.2.0 → 5.1.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/imap-backup.gemspec +2 -0
- data/lib/imap/backup/account/connection.rb +4 -4
- data/lib/imap/backup/account/folder.rb +8 -0
- data/lib/imap/backup/cli/folders.rb +1 -1
- data/lib/imap/backup/cli/helpers.rb +4 -1
- data/lib/imap/backup/cli/local.rb +1 -1
- data/lib/imap/backup/cli/migrate.rb +114 -0
- data/lib/imap/backup/cli/remote.rb +15 -0
- data/lib/imap/backup/cli/restore.rb +20 -4
- data/lib/imap/backup/cli.rb +55 -10
- data/lib/imap/backup/client/default.rb +2 -2
- data/lib/imap/backup/downloader.rb +23 -9
- data/lib/imap/backup/migrator.rb +51 -0
- data/lib/imap/backup/sanitizer.rb +7 -4
- data/lib/imap/backup/version.rb +2 -2
- data/spec/features/backup_spec.rb +13 -12
- data/spec/features/configuration/minimal_configuration.rb +15 -0
- data/spec/features/configuration/missing_configuration.rb +14 -0
- data/spec/features/folders_spec.rb +36 -0
- data/spec/features/local/list_accounts_spec.rb +12 -0
- data/spec/features/local/list_emails_spec.rb +21 -0
- data/spec/features/local/list_folders_spec.rb +21 -0
- data/spec/features/local/show_an_email_spec.rb +34 -0
- data/spec/features/migrate_spec.rb +35 -0
- data/spec/features/remote/list_account_folders_spec.rb +16 -0
- data/spec/features/restore_spec.rb +7 -5
- data/spec/features/support/aruba.rb +73 -0
- data/spec/features/support/backup_directory.rb +0 -4
- data/spec/features/support/email_server.rb +1 -1
- data/spec/spec_helper.rb +2 -3
- data/spec/unit/imap/backup/account/connection_spec.rb +6 -8
- data/spec/unit/imap/backup/account/folder_spec.rb +26 -5
- data/spec/unit/imap/backup/cli/helpers_spec.rb +87 -0
- data/spec/unit/imap/backup/migrator_spec.rb +58 -0
- metadata +57 -11
- data/lib/thunderbird/install.rb +0 -16
- data/lib/thunderbird/local_folder.rb +0 -65
- data/lib/thunderbird/profile.rb +0 -30
- data/lib/thunderbird/profiles.rb +0 -71
- data/lib/thunderbird/subdirectory.rb +0 -93
- data/lib/thunderbird/subdirectory_placeholder.rb +0 -21
- data/lib/thunderbird.rb +0 -14
- data/spec/gather_rspec_coverage.rb +0 -1
data/lib/thunderbird/install.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
require "thunderbird/profiles"
|
2
|
-
|
3
|
-
class Thunderbird::Install
|
4
|
-
attr_reader :title
|
5
|
-
attr_reader :entries
|
6
|
-
|
7
|
-
# entries are lines from profile.ini
|
8
|
-
def initialize(title, entries)
|
9
|
-
@title = title
|
10
|
-
@entries = entries
|
11
|
-
end
|
12
|
-
|
13
|
-
def default
|
14
|
-
Thunderbird::Profiles.new.profile_for_path(entries[:Default])
|
15
|
-
end
|
16
|
-
end
|
@@ -1,65 +0,0 @@
|
|
1
|
-
require "thunderbird/profile"
|
2
|
-
require "thunderbird/subdirectory"
|
3
|
-
|
4
|
-
# A local folder is a file containing emails
|
5
|
-
class Thunderbird::LocalFolder
|
6
|
-
attr_reader :path
|
7
|
-
attr_reader :profile
|
8
|
-
|
9
|
-
def initialize(profile, path)
|
10
|
-
@profile = profile
|
11
|
-
@path = path
|
12
|
-
end
|
13
|
-
|
14
|
-
def set_up
|
15
|
-
return if path_elements.empty?
|
16
|
-
|
17
|
-
return true if !in_subdirectory?
|
18
|
-
|
19
|
-
subdirectory.set_up
|
20
|
-
end
|
21
|
-
|
22
|
-
def full_path
|
23
|
-
if in_subdirectory?
|
24
|
-
File.join(subdirectory.full_path, folder_name)
|
25
|
-
else
|
26
|
-
folder_name
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def exists?
|
31
|
-
File.exist?(full_path)
|
32
|
-
end
|
33
|
-
|
34
|
-
def msf_path
|
35
|
-
"#{path}.msf"
|
36
|
-
end
|
37
|
-
|
38
|
-
def msf_exists?
|
39
|
-
File.exist?(msf_path)
|
40
|
-
end
|
41
|
-
|
42
|
-
private
|
43
|
-
|
44
|
-
def in_subdirectory?
|
45
|
-
path_elements.count > 1
|
46
|
-
end
|
47
|
-
|
48
|
-
def subdirectory
|
49
|
-
return nil if !in_subdirectory?
|
50
|
-
|
51
|
-
Thunderbird::Subdirectory.new(profile, subdirectory_path)
|
52
|
-
end
|
53
|
-
|
54
|
-
def path_elements
|
55
|
-
path.split(File::SEPARATOR)
|
56
|
-
end
|
57
|
-
|
58
|
-
def subdirectory_path
|
59
|
-
File.join(path_elements[0..-2])
|
60
|
-
end
|
61
|
-
|
62
|
-
def folder_name
|
63
|
-
path_elements[-1]
|
64
|
-
end
|
65
|
-
end
|
data/lib/thunderbird/profile.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
require "thunderbird"
|
2
|
-
|
3
|
-
class Thunderbird::Profile
|
4
|
-
attr_reader :title
|
5
|
-
attr_reader :entries
|
6
|
-
|
7
|
-
# entries are lines from profile.ini
|
8
|
-
def initialize(title, entries)
|
9
|
-
@title = title
|
10
|
-
@entries = entries
|
11
|
-
end
|
12
|
-
|
13
|
-
def root
|
14
|
-
if relative?
|
15
|
-
File.join(Thunderbird.new.data_path, entries[:Path])
|
16
|
-
else
|
17
|
-
entries[:Path]
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def local_folders_path
|
22
|
-
File.join(root, "Mail", "Local Folders")
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def relative?
|
28
|
-
entries[:IsRelative] == "1"
|
29
|
-
end
|
30
|
-
end
|
data/lib/thunderbird/profiles.rb
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
require "thunderbird"
|
2
|
-
require "thunderbird/install"
|
3
|
-
require "thunderbird/profile"
|
4
|
-
|
5
|
-
# http://kb.mozillazine.org/Profiles.ini_file
|
6
|
-
class Thunderbird::Profiles
|
7
|
-
def profile_for_path(path)
|
8
|
-
title, entries = blocks.find { |_name, entries| entries[:Path] == path }
|
9
|
-
|
10
|
-
Thunderbird::Profile.new(title, entries) if title
|
11
|
-
end
|
12
|
-
|
13
|
-
def profile(name)
|
14
|
-
title, entries = blocks.find { |_name, entries| entries[:Name] == name }
|
15
|
-
|
16
|
-
Thunderbird::Profile.new(title, entries) if title
|
17
|
-
end
|
18
|
-
|
19
|
-
def installs
|
20
|
-
@installs ||= begin
|
21
|
-
pairs = blocks.filter { |name, _entries| name.start_with?("Install") }
|
22
|
-
pairs.map { |title, entries| Thunderbird::Install.new(title, entries) }
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
# Parse profiles.ini.
|
29
|
-
# Blocks start with a title, e.g. '[Abc]'
|
30
|
-
# and are followed by a number of lines
|
31
|
-
def blocks
|
32
|
-
@blocks ||= begin
|
33
|
-
blocks = {}
|
34
|
-
File.open(profiles_ini_path, "rb") do |f|
|
35
|
-
title = nil
|
36
|
-
entries = nil
|
37
|
-
|
38
|
-
loop do
|
39
|
-
line = f.gets
|
40
|
-
if !line
|
41
|
-
blocks[title] = entries if title
|
42
|
-
break
|
43
|
-
end
|
44
|
-
|
45
|
-
line.chomp!
|
46
|
-
|
47
|
-
# Is this line the start of a new block
|
48
|
-
match = line.match(/\A\[([A-Za-z0-9]+)\]\z/)
|
49
|
-
if match
|
50
|
-
# Store what we got before this title as a new block
|
51
|
-
blocks[title] = entries if title
|
52
|
-
|
53
|
-
# Start a new block
|
54
|
-
title = match[1]
|
55
|
-
entries = {}
|
56
|
-
elsif line != ""
|
57
|
-
# Collect entries until we get to the next title
|
58
|
-
key, value = line.split("=")
|
59
|
-
entries[key.to_sym] = value
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
blocks
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def profiles_ini_path
|
69
|
-
File.join(Thunderbird.new.data_path, "profiles.ini")
|
70
|
-
end
|
71
|
-
end
|
@@ -1,93 +0,0 @@
|
|
1
|
-
require "thunderbird/subdirectory_placeholder"
|
2
|
-
|
3
|
-
class Thunderbird::Subdirectory
|
4
|
-
# `path` is the UI path, it doesn't have the '.sbd' extensions
|
5
|
-
# that are present in the real, file system path
|
6
|
-
attr_reader :path
|
7
|
-
attr_reader :profile
|
8
|
-
|
9
|
-
def initialize(profile, path)
|
10
|
-
@profile = profile
|
11
|
-
@path = path
|
12
|
-
end
|
13
|
-
|
14
|
-
def set_up
|
15
|
-
raise "Cannot create a subdirectory without a path" if !sub_directory?
|
16
|
-
|
17
|
-
if sub_sub_directory?
|
18
|
-
parent_ok = parent.set_up
|
19
|
-
return false if !parent_ok
|
20
|
-
end
|
21
|
-
|
22
|
-
ok = check
|
23
|
-
return false if !ok
|
24
|
-
|
25
|
-
FileUtils.mkdir_p full_path
|
26
|
-
placeholder.touch
|
27
|
-
|
28
|
-
true
|
29
|
-
end
|
30
|
-
|
31
|
-
# subdirectory relative path is 'Foo.sbd/Bar.sbd/Baz.sbd'
|
32
|
-
def full_path
|
33
|
-
relative_path = File.join(subdirectories)
|
34
|
-
File.join(profile.local_folders_path, relative_path)
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def sub_directory?
|
40
|
-
path_elements.any?
|
41
|
-
end
|
42
|
-
|
43
|
-
def sub_sub_directory?
|
44
|
-
path_elements.count > 1
|
45
|
-
end
|
46
|
-
|
47
|
-
def parent
|
48
|
-
return nil if !sub_sub_directory?
|
49
|
-
|
50
|
-
self.class.new(profile, File.join(path_elements[0..-2]))
|
51
|
-
end
|
52
|
-
|
53
|
-
# placeholder relative path is 'Foo.sbd/Bar.sbd/Baz'
|
54
|
-
def placeholder
|
55
|
-
@placeholder = begin
|
56
|
-
relative_path = File.join(subdirectories[0..-2], path_elements[-1])
|
57
|
-
path = File.join(profile.local_folders_path, relative_path)
|
58
|
-
Thunderbird::SubdirectoryPlaceholder.new(path)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def path_elements
|
63
|
-
path.split(File::SEPARATOR)
|
64
|
-
end
|
65
|
-
|
66
|
-
def exists?
|
67
|
-
File.exist?(full_path)
|
68
|
-
end
|
69
|
-
|
70
|
-
def directory?
|
71
|
-
File.directory?(full_path)
|
72
|
-
end
|
73
|
-
|
74
|
-
def subdirectories
|
75
|
-
path_elements.map { |p| "#{p}.sbd" }
|
76
|
-
end
|
77
|
-
|
78
|
-
def check
|
79
|
-
case
|
80
|
-
when exists? && !placeholder.exists?
|
81
|
-
Kernel.puts "Can't set up folder '#{full_path}': '#{full_path}' exists, but '#{placeholder.path}' is missing"
|
82
|
-
false
|
83
|
-
when placeholder.exists? && !placeholder.regular?
|
84
|
-
Kernel.puts "Can't set up folder '#{full_path}': '#{placeholder.path}' exists, but it is not a regular file"
|
85
|
-
false
|
86
|
-
when exists? && !directory?
|
87
|
-
Kernel.puts "Can't set up folder '#{full_path}': '#{full_path}' exists, but it is not a directory"
|
88
|
-
false
|
89
|
-
else
|
90
|
-
true
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
# Each subdirectory is "accompanied" by a blank
|
2
|
-
# file of the same name (without the '.sbd' extension)
|
3
|
-
class Thunderbird::SubdirectoryPlaceholder
|
4
|
-
attr_reader :path
|
5
|
-
|
6
|
-
def initialize(path)
|
7
|
-
@path = path
|
8
|
-
end
|
9
|
-
|
10
|
-
def exists?
|
11
|
-
File.exist?(path)
|
12
|
-
end
|
13
|
-
|
14
|
-
def regular?
|
15
|
-
File.file?(path)
|
16
|
-
end
|
17
|
-
|
18
|
-
def touch
|
19
|
-
FileUtils.touch path
|
20
|
-
end
|
21
|
-
end
|
data/lib/thunderbird.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
require "os"
|
2
|
-
|
3
|
-
class Thunderbird
|
4
|
-
def data_path
|
5
|
-
case
|
6
|
-
when OS.linux?
|
7
|
-
File.join(Dir.home, ".thunderbird")
|
8
|
-
when OS.mac?
|
9
|
-
File.join(Dir.home, "Library", "Thunderbird")
|
10
|
-
when OS.windows?
|
11
|
-
File.join(ENV["APPDATA"].gsub("\\", "/"), "Thunderbird")
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
@@ -1 +0,0 @@
|
|
1
|
-
GATHER_RSPEC_COVERAGE = 1
|