imap-backup 1.0.5 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/.travis.yml +1 -1
  4. data/Gemfile +0 -1
  5. data/README.md +0 -1
  6. data/Rakefile +4 -9
  7. data/bin/imap-backup +0 -1
  8. data/imap-backup.gemspec +0 -1
  9. data/lib/email/mboxrd/message.rb +31 -32
  10. data/lib/imap/backup.rb +17 -4
  11. data/lib/imap/backup/account/connection.rb +70 -64
  12. data/lib/imap/backup/account/folder.rb +21 -26
  13. data/lib/imap/backup/configuration/account.rb +127 -73
  14. data/lib/imap/backup/configuration/asker.rb +38 -31
  15. data/lib/imap/backup/configuration/connection_tester.rb +9 -14
  16. data/lib/imap/backup/configuration/folder_chooser.rb +43 -48
  17. data/lib/imap/backup/configuration/list.rb +19 -24
  18. data/lib/imap/backup/configuration/setup.rb +56 -51
  19. data/lib/imap/backup/configuration/store.rb +47 -52
  20. data/lib/imap/backup/downloader.rb +11 -14
  21. data/lib/imap/backup/serializer/base.rb +8 -11
  22. data/lib/imap/backup/serializer/directory.rb +36 -41
  23. data/lib/imap/backup/serializer/mbox.rb +83 -88
  24. data/lib/imap/backup/utils.rb +0 -3
  25. data/lib/imap/backup/version.rb +1 -2
  26. data/spec/gather_rspec_coverage.rb +0 -1
  27. data/spec/spec_helper.rb +2 -7
  28. data/spec/unit/account/connection_spec.rb +0 -1
  29. data/spec/unit/account/folder_spec.rb +0 -1
  30. data/spec/unit/configuration/account_spec.rb +207 -136
  31. data/spec/unit/configuration/asker_spec.rb +59 -85
  32. data/spec/unit/configuration/connection_tester_spec.rb +36 -26
  33. data/spec/unit/configuration/folder_chooser_spec.rb +3 -6
  34. data/spec/unit/configuration/list_spec.rb +0 -1
  35. data/spec/unit/configuration/setup_spec.rb +8 -9
  36. data/spec/unit/configuration/store_spec.rb +1 -4
  37. data/spec/unit/downloader_spec.rb +0 -1
  38. data/spec/unit/email/mboxrd/message_spec.rb +0 -1
  39. data/spec/unit/serializer/base_spec.rb +0 -1
  40. data/spec/unit/serializer/directory_spec.rb +0 -1
  41. data/spec/unit/serializer/mbox_spec.rb +0 -1
  42. data/spec/unit/utils_spec.rb +0 -1
  43. metadata +2 -2
@@ -1,40 +1,47 @@
1
1
  # encoding: utf-8
2
2
 
3
- module Imap
4
- module Backup
5
- module Configuration
6
- module Asker
7
- EMAIL_MATCHER = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i
3
+ module Imap::Backup::Configuration
4
+ class Asker < Struct.new(:highline)
5
+ EMAIL_MATCHER = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i
8
6
 
9
- def self.email(default = '')
10
- Setup.highline.ask('email address: ') do |q|
11
- q.default = default
12
- q.readline = true
13
- q.validate = EMAIL_MATCHER
14
- q.responses[:not_valid] = 'Enter a valid email address '
15
- end
16
- end
7
+ def email(default = '')
8
+ highline.ask('email address: ') do |q|
9
+ q.default = default
10
+ q.readline = true
11
+ q.validate = EMAIL_MATCHER
12
+ q.responses[:not_valid] = 'Enter a valid email address '
13
+ end
14
+ end
17
15
 
18
- def self.password
19
- password = Setup.highline.ask('password: ') { |q| q.echo = false }
20
- confirmation = Setup.highline.ask('repeat password: ') { |q| q.echo = false }
21
- if password != confirmation
22
- return nil unless Setup.highline.agree("the password and confirmation did not match.\nContinue? (y/n) ")
23
- return self.password
24
- end
25
- password
26
- end
16
+ def password
17
+ password = highline.ask('password: ') { |q| q.echo = false }
18
+ confirmation = highline.ask('repeat password: ') { |q| q.echo = false }
19
+ if password != confirmation
20
+ return nil unless highline.agree("the password and confirmation did not match.\nContinue? (y/n) ")
21
+ return self.password
22
+ end
23
+ password
24
+ end
27
25
 
28
- def self.backup_path(default, validator)
29
- Setup.highline.ask('backup directory: ') do |q|
30
- q.default = default
31
- q.readline = true
32
- q.validate = validator
33
- q.responses[:not_valid] = 'Choose a different directory '
34
- end
35
- end
26
+ def backup_path(default, validator)
27
+ highline.ask('backup directory: ') do |q|
28
+ q.default = default
29
+ q.readline = true
30
+ q.validate = validator
31
+ q.responses[:not_valid] = 'Choose a different directory '
36
32
  end
37
33
  end
34
+
35
+ def self.email(default = '')
36
+ new(Setup.highline).email(default)
37
+ end
38
+
39
+ def self.password
40
+ new(Setup.highline).password
41
+ end
42
+
43
+ def self.backup_path(default, validator)
44
+ new(Setup.highline).backup_path(default, validator)
45
+ end
38
46
  end
39
47
  end
40
-
@@ -1,19 +1,14 @@
1
1
  # encoding: utf-8
2
2
 
3
- module Imap
4
- module Backup
5
- module Configuration
6
- module ConnectionTester
7
- def self.test(account)
8
- Imap::Backup::Account::Connection.new(account)
9
- return 'Connection successful'
10
- rescue Net::IMAP::NoResponseError
11
- return 'No response'
12
- rescue Exception => e
13
- return "Unexpected error: #{e}"
14
- end
15
- end
3
+ module Imap::Backup::Configuration
4
+ module ConnectionTester
5
+ def self.test(account)
6
+ Imap::Backup::Account::Connection.new(account).imap
7
+ return 'Connection successful'
8
+ rescue Net::IMAP::NoResponseError
9
+ return 'No response'
10
+ rescue Exception => e
11
+ return "Unexpected error: #{e}"
16
12
  end
17
13
  end
18
14
  end
19
-
@@ -1,60 +1,55 @@
1
1
  # encoding: utf-8
2
2
 
3
- module Imap
4
- module Backup
5
- module Configuration
6
- class FolderChooser
7
- def initialize(account)
8
- @account = account
9
- end
3
+ module Imap::Backup::Configuration
4
+ class FolderChooser
5
+ def initialize(account)
6
+ @account = account
7
+ end
10
8
 
11
- def run
12
- begin
13
- @connection = Imap::Backup::Account::Connection.new(@account)
14
- rescue => e
15
- puts 'Connection failed'
16
- Setup.highline.ask 'Press a key '
17
- return
18
- end
19
- @folders = @connection.folders
20
- if @folders.nil?
21
- puts 'Unable to get folder list'
22
- Setup.highline.ask 'Press a key '
23
- return
24
- end
25
- loop do
26
- system('clear')
27
- Setup.highline.choose do |menu|
28
- menu.header = 'Add/remove folders'
29
- menu.index = :number
30
- @folders.each do |folder|
31
- name = folder.name
32
- found = @account[:folders].find { |f| f[:name] == name }
33
- mark =
34
- if found
35
- '+'
36
- else
37
- '-'
38
- end
39
- menu.choice("#{mark} #{name}") do
40
- if found
41
- @account[:folders].reject! { |f| f[:name] == name }
42
- else
43
- @account[:folders] << { :name => name }
44
- end
45
- end
46
- end
47
- menu.choice('return to the account menu') do
48
- return
9
+ def run
10
+ begin
11
+ @connection = Imap::Backup::Account::Connection.new(@account)
12
+ rescue => e
13
+ puts 'Connection failed'
14
+ Setup.highline.ask 'Press a key '
15
+ return
16
+ end
17
+ @folders = @connection.folders
18
+ if @folders.nil?
19
+ puts 'Unable to get folder list'
20
+ Setup.highline.ask 'Press a key '
21
+ return
22
+ end
23
+ loop do
24
+ system('clear')
25
+ Setup.highline.choose do |menu|
26
+ menu.header = 'Add/remove folders'
27
+ menu.index = :number
28
+ @folders.each do |folder|
29
+ name = folder.name
30
+ found = @account[:folders].find { |f| f[:name] == name }
31
+ mark =
32
+ if found
33
+ '+'
34
+ else
35
+ '-'
49
36
  end
50
- menu.hidden('quit') do
51
- return
37
+ menu.choice("#{mark} #{name}") do
38
+ if found
39
+ @account[:folders].reject! { |f| f[:name] == name }
40
+ else
41
+ @account[:folders] << { :name => name }
52
42
  end
53
43
  end
54
44
  end
45
+ menu.choice('return to the account menu') do
46
+ return
47
+ end
48
+ menu.hidden('quit') do
49
+ return
50
+ end
55
51
  end
56
52
  end
57
53
  end
58
54
  end
59
55
  end
60
-
@@ -1,33 +1,28 @@
1
1
  # encoding: utf-8
2
2
 
3
- module Imap
4
- module Backup
5
- module Configuration
6
- class List
7
- attr_reader :accounts
3
+ module Imap::Backup::Configuration
4
+ class List
5
+ attr_reader :accounts
8
6
 
9
- def initialize(accounts = nil)
10
- if not Imap::Backup::Configuration::Store.exist?
11
- raise ConfigurationNotFound.new("Configuration file '#{Imap::Backup::Configuration::Store.default_pathname}' not found")
12
- end
13
- @config = Imap::Backup::Configuration::Store.new
7
+ def initialize(accounts = nil)
8
+ if not Imap::Backup::Configuration::Store.exist?
9
+ raise Imap::Backup::ConfigurationNotFound.new("Configuration file '#{Imap::Backup::Configuration::Store.default_pathname}' not found")
10
+ end
11
+ @config = Imap::Backup::Configuration::Store.new
14
12
 
15
- if accounts.nil?
16
- @accounts = @config.data[:accounts]
17
- else
18
- @accounts = @config.data[:accounts].select{ |account| accounts.include?(account[:username]) }
19
- end
20
- end
13
+ if accounts.nil?
14
+ @accounts = @config.data[:accounts]
15
+ else
16
+ @accounts = @config.data[:accounts].select{ |account| accounts.include?(account[:username]) }
17
+ end
18
+ end
21
19
 
22
- def each_connection
23
- @accounts.each do |account|
24
- connection = Imap::Backup::Account::Connection.new(account)
25
- yield connection
26
- connection.disconnect
27
- end
28
- end
20
+ def each_connection
21
+ @accounts.each do |account|
22
+ connection = Imap::Backup::Account::Connection.new(account)
23
+ yield connection
24
+ connection.disconnect
29
25
  end
30
26
  end
31
27
  end
32
28
  end
33
-
@@ -2,66 +2,71 @@
2
2
  require 'rubygems' if RUBY_VERSION < '1.9'
3
3
  require 'highline'
4
4
 
5
- module Imap
6
- module Backup
7
- module Configuration
8
- class Setup
9
- class << self
10
- attr_accessor :highline
11
- end
12
- self.highline = HighLine.new
13
-
14
- def initialize
15
- @config = Imap::Backup::Configuration::Store.new
16
- end
5
+ module Imap::Backup::Configuration
6
+ class Setup
7
+ class << self
8
+ attr_accessor :highline
9
+ end
10
+ self.highline = HighLine.new
17
11
 
18
- def run
19
- loop do
20
- system('clear')
21
- self.class.highline.choose do |menu|
22
- menu.header = 'Choose an action'
23
- @config.data[:accounts].each do |account|
24
- menu.choice("#{account[:username]}") do
25
- edit_account account[:username]
26
- end
27
- end
28
- menu.choice('add account') do
29
- username = Asker.email
30
- edit_account username
31
- end
32
- menu.choice('save and exit') do
33
- @config.save
34
- return
35
- end
36
- menu.choice(:quit) do
37
- return
38
- end
12
+ def run
13
+ setup_logging
14
+ loop do
15
+ system('clear')
16
+ self.class.highline.choose do |menu|
17
+ menu.header = 'Choose an action'
18
+ config.data[:accounts].each do |account|
19
+ menu.choice("#{account[:username]}") do
20
+ edit_account account[:username]
39
21
  end
40
22
  end
23
+ menu.choice('add account') do
24
+ username = Asker.email
25
+ edit_account username
26
+ end
27
+ menu.choice('save and exit') do
28
+ config.save
29
+ return
30
+ end
31
+ menu.choice(:quit) do
32
+ return
33
+ end
41
34
  end
35
+ end
36
+ end
42
37
 
43
- private
38
+ private
44
39
 
45
- def add_account(username)
46
- account = {
47
- :username => username,
48
- :password => '',
49
- :local_path => File.join(@config.path, username.gsub('@', '_')),
50
- :folders => []
51
- }
52
- @config.data[:accounts] << account
53
- account
54
- end
40
+ def config
41
+ @config ||= Imap::Backup::Configuration::Store.new
42
+ end
55
43
 
56
- def edit_account(username)
57
- account = @config.data[:accounts].find { |a| a[:username] == username }
58
- if account.nil?
59
- account = add_account(username)
60
- end
61
- Account.new(@config, account).run
44
+ def setup_logging
45
+ Imap::Backup.logger.level =
46
+ if config.data[:debug]
47
+ ::Logger::Severity::DEBUG
48
+ else
49
+ ::Logger::Severity::ERROR
62
50
  end
