imap-backup 0.0.1

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.
@@ -0,0 +1,8 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ coverage
5
+ pkg
6
+ .rbenv-version
7
+ vendor
8
+
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.3
5
+ script: "bundle exec rake spec"
6
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source :rubygems
2
+
3
+ gemspec
4
+
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Joe Yates
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,64 @@
1
+ imap-backup [![Build Status](https://secure.travis-ci.org/joeyates/imap-backup.png)][Continuous Integration]
2
+ ===========
3
+
4
+ *Backup GMail (or other IMAP) accounts to disk*
5
+
6
+ * [Source Code]
7
+ * [API documentation]
8
+ * [Rubygem]
9
+ * [Continuous Integration]
10
+
11
+ [Source Code]: https://github.com/joeyates/imap-backup "Source code at GitHub"
12
+ [API documentation]: http://rubydoc.info/gems/imap-backup/frames "RDoc API Documentation at Rubydoc.info"
13
+ [Rubygem]: http://rubygems.org/gems/imap-backup "Ruby gem at rubygems.org"
14
+ [Continuous Integration]: http://travis-ci.org/joeyates/imap-backup "Build status by Travis-CI"
15
+
16
+ Installation
17
+ ============
18
+
19
+ Add this line to your application's Gemfile:
20
+
21
+ gem 'imap/backup'
22
+
23
+ And then execute:
24
+
25
+ $ bundle
26
+
27
+ Or install it yourself as:
28
+
29
+ gem install 'imap-backup'
30
+
31
+ Basic Usage
32
+ ===========
33
+
34
+ * Create ~/.imap-backup
35
+ * Run
36
+
37
+ imap-backup
38
+
39
+ Usage
40
+ =====
41
+
42
+ Check connection:
43
+
44
+ imap-backup --check
45
+
46
+ List IMAP folders:
47
+
48
+ imap-backup --list
49
+
50
+ Design Goals
51
+ ============
52
+
53
+ * Secure - use a local file protected by permissions
54
+ * Restartable - calculate start point based on alreadt downloaded messages
55
+ * Standards compliant - save emails in a standard format
56
+ * Standalone - does not rely on an email client or MTA
57
+
58
+ Similar Software
59
+ ================
60
+
61
+ * https://github.com/thefloweringash/gmail-imap-backup
62
+ * https://github.com/mleonhard/imapbackup
63
+ * https://github.com/rgrove/larch - copies between IMAP servers
64
+
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env rake
2
+ require 'bundler/gem_tasks'
3
+ require 'rspec/core/rake_task'
4
+
5
+ task :default => :spec
6
+
7
+ RSpec::Core::RakeTask.new do | t |
8
+ t.pattern = 'spec/**/*_spec.rb'
9
+ end
10
+
11
+ if RUBY_VERSION < '1.9'
12
+
13
+ RSpec::Core::RakeTask.new( 'spec:coverage' ) do |t|
14
+ t.pattern = 'spec/**/*_spec.rb'
15
+ t.rcov = true
16
+ t.rcov_opts = [ '--exclude', 'spec/,/gems/,vendor/' ]
17
+ end
18
+
19
+ else
20
+
21
+ desc 'Run specs and create coverage output'
22
+ RSpec::Core::RakeTask.new( 'spec:coverage' ) do |t|
23
+ t.pattern = ['spec/gather_rspec_coverage.rb', 'spec/**/*_spec.rb']
24
+ end
25
+
26
+ end
27
+
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- encoding: utf-8 -*-
3
+
4
+ $:.unshift(File.expand_path('../../lib/', __FILE__))
5
+ require 'imap/backup'
6
+
7
+ settings = Imap::Backup::Settings.new
8
+
9
+ if ARGV[0] == '--list'
10
+ settings.each_account do |account|
11
+ account.folders.each { |f| puts f.name }
12
+ end
13
+ else
14
+ settings.each_account do |account|
15
+ account.backup_folders.each do |folder|
16
+ d = Imap::Backup::Downloader.new(account, folder['name'])
17
+ d.run
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.unshift(File.expand_path('../lib/', __FILE__))
3
+ require 'imap/backup/version'
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.authors = ['Joe Yates']
7
+ gem.email = ['joe.g.yates@gmail.com']
8
+ gem.description = %q{Backup GMail, or any other IMAP email service, to disk.}
9
+ gem.summary = %q{Backup GMail (or other IMAP) accounts to disk}
10
+ gem.homepage = 'https://github.com/joeyates/imap-backup'
11
+
12
+ gem.files = `git ls-files`.split($\)
13
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
14
+ gem.test_files = gem.files.grep(%r{^spec/})
15
+ gem.name = 'imap-backup'
16
+ gem.require_paths = ['lib']
17
+ gem.version = Imap::Backup::VERSION
18
+
19
+ gem.add_development_dependency 'pry'
20
+ gem.add_development_dependency 'pry-doc'
21
+ gem.add_development_dependency 'rspec', '>= 2.3.0'
22
+ if RUBY_VERSION < '1.9'
23
+ gem.add_development_dependency 'rcov'
24
+ else
25
+ gem.add_development_dependency 'simplecov'
26
+ end
27
+
28
+ end
29
+
@@ -0,0 +1,6 @@
1
+ require 'imap/backup/utils'
2
+ require 'imap/backup/account'
3
+ require 'imap/backup/downloader'
4
+ require 'imap/backup/settings'
5
+ require 'imap/backup/version'
6
+
@@ -0,0 +1,42 @@
1
+ require 'net/imap'
2
+
3
+ module Imap
4
+ module Backup
5
+ class Account
6
+
7
+ REQUESTED_ATTRIBUTES = ['RFC822', 'FLAGS', 'INTERNALDATE']
8
+
9
+ attr_accessor :local_path
10
+ attr_accessor :backup_folders
11
+
12
+ def initialize(options)
13
+ @local_path, @backup_folders = options['local_path'], options['folders']
14
+ @imap = Net::IMAP.new('imap.gmail.com', 993, true)
15
+ @imap.login(options['username'], options['password'])
16
+ end
17
+
18
+ def disconnect
19
+ @imap.disconnect
20
+ end
21
+
22
+ def folders
23
+ @imap.list('/', '*')
24
+ end
25
+
26
+ def each_uid(folder)
27
+ @imap.examine(folder)
28
+ @imap.uid_search(['ALL']).each do |uid|
29
+ yield uid
30
+ end
31
+ end
32
+
33
+ def fetch(uid)
34
+ message = @imap.uid_fetch([uid], REQUESTED_ATTRIBUTES)[0][1]
35
+ message['RFC822'].force_encoding('utf-8') if RUBY_VERSION > '1.9'
36
+ message
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+
@@ -0,0 +1,32 @@
1
+ require 'json'
2
+
3
+ module Imap
4
+ module Backup
5
+ class Downloader
6
+
7
+ include Imap::Backup::Utils
8
+
9
+ def initialize(account, folder)
10
+ @account, @folder = account, folder
11
+
12
+ check_permissions(@account.local_path, 0700)
13
+ end
14
+
15
+ def run
16
+ make_folder(@account.local_path, @folder, 'g-wrx,o-wrx')
17
+ destination_path = File.join(@account.local_path, @folder)
18
+ @account.each_uid(@folder) do |uid|
19
+ message_filename = "#{destination_path}/%012u.json" % uid.to_i
20
+ next if File.exist?(message_filename)
21
+
22
+ message = @account.fetch(uid)
23
+
24
+ File.open(message_filename, 'w') { |f| f.write message.to_json }
25
+ FileUtils.chmod 0600, message_filename
26
+ end
27
+ end
28
+
29
+ end
30
+ end
31
+ end
32
+
@@ -0,0 +1,28 @@
1
+ require 'json'
2
+
3
+ module Imap
4
+ module Backup
5
+
6
+ class Settings
7
+
8
+ include Imap::Backup::Utils
9
+
10
+ def initialize
11
+ config_pathname = File.expand_path('~/.imap-backup/config.json')
12
+ raise "Configuration file '#{config_pathname}' not found" if ! File.exist?(config_pathname)
13
+ check_permissions(config_pathname, 0600)
14
+ @settings = JSON.load(File.open(config_pathname))
15
+ end
16
+
17
+ def each_account
18
+ @settings['accounts'].each do |account|
19
+ a = Account.new(account)
20
+ yield a
21
+ a.disconnect
22
+ end
23
+ end
24
+
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,34 @@
1
+ require 'fileutils'
2
+
3
+ module Imap
4
+ module Backup
5
+ module Utils
6
+
7
+ def check_permissions(filename, limit)
8
+ stat = File.stat(filename)
9
+ actual = stat.mode & 0777
10
+ mask = ~limit & 0777
11
+ if actual & mask != 0
12
+ raise "Permissions on '#{filename}' should be #{oct(limit)}, not #{oct(actual)}"
13
+ end
14
+ end
15
+
16
+ def make_folder(base_path, path, permissions)
17
+ parts = path.split('/')
18
+ return if parts.size == 0
19
+ full_path = File.join(base_path, path)
20
+ FileUtils.mkdir_p(full_path)
21
+ first_directory = File.join(base_path, parts[0])
22
+ FileUtils.chmod_R(permissions, first_directory)
23
+ end
24
+
25
+ private
26
+
27
+ def oct(permissions)
28
+ "0%o" % permissions
29
+ end
30
+
31
+ end
32
+ end
33
+ end
34
+
@@ -0,0 +1,9 @@
1
+ module Imap
2
+ module Backup
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ REVISION = 1
6
+ VERSION = [ MAJOR, MINOR, REVISION ].map( &:to_s ).join( '.' )
7
+ end
8
+ end
9
+
@@ -0,0 +1,2 @@
1
+ GATHER_RSPEC_COVERAGE = 1
2
+
@@ -0,0 +1,16 @@
1
+ require 'rspec'
2
+
3
+ if RUBY_VERSION < '1.9'
4
+ require 'rspec/autorun'
5
+ else
6
+ require 'simplecov'
7
+ if defined?( GATHER_RSPEC_COVERAGE )
8
+ SimpleCov.start do
9
+ add_filter "/spec/"
10
+ add_filter "/vendor/"
11
+ end
12
+ end
13
+ end
14
+
15
+ require File.expand_path( File.dirname(__FILE__) + '/../lib/imap/backup' )
16
+
@@ -0,0 +1,95 @@
1
+ # encoding: utf-8
2
+ load File.expand_path( '../spec_helper.rb', File.dirname(__FILE__) )
3
+
4
+ describe Imap::Backup::Account do
5
+
6
+ context '#initialize' do
7
+
8
+ it 'should login to the imap server' do
9
+ imap = stub('Net::IMAP')
10
+ Net::IMAP.should_receive(:new).with('imap.gmail.com', 993, true).and_return(imap)
11
+ imap.should_receive('login').with('myuser', 'secret')
12
+
13
+ Imap::Backup::Account.new('username' => 'myuser', 'password' => 'secret')
14
+ end
15
+
16
+ end
17
+
18
+ context 'with imap' do
19
+ before :each do
20
+ @imap = stub('Net::IMAP', :login => nil)
21
+ Net::IMAP.stub!(:new).and_return(@imap)
22
+ end
23
+
24
+ subject { Imap::Backup::Account.new('username' => 'myuser', 'password' => 'secret') }
25
+
26
+ context '#disconnect' do
27
+ it 'should disconnect from the server' do
28
+ @imap.should_receive(:disconnect)
29
+
30
+ subject.disconnect
31
+ end
32
+ end
33
+
34
+ context '#folders' do
35
+ it 'should list all folders' do
36
+ @imap.should_receive(:list).with('/', '*')
37
+
38
+ subject.folders
39
+ end
40
+ end
41
+
42
+ context '#each_uid' do
43
+ it 'should examine the folder' do
44
+ @imap.stub!(:uid_search => [])
45
+ @imap.should_receive(:examine).with('my_folder')
46
+
47
+ subject.each_uid('my_folder') {}
48
+ end
49
+
50
+ it 'should call the block with each message uid' do
51
+ @imap.stub!(:examine).with('my_folder')
52
+ @imap.should_receive(:uid_search).with(['ALL']).and_return(['123', '456'])
53
+
54
+ uids = []
55
+ subject.each_uid('my_folder') do |uid|
56
+ uids << uid
57
+ end
58
+
59
+ uids.should == ['123', '456']
60
+ end
61
+ end
62
+
63
+ context '#fetch' do
64
+ before :each do
65
+ @message_body = 'the body'
66
+ @message = {
67
+ 'RFC822' => @message_body,
68
+ 'other' => 'xxx'
69
+ }
70
+ end
71
+
72
+ it 'should request the message, the flags and the date' do
73
+ @imap.should_receive(:uid_fetch).
74
+ with(['123'], ['RFC822', 'FLAGS', 'INTERNALDATE']).
75
+ and_return([[nil, @message]])
76
+
77
+ subject.fetch('123')
78
+ end
79
+
80
+ if RUBY_VERSION > '1.9'
81
+ it 'should set the encoding on the message' do
82
+ @imap.stub!(:uid_fetch => [[nil, @message]])
83
+
84
+ @message_body.should_receive(:force_encoding).with('utf-8')
85
+
86
+ subject.fetch('123')
87
+ end
88
+ end
89
+
90
+ end
91
+
92
+ end
93
+
94
+ end
95
+
@@ -0,0 +1,136 @@
1
+ # encoding: utf-8
2
+ load File.expand_path( '../spec_helper.rb', File.dirname(__FILE__) )
3
+
4
+ describe Imap::Backup::Downloader do
5
+
6
+ context '#initialize' do
7
+
8
+ it 'should fail if download path file permissions are to lax' do
9
+ account = stub('Imap::Backup::Account', :local_path => 'foobar')
10
+ stat = stub('File::Stat', :mode => 0345)
11
+ File.should_receive(:stat).with('foobar').and_return(stat)
12
+
13
+ expect do
14
+ Imap::Backup::Downloader.new(account, 'foo')
15
+ end.to raise_error(RuntimeError, "Permissions on 'foobar' should be 0700, not 0345")
16
+ end
17
+
18
+ end
19
+
20
+ context '#run' do
21
+
22
+ before :each do
23
+ stat = stub('File::Stat', :mode => 0700)
24
+ File.stub!(:stat => stat)
25
+
26
+ @account = stub('Imap::Backup::Account', :local_path => '/base/path')
27
+ @d = Imap::Backup::Downloader.new(@account, 'my_folder')
28
+ end
29
+
30
+ it 'should create the folder and update permissions' do
31
+ @account.stub!(:each_uid)
32
+ FileUtils.should_receive(:mkdir_p).with('/base/path/my_folder')
33
+ FileUtils.should_receive(:chmod_R).with('g-wrx,o-wrx', '/base/path/my_folder')
34
+
35
+ @d.run
36
+ end
37
+
38
+ context 'with folder' do
39
+ before :each do
40
+ FileUtils.stub!(:mkdir_p)
41
+ FileUtils.stub!(:chmod_R)
42
+ end
43
+
44
+ it 'should list messages' do
45
+ @account.should_receive(:each_uid)
46
+
47
+ @d.run
48
+ end
49
+
50
+ context 'with messages' do
51
+ before :each do
52
+ @account.should_receive(:each_uid) do |&block|
53
+ block.call '123'
54
+ block.call '999'
55
+ block.call '1234'
56
+ end
57
+ end
58
+
59
+ it 'should check if messages exist' do
60
+ File.should_receive(:exist?).with(%r{/base/path/my_folder/\d+.json}).exactly(3).times.and_return(true)
61
+
62
+ @d.run
63
+ end
64
+
65
+ it 'should skip messages that are downloaded' do
66
+ File.stub!(:exist?).and_return(true)
67
+
68
+ @account.should_not_receive(:fetch)
69
+
70
+ @d.run
71
+ end
72
+
73
+ context 'to download' do
74
+ before :each do
75
+ # N.B. messages 999 and 1234 wil be 'fetched'
76
+ File.stub!(:exist?) do |path|
77
+ if path =~ %r{123.json$}
78
+ true
79
+ else
80
+ false
81
+ end
82
+ end
83
+
84
+ @message = {
85
+ 'RFC822' => 'the body',
86
+ 'other' => 'xxx'
87
+ }
88
+ @account.stub!(:fetch => @message)
89
+ File.stub!(:open)
90
+ FileUtils.stub!(:chmod)
91
+ end
92
+
93
+ it 'should request messages' do
94
+ @account.should_receive(:fetch).with('999')
95
+ @account.should_receive(:fetch).with('1234')
96
+
97
+ @d.run
98
+ end
99
+
100
+ it 'should save messages' do
101
+ file = stub('File')
102
+ File.should_receive(:open) do |&block|
103
+ block.call file
104
+ end
105
+ file.should_receive(:write).with(/the body/)
106
+
107
+ @d.run
108
+ end
109
+
110
+ it 'should JSON encode messages' do
111
+ file = stub('File', :write => nil)
112
+ File.stub!(:open) do |&block|
113
+ block.call file
114
+ end
115
+
116
+ @message.should_receive(:to_json).twice
117
+
118
+ @d.run
119
+ end
120
+
121
+ it 'should set file permissions' do
122
+ FileUtils.should_receive(:chmod).with(0600, /999.json$/)
123
+ FileUtils.should_receive(:chmod).with(0600, /1234.json$/)
124
+
125
+ @d.run
126
+ end
127
+
128
+ end
129
+ end
130
+
131
+ end
132
+
133
+ end
134
+
135
+ end
136
+
@@ -0,0 +1,84 @@
1
+ # encoding: utf-8
2
+ load File.expand_path( '../spec_helper.rb', File.dirname(__FILE__) )
3
+
4
+ describe Imap::Backup::Settings do
5
+
6
+ context '#initialize' do
7
+
8
+ it 'should fail if the config file is missing' do
9
+ File.should_receive(:exist?).and_return(false)
10
+
11
+ expect do
12
+ Imap::Backup::Settings.new
13
+ end.to raise_error(RuntimeError, /not found/)
14
+ end
15
+
16
+ it 'should fail if the config file permissions are too lax' do
17
+ File.stub!(:exist?).and_return(true)
18
+
19
+ stat = stub('File::Stat', :mode => 0644)
20
+ File.should_receive(:stat).and_return(stat)
21
+
22
+ expect do
23
+ Imap::Backup::Settings.new
24
+ end.to raise_error(RuntimeError, /Permissions.*?should be 0600/)
25
+ end
26
+
27
+ it 'should load the config file' do
28
+ File.stub!(:exist?).and_return(true)
29
+
30
+ stat = stub('File::Stat', :mode => 0600)
31
+ File.stub!(:stat).and_return(stat)
32
+
33
+ file = stub('file')
34
+ File.should_receive(:open).with(%r{/.imap-backup/config.json}).and_return(file)
35
+ JSON.should_receive(:load).with(file)
36
+
37
+ Imap::Backup::Settings.new
38
+ end
39
+
40
+ end
41
+
42
+ context '#each_account' do
43
+ before :each do
44
+ @account1_settings = stub('account1 settings')
45
+ settings = {
46
+ 'accounts' => [
47
+ @account1_settings
48
+ ]
49
+ }
50
+ File.stub!(:open)
51
+ JSON.stub!(:load).and_return(settings)
52
+ @account = stub('Imap::Backup::Settings', :disconnect => nil)
53
+ end
54
+
55
+ subject { Imap::Backup::Settings.new }
56
+
57
+ it 'should create accounts' do
58
+ Imap::Backup::Account.should_receive(:new).with(@account1_settings).and_return(@account)
59
+ subject.each_account {}
60
+ end
61
+
62
+ it 'should call the block' do
63
+ Imap::Backup::Account.stub!(:new).and_return(@account)
64
+ calls = 0
65
+
66
+ subject.each_account do |a|
67
+ calls += 1
68
+ a.should == @account
69
+ end
70
+ calls.should == 1
71
+ end
72
+
73
+ it 'should disconnect the account' do
74
+ Imap::Backup::Account.stub!(:new).and_return(@account)
75
+
76
+ @account.should_receive(:disconnect)
77
+
78
+ subject.each_account {}
79
+ end
80
+
81
+ end
82
+
83
+ end
84
+
@@ -0,0 +1,73 @@
1
+ # encoding: utf-8
2
+ load File.expand_path( '../spec_helper.rb', File.dirname(__FILE__) )
3
+
4
+ describe Imap::Backup::Utils do
5
+
6
+ include Imap::Backup::Utils
7
+
8
+ context '#check_permissions' do
9
+
10
+ it 'should stat the file' do
11
+ stat = stub('File::Stat', :mode => 0100)
12
+ File.should_receive(:stat).with('foobar').and_return(stat)
13
+
14
+ check_permissions('foobar', 0345)
15
+ end
16
+
17
+ it 'should succeed if file permissions are less than limit' do
18
+ stat = stub('File::Stat', :mode => 0100)
19
+ File.stub!(:stat).and_return(stat)
20
+
21
+ expect do
22
+ check_permissions('foobar', 0345)
23
+ end.to_not raise_error
24
+ end
25
+
26
+ it 'should succeed if file permissions are equal to limit' do
27
+ stat = stub('File::Stat', :mode => 0345)
28
+ File.stub!(:stat).and_return(stat)
29
+
30
+ expect do
31
+ check_permissions('foobar', 0345)
32
+ end.to_not raise_error
33
+ end
34
+
35
+ it 'should fail if file permissions are over the limit' do
36
+ stat = stub('File::Stat', :mode => 0777)
37
+ File.stub!(:stat).and_return(stat)
38
+
39
+ expect do
40
+ check_permissions('foobar', 0345)
41
+ end.to raise_error(RuntimeError, "Permissions on 'foobar' should be 0345, not 0777")
42
+ end
43
+
44
+ end
45
+
46
+ context '#make_folder' do
47
+
48
+ it 'should do nothing if an empty path is supplied' do
49
+ FileUtils.should_not_receive(:mkdir_p)
50
+
51
+ make_folder('aaa', '', 0222)
52
+ end
53
+
54
+ it 'should create the path' do
55
+ FileUtils.stub!(:chmod_R)
56
+
57
+ FileUtils.should_receive(:mkdir_p).with('/base/path/new/folder')
58
+
59
+ make_folder('/base/path', 'new/folder', 0222)
60
+ end
61
+
62
+ it 'should set permissions on the path' do
63
+ FileUtils.stub!(:mkdir_p)
64
+
65
+ FileUtils.should_receive(:chmod_R).with(0222, '/base/path/new')
66
+
67
+ make_folder('/base/path', 'new/folder', 0222)
68
+ end
69
+
70
+ end
71
+
72
+ end
73
+
metadata ADDED
@@ -0,0 +1,143 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: imap-backup
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Joe Yates
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-10 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: pry
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: pry-doc
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: 2.3.0
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 2.3.0
62
+ - !ruby/object:Gem::Dependency
63
+ name: simplecov
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: Backup GMail, or any other IMAP email service, to disk.
79
+ email:
80
+ - joe.g.yates@gmail.com
81
+ executables:
82
+ - imap-backup
83
+ extensions: []
84
+ extra_rdoc_files: []
85
+ files:
86
+ - .gitignore
87
+ - .travis.yml
88
+ - Gemfile
89
+ - LICENSE
90
+ - README.md
91
+ - Rakefile
92
+ - bin/imap-backup
93
+ - imap-backup.gemspec
94
+ - lib/imap/backup.rb
95
+ - lib/imap/backup/account.rb
96
+ - lib/imap/backup/downloader.rb
97
+ - lib/imap/backup/settings.rb
98
+ - lib/imap/backup/utils.rb
99
+ - lib/imap/backup/version.rb
100
+ - spec/gather_rspec_coverage.rb
101
+ - spec/spec_helper.rb
102
+ - spec/unit/account_spec.rb
103
+ - spec/unit/downloader_spec.rb
104
+ - spec/unit/settings_spec.rb
105
+ - spec/unit/utils_spec.rb
106
+ homepage: https://github.com/joeyates/imap-backup
107
+ licenses: []
108
+ post_install_message:
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ segments:
119
+ - 0
120
+ hash: 3027570741254356503
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ! '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ segments:
128
+ - 0
129
+ hash: 3027570741254356503
130
+ requirements: []
131
+ rubyforge_project:
132
+ rubygems_version: 1.8.23
133
+ signing_key:
134
+ specification_version: 3
135
+ summary: Backup GMail (or other IMAP) accounts to disk
136
+ test_files:
137
+ - spec/gather_rspec_coverage.rb
138
+ - spec/spec_helper.rb
139
+ - spec/unit/account_spec.rb
140
+ - spec/unit/downloader_spec.rb
141
+ - spec/unit/settings_spec.rb
142
+ - spec/unit/utils_spec.rb
143
+ has_rdoc: