imap-backup 4.2.0 → 5.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|