51
+ end
52
+
53
+ def add_account(username)
54
+ account = {
55
+ :username => username,
56
+ :password => '',
57
+ :local_path => File.join(config.path, username.gsub('@', '_')),
58
+ :folders => []
59
+ }
60
+ config.data[:accounts] << account
61
+ account
62
+ end
63
+
64
+ def edit_account(username)
65
+ account = config.data[:accounts].find { |a| a[:username] == username }
66
+ if account.nil?
67
+ account = add_account(username)
63
68
  end
69
+ Account.new(config, account, Imap::Backup::Configuration::Setup.highline).run
64
70
  end
65
71
  end
66
72
  end
67
-
@@ -2,69 +2,64 @@
2
2
  require 'rubygems' if RUBY_VERSION < '1.9'
3
3
  require 'json'
4
4
 
5
- module Imap
6
- module Backup
7
- module Configuration
8
- class Store
9
- CONFIGURATION_DIRECTORY = File.expand_path('~/.imap-backup')
5
+ module Imap::Backup::Configuration
6
+ class Store
7
+ CONFIGURATION_DIRECTORY = File.expand_path('~/.imap-backup')
10
8
 
11
- attr_reader :data
12
- attr_reader :path
9
+ attr_reader :data
10
+ attr_reader :path
13
11
 
14
- def self.default_pathname
15
- File.join(CONFIGURATION_DIRECTORY, 'config.json')
16
- end
12
+ def self.default_pathname
13
+ File.join(CONFIGURATION_DIRECTORY, 'config.json')
14
+ end
17
15
 
18
- def self.exist?(pathname = default_pathname)
19
- File.exist?(pathname)
20
- end
16
+ def self.exist?(pathname = default_pathname)
17
+ File.exist?(pathname)
18
+ end
21
19
 
22
- def initialize(pathname = self.class.default_pathname)
23
- @pathname = pathname
24
- if File.directory?(path)
25
- Imap::Backup::Utils.check_permissions path, 0700
26
- end
27
- if File.exist?(@pathname)
28
- Imap::Backup::Utils.check_permissions @pathname, 0600
29
- @data = JSON.parse(File.read(@pathname), :symbolize_names => true)
30
- else
31
- @data = {:accounts => []}
32
- end
33
- end
20
+ def initialize(pathname = self.class.default_pathname)
21
+ @pathname = pathname
22
+ if File.directory?(path)
23
+ Imap::Backup::Utils.check_permissions path, 0700
24
+ end
25
+ if File.exist?(@pathname)
26
+ Imap::Backup::Utils.check_permissions @pathname, 0600
27
+ @data = JSON.parse(File.read(@pathname), :symbolize_names => true)
28
+ else
29
+ @data = {:accounts => []}
30
+ end
31
+ end
34
32
 
35
- def save
36
- mkdir_private path
37
- File.open(@pathname, 'w') { |f| f.write(JSON.pretty_generate(@data)) }
38
- FileUtils.chmod 0600, @pathname
39
- @data[:accounts].each do |account|
40
- mkdir_private account[:local_path]
41
- account[:folders].each do |f|
42
- parts = f[:name].split('/')
43
- p = account[:local_path].clone
44
- parts.each do |part|
45
- p = File.join(p, part)
46
- mkdir_private p
47
- end
48
- end
33
+ def save
34
+ mkdir_private path
35
+ File.open(@pathname, 'w') { |f| f.write(JSON.pretty_generate(@data)) }
36
+ FileUtils.chmod 0600, @pathname
37
+ @data[:accounts].each do |account|
38
+ mkdir_private account[:local_path]
39
+ account[:folders].each do |f|
40
+ parts = f[:name].split('/')
41
+ p = account[:local_path].clone
42
+ parts.each do |part|
43
+ p = File.join(p, part)
44
+ mkdir_private p
49
45
  end
50
46
  end
47
+ end
48
+ end
51
49
 
52
- def path
53
- File.dirname(@pathname)
54
- end
50
+ def path
51
+ File.dirname(@pathname)
52
+ end
55
53
 
56
- private
54
+ private
57
55
 
58
- def mkdir_private(path)
59
- if ! File.directory?(path)
60
- FileUtils.mkdir path
61
- end
62
- if Imap::Backup::Utils::stat(path) != 0700
63
- FileUtils.chmod 0700, path
64
- end
65
- end
56
+ def mkdir_private(path)
57
+ if ! File.directory?(path)
58
+ FileUtils.mkdir path
59
+ end
60
+ if Imap::Backup::Utils::stat(path) != 0700
61
+ FileUtils.chmod 0700, path
66
62
  end
67
63
  end
68
64
  end
69
65
  end
70
-