imap-backup 1.0.9 → 1.0.10
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 +7 -0
- data/.travis.yml +1 -0
- data/Rakefile +0 -5
- data/imap-backup.gemspec +5 -5
- data/lib/email/mboxrd/message.rb +1 -1
- data/lib/imap/backup.rb +3 -1
- data/lib/imap/backup/account/connection.rb +9 -7
- data/lib/imap/backup/account/folder.rb +6 -4
- data/lib/imap/backup/configuration/account.rb +9 -7
- data/lib/imap/backup/configuration/asker.rb +7 -5
- data/lib/imap/backup/configuration/connection_tester.rb +5 -3
- data/lib/imap/backup/configuration/folder_chooser.rb +10 -8
- data/lib/imap/backup/configuration/list.rb +8 -6
- data/lib/imap/backup/configuration/setup.rb +7 -5
- data/lib/imap/backup/configuration/store.rb +7 -5
- data/lib/imap/backup/serializer/base.rb +2 -1
- data/lib/imap/backup/serializer/directory.rb +5 -3
- data/lib/imap/backup/serializer/mbox.rb +10 -5
- data/lib/imap/backup/utils.rb +23 -30
- data/lib/imap/backup/version.rb +7 -7
- data/spec/spec_helper.rb +10 -27
- data/spec/support/higline_test_helpers.rb +8 -0
- data/spec/support/silence_logging.rb +7 -0
- data/spec/unit/account/connection_spec.rb +1 -1
- data/spec/unit/account/folder_spec.rb +33 -52
- data/spec/unit/configuration/asker_spec.rb +46 -5
- data/spec/unit/configuration/folder_chooser_spec.rb +62 -102
- data/spec/unit/configuration/list_spec.rb +40 -48
- data/spec/unit/configuration/setup_spec.rb +41 -62
- data/spec/unit/configuration/store_spec.rb +107 -99
- data/spec/unit/downloader_spec.rb +8 -8
- data/spec/unit/email/mboxrd/message_spec.rb +9 -19
- data/spec/unit/serializer/base_spec.rb +7 -5
- data/spec/unit/serializer/directory_spec.rb +30 -38
- data/spec/unit/serializer/mbox_spec.rb +64 -58
- data/spec/unit/utils_spec.rb +67 -41
- metadata +107 -141
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            SHA1:
         | 
| 3 | 
            +
              metadata.gz: 21c07957777ccdca22ec2b9b98aa5ee23e03f9d4
         | 
| 4 | 
            +
              data.tar.gz: 7f341ff59529f01e6d7c4ccb7eefa73610b68a57
         | 
| 5 | 
            +
            SHA512:
         | 
| 6 | 
            +
              metadata.gz: d9cbe70b6dbe617645a4a3fadbaa75a9fa73870b889d361adeb9a3cd9bcee91143736327db1050e6dc4c9383fabe9161413bb6061b5ce26831ed1c0897fa7c2f
         | 
| 7 | 
            +
              data.tar.gz: ce740410c22cfea3f5119cd7a65196db97296d56416b662b575f049bba4e45669a66bccca78af52dcb915ab51ced4690e760246237df1ec85aa3ec10c7fb3669
         | 
    
        data/.travis.yml
    CHANGED
    
    
    
        data/Rakefile
    CHANGED
    
    | @@ -14,9 +14,4 @@ if RUBY_VERSION < '1.9' | |
| 14 14 | 
             
                t.rcov      = true
         | 
| 15 15 | 
             
                t.rcov_opts = ['--exclude', 'spec/,/gems/,vendor/']
         | 
| 16 16 | 
             
              end
         | 
| 17 | 
            -
            else
         | 
| 18 | 
            -
              desc 'Run specs and create coverage output'
         | 
| 19 | 
            -
              RSpec::Core::RakeTask.new('spec:coverage') do |t|
         | 
| 20 | 
            -
                t.pattern = ['spec/gather_rspec_coverage.rb', 'spec/**/*_spec.rb']
         | 
| 21 | 
            -
              end
         | 
| 22 17 | 
             
            end
         | 
    
        data/imap-backup.gemspec
    CHANGED
    
    | @@ -1,18 +1,18 @@ | |
| 1 1 | 
             
            # -*- encoding: utf-8 -*-
         | 
| 2 | 
            -
             | 
| 2 | 
            +
            $LOAD_PATH.unshift(File.expand_path('../lib', __FILE__))
         | 
| 3 3 | 
             
            require 'imap/backup/version'
         | 
| 4 4 |  | 
| 5 5 | 
             
            Gem::Specification.new do |gem|
         | 
| 6 | 
            -
              gem. | 
| 7 | 
            -
              gem.email         = ['joe.g.yates@gmail.com']
         | 
| 6 | 
            +
              gem.name          = 'imap-backup'
         | 
| 8 7 | 
             
              gem.description   = %q{Backup GMail, or any other IMAP email service, to disk.}
         | 
| 9 8 | 
             
              gem.summary       = %q{Backup GMail (or other IMAP) accounts to disk}
         | 
| 9 | 
            +
              gem.authors       = ['Joe Yates']
         | 
| 10 | 
            +
              gem.email         = ['joe.g.yates@gmail.com']
         | 
| 10 11 | 
             
              gem.homepage      = 'https://github.com/joeyates/imap-backup'
         | 
| 11 12 |  | 
| 12 13 | 
             
              gem.files         = `git ls-files`.split($\)
         | 
| 13 | 
            -
              gem.executables   = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
         | 
| 14 | 
            +
              gem.executables   = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
         | 
| 14 15 | 
             
              gem.test_files    = gem.files.grep(%r{^spec/})
         | 
| 15 | 
            -
              gem.name          = 'imap-backup'
         | 
| 16 16 | 
             
              gem.require_paths = ['lib']
         | 
| 17 17 | 
             
              gem.version       = Imap::Backup::VERSION
         | 
| 18 18 |  | 
    
        data/lib/email/mboxrd/message.rb
    CHANGED
    
    
    
        data/lib/imap/backup.rb
    CHANGED
    
    | @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            module Imap; end
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            require 'imap/backup/utils'
         | 
| 2 4 | 
             
            require 'imap/backup/account/connection'
         | 
| 3 5 | 
             
            require 'imap/backup/account/folder'
         | 
| @@ -30,6 +32,6 @@ module Imap::Backup | |
| 30 32 | 
             
              end
         | 
| 31 33 |  | 
| 32 34 | 
             
              def self.logger
         | 
| 33 | 
            -
                 | 
| 35 | 
            +
                Logger.instance.logger
         | 
| 34 36 | 
             
              end
         | 
| 35 37 | 
             
            end
         | 
| @@ -1,7 +1,9 @@ | |
| 1 1 | 
             
            require 'net/imap'
         | 
| 2 2 |  | 
| 3 | 
            -
            module Imap::Backup | 
| 4 | 
            -
               | 
| 3 | 
            +
            module Imap::Backup
         | 
| 4 | 
            +
              module Account; end
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              class Account::Connection
         | 
| 5 7 | 
             
                attr_reader :username, :local_path, :backup_folders, :server
         | 
| 6 8 |  | 
| 7 9 | 
             
                def initialize(options)
         | 
| @@ -17,17 +19,17 @@ module Imap::Backup::Account | |
| 17 19 |  | 
| 18 20 | 
             
                def status
         | 
| 19 21 | 
             
                  backup_folders.map do |folder|
         | 
| 20 | 
            -
                    f =  | 
| 21 | 
            -
                    s =  | 
| 22 | 
            +
                    f = Account::Folder.new(self, folder[:name])
         | 
| 23 | 
            +
                    s = Serializer::Directory.new(local_path, folder[:name])
         | 
| 22 24 | 
             
                    {:name => folder[:name], :local => s.uids, :remote => f.uids}
         | 
| 23 25 | 
             
                  end
         | 
| 24 26 | 
             
                end
         | 
| 25 27 |  | 
| 26 28 | 
             
                def run_backup
         | 
| 27 29 | 
             
                  backup_folders.each do |folder|
         | 
| 28 | 
            -
                    f =  | 
| 29 | 
            -
                    s =  | 
| 30 | 
            -
                    d =  | 
| 30 | 
            +
                    f = Account::Folder.new(self, folder[:name])
         | 
| 31 | 
            +
                    s = Serializer::Mbox.new(local_path, folder[:name])
         | 
| 32 | 
            +
                    d = Downloader.new(f, s)
         | 
| 31 33 | 
             
                    d.run
         | 
| 32 34 | 
             
                  end
         | 
| 33 35 | 
             
                end
         | 
| @@ -1,7 +1,9 @@ | |
| 1 1 | 
             
            # encoding: utf-8
         | 
| 2 2 |  | 
| 3 | 
            -
            module Imap::Backup | 
| 4 | 
            -
               | 
| 3 | 
            +
            module Imap::Backup
         | 
| 4 | 
            +
              module Account; end
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              class Account::Folder
         | 
| 5 7 | 
             
                REQUESTED_ATTRIBUTES = ['RFC822', 'FLAGS', 'INTERNALDATE']
         | 
| 6 8 |  | 
| 7 9 | 
             
                def initialize(connection, folder)
         | 
| @@ -12,7 +14,7 @@ module Imap::Backup::Account | |
| 12 14 | 
             
                  @connection.imap.examine(@folder)
         | 
| 13 15 | 
             
                  @connection.imap.uid_search(['ALL']).sort
         | 
| 14 16 | 
             
                rescue Net::IMAP::NoResponseError => e
         | 
| 15 | 
            -
                  warn "Folder '#{@folder}' does not exist"
         | 
| 17 | 
            +
                  Imap::Backup.logger.warn "Folder '#{@folder}' does not exist"
         | 
| 16 18 | 
             
                  []
         | 
| 17 19 | 
             
                end
         | 
| 18 20 |  | 
| @@ -22,7 +24,7 @@ module Imap::Backup::Account | |
| 22 24 | 
             
                  message['RFC822'].force_encoding('utf-8') if RUBY_VERSION > '1.9'
         | 
| 23 25 | 
             
                  message
         | 
| 24 26 | 
             
                rescue Net::IMAP::NoResponseError => e
         | 
| 25 | 
            -
                  warn "Folder '#{@folder}' does not exist"
         | 
| 27 | 
            +
                  Imap::Backup.logger.warn "Folder '#{@folder}' does not exist"
         | 
| 26 28 | 
             
                  nil
         | 
| 27 29 | 
             
                end
         | 
| 28 30 | 
             
              end
         | 
| @@ -1,7 +1,9 @@ | |
| 1 1 | 
             
            # encoding: utf-8
         | 
| 2 2 |  | 
| 3 | 
            -
            module Imap::Backup | 
| 4 | 
            -
               | 
| 3 | 
            +
            module Imap::Backup
         | 
| 4 | 
            +
              module Configuration; end
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              class Configuration::Account < Struct.new(:store, :account, :highline)
         | 
| 5 7 | 
             
                def run
         | 
| 6 8 | 
             
                  catch :done do
         | 
| 7 9 | 
             
                    loop do
         | 
| @@ -41,7 +43,7 @@ Account: | |
| 41 43 |  | 
| 42 44 | 
             
                def modify_email(menu)
         | 
| 43 45 | 
             
                  menu.choice('modify email') do
         | 
| 44 | 
            -
                    username = Asker.email(username)
         | 
| 46 | 
            +
                    username = Configuration::Asker.email(username)
         | 
| 45 47 | 
             
                    puts "username: #{username}"
         | 
| 46 48 | 
             
                    others   = store.data[:accounts].select { |a| a != account}.map { |a| a[:username] }
         | 
| 47 49 | 
             
                    puts "others: #{others.inspect}"
         | 
| @@ -58,7 +60,7 @@ Account: | |
| 58 60 |  | 
| 59 61 | 
             
                def modify_password(menu)
         | 
| 60 62 | 
             
                  menu.choice('modify password') do
         | 
| 61 | 
            -
                    password = Asker.password
         | 
| 63 | 
            +
                    password = Configuration::Asker.password
         | 
| 62 64 | 
             
                    if ! password.nil?
         | 
| 63 65 | 
             
                      account[:password] = password
         | 
| 64 66 | 
             
                    end
         | 
| @@ -87,19 +89,19 @@ Account: | |
| 87 89 | 
             
                        true
         | 
| 88 90 | 
             
                      end
         | 
| 89 91 | 
             
                    end
         | 
| 90 | 
            -
                    account[:local_path] = Asker.backup_path(account[:local_path], validator)
         | 
| 92 | 
            +
                    account[:local_path] = Configuration::Asker.backup_path(account[:local_path], validator)
         | 
| 91 93 | 
             
                  end
         | 
| 92 94 | 
             
                end
         | 
| 93 95 |  | 
| 94 96 | 
             
                def choose_folders(menu)
         | 
| 95 97 | 
             
                  menu.choice('choose backup folders') do
         | 
| 96 | 
            -
                    FolderChooser.new(account).run
         | 
| 98 | 
            +
                    Configuration::FolderChooser.new(account).run
         | 
| 97 99 | 
             
                  end
         | 
| 98 100 | 
             
                end
         | 
| 99 101 |  | 
| 100 102 | 
             
                def test_connection(menu)
         | 
| 101 103 | 
             
                  menu.choice('test connection') do
         | 
| 102 | 
            -
                    result = ConnectionTester.test(account)
         | 
| 104 | 
            +
                    result = Configuration::ConnectionTester.test(account)
         | 
| 103 105 | 
             
                    puts result
         | 
| 104 106 | 
             
                    highline.ask 'Press a key '
         | 
| 105 107 | 
             
                  end
         | 
| @@ -1,7 +1,9 @@ | |
| 1 1 | 
             
            # encoding: utf-8
         | 
| 2 2 |  | 
| 3 | 
            -
            module Imap::Backup | 
| 4 | 
            -
               | 
| 3 | 
            +
            module Imap::Backup
         | 
| 4 | 
            +
              module Configuration; end
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              class Configuration::Asker < Struct.new(:highline)
         | 
| 5 7 | 
             
                EMAIL_MATCHER = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i
         | 
| 6 8 |  | 
| 7 9 | 
             
                def email(default = '')
         | 
| @@ -33,15 +35,15 @@ module Imap::Backup::Configuration | |
| 33 35 | 
             
                end
         | 
| 34 36 |  | 
| 35 37 | 
             
                def self.email(default = '')
         | 
| 36 | 
            -
                  new(Setup.highline).email(default)
         | 
| 38 | 
            +
                  new(Configuration::Setup.highline).email(default)
         | 
| 37 39 | 
             
                end
         | 
| 38 40 |  | 
| 39 41 | 
             
                def self.password
         | 
| 40 | 
            -
                  new(Setup.highline).password
         | 
| 42 | 
            +
                  new(Configuration::Setup.highline).password
         | 
| 41 43 | 
             
                end
         | 
| 42 44 |  | 
| 43 45 | 
             
                def self.backup_path(default, validator)
         | 
| 44 | 
            -
                  new(Setup.highline).backup_path(default, validator)
         | 
| 46 | 
            +
                  new(Configuration::Setup.highline).backup_path(default, validator)
         | 
| 45 47 | 
             
                end
         | 
| 46 48 | 
             
              end
         | 
| 47 49 | 
             
            end
         | 
| @@ -1,9 +1,11 @@ | |
| 1 1 | 
             
            # encoding: utf-8
         | 
| 2 2 |  | 
| 3 | 
            -
            module Imap::Backup | 
| 4 | 
            -
              module  | 
| 3 | 
            +
            module Imap::Backup
         | 
| 4 | 
            +
              module Configuration; end
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              module Configuration::ConnectionTester
         | 
| 5 7 | 
             
                def self.test(account)
         | 
| 6 | 
            -
                   | 
| 8 | 
            +
                  Account::Connection.new(account).imap
         | 
| 7 9 | 
             
                  return 'Connection successful'
         | 
| 8 10 | 
             
                rescue Net::IMAP::NoResponseError
         | 
| 9 11 | 
             
                  return 'No response'
         | 
| @@ -1,28 +1,30 @@ | |
| 1 1 | 
             
            # encoding: utf-8
         | 
| 2 2 |  | 
| 3 | 
            -
            module Imap::Backup | 
| 4 | 
            -
               | 
| 3 | 
            +
            module Imap::Backup
         | 
| 4 | 
            +
              module Configuration; end
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              class Configuration::FolderChooser
         | 
| 5 7 | 
             
                def initialize(account)
         | 
| 6 8 | 
             
                  @account = account
         | 
| 7 9 | 
             
                end
         | 
| 8 10 |  | 
| 9 11 | 
             
                def run
         | 
| 10 12 | 
             
                  begin
         | 
| 11 | 
            -
                    @connection =  | 
| 13 | 
            +
                    @connection = Account::Connection.new(@account)
         | 
| 12 14 | 
             
                  rescue => e
         | 
| 13 | 
            -
                     | 
| 14 | 
            -
                    Setup.highline.ask 'Press a key '
         | 
| 15 | 
            +
                    Imap::Backup.logger.warn 'Connection failed'
         | 
| 16 | 
            +
                    Configuration::Setup.highline.ask 'Press a key '
         | 
| 15 17 | 
             
                    return
         | 
| 16 18 | 
             
                  end
         | 
| 17 19 | 
             
                  @folders = @connection.folders
         | 
| 18 20 | 
             
                  if @folders.nil?
         | 
| 19 | 
            -
                     | 
| 20 | 
            -
                    Setup.highline.ask 'Press a key '
         | 
| 21 | 
            +
                    Imap::Backup.logger.warn 'Unable to get folder list'
         | 
| 22 | 
            +
                    Configuration::Setup.highline.ask 'Press a key '
         | 
| 21 23 | 
             
                    return
         | 
| 22 24 | 
             
                  end
         | 
| 23 25 | 
             
                  loop do
         | 
| 24 26 | 
             
                    system('clear')
         | 
| 25 | 
            -
                    Setup.highline.choose do |menu|
         | 
| 27 | 
            +
                    Configuration::Setup.highline.choose do |menu|
         | 
| 26 28 | 
             
                      menu.header = 'Add/remove folders'
         | 
| 27 29 | 
             
                      menu.index = :number
         | 
| 28 30 | 
             
                      @folders.each do |folder|
         | 
| @@ -1,14 +1,16 @@ | |
| 1 1 | 
             
            # encoding: utf-8
         | 
| 2 2 |  | 
| 3 | 
            -
            module Imap::Backup | 
| 4 | 
            -
               | 
| 3 | 
            +
            module Imap::Backup
         | 
| 4 | 
            +
              module Configuration; end
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              class Configuration::List
         | 
| 5 7 | 
             
                attr_reader :accounts
         | 
| 6 8 |  | 
| 7 9 | 
             
                def initialize(accounts = nil)
         | 
| 8 | 
            -
                  if not  | 
| 9 | 
            -
                    raise  | 
| 10 | 
            +
                  if not Configuration::Store.exist?
         | 
| 11 | 
            +
                    raise ConfigurationNotFound.new("Configuration file '#{Configuration::Store.default_pathname}' not found")
         | 
| 10 12 | 
             
                  end
         | 
| 11 | 
            -
                  @config =  | 
| 13 | 
            +
                  @config = Configuration::Store.new
         | 
| 12 14 |  | 
| 13 15 | 
             
                  if accounts.nil?
         | 
| 14 16 | 
             
                    @accounts = @config.data[:accounts]
         | 
| @@ -19,7 +21,7 @@ module Imap::Backup::Configuration | |
| 19 21 |  | 
| 20 22 | 
             
                def each_connection
         | 
| 21 23 | 
             
                  @accounts.each do |account|
         | 
| 22 | 
            -
                    connection =  | 
| 24 | 
            +
                    connection = Account::Connection.new(account)
         | 
| 23 25 | 
             
                    yield connection
         | 
| 24 26 | 
             
                    connection.disconnect
         | 
| 25 27 | 
             
                  end
         | 
| @@ -2,8 +2,10 @@ | |
| 2 2 | 
             
            require 'rubygems' if RUBY_VERSION < '1.9'
         | 
| 3 3 | 
             
            require 'highline'
         | 
| 4 4 |  | 
| 5 | 
            -
            module Imap::Backup | 
| 6 | 
            -
               | 
| 5 | 
            +
            module Imap::Backup
         | 
| 6 | 
            +
              module Configuration; end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              class Configuration::Setup
         | 
| 7 9 | 
             
                class << self
         | 
| 8 10 | 
             
                  attr_accessor :highline
         | 
| 9 11 | 
             
                end
         | 
| @@ -21,7 +23,7 @@ module Imap::Backup::Configuration | |
| 21 23 | 
             
                        end
         | 
| 22 24 | 
             
                      end
         | 
| 23 25 | 
             
                      menu.choice('add account') do
         | 
| 24 | 
            -
                        username = Asker.email
         | 
| 26 | 
            +
                        username = Configuration::Asker.email
         | 
| 25 27 | 
             
                        edit_account username
         | 
| 26 28 | 
             
                      end
         | 
| 27 29 | 
             
                      menu.choice('save and exit') do
         | 
| @@ -38,7 +40,7 @@ module Imap::Backup::Configuration | |
| 38 40 | 
             
                private
         | 
| 39 41 |  | 
| 40 42 | 
             
                def config
         | 
| 41 | 
            -
                  @config ||=  | 
| 43 | 
            +
                  @config ||= Configuration::Store.new
         | 
| 42 44 | 
             
                end
         | 
| 43 45 |  | 
| 44 46 | 
             
                def setup_logging
         | 
| @@ -66,7 +68,7 @@ module Imap::Backup::Configuration | |
| 66 68 | 
             
                  if account.nil?
         | 
| 67 69 | 
             
                    account = add_account(username)
         | 
| 68 70 | 
             
                  end
         | 
| 69 | 
            -
                  Account.new(config, account,  | 
| 71 | 
            +
                  Configuration::Account.new(config, account, Configuration::Setup.highline).run
         | 
| 70 72 | 
             
                end
         | 
| 71 73 | 
             
              end
         | 
| 72 74 | 
             
            end
         | 
| @@ -2,8 +2,10 @@ | |
| 2 2 | 
             
            require 'rubygems' if RUBY_VERSION < '1.9'
         | 
| 3 3 | 
             
            require 'json'
         | 
| 4 4 |  | 
| 5 | 
            -
            module Imap::Backup | 
| 6 | 
            -
               | 
| 5 | 
            +
            module Imap::Backup
         | 
| 6 | 
            +
              module Configuration; end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              class Configuration::Store
         | 
| 7 9 | 
             
                CONFIGURATION_DIRECTORY = File.expand_path('~/.imap-backup')
         | 
| 8 10 |  | 
| 9 11 | 
             
                attr_reader :data
         | 
| @@ -20,10 +22,10 @@ module Imap::Backup::Configuration | |
| 20 22 | 
             
                def initialize(pathname = self.class.default_pathname)
         | 
| 21 23 | 
             
                  @pathname = pathname
         | 
| 22 24 | 
             
                  if File.directory?(path)
         | 
| 23 | 
            -
                     | 
| 25 | 
            +
                    Utils.check_permissions path, 0700
         | 
| 24 26 | 
             
                  end
         | 
| 25 27 | 
             
                  if File.exist?(@pathname)
         | 
| 26 | 
            -
                     | 
| 28 | 
            +
                    Utils.check_permissions @pathname, 0600
         | 
| 27 29 | 
             
                    @data = JSON.parse(File.read(@pathname), :symbolize_names => true)
         | 
| 28 30 | 
             
                  else
         | 
| 29 31 | 
             
                    @data = {:accounts => []}
         | 
| @@ -57,7 +59,7 @@ module Imap::Backup::Configuration | |
| 57 59 | 
             
                  if ! File.directory?(path)
         | 
| 58 60 | 
             
                    FileUtils.mkdir path
         | 
| 59 61 | 
             
                  end
         | 
| 60 | 
            -
                  if  | 
| 62 | 
            +
                  if Utils::stat(path) != 0700
         | 
| 61 63 | 
             
                    FileUtils.chmod 0700, path
         | 
| 62 64 | 
             
                  end
         | 
| 63 65 | 
             
                end
         | 
| @@ -4,10 +4,11 @@ module Imap::Backup | |
| 4 4 | 
             
              module Serializer
         | 
| 5 5 | 
             
                DIRECTORY_PERMISSIONS = 0700
         | 
| 6 6 | 
             
                FILE_PERMISSIONS      = 0600
         | 
| 7 | 
            +
             | 
| 7 8 | 
             
                class Base
         | 
| 8 9 | 
             
                  def initialize(path, folder)
         | 
| 9 10 | 
             
                    @path, @folder = path, folder
         | 
| 10 | 
            -
                     | 
| 11 | 
            +
                    Utils.check_permissions(@path, DIRECTORY_PERMISSIONS)
         | 
| 11 12 | 
             
                  end
         | 
| 12 13 | 
             
                end
         | 
| 13 14 | 
             
              end
         | 
| @@ -1,11 +1,13 @@ | |
| 1 1 | 
             
            # encoding: utf-8
         | 
| 2 2 | 
             
            require 'fileutils'
         | 
| 3 3 |  | 
| 4 | 
            -
            module Imap::Backup | 
| 5 | 
            -
               | 
| 4 | 
            +
            module Imap::Backup
         | 
| 5 | 
            +
              module Serializer; end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              class Serializer::Directory < Serializer::Base
         | 
| 6 8 | 
             
                def initialize(path, folder)
         | 
| 7 9 | 
             
                  super
         | 
| 8 | 
            -
                   | 
| 10 | 
            +
                  Utils.make_folder(@path, @folder, Serializer::DIRECTORY_PERMISSIONS)
         | 
| 9 11 | 
             
                end
         | 
| 10 12 |  | 
| 11 13 | 
             
                def uids
         | 
| @@ -2,8 +2,10 @@ | |
| 2 2 | 
             
            require 'csv'
         | 
| 3 3 | 
             
            require 'email/mboxrd/message'
         | 
| 4 4 |  | 
| 5 | 
            -
            module Imap::Backup | 
| 6 | 
            -
               | 
| 5 | 
            +
            module Imap::Backup
         | 
| 6 | 
            +
              module Serializer; end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              class Serializer::Mbox < Serializer::Base
         | 
| 7 9 | 
             
                def initialize(path, folder)
         | 
| 8 10 | 
             
                  super
         | 
| 9 11 | 
             
                  create_containing_directory
         | 
| @@ -27,13 +29,16 @@ module Imap::Backup::Serializer | |
| 27 29 | 
             
                def save(uid, message)
         | 
| 28 30 | 
             
                  uid = uid.to_s
         | 
| 29 31 | 
             
                  return if uids.include?(uid)
         | 
| 30 | 
            -
                   | 
| 32 | 
            +
                  body = message['RFC822']
         | 
| 33 | 
            +
                  mboxrd_message = Email::Mboxrd::Message.new(body)
         | 
| 31 34 | 
             
                  mbox = imap = nil
         | 
| 32 35 | 
             
                  begin
         | 
| 33 36 | 
             
                    mbox = File.open(mbox_pathname, 'ab')
         | 
| 34 37 | 
             
                    imap = File.open(imap_pathname, 'ab')
         | 
| 35 | 
            -
                    mbox.write  | 
| 38 | 
            +
                    mbox.write mboxrd_message.to_s
         | 
| 36 39 | 
             
                    imap.write uid + "\n"
         | 
| 40 | 
            +
                  rescue ArgumentError => e
         | 
| 41 | 
            +
                    Imap::Backup.logger.warn "Failed to save message #{uid}:\n#{body}. #{e}"
         | 
| 37 42 | 
             
                  ensure
         | 
| 38 43 | 
             
                    mbox.close if mbox
         | 
| 39 44 | 
             
                    imap.close if imap
         | 
| @@ -52,7 +57,7 @@ module Imap::Backup::Serializer | |
| 52 57 | 
             
                def create_containing_directory
         | 
| 53 58 | 
             
                  mbox_relative_path = File.dirname(mbox_relative_pathname)
         | 
| 54 59 | 
             
                  return if mbox_relative_path == '.'
         | 
| 55 | 
            -
                   | 
| 60 | 
            +
                  Utils.make_folder(@path, mbox_relative_path, Serializer::DIRECTORY_PERMISSIONS)
         | 
| 56 61 | 
             
                end
         | 
| 57 62 |  | 
| 58 63 | 
             
                def exist?
         |