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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/imap-backup.gemspec +2 -0
  3. data/lib/imap/backup/account/connection.rb +4 -4
  4. data/lib/imap/backup/account/folder.rb +8 -0
  5. data/lib/imap/backup/cli/folders.rb +1 -1
  6. data/lib/imap/backup/cli/helpers.rb +4 -1
  7. data/lib/imap/backup/cli/local.rb +1 -1
  8. data/lib/imap/backup/cli/migrate.rb +114 -0
  9. data/lib/imap/backup/cli/remote.rb +15 -0
  10. data/lib/imap/backup/cli/restore.rb +20 -4
  11. data/lib/imap/backup/cli.rb +55 -10
  12. data/lib/imap/backup/client/default.rb +2 -2
  13. data/lib/imap/backup/downloader.rb +23 -9
  14. data/lib/imap/backup/migrator.rb +51 -0
  15. data/lib/imap/backup/sanitizer.rb +7 -4
  16. data/lib/imap/backup/version.rb +2 -2
  17. data/spec/features/backup_spec.rb +13 -12
  18. data/spec/features/configuration/minimal_configuration.rb +15 -0
  19. data/spec/features/configuration/missing_configuration.rb +14 -0
  20. data/spec/features/folders_spec.rb +36 -0
  21. data/spec/features/local/list_accounts_spec.rb +12 -0
  22. data/spec/features/local/list_emails_spec.rb +21 -0
  23. data/spec/features/local/list_folders_spec.rb +21 -0
  24. data/spec/features/local/show_an_email_spec.rb +34 -0
  25. data/spec/features/migrate_spec.rb +35 -0
  26. data/spec/features/remote/list_account_folders_spec.rb +16 -0
  27. data/spec/features/restore_spec.rb +7 -5
  28. data/spec/features/support/aruba.rb +73 -0
  29. data/spec/features/support/backup_directory.rb +0 -4
  30. data/spec/features/support/email_server.rb +1 -1
  31. data/spec/spec_helper.rb +2 -3
  32. data/spec/unit/imap/backup/account/connection_spec.rb +6 -8
  33. data/spec/unit/imap/backup/account/folder_spec.rb +26 -5
  34. data/spec/unit/imap/backup/cli/helpers_spec.rb +87 -0
  35. data/spec/unit/imap/backup/migrator_spec.rb +58 -0
  36. metadata +57 -11
  37. data/lib/thunderbird/install.rb +0 -16
  38. data/lib/thunderbird/local_folder.rb +0 -65
  39. data/lib/thunderbird/profile.rb +0 -30
  40. data/lib/thunderbird/profiles.rb +0 -71
  41. data/lib/thunderbird/subdirectory.rb +0 -93
  42. data/lib/thunderbird/subdirectory_placeholder.rb +0 -21
  43. data/lib/thunderbird.rb +0 -14
  44. data/spec/gather_rspec_coverage.rb +0 -1
@@ -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
@@ -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
@@ -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