imap_guard 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format d
3
+ --order random
@@ -0,0 +1,17 @@
1
+ language: ruby
2
+ after_script:
3
+ - cane
4
+ - yard stats --list-undoc
5
+ rvm:
6
+ - 1.9.3
7
+ - 2.0.0
8
+ - ruby-head
9
+ - rbx-19mode
10
+ matrix:
11
+ allow_failures:
12
+ - rvm: ruby-head
13
+ - rvm: rbx-19mode
14
+ notifications:
15
+ email:
16
+ on_success: always
17
+ on_failure: always
@@ -0,0 +1,10 @@
1
+ # More info at https://github.com/guard/guard#readme
2
+
3
+ guard 'rspec' do
4
+ watch(%r{^spec/.+_spec\.rb$})
5
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
6
+ watch(%r{^lib/(.+)/(.+)\.rb$}) { |m| "spec/#{m[1]}/#{m[2]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ watch(%r{^spec/support/.+\.rb$}) { "spec" }
9
+ end
10
+
data/README.md CHANGED
@@ -1,65 +1,94 @@
1
- # ImapGuard
1
+ # ImapGuard [![Build Status](https://secure.travis-ci.org/infertux/imap_guard.png?branch=master)](https://travis-ci.org/infertux/imap_guard) [![Dependency Status](https://gemnasium.com/infertux/imap_guard.png)](https://gemnasium.com/infertux/imap_guard) [![Code Climate](https://codeclimate.com/github/infertux/imap_guard.png)](https://codeclimate.com/github/infertux/imap_guard)
2
2
 
3
- TODO: Write a gem description
3
+ A guard for your IMAP mailboxes.
4
+
5
+ ImapGuard connects to your IMAP server and processes your emails.
6
+ You can finely pick them thanks to advanced search queries and Ruby blocks.
7
+ Then you can `move` or `delete` them in batch.
8
+
9
+ Of course, there is a _dry-run_ mode (i.e. read-only) available to double check what it would do.
10
+
11
+ It can be used by a disposable script to clean things up or with a cron job to keep them tidy.
4
12
 
5
13
  ## Installation
6
14
 
7
- Add this line to your application's Gemfile:
15
+ $ gem install imap_guard
8
16
 
9
- gem 'imap_guard'
17
+ ## Usage
10
18
 
11
- And then execute:
19
+ Example initialization:
12
20
 
13
- $ bundle
21
+ ```ruby
22
+ require 'imap_guard'
14
23
 
15
- Or install it yourself as:
24
+ SETTINGS = {
25
+ host: 'mail.google.com',
26
+ port: 993,
27
+ username: 'login',
28
+ password: 'pass',
29
+ read_only: true # don't perform any modification aka dry-run mode
30
+ }
31
+
32
+ guard = IMAPGuard::Guard.new SETTINGS
33
+ guard.login # authenticate the user
34
+ guard.select 'INBOX.ops' # select the mailbox
35
+ ```
16
36
 
17
- $ gem install imap_guard
37
+ IMAP search query syntax can be a bit tricky.
38
+ `IMAPGuard::Query` can help you to build queries with a simple Ruby DSL:
18
39
 
19
- ## Usage
40
+ ```ruby
41
+ base_query = IMAPGuard::Query.new.unflagged.unanswered.seen.freeze
42
+ query = base_query.dup.before(7).subject("abc").from("root")
43
+ p query #=> ["UNFLAGGED", "UNANSWERED", "SEEN", "BEFORE", "13-Mar-2013", "SUBJECT", "abc", "FROM", "root"]
44
+ guard.delete query # will delete every emails which match this query
45
+ ```
20
46
 
21
- TODO: Write usage instructions here
47
+ Unfortunately, IMAP search queries are limited too.
48
+ For instance, the pattern passed to `subject` and `from` is a mere string.
49
+ IMAP doesn't allow advanced filtering such as regexp matching.
22
50
 
51
+ To do so, you can pass an optional block to `delete`.
52
+ The yielded object is a [Mail](https://github.com/mikel/mail) instance of the current mail providing many methods.
53
+ However, wrapping the mail into a nice `Mail` object is slow and you should avoid to use it if you can.
23
54
 
24
55
  ```ruby
25
- require 'imap_guard'
26
- load File.expand_path('../settings.rb', __FILE__)
27
- settings = SETTINGS.merge({ read_only: true })
28
-
29
- s = IMAPGuard::Guard.new settings
30
- s.select 'INBOX.ops'
31
-
32
- query = IMAPGuard::Query.new.before(7).subject("abc").from("root")
33
- s.delete query
34
-
35
- pattern = "monit alert -- Resource limit "
36
- query = IMAPGuard::Query.new.subject(pattern).before(7)
37
- s.delete query do |mail|
38
- # the pattern given to subject() is a mere string
39
- # pass an optional block to perform advanced filtering such as regexp matching
40
- # the yielded mail object is an instance of the current mail providing many methods
41
- mail.subject.start_with? pattern
56
+ guard.delete base_query.dup.before(7).subject("Logwatch for ") do |mail|
57
+ mail.subject =~ /\ALogwatch for \w \(Linux\)\Z/ and \
58
+ mail.multipart? and \
59
+ mail.parts.length == 2
42
60
  end
61
+ ```
43
62
 
44
- query = IMAPGuard::Query.new.before(7).subject("Logwatch for ")
45
- s.delete query do |mail|
46
- mail.subject =~ /\ALogwatch for \w \(Linux\)\Z/
47
- end
63
+ Finally, you can always forge your own raw IMAP search queries (the [RFC](http://tools.ietf.org/html/rfc3501#section-6.4.4) can help in that case):
48
64
 
49
- # You can also forge your own raw IMAP search queries like this
65
+ ```ruby
50
66
  query = 'SEEN SUBJECT "ALERT" FROM "root"'
51
- s.delete query do |mail|
52
- mail.subject == "ALERT" and \
67
+ guard.delete query do |mail|
53
68
  mail.body == "ALERT"
54
69
  end
70
+ ```
71
+
72
+ Be aware that emails won't be touched until you `expunge` or `close` the mailbox:
55
73
 
56
- s.close
74
+ ```ruby
75
+ guard.expunge # effectively delete emails marked as deleted
76
+ guard.close # expunge then close the connection
77
+ ```
78
+
79
+ Oh, and there is a `move` method as well:
80
+
81
+ ```ruby
82
+ guard.move query, 'destination_folder' do |mail|
83
+ # and it can take a filter block like `delete`
84
+ end
57
85
  ```
58
86
 
59
87
  ## Contributing
60
88
 
61
- 1. Fork it
62
- 2. Create your feature branch (`git checkout -b my-new-feature`)
63
- 3. Commit your changes (`git commit -am 'Add some feature'`)
64
- 4. Push to the branch (`git push origin my-new-feature`)
65
- 5. Create new Pull Request
89
+ Bug reports and patches are most welcome.
90
+
91
+ ## License
92
+
93
+ MIT
94
+
data/Rakefile CHANGED
@@ -1 +1,9 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec) do |t|
5
+ t.ruby_opts = '-w'
6
+ end
7
+
8
+ task default: :spec
9
+
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["cedric@felizard.fr"]
11
11
  spec.description = %q{A guard for your IMAP server}
12
12
  spec.summary = spec.description
13
- spec.homepage = ""
13
+ spec.homepage = "https://github.com/infertux/imap_guard"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files`.split($/)
@@ -19,7 +19,14 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_dependency 'mail', '~> 2.5.3'
22
+ spec.add_dependency 'colored', '~> 1.2'
22
23
 
23
24
  spec.add_development_dependency 'bundler', '~> 1.3'
24
25
  spec.add_development_dependency 'rake'
26
+ spec.add_development_dependency 'simplecov'
27
+ spec.add_development_dependency 'rspec'
28
+ spec.add_development_dependency 'guard-rspec'
29
+ spec.add_development_dependency 'rb-inotify'
30
+ spec.add_development_dependency 'cane'
31
+ spec.add_development_dependency 'yard'
25
32
  end
@@ -1,15 +1,21 @@
1
1
  require 'net/imap'
2
- require 'mail'
3
2
  require 'ostruct'
3
+ require 'mail'
4
+ require 'colored'
4
5
 
5
6
  module IMAPGuard
6
7
  class Guard
8
+ attr_reader :settings
9
+
7
10
  def initialize settings
8
- @settings = OpenStruct.new(settings).freeze
11
+ self.settings = settings
12
+ end
9
13
 
10
- # http://www.ruby-doc.org/stdlib-1.9.3/libdoc/net/imap/rdoc/Net/IMAP.html#method-c-new
14
+ # @see http://www.ruby-doc.org/stdlib-1.9.3/libdoc/net/imap/rdoc/Net/IMAP.html#method-c-new
15
+ def login
11
16
  @imap = Net::IMAP.new(@settings.host, @settings.port, true, nil, false)
12
17
  @imap.login(@settings.username, @settings.password)
18
+ verbose.puts "Logged in successfully"
13
19
  end
14
20
 
15
21
  def select mailbox
@@ -20,51 +26,97 @@ module IMAPGuard
20
26
  end
21
27
  end
22
28
 
23
- def delete query
24
- unless query.is_a? String
25
- if query.respond_to? :to_s
26
- query = query.to_s
27
- else
28
- raise ArgumentError, "query must provide #to_s"
29
- end
30
- end
29
+ # @param mailbox Destination mailbox
30
+ def move query, mailbox, &filter
31
+ operation = lambda { |message_id|
32
+ @imap.copy(message_id, mailbox) unless @settings.read_only
33
+ @imap.store(message_id, "+FLAGS", [:Deleted])
34
+ "moved to #{mailbox}".cyan
35
+ }
36
+ process query, operation, &filter
37
+ end
31
38
 
32
- messages = @imap.search query
33
- count = messages.size
34
- puts "Query: #{query.inspect}: #{count} results"
35
-
36
- counter = 0
37
- messages.each do |message_id|
38
- counter += 1
39
- # puts message_id
40
- mail = nil
39
+ def delete query, &filter
40
+ operation = lambda { |message_id|
41
+ @imap.store(message_id, "+FLAGS", [:Deleted])
42
+ 'deleted'.red
43
+ }
44
+ process query, operation, &filter
45
+ end
46
+
47
+ def expunge
48
+ @imap.expunge
49
+ end
50
+
51
+ def close
52
+ puts "Expunging deleted messages and closing mailbox..."
53
+ @imap.close
54
+ end
55
+
56
+ private
57
+
58
+ def process query, operation
59
+ message_ids = search query
60
+ count = message_ids.size
61
+
62
+ message_ids.each_with_index do |message_id, index|
63
+ print "Processing UID #{message_id} (#{index + 1}/#{count}): "
64
+
65
+ result = true
41
66
  if block_given?
42
- msg = @imap.fetch(message_id, 'RFC822')[0].attr['RFC822']
43
- mail = Mail.read_from_string msg
44
- result = yield mail
45
- if result
46
- # puts "Given filter matched"
47
- else
48
- # puts "Given filter returned falsy"
49
- next
50
- end
67
+ mail = fetch_mail message_id
68
+ result = yield(mail)
69
+ verbose.print "(given filter result: #{result.inspect}) "
51
70
  end
52
71
 
53
- print "Deleting UID #{message_id} (#{counter}/#{count})"
54
- print " (DRY-RUN)" if @settings.read_only
55
- if mail
56
- puts ": #{mail.subject} (#{mail.body.to_s.length})"
72
+ if result
73
+ puts operation.call(message_id)
57
74
  else
58
- puts
75
+ puts "ignored".yellow
59
76
  end
60
- @imap.store(message_id, "+FLAGS", [:Deleted])
61
77
  end
62
78
  end
63
79
 
64
- def close
65
- puts "Expunging deleted messages and closing mailbox..."
66
- # p imap.expunge
67
- @imap.close
80
+ def fetch_mail message_id
81
+ msg = @imap.fetch(message_id, 'RFC822')[0].attr['RFC822']
82
+ Mail.read_from_string msg
83
+ end
84
+
85
+ def search query
86
+ unless [Array, String].any? { |type| query.is_a? type }
87
+ raise ArgumentError, "query must be either a string holding the entire search string, or a single-dimension array of search keywords and arguments"
88
+ end
89
+
90
+ messages = @imap.search query
91
+ puts "Query: #{query.inspect}: #{messages.count} results".cyan
92
+
93
+ messages
94
+ end
95
+
96
+ def verbose
97
+ @verbose ||= if @settings.verbose
98
+ $stdout
99
+ else
100
+ # anonymous null object
101
+ Class.new do
102
+ def method_missing(*args, &block)
103
+ nil
104
+ end
105
+ end.new
106
+ end
107
+ end
108
+
109
+ def settings= settings
110
+ required = %w(host port username password).map!(&:to_sym)
111
+ missing = required - settings.keys
112
+ raise ArgumentError, "Missing settings: #{missing}" unless missing.empty?
113
+
114
+ optional = %w(read_only verbose).map!(&:to_sym)
115
+ unknown = settings.keys - required - optional
116
+ raise ArgumentError, "Unknown settings: #{unknown}" unless unknown.empty?
117
+
118
+ @settings = OpenStruct.new(settings).freeze
119
+ puts "DRY-RUN MODE ENABLED".yellow.bold.reversed if @settings.read_only
68
120
  end
69
121
  end
70
122
  end
@@ -1,49 +1,38 @@
1
1
  module IMAPGuard
2
- class Query
3
- def initialize
4
- @criteria = []
5
- seen.unanswered.unflagged
6
- end
7
-
8
- def to_s
9
- @criteria.join ' '
10
- end
11
-
2
+ class Query < Array
12
3
  def seen
13
- @criteria << 'SEEN'
14
- self
4
+ self << 'SEEN'
15
5
  end
16
6
 
17
7
  def unanswered
18
- @criteria << 'UNANSWERED'
19
- self
8
+ self << 'UNANSWERED'
20
9
  end
21
10
 
22
11
  def unflagged
23
- @criteria << 'UNFLAGGED'
24
- self
12
+ self << 'UNFLAGGED'
25
13
  end
26
14
 
27
15
  def subject string
28
- @criteria << "SUBJECT \"#{string}\""
29
- self
16
+ self << 'SUBJECT' << string
30
17
  end
31
18
 
32
19
  def from string
33
- @criteria << "FROM \"#{string}\""
34
- self
20
+ self << 'FROM' << string
35
21
  end
36
22
 
37
23
  def before date
38
24
  case date
25
+ when String
26
+ # noop, uses it as is
39
27
  when Fixnum
40
28
  date = (Date.today - date).strftime '%e-%b-%Y'
41
29
  when Date
42
- date = Date.strptime date, '%e-%b-%Y'
30
+ date = date.strftime '%e-%b-%Y'
31
+ else
32
+ raise ArgumentError, "#{date.inspect} is invalid"
43
33
  end
44
34
 
45
- @criteria << "BEFORE #{date}"
46
- self
35
+ self << 'BEFORE' << date
47
36
  end
48
37
  end
49
38
  end
@@ -1,3 +1,3 @@
1
1
  module ImapGuard
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,197 @@
1
+ require 'spec_helper'
2
+
3
+ module IMAPGuard
4
+ describe Guard do
5
+ before do
6
+ $stdout = StringIO.new # mute stdout - comment to debug
7
+ end
8
+
9
+ let(:settings) do
10
+ {
11
+ host: 'localhost',
12
+ port: 993,
13
+ username: 'bob',
14
+ password: 'PASS',
15
+ }
16
+ end
17
+
18
+ let(:imap) {
19
+ double('Net::IMAP', search: [7, 28])
20
+ }
21
+
22
+ def guard_instance custom_settings = {}
23
+ guard = Guard.new(settings.merge(custom_settings))
24
+ guard.instance_variable_set(:@imap, imap)
25
+ guard.stub(:fetch_mail)
26
+ guard
27
+ end
28
+
29
+ describe "#select" do
30
+ context "with settings.read_only = true" do
31
+ let(:guard) { guard_instance(read_only: true) }
32
+
33
+ it "opens the mailbox in read-only" do
34
+ imap.should_receive(:examine)
35
+ guard.select nil
36
+ end
37
+ end
38
+
39
+ context "with settings.read_only = false" do
40
+ let(:guard) { guard_instance(read_only: false) }
41
+
42
+ it "opens the mailbox in read-write" do
43
+ imap.should_receive(:select)
44
+ guard.select nil
45
+ end
46
+ end
47
+ end
48
+
49
+ describe "#search" do
50
+ before do
51
+ imap.should_receive(:search) do |arg|
52
+ [13, 37] if [['ALL'], 'ALL'].include? arg
53
+ end
54
+ end
55
+
56
+ it "accepts arrays" do
57
+ expect {
58
+ guard_instance.send(:search, ['ALL'])
59
+ }.to_not raise_error
60
+ end
61
+
62
+ it "accepts strings" do
63
+ expect {
64
+ guard_instance.send(:search, 'ALL')
65
+ }.to_not raise_error
66
+ end
67
+
68
+ it "returns results" do
69
+ messages = guard_instance.send(:search, 'ALL')
70
+ messages.should eq [13, 37]
71
+ end
72
+ end
73
+
74
+ describe "#process" do
75
+ let(:guard) { guard_instance(verbose: true) }
76
+ let(:opeartion) { ->(id) {} }
77
+
78
+ context "without a filter block" do
79
+ it "does perform the operation" do
80
+ opeartion.should_receive(:call).with(7)
81
+ opeartion.should_receive(:call).with(28)
82
+
83
+ guard.send(:process, 'ALL', opeartion)
84
+ end
85
+
86
+ it "does not execute the filter block" do
87
+ guard.should_not_receive(:fetch_mail)
88
+
89
+ guard.send(:process, 'ALL', opeartion)
90
+ end
91
+ end
92
+
93
+ context "with a filter block" do
94
+ it "executes the filter block" do
95
+ guard.should_receive(:fetch_mail).twice
96
+
97
+ guard.send(:process, 'ALL', opeartion) { }
98
+ end
99
+
100
+ context "returning false" do
101
+ it "does not perform the operation" do
102
+ opeartion.should_not_receive(:call)
103
+
104
+ guard.send(:process, 'ALL', opeartion) { false }
105
+ end
106
+ end
107
+
108
+ context "returning true" do
109
+ it "does perform the operation" do
110
+ opeartion.should_receive(:call).twice
111
+
112
+ guard.send(:process, 'ALL', opeartion) { true }
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+ describe "#move" do
119
+ it "copies emails before adding the :Deleted flag" do
120
+ imap.should_receive(:search)
121
+ imap.should_receive(:copy).with(7, 'destination').ordered
122
+ imap.should_receive(:store).with(7, '+FLAGS', [:Deleted]).ordered
123
+ imap.should_receive(:copy).with(28, 'destination').ordered
124
+ imap.should_receive(:store).with(28, '+FLAGS', [:Deleted]).ordered
125
+
126
+ guard_instance.move 'ALL', 'destination'
127
+ end
128
+ end
129
+
130
+ describe "#delete" do
131
+ it "adds the :Deleted flag" do
132
+ imap.should_receive(:search)
133
+ imap.should_receive(:store).with(7, '+FLAGS', [:Deleted])
134
+ imap.should_receive(:store).with(28, '+FLAGS', [:Deleted])
135
+
136
+ guard_instance.delete 'ALL'
137
+ end
138
+ end
139
+
140
+ describe "#expunge" do
141
+ it "expunges the folder" do
142
+ imap.should_receive(:expunge)
143
+ guard_instance.expunge
144
+ end
145
+ end
146
+
147
+ describe "#close" do
148
+ it "closes the IMAP connection" do
149
+ imap.should_receive(:close)
150
+ guard_instance.close
151
+ end
152
+ end
153
+
154
+ describe "#verbose" do
155
+ context "with settings.verbose = true" do
156
+ let(:guard) { guard_instance(verbose: true) }
157
+
158
+ it "does output to $stdout" do
159
+ $stdout.should_receive(:write).with("ham")
160
+ guard.send(:verbose).print "ham"
161
+ end
162
+ end
163
+
164
+ context "with settings.verbose = false" do
165
+ let(:guard) { guard_instance(verbose: false) }
166
+
167
+ it "does not output to $stdout" do
168
+ $stdout.should_not_receive(:write)
169
+ guard.send(:verbose).print "ham"
170
+ end
171
+ end
172
+ end
173
+
174
+ describe "#settings=" do
175
+ it "freezes the settings" do
176
+ guard = Guard.new(settings)
177
+
178
+ expect {
179
+ guard.settings.host = 'example.net'
180
+ }.to raise_error(TypeError, /frozen/)
181
+ end
182
+
183
+ it "raises ArgumentError if any required key is missing" do
184
+ expect {
185
+ Guard.new({})
186
+ }.to raise_error ArgumentError, /missing/i
187
+ end
188
+
189
+ it "raises ArgumentError if any key is unknown" do
190
+ expect {
191
+ Guard.new(settings.merge(coffee: true))
192
+ }.to raise_error ArgumentError, /unknown/i
193
+ end
194
+ end
195
+ end
196
+ end
197
+
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ module IMAPGuard
4
+ describe Query do
5
+ describe "#initialize" do
6
+ it { should be_empty }
7
+ end
8
+
9
+ describe "#seen" do
10
+ it "adds 'SEEN'" do
11
+ subject.seen
12
+ subject.last.should eq 'SEEN'
13
+ end
14
+ end
15
+
16
+ describe "#unanswered" do
17
+ it "adds 'UNANSWERED'" do
18
+ subject.unanswered
19
+ subject.last.should eq 'UNANSWERED'
20
+ end
21
+ end
22
+
23
+ describe "#unflagged" do
24
+ it "adds 'UNFLAGGED'" do
25
+ subject.unflagged
26
+ subject.last.should eq 'UNFLAGGED'
27
+ end
28
+ end
29
+
30
+ describe "#subject" do
31
+ it "adds the search value" do
32
+ subject.subject("Hey you")
33
+ subject.last.should eq "Hey you"
34
+ end
35
+ end
36
+
37
+ describe "#from" do
38
+ it "adds the search value" do
39
+ subject.from("root@example.net")
40
+ subject.last.should eq "root@example.net"
41
+ end
42
+ end
43
+
44
+ describe "#before" do
45
+ context "when I pass 'nil' as an argument" do
46
+ it "raises" do
47
+ expect {
48
+ subject.before(nil)
49
+ }.to raise_error ArgumentError
50
+ end
51
+ end
52
+
53
+ context "when I pass '1' as an argument" do
54
+ it "returns yesterday" do
55
+ subject.before(1)
56
+ Date.parse(subject.last).should eq Date.today.prev_day
57
+ end
58
+ end
59
+
60
+ context "when I pass an integer" do
61
+ it "uses it as a negative offset in days" do
62
+ subject.before(3)
63
+ (Date.today - Date.parse(subject.last)).should eq 3
64
+ end
65
+ end
66
+
67
+ context "when I pass '18-Mar-2013' as an argument" do
68
+ it "uses it as is" do
69
+ subject.before('18-Mar-2013')
70
+ subject.last.should eq '18-Mar-2013'
71
+ end
72
+ end
73
+
74
+ context "when I pass an instance of Date as an argument" do
75
+ it "extracts the date" do
76
+ subject.before(Date.today)
77
+ Date.parse(subject.last).should eq Date.today
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+
@@ -0,0 +1,11 @@
1
+ require 'simplecov'
2
+ SimpleCov.start do
3
+ minimum_coverage 90
4
+ add_group "Sources", "lib"
5
+ add_group "Tests", "spec"
6
+ end
7
+
8
+ require 'imap_guard'
9
+
10
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |file| require file }
11
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: imap_guard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-19 00:00:00.000000000 Z
12
+ date: 2013-03-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mail
@@ -27,6 +27,22 @@ dependencies:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
29
  version: 2.5.3
30
+ - !ruby/object:Gem::Dependency
31
+ name: colored
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '1.2'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.2'
30
46
  - !ruby/object:Gem::Dependency
31
47
  name: bundler
32
48
  requirement: !ruby/object:Gem::Requirement
@@ -59,6 +75,102 @@ dependencies:
59
75
  - - ! '>='
60
76
  - !ruby/object:Gem::Version
61
77
  version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: simplecov
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: rspec
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: guard-rspec
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: rb-inotify
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: cane
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ - !ruby/object:Gem::Dependency
159
+ name: yard
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
62
174
  description: A guard for your IMAP server
63
175
  email:
64
176
  - cedric@felizard.fr
@@ -67,8 +179,11 @@ extensions: []
67
179
  extra_rdoc_files: []
68
180
  files:
69
181
  - .gitignore
182
+ - .rspec
70
183
  - .ruby-version
184
+ - .travis.yml
71
185
  - Gemfile
186
+ - Guardfile
72
187
  - LICENSE.txt
73
188
  - README.md
74
189
  - Rakefile
@@ -77,7 +192,10 @@ files:
77
192
  - lib/imap_guard/guard.rb
78
193
  - lib/imap_guard/query.rb
79
194
  - lib/imap_guard/version.rb
80
- homepage: ''
195
+ - spec/imap_guard/guard_spec.rb
196
+ - spec/imap_guard/query_spec.rb
197
+ - spec/spec_helper.rb
198
+ homepage: https://github.com/infertux/imap_guard
81
199
  licenses:
82
200
  - MIT
83
201
  post_install_message:
@@ -92,7 +210,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
92
210
  version: '0'
93
211
  segments:
94
212
  - 0
95
- hash: -502947235
213
+ hash: -500228931
96
214
  required_rubygems_version: !ruby/object:Gem::Requirement
97
215
  none: false
98
216
  requirements:
@@ -101,11 +219,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
219
  version: '0'
102
220
  segments:
103
221
  - 0
104
- hash: -502947235
222
+ hash: -500228931
105
223
  requirements: []
106
224
  rubyforge_project:
107
225
  rubygems_version: 1.8.25
108
226
  signing_key:
109
227
  specification_version: 3
110
228
  summary: A guard for your IMAP server
111
- test_files: []
229
+ test_files:
230
+ - spec/imap_guard/guard_spec.rb
231
+ - spec/imap_guard/query_spec.rb
232
+ - spec/spec_helper.rb
233
+ has_rdoc: