imap-backup 1.2.2 → 1.2.3

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/.rubocop.yml +7 -0
  3. data/Gemfile +1 -1
  4. data/Rakefile +4 -4
  5. data/bin/imap-backup +23 -25
  6. data/imap-backup.gemspec +14 -14
  7. data/lib/email/mboxrd/message.rb +23 -5
  8. data/lib/email/provider.rb +4 -4
  9. data/lib/imap/backup.rb +18 -18
  10. data/lib/imap/backup/account/connection.rb +6 -6
  11. data/lib/imap/backup/account/folder.rb +4 -5
  12. data/lib/imap/backup/configuration/account.rb +20 -22
  13. data/lib/imap/backup/configuration/asker.rb +8 -10
  14. data/lib/imap/backup/configuration/connection_tester.rb +3 -5
  15. data/lib/imap/backup/configuration/folder_chooser.rb +10 -12
  16. data/lib/imap/backup/configuration/list.rb +1 -3
  17. data/lib/imap/backup/configuration/setup.rb +13 -14
  18. data/lib/imap/backup/configuration/store.rb +7 -8
  19. data/lib/imap/backup/downloader.rb +0 -2
  20. data/lib/imap/backup/serializer/base.rb +0 -2
  21. data/lib/imap/backup/serializer/directory.rb +3 -4
  22. data/lib/imap/backup/serializer/mbox.rb +11 -12
  23. data/lib/imap/backup/utils.rb +2 -3
  24. data/lib/imap/backup/version.rb +2 -2
  25. data/spec/spec_helper.rb +6 -6
  26. data/spec/support/higline_test_helpers.rb +1 -1
  27. data/spec/support/shared_examples/account_flagging.rb +6 -6
  28. data/spec/unit/account/connection_spec.rb +50 -51
  29. data/spec/unit/account/folder_spec.rb +18 -19
  30. data/spec/unit/configuration/account_spec.rb +96 -97
  31. data/spec/unit/configuration/asker_spec.rb +33 -34
  32. data/spec/unit/configuration/connection_tester_spec.rb +18 -19
  33. data/spec/unit/configuration/folder_chooser_spec.rb +34 -35
  34. data/spec/unit/configuration/list_spec.rb +13 -14
  35. data/spec/unit/configuration/setup_spec.rb +46 -47
  36. data/spec/unit/configuration/store_spec.rb +56 -57
  37. data/spec/unit/downloader_spec.rb +18 -19
  38. data/spec/unit/email/mboxrd/message_spec.rb +55 -11
  39. data/spec/unit/email/provider_spec.rb +12 -12
  40. data/spec/unit/serializer/base_spec.rb +7 -9
  41. data/spec/unit/serializer/directory_spec.rb +18 -19
  42. data/spec/unit/serializer/mbox_spec.rb +35 -37
  43. data/spec/unit/utils_spec.rb +26 -27
  44. metadata +17 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 85975662cee269fb87e3de1150cd3a02c123e729e2d2f4e1a2e4905de477a897
4
- data.tar.gz: 06aa1c25d470bc8f38cf78e124d00f90f498e9ba2e803804ebf7a58ce9f81579
3
+ metadata.gz: 55d07b2ed9eae209a118323f3e8c494b831183468ef92e05cfe2ae139177f82b
4
+ data.tar.gz: c76ad04b8363dd146fc2abdc5ba6243fe3cd446a107f946187bf45bf16689906
5
5
  SHA512:
6
- metadata.gz: c75aff4a749a5630fe86bca252f676be0338c30c492ce3fdbe654c895143dcd7846ab654733f2aeb3a4316fe4b8f630d3ca0a1db0227c7d06918e7362d17970b
7
- data.tar.gz: b3b267870e606d407931ac337c36865aaccf430b1b91ab0a9a3dfe49e1db65ae159ddaeaf2f22041715e6998a8d00db8d76b02dafc6ac0a11dcd91218129a62e
6
+ metadata.gz: cd396bf6b70d293ef00ac83bc4e3f3ac0efdfdbf56c835484abf5c503ec84d5690537c0f36c5d23cf9e18f27f64372b66157b45491954fa6dfd0c2779b8b7aac
7
+ data.tar.gz: 1af9c675e2641debc9e897b4a4ae1a13834550e234887bcdd8ef75cafd3aadde58b296fdd903c377bddf142b340f9ed32fd8e8d6305d673e7fde5a7acb4437a5
@@ -0,0 +1,7 @@
1
+ inherit_from: https://gist.githubusercontent.com/joeyates/4763b79425cf903fc70df3bc8fccda36/raw/356fa04037feedb212735d4e7002cbd8778a33e8/.rubocop.yaml
2
+
3
+ AllCops:
4
+ Exclude:
5
+ - "bin/stubs/*"
6
+ DisplayCopNames:
7
+ Enabled: true
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
3
  gemspec
data/Rakefile CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env rake
2
- require 'bundler/gem_tasks'
3
- require 'rspec/core/rake_task'
2
+ require "bundler/gem_tasks"
3
+ require "rspec/core/rake_task"
4
4
 
5
- task :default => :spec
5
+ task default: :spec
6
6
 
7
7
  RSpec::Core::RakeTask.new do |t|
8
- t.pattern = 'spec/**/*_spec.rb'
8
+ t.pattern = "spec/**/*_spec.rb"
9
9
  end
@@ -1,32 +1,30 @@
1
1
  #!/usr/bin/env ruby
2
- # -*- encoding: utf-8 -*-
2
+ require "optparse"
3
3
 
4
- require 'optparse'
5
-
6
- $:.unshift(File.expand_path('../../lib/', __FILE__))
7
- require 'imap/backup'
4
+ $LOAD_PATH.unshift(File.expand_path("../../lib/", __FILE__))
5
+ require "imap/backup"
8
6
 
9
7
  KNOWN_COMMANDS = [
10
- {:name => 'setup', :help => 'Create/edit the configuration file'},
11
- {:name => 'backup', :help => 'Do the backup (default)'},
12
- {:name => 'folders', :help => 'List folders for all (or selected) accounts'},
13
- {:name => 'status', :help => 'List count of non backed-up emails per folder'},
14
- {:name => 'help', :help => 'Show usage'},
8
+ {name: "setup", help: "Create/edit the configuration file"},
9
+ {name: "backup", help: "Do the backup (default)"},
10
+ {name: "folders", help: "List folders for all (or selected) accounts"},
11
+ {name: "status", help: "List count of non backed-up emails per folder"},
12
+ {name: "help", help: "Show usage"}
15
13
  ]
16
14
 
17
- options = {:command => 'backup'}
15
+ options = {command: "backup"}
18
16
  opts = OptionParser.new do |opts|
19
- opts.banner = "Usage: #{$0} [options] COMMAND"
17
+ opts.banner = "Usage: #{$PROGRAM_NAME} [options] COMMAND"
20
18
 
21
- opts.separator ''
22
- opts.separator 'Commands:'
19
+ opts.separator ""
20
+ opts.separator "Commands:"
23
21
  KNOWN_COMMANDS.each do |command|
24
22
  opts.separator "\t%- 20s %s" % [command[:name], command[:help]]
25
23
  end
26
- opts.separator ''
27
- opts.separator 'Common options:'
24
+ opts.separator ""
25
+ opts.separator "Common options:"
28
26
 
29
- opts.on('-a', '--accounts ACCOUNT1[,ACCOUNT2,...]', Array, 'only these accounts') do |account|
27
+ opts.on("-a", "--accounts ACCOUNT1[,ACCOUNT2,...]", Array, "only these accounts") do |account|
30
28
  options[:accounts] = account
31
29
  end
32
30
 
@@ -35,7 +33,7 @@ opts = OptionParser.new do |opts|
35
33
  exit
36
34
  end
37
35
 
38
- opts.on_tail("--version", "Show version" ) do
36
+ opts.on_tail("--version", "Show version") do
39
37
  puts Imap::Backup::VERSION
40
38
  exit
41
39
  end
@@ -46,11 +44,11 @@ if ARGV.size > 0
46
44
  options[:command] = ARGV.shift
47
45
  end
48
46
 
49
- if KNOWN_COMMANDS.find{ |c| c[:name] == options[:command] }.nil?
47
+ if KNOWN_COMMANDS.find { |c| c[:name] == options[:command] }.nil?
50
48
  raise "Unknown command '#{options[:command]}'"
51
49
  end
52
50
 
53
- if options[:command] == 'help'
51
+ if options[:command] == "help"
54
52
  puts opts
55
53
  exit
56
54
  end
@@ -65,23 +63,23 @@ end
65
63
  configuration.setup_logging
66
64
 
67
65
  case options[:command]
68
- when 'setup'
66
+ when "setup"
69
67
  Imap::Backup::Configuration::Setup.new.run
70
- when 'backup'
68
+ when "backup"
71
69
  configuration.each_connection do |connection|
72
70
  connection.run_backup
73
71
  end
74
- when 'folders'
72
+ when "folders"
75
73
  configuration.each_connection do |connection|
76
74
  puts connection.username
77
75
  folders = connection.folders
78
76
  if folders.nil?
79
- warn 'Unable to list account folders'
77
+ warn "Unable to list account folders"
80
78
  exit 1
81
79
  end
82
80
  folders.each { |f| puts "\t" + f.name }
83
81
  end
84
- when 'status'
82
+ when "status"
85
83
  configuration.each_connection do |connection|
86
84
  puts connection.username
87
85
  folders = connection.status
@@ -1,26 +1,26 @@
1
- # -*- encoding: utf-8 -*-
2
- $LOAD_PATH.unshift(File.expand_path('../lib', __FILE__))
3
- require 'imap/backup/version'
1
+ $LOAD_PATH.unshift(File.expand_path("../lib", __FILE__))
2
+ require "imap/backup/version"
4
3
 
5
4
  Gem::Specification.new do |gem|
6
- gem.name = 'imap-backup'
5
+ gem.name = "imap-backup"
7
6
  gem.description = %q{Backup GMail, or any other IMAP email service, to disk.}
8
7
  gem.summary = %q{Backup GMail (or other IMAP) accounts to disk}
9
- gem.authors = ['Joe Yates']
10
- gem.email = ['joe.g.yates@gmail.com']
11
- gem.homepage = 'https://github.com/joeyates/imap-backup'
8
+ gem.authors = ["Joe Yates"]
9
+ gem.email = ["joe.g.yates@gmail.com"]
10
+ gem.homepage = "https://github.com/joeyates/imap-backup"
12
11
 
13
12
  gem.files = `git ls-files`.split($\)
14
13
  gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
15
14
  gem.test_files = gem.files.grep(%r{^spec/})
16
- gem.require_paths = ['lib']
15
+ gem.require_paths = ["lib"]
17
16
  gem.version = Imap::Backup::VERSION
18
17
 
19
- gem.add_runtime_dependency 'rake'
20
- gem.add_runtime_dependency 'highline'
21
- gem.add_runtime_dependency 'mail'
18
+ gem.add_runtime_dependency "rake"
19
+ gem.add_runtime_dependency "highline"
20
+ gem.add_runtime_dependency "mail"
22
21
 
23
- gem.add_development_dependency 'codeclimate-test-reporter', '~> 0.4.8'
24
- gem.add_development_dependency 'rspec', '>= 3.0.0'
25
- gem.add_development_dependency 'simplecov'
22
+ gem.add_development_dependency "codeclimate-test-reporter", "~> 0.4.8"
23
+ gem.add_development_dependency "rspec", ">= 3.0.0"
24
+ gem.add_development_dependency "rubocop-rspec"
25
+ gem.add_development_dependency "simplecov"
26
26
  end
@@ -1,4 +1,4 @@
1
- require 'mail'
1
+ require "mail"
2
2
 
3
3
  module Email; end
4
4
 
@@ -8,11 +8,11 @@ module Email::Mboxrd
8
8
 
9
9
  def initialize(supplied_body)
10
10
  @supplied_body = supplied_body.clone
11
- @supplied_body.force_encoding('binary')
11
+ @supplied_body.force_encoding("binary")
12
12
  end
13
13
 
14
14
  def to_s
15
- 'From ' + from + "\n" + mboxrd_body + "\n"
15
+ "From " + from + "\n" + mboxrd_body + "\n"
16
16
  end
17
17
 
18
18
  private
@@ -21,8 +21,26 @@ module Email::Mboxrd
21
21
  @parsed ||= Mail.new(supplied_body)
22
22
  end
23
23
 
24
+ def best_from
25
+ if parsed.from.is_a? Enumerable
26
+ parsed.from.each do |addr|
27
+ if addr
28
+ return addr
29
+ end
30
+ end
31
+ end
32
+ if parsed.envelope_from
33
+ return parsed.envelope_from
34
+ end
35
+ if parsed.return_path
36
+ return parsed.return_path
37
+ end
38
+
39
+ return ''
40
+ end
41
+
24
42
  def from
25
- parsed.from[0] + ' ' + asctime
43
+ best_from + " " + asctime
26
44
  end
27
45
 
28
46
  def mboxrd_body
@@ -33,7 +51,7 @@ module Email::Mboxrd
33
51
  end
34
52
 
35
53
  def asctime
36
- date ? date.asctime : ''
54
+ date ? date.asctime : ""
37
55
  end
38
56
 
39
57
  def date
@@ -3,9 +3,9 @@ module Email; end
3
3
  class Email::Provider
4
4
  def self.for_address(address)
5
5
  case
6
- when address.end_with?('@gmail.com')
6
+ when address.end_with?("@gmail.com")
7
7
  new(:gmail)
8
- when address.end_with?('@fastmail.fm')
8
+ when address.end_with?("@fastmail.fm")
9
9
  new(:fastmail)
10
10
  else
11
11
  new(:default)
@@ -32,9 +32,9 @@ class Email::Provider
32
32
  def host
33
33
  case provider
34
34
  when :gmail
35
- 'imap.gmail.com'
35
+ "imap.gmail.com"
36
36
  when :fastmail
37
- 'mail.messagingengine.com'
37
+ "mail.messagingengine.com"
38
38
  end
39
39
  end
40
40
  end
@@ -1,23 +1,23 @@
1
1
  module Imap; end
2
2
 
3
- require 'imap/backup/utils'
4
- require 'imap/backup/account/connection'
5
- require 'imap/backup/account/folder'
6
- require 'imap/backup/configuration/account'
7
- require 'imap/backup/configuration/asker'
8
- require 'imap/backup/configuration/connection_tester'
9
- require 'imap/backup/configuration/folder_chooser'
10
- require 'imap/backup/configuration/list'
11
- require 'imap/backup/configuration/setup'
12
- require 'imap/backup/configuration/store'
13
- require 'imap/backup/downloader'
14
- require 'imap/backup/serializer/base'
15
- require 'imap/backup/serializer/directory'
16
- require 'imap/backup/serializer/mbox'
17
- require 'imap/backup/version'
18
- require 'email/provider'
19
-
20
- require 'logger'
3
+ require "imap/backup/utils"
4
+ require "imap/backup/account/connection"
5
+ require "imap/backup/account/folder"
6
+ require "imap/backup/configuration/account"
7
+ require "imap/backup/configuration/asker"
8
+ require "imap/backup/configuration/connection_tester"
9
+ require "imap/backup/configuration/folder_chooser"
10
+ require "imap/backup/configuration/list"
11
+ require "imap/backup/configuration/setup"
12
+ require "imap/backup/configuration/store"
13
+ require "imap/backup/downloader"
14
+ require "imap/backup/serializer/base"
15
+ require "imap/backup/serializer/directory"
16
+ require "imap/backup/serializer/mbox"
17
+ require "imap/backup/version"
18
+ require "email/provider"
19
+
20
+ require "logger"
21
21
 
22
22
  module Imap::Backup
23
23
  class ConfigurationNotFound < StandardError; end
@@ -1,4 +1,4 @@
1
- require 'net/imap'
1
+ require "net/imap"
2
2
 
3
3
  module Imap::Backup
4
4
  module Account; end
@@ -20,7 +20,7 @@ module Imap::Backup
20
20
 
21
21
  def folders
22
22
  return @folders if @folders
23
- @folders = imap.list('', '*')
23
+ @folders = imap.list("", "*")
24
24
  if @folders.nil?
25
25
  Imap::Backup.logger.warn "Unable to get folder list for account #{username}"
26
26
  end
@@ -31,7 +31,7 @@ module Imap::Backup
31
31
  backup_folders.map do |folder|
32
32
  f = Account::Folder.new(self, folder[:name])
33
33
  s = Serializer::Directory.new(local_path, folder[:name])
34
- {:name => folder[:name], :local => s.uids, :remote => f.uids}
34
+ {name: folder[:name], local: s.uids, remote: f.uids}
35
35
  end
36
36
  end
37
37
 
@@ -83,12 +83,12 @@ module Imap::Backup
83
83
  end
84
84
 
85
85
  def masked_password
86
- password.gsub(/./, 'x')
86
+ password.gsub(/./, "x")
87
87
  end
88
88
 
89
89
  def backup_folders
90
- return @backup_folders if @backup_folders and @backup_folders.size > 0
91
- (folders || []).map { |f| {:name => f.name} }
90
+ return @backup_folders if @backup_folders && (@backup_folders.size > 0)
91
+ (folders || []).map { |f| {name: f.name} }
92
92
  end
93
93
 
94
94
  def provider
@@ -1,5 +1,4 @@
1
- # encoding: utf-8
2
- require 'forwardable'
1
+ require "forwardable"
3
2
 
4
3
  module Imap::Backup
5
4
  module Account; end
@@ -7,7 +6,7 @@ module Imap::Backup
7
6
  class Account::Folder
8
7
  extend Forwardable
9
8
 
10
- REQUESTED_ATTRIBUTES = ['RFC822', 'FLAGS', 'INTERNALDATE']
9
+ REQUESTED_ATTRIBUTES = ["RFC822", "FLAGS", "INTERNALDATE"]
11
10
 
12
11
  attr_reader :connection
13
12
  attr_reader :name
@@ -25,7 +24,7 @@ module Imap::Backup
25
24
 
26
25
  def uids
27
26
  imap.examine(name)
28
- imap.uid_search(['ALL']).sort
27
+ imap.uid_search(["ALL"]).sort
29
28
  rescue Net::IMAP::NoResponseError => e
30
29
  Imap::Backup.logger.warn "Folder '#{name}' does not exist"
31
30
  []
@@ -37,7 +36,7 @@ module Imap::Backup
37
36
  return nil if fetch_data_items.nil?
38
37
  fetch_data_item = fetch_data_items[0]
39
38
  attributes = fetch_data_item.attr
40
- attributes['RFC822'].force_encoding('utf-8')
39
+ attributes["RFC822"].force_encoding("utf-8")
41
40
  attributes
42
41
  rescue Net::IMAP::NoResponseError => e
43
42
  Imap::Backup.logger.warn "Folder '#{name}' does not exist"
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  module Imap::Backup
4
2
  module Configuration; end
5
3
 
@@ -11,7 +9,7 @@ module Imap::Backup
11
9
  def run
12
10
  catch :done do
13
11
  loop do
14
- system('clear')
12
+ system("clear")
15
13
  create_menu
16
14
  end
17
15
  end
@@ -29,8 +27,8 @@ module Imap::Backup
29
27
  choose_folders menu
30
28
  test_connection menu
31
29
  delete_account menu
32
- menu.choice('return to main menu') { throw :done }
33
- menu.hidden('quit') { throw :done }
30
+ menu.choice("return to main menu") { throw :done }
31
+ menu.hidden("quit") { throw :done }
34
32
  end
35
33
  end
36
34
 
@@ -46,16 +44,16 @@ Account:
46
44
  end
47
45
 
48
46
  def modify_email(menu)
49
- menu.choice('modify email') do
47
+ menu.choice("modify email") do
50
48
  username = Configuration::Asker.email(username)
51
49
  puts "username: #{username}"
52
- others = store.accounts.select { |a| a != account}.map { |a| a[:username] }
50
+ others = store.accounts.select { |a| a != account }.map { |a| a[:username] }
53
51
  puts "others: #{others.inspect}"
54
52
  if others.include?(username)
55
- puts 'There is already an account set up with that email address'
53
+ puts "There is already an account set up with that email address"
56
54
  else
57
55
  account[:username] = username
58
- if account[:server].nil? or account[:server] == ''
56
+ if account[:server].nil? || (account[:server] == "")
59
57
  account[:server] = default_server(username)
60
58
  end
61
59
  account[:modified] = true
@@ -64,9 +62,9 @@ Account:
64
62
  end
65
63
 
66
64
  def modify_password(menu)
67
- menu.choice('modify password') do
65
+ menu.choice("modify password") do
68
66
  password = Configuration::Asker.password
69
- if ! password.nil?
67
+ if !password.nil?
70
68
  account[:password] = password
71
69
  account[:modified] = true
72
70
  end
@@ -74,9 +72,9 @@ Account:
74
72
  end
75
73
 
76
74
  def modify_server(menu)
77
- menu.choice('modify server') do
78
- server = highline.ask('server: ')
79
- if ! server.nil?
75
+ menu.choice("modify server") do
76
+ server = highline.ask("server: ")
77
+ if !server.nil?
80
78
  account[:server] = server
81
79
  account[:modified] = true
82
80
  end
@@ -84,7 +82,7 @@ Account:
84
82
  end
85
83
 
86
84
  def modify_backup_path(menu)
87
- menu.choice('modify backup path') do
85
+ menu.choice("modify backup path") do
88
86
  validator = lambda do |p|
89
87
  same = store.accounts.find do |a|
90
88
  a[:username] != account[:username] && a[:local_path] == p
@@ -103,21 +101,21 @@ Account:
103
101
  end
104
102
 
105
103
  def choose_folders(menu)
106
- menu.choice('choose backup folders') do
104
+ menu.choice("choose backup folders") do
107
105
  Configuration::FolderChooser.new(account).run
108
106
  end
109
107
  end
110
108
 
111
109
  def test_connection(menu)
112
- menu.choice('test connection') do
110
+ menu.choice("test connection") do
113
111
  result = Configuration::ConnectionTester.test(account)
114
112
  puts result
115
- highline.ask 'Press a key '
113
+ highline.ask "Press a key "
116
114
  end
117
115
  end
118
116
 
119
117
  def delete_account(menu)
120
- menu.choice('delete') do
118
+ menu.choice("delete") do
121
119
  if highline.agree("Are you sure? (y/n) ")
122
120
  account[:delete] = true
123
121
  throw :done
@@ -130,10 +128,10 @@ Account:
130
128
  end
131
129
 
132
130
  def masked_password
133
- if account[:password] == '' or account[:password].nil?
134
- '(unset)'
131
+ if (account[:password] == "") || account[:password].nil?
132
+ "(unset)"
135
133
  else
136
- account[:password].gsub(/./, 'x')
134
+ account[:password].gsub(/./, "x")
137
135
  end
138
136
  end
139
137