gmail-britta 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -8,7 +8,9 @@ gem 'haml', '~> 3.1.6'
8
8
  group :development do
9
9
  gem "shoulda", ">= 0"
10
10
  gem "rdoc", "~> 3.12"
11
- gem "bundler", "~> 1.1.0"
11
+ gem "bundler", "~> 1.2.0"
12
12
  gem "jeweler", "~> 1.8.4"
13
13
  gem "rcov", ">= 0"
14
+ gem "minitest"
15
+ gem "nokogiri"
14
16
  end
@@ -13,7 +13,9 @@ GEM
13
13
  rake
14
14
  rdoc
15
15
  json (1.7.5)
16
+ minitest (3.1.0)
16
17
  multi_json (1.3.6)
18
+ nokogiri (1.5.6)
17
19
  rake (0.9.2.2)
18
20
  rcov (1.0.0)
19
21
  rdoc (3.12)
@@ -29,9 +31,11 @@ PLATFORMS
29
31
  ruby
30
32
 
31
33
  DEPENDENCIES
32
- bundler (~> 1.1.0)
34
+ bundler (~> 1.2.0)
33
35
  haml (~> 3.1.6)
34
36
  jeweler (~> 1.8.4)
37
+ minitest
38
+ nokogiri
35
39
  rcov
36
40
  rdoc (~> 3.12)
37
41
  shoulda
@@ -4,6 +4,10 @@ This gem assists in writing complex gmail filters. You probably have a
4
4
  lot of questions, and I'm sorry this README currently answers so few
5
5
  of them )-:
6
6
 
7
+ A lot of this is very hacky, as it started as a oneoff ruby script -
8
+ very sorry for any amateurish code you may encounter. All I can say
9
+ is, it works for me [-:
10
+
7
11
  == Contributing to gmail-britta
8
12
 
9
13
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
@@ -11,7 +15,7 @@ of them )-:
11
15
  * Fork the project.
12
16
  * Start a feature/bugfix branch.
13
17
  * Commit and push until you are happy with your contribution.
14
- * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
18
+ * Make sure to add tests for it. (Note that are only very few tests yet. I would totally appreciate if you started fleshing out this suite, but I wouldn't expect you to add much of anything.)
15
19
  * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
16
20
 
17
21
  == Copyright
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.1.3
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "gmail-britta"
8
- s.version = "0.1.2"
8
+ s.version = "0.1.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Andreas Fuchs"]
12
- s.date = "2012-10-12"
12
+ s.date = "2012-12-22"
13
13
  s.description = "This gem helps create large (>50) gmail filter chains by writing xml compatible with gmail's \"import/export filters\" feature."
14
14
  s.email = "asf@boinkor.net"
15
15
  s.extra_rdoc_files = [
@@ -25,7 +25,11 @@ Gem::Specification.new do |s|
25
25
  "Rakefile",
26
26
  "VERSION",
27
27
  "gmail-britta.gemspec",
28
- "lib/gmail-britta.rb"
28
+ "lib/gmail-britta.rb",
29
+ "lib/gmail-britta/delegate.rb",
30
+ "lib/gmail-britta/filter.rb",
31
+ "lib/gmail-britta/single_write_accessors.rb",
32
+ "test/test_gmail-britta.rb"
29
33
  ]
30
34
  s.homepage = "http://github.com/antifuchs/gmail-britta"
31
35
  s.licenses = ["MIT"]
@@ -40,24 +44,30 @@ Gem::Specification.new do |s|
40
44
  s.add_runtime_dependency(%q<haml>, ["~> 3.1.6"])
41
45
  s.add_development_dependency(%q<shoulda>, [">= 0"])
42
46
  s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
43
- s.add_development_dependency(%q<bundler>, ["~> 1.1.0"])
47
+ s.add_development_dependency(%q<bundler>, ["~> 1.2.0"])
44
48
  s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
45
49
  s.add_development_dependency(%q<rcov>, [">= 0"])
50
+ s.add_development_dependency(%q<minitest>, [">= 0"])
51
+ s.add_development_dependency(%q<nokogiri>, [">= 0"])
46
52
  else
47
53
  s.add_dependency(%q<haml>, ["~> 3.1.6"])
48
54
  s.add_dependency(%q<shoulda>, [">= 0"])
49
55
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
50
- s.add_dependency(%q<bundler>, ["~> 1.1.0"])
56
+ s.add_dependency(%q<bundler>, ["~> 1.2.0"])
51
57
  s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
52
58
  s.add_dependency(%q<rcov>, [">= 0"])
59
+ s.add_dependency(%q<minitest>, [">= 0"])
60
+ s.add_dependency(%q<nokogiri>, [">= 0"])
53
61
  end
54
62
  else
55
63
  s.add_dependency(%q<haml>, ["~> 3.1.6"])
56
64
  s.add_dependency(%q<shoulda>, [">= 0"])
57
65
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
58
- s.add_dependency(%q<bundler>, ["~> 1.1.0"])
66
+ s.add_dependency(%q<bundler>, ["~> 1.2.0"])
59
67
  s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
60
68
  s.add_dependency(%q<rcov>, [">= 0"])
69
+ s.add_dependency(%q<minitest>, [">= 0"])
70
+ s.add_dependency(%q<nokogiri>, [">= 0"])
61
71
  end
62
72
  end
63
73
 
@@ -10,242 +10,34 @@ require 'time'
10
10
  require 'haml'
11
11
  require 'logger'
12
12
 
13
- $log = Logger.new(STDERR)
14
- $log.level = Logger::INFO
13
+ require 'gmail-britta/single_write_accessors'
14
+ require 'gmail-britta/delegate'
15
+ require 'gmail-britta/filter'
15
16
 
16
- module SingleWriteAccessors
17
- module ClassMethods
18
- def ivar_name(name)
19
- "@#{name}".intern
17
+ module GmailBritta
18
+ class Britta
19
+ def initialize(opts={})
20
+ @filters = []
21
+ @me = opts[:me] || 'me'
22
+ @logger = opts[:logger] || allocate_logger
20
23
  end
21
24
 
22
- def single_write_accessors
23
- @single_write_accessors ||= {}
25
+ def allocate_logger
26
+ logger = Logger.new(STDERR)
27
+ logger.level = Logger::WARN
28
+ logger
24
29
  end
25
30
 
26
- def single_write_accessor(name, gmail_name, &block)
27
- single_write_accessors[name] = gmail_name
28
- ivar_name = self.ivar_name(name)
29
- define_method(name) do |words|
30
- if instance_variable_get(ivar_name)
31
- raise "Only one use of #{name} is permitted per filter"
32
- end
33
- instance_variable_set(ivar_name, words)
34
- end
35
- define_method("get_#{name}") do
36
- instance_variable_get(ivar_name)
37
- end
38
- if block_given?
39
- define_method("output_#{name}") do
40
- instance_variable_get(ivar_name) && block.call(instance_variable_get(ivar_name))
41
- end
42
- else
43
- define_method("output_#{name}") do
44
- instance_variable_get(ivar_name)
45
- end
46
- end
47
- end
48
-
49
- def single_write_boolean_accessor(name, gmail_name)
50
- single_write_accessors[name] = gmail_name
51
- ivar_name = self.ivar_name(name)
52
- define_method(name) do |*args|
53
- value = args.length > 0 ? args[0] : true
54
- if instance_variable_get(ivar_name)
55
- raise "Only one use of #{name} is permitted per filter"
56
- end
57
- instance_variable_set(ivar_name, value)
58
- end
59
- define_method("get_#{name}") do
60
- instance_variable_get(ivar_name)
61
- end
62
- define_method("output_#{name}") do
63
- instance_variable_get(ivar_name)
64
- end
65
- end
66
- end
67
-
68
- def self.included(base)
69
- base.extend(ClassMethods)
70
- end
71
- end
72
-
73
- class GmailBritta
74
- def initialize(opts={})
75
- @filters = []
76
- @me = opts[:me] || 'me'
77
- end
78
-
79
- attr_accessor :filters
80
- attr_accessor :me
81
-
82
- def self.filterset(opts={}, &block)
83
- (britta = GmailBritta.new(opts)).rules(&block)
84
- britta
85
- end
31
+ attr_accessor :filters
32
+ attr_accessor :me
33
+ attr_accessor :logger
86
34
 
87
- def rules(&block)
88
- Delegate.new(self).perform(&block)
89
- end
90
-
91
- class Delegate
92
- def initialize(britta)
93
- @britta = britta
94
- @filter = nil
95
- end
96
-
97
- def filter(&block)
98
- Filter.new(@britta).perform(&block)
99
- end
100
-
101
- def perform(&block)
102
- instance_eval(&block)
103
- end
104
- end
105
-
106
- class Filter
107
- include SingleWriteAccessors
108
- single_write_accessor :has, 'hasTheWord' do |list|
109
- emit_filter_spec(list)
35
+ def rules(&block)
36
+ GmailBritta::Delegate.new(self, :logger => @logger).perform(&block)
110
37
  end
111
- single_write_accessor :has_not, 'doesNotHaveTheWord' do |list|
112
- emit_filter_spec(list)
113
- end
114
- single_write_boolean_accessor :archive, 'shouldArchive'
115
- single_write_boolean_accessor :delete_it, 'shouldTrash'
116
- single_write_boolean_accessor :mark_read, 'shouldMarkAsRead'
117
- single_write_boolean_accessor :mark_important, 'shouldAlwaysMarkAsImportant'
118
- single_write_boolean_accessor :mark_unimportant, 'shouldNeverMarkAsImportant'
119
- single_write_boolean_accessor :star, 'shouldStar'
120
- single_write_boolean_accessor :never_spam, 'shouldNeverSpam'
121
- single_write_accessor :label, 'label'
122
- single_write_accessor :forward_to, 'forwardTo'
123
38
 
124
- def generate_xml
39
+ def generate
125
40
  engine = Haml::Engine.new(<<-ATOM)
126
- %entry
127
- %category{:term => 'filter'}
128
- %title Mail Filter
129
- %content
130
- - self.class.single_write_accessors.keys.each do |name|
131
- - gmail_name = self.class.single_write_accessors[name]
132
- - if value = self.send("output_\#{name}".intern)
133
- %apps:property{:name => gmail_name, :value => value.to_s}
134
- ATOM
135
- engine.render(self)
136
- end
137
-
138
- def self.emit_filter_spec(filter, infix=' ')
139
- str = ''
140
- case filter
141
- when String
142
- str << filter
143
- when Hash
144
- filter.keys.each do |key|
145
- case key
146
- when :or
147
- str << '('
148
- str << emit_filter_spec(filter[key], ' OR ')
149
- str << ')'
150
- when :not
151
- str << '-('
152
- str << emit_filter_spec(filter[key], ' ')
153
- str << ')'
154
- end
155
- end
156
- when Array
157
- str << filter.map {|elt| emit_filter_spec(elt, ' ')}.join(infix)
158
- end
159
- $log.debug " Filter spec #{filter.inspect} + #{infix.inspect} => #{str.inspect}"
160
- str
161
- end
162
-
163
- def me
164
- @britta.me
165
- end
166
-
167
- def initialize(britta)
168
- @britta=britta
169
- end
170
-
171
- def log_definition
172
- $log.debug "Filter: #{self}"
173
- Filter.single_write_accessors.each do |name|
174
- val = instance_variable_get(Filter.ivar_name(name))
175
- $log.debug " #{name}: #{val}" if val
176
- end
177
- self
178
- end
179
-
180
- def perform(&block)
181
- instance_eval(&block)
182
- @britta.filters << self
183
- self
184
- end
185
-
186
- def merge_negated_criteria(filter)
187
- old_has_not = Marshal.load(Marshal.dump((filter.get_has_not || []).reject { |elt|
188
- @has.member?(elt)
189
- }))
190
- old_has = Marshal.load( Marshal.dump((filter.get_has || []).reject { |elt|
191
- @has.member?(elt)
192
- }))
193
- $log.debug(" M: oh #{old_has.inspect}")
194
- $log.debug(" M: ohn #{old_has_not.inspect}")
195
-
196
- @has_not ||= []
197
- @has_not += case
198
- when old_has_not.first.is_a?(Hash) && old_has_not.first[:or]
199
- old_has_not.first[:or] += old_has
200
- old_has_not
201
- when old_has_not.length > 0
202
- [{:or => old_has_not + old_has}]
203
- else
204
- old_has
205
- end
206
- $log.debug(" M: h #{@has.inspect}")
207
- $log.debug(" M: nhn #{@has_not.inspect}")
208
- end
209
-
210
- def otherwise(&block)
211
- filter = Filter.new(@britta).perform(&block)
212
- filter.merge_negated_criteria(self)
213
- filter.log_definition
214
- filter
215
- end
216
-
217
- def merge_positive_criteria(filter)
218
- new_has = (@has || []) + (filter.get_has || [])
219
- new_has_not = (@has_not || []) + (filter.get_has_not || [])
220
- @has = new_has
221
- @has_not = new_has_not
222
- end
223
-
224
- def also(&block)
225
- filter = Filter.new(@britta).perform(&block)
226
- filter.merge_positive_criteria(self)
227
- filter.log_definition
228
- filter
229
- end
230
-
231
- def archive_unless_directed(options={})
232
- mark_as_read=options[:mark_read]
233
- tos=(options[:to] || me).to_a
234
- filter = Filter.new(@britta).perform do
235
- has_not [{:or => tos.map {|to| "to:#{to}"}}]
236
- archive
237
- if mark_as_read
238
- mark_read
239
- end
240
- end
241
- filter.merge_positive_criteria(self)
242
- filter.log_definition
243
- self
244
- end
245
- end
246
-
247
- def generate
248
- engine = Haml::Engine.new(<<-ATOM)
249
41
  !!! XML
250
42
  %feed{:xmlns => 'http://www.w3.org/2005/Atom', 'xmlns:apps' => 'http://schemas.google.com/apps/2006'}
251
43
  %title Mail Filters
@@ -257,6 +49,12 @@ ATOM
257
49
  - filters.each do |filter|
258
50
  != filter.generate_xml
259
51
  ATOM
260
- engine.render(self)
52
+ engine.render(self)
53
+ end
54
+ end
55
+
56
+ def self.filterset(opts={}, &block)
57
+ (britta = Britta.new(opts)).rules(&block)
58
+ britta
261
59
  end
262
60
  end
@@ -0,0 +1,17 @@
1
+ module GmailBritta
2
+ class Delegate
3
+ def initialize(britta, options={})
4
+ @britta = britta
5
+ @log = options[:logger]
6
+ @filter = nil
7
+ end
8
+
9
+ def filter(&block)
10
+ GmailBritta::Filter.new(@britta, :log => @log).perform(&block)
11
+ end
12
+
13
+ def perform(&block)
14
+ instance_eval(&block)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,142 @@
1
+ module GmailBritta
2
+ class Filter
3
+ include SingleWriteAccessors
4
+ single_write_accessor :has, 'hasTheWord' do |list|
5
+ emit_filter_spec(list)
6
+ end
7
+ single_write_accessor :has_not, 'doesNotHaveTheWord' do |list|
8
+ emit_filter_spec(list)
9
+ end
10
+ single_write_boolean_accessor :archive, 'shouldArchive'
11
+ single_write_boolean_accessor :delete_it, 'shouldTrash'
12
+ single_write_boolean_accessor :mark_read, 'shouldMarkAsRead'
13
+ single_write_boolean_accessor :mark_important, 'shouldAlwaysMarkAsImportant'
14
+ single_write_boolean_accessor :mark_unimportant, 'shouldNeverMarkAsImportant'
15
+ single_write_boolean_accessor :star, 'shouldStar'
16
+ single_write_boolean_accessor :never_spam, 'shouldNeverSpam'
17
+ single_write_accessor :label, 'label'
18
+ single_write_accessor :forward_to, 'forwardTo'
19
+
20
+ def initialize(britta, options={})
21
+ @britta = britta
22
+ @log = options[:log]
23
+ end
24
+
25
+ def generate_xml
26
+ engine = Haml::Engine.new(<<-ATOM)
27
+ %entry
28
+ %category{:term => 'filter'}
29
+ %title Mail Filter
30
+ %content
31
+ - self.class.single_write_accessors.keys.each do |name|
32
+ - gmail_name = self.class.single_write_accessors[name]
33
+ - if value = self.send("output_\#{name}".intern)
34
+ %apps:property{:name => gmail_name, :value => value.to_s}
35
+ ATOM
36
+ engine.render(self)
37
+ end
38
+
39
+ def self.emit_filter_spec(filter, infix=' ')
40
+ str = ''
41
+ case filter
42
+ when String
43
+ str << filter
44
+ when Hash
45
+ filter.keys.each do |key|
46
+ case key
47
+ when :or
48
+ str << '('
49
+ str << emit_filter_spec(filter[key], ' OR ')
50
+ str << ')'
51
+ when :not
52
+ str << '-('
53
+ str << emit_filter_spec(filter[key], ' ')
54
+ str << ')'
55
+ end
56
+ end
57
+ when Array
58
+ str << filter.map {|elt| emit_filter_spec(elt, ' ')}.join(infix)
59
+ end
60
+ str
61
+ end
62
+
63
+ def me
64
+ @britta.me
65
+ end
66
+
67
+ def log_definition
68
+ @log.debug "Filter: #{self}"
69
+ Filter.single_write_accessors.each do |name|
70
+ val = instance_variable_get(Filter.ivar_name(name))
71
+ @log.debug " #{name}: #{val}" if val
72
+ end
73
+ self
74
+ end
75
+
76
+ def perform(&block)
77
+ instance_eval(&block)
78
+ @britta.filters << self
79
+ self
80
+ end
81
+
82
+ def merge_negated_criteria(filter)
83
+ old_has_not = Marshal.load(Marshal.dump((filter.get_has_not || []).reject { |elt|
84
+ @has.member?(elt)
85
+ }))
86
+ old_has = Marshal.load( Marshal.dump((filter.get_has || []).reject { |elt|
87
+ @has.member?(elt)
88
+ }))
89
+ @log.debug(" M: oh #{old_has.inspect}")
90
+ @log.debug(" M: ohn #{old_has_not.inspect}")
91
+
92
+ @has_not ||= []
93
+ @has_not += case
94
+ when old_has_not.first.is_a?(Hash) && old_has_not.first[:or]
95
+ old_has_not.first[:or] += old_has
96
+ old_has_not
97
+ when old_has_not.length > 0
98
+ [{:or => old_has_not + old_has}]
99
+ else
100
+ old_has
101
+ end
102
+ @log.debug(" M: h #{@has.inspect}")
103
+ @log.debug(" M: nhn #{@has_not.inspect}")
104
+ end
105
+
106
+ def otherwise(&block)
107
+ filter = Filter.new(@britta).perform(&block)
108
+ filter.merge_negated_criteria(self)
109
+ filter.log_definition
110
+ filter
111
+ end
112
+
113
+ def merge_positive_criteria(filter)
114
+ new_has = (@has || []) + (filter.get_has || [])
115
+ new_has_not = (@has_not || []) + (filter.get_has_not || [])
116
+ @has = new_has
117
+ @has_not = new_has_not
118
+ end
119
+
120
+ def also(&block)
121
+ filter = Filter.new(@britta).perform(&block)
122
+ filter.merge_positive_criteria(self)
123
+ filter.log_definition
124
+ filter
125
+ end
126
+
127
+ def archive_unless_directed(options={})
128
+ mark_as_read=options[:mark_read]
129
+ tos=(options[:to] || me).to_a
130
+ filter = Filter.new(@britta).perform do
131
+ has_not [{:or => tos.map {|to| "to:#{to}"}}]
132
+ archive
133
+ if mark_as_read
134
+ mark_read
135
+ end
136
+ end
137
+ filter.merge_positive_criteria(self)
138
+ filter.log_definition
139
+ self
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,58 @@
1
+ module GmailBritta
2
+ module SingleWriteAccessors
3
+ module ClassMethods
4
+ def ivar_name(name)
5
+ "@#{name}".intern
6
+ end
7
+
8
+ def single_write_accessors
9
+ @single_write_accessors ||= {}
10
+ end
11
+
12
+ def single_write_accessor(name, gmail_name, &block)
13
+ single_write_accessors[name] = gmail_name
14
+ ivar_name = self.ivar_name(name)
15
+ define_method(name) do |words|
16
+ if instance_variable_get(ivar_name)
17
+ raise "Only one use of #{name} is permitted per filter"
18
+ end
19
+ instance_variable_set(ivar_name, words)
20
+ end
21
+ define_method("get_#{name}") do
22
+ instance_variable_get(ivar_name)
23
+ end
24
+ if block_given?
25
+ define_method("output_#{name}") do
26
+ instance_variable_get(ivar_name) && block.call(instance_variable_get(ivar_name))
27
+ end
28
+ else
29
+ define_method("output_#{name}") do
30
+ instance_variable_get(ivar_name)
31
+ end
32
+ end
33
+ end
34
+
35
+ def single_write_boolean_accessor(name, gmail_name)
36
+ single_write_accessors[name] = gmail_name
37
+ ivar_name = self.ivar_name(name)
38
+ define_method(name) do |*args|
39
+ value = args.length > 0 ? args[0] : true
40
+ if instance_variable_get(ivar_name)
41
+ raise "Only one use of #{name} is permitted per filter"
42
+ end
43
+ instance_variable_set(ivar_name, value)
44
+ end
45
+ define_method("get_#{name}") do
46
+ instance_variable_get(ivar_name)
47
+ end
48
+ define_method("output_#{name}") do
49
+ instance_variable_get(ivar_name)
50
+ end
51
+ end
52
+ end
53
+
54
+ def self.included(base)
55
+ base.extend(ClassMethods)
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,45 @@
1
+ require 'bundler/setup'
2
+ require 'minitest/unit'
3
+ require 'nokogiri'
4
+ require 'minitest/autorun'
5
+
6
+ require 'gmail-britta'
7
+
8
+ describe GmailBritta do
9
+ def simple_filterset
10
+ fs = GmailBritta.filterset() do
11
+ filter {
12
+ has 'to:asf@boinkor.net'
13
+ label 'ohai'
14
+ }
15
+ end
16
+ end
17
+
18
+ def dom(filterset)
19
+ text = simple_filterset.generate
20
+ #puts text
21
+ Nokogiri::XML.parse(text)
22
+ end
23
+
24
+ def ns
25
+ {
26
+ 'a' => 'http://www.w3.org/2005/Atom',
27
+ 'apps' => 'http://schemas.google.com/apps/2006'
28
+ }
29
+ end
30
+
31
+ it "runs" do
32
+ filters = simple_filterset.generate
33
+ assert(filters, "Should generate something")
34
+ assert(filters.is_a?(String), "Generated filters should be a string")
35
+ end
36
+
37
+ it "generates xml" do
38
+ filters = dom(simple_filterset)
39
+
40
+ assert_equal(1, filters.xpath('/a:feed/a:entry',ns).length, "Should have exactly one filter entry")
41
+ assert_equal(2, filters.xpath('/a:feed/a:entry/apps:property',ns).length, "Should have two properties")
42
+ assert_equal(1, filters.xpath('/a:feed/a:entry/apps:property[@name="label"]',ns).length, "Should have exactly one 'label' property")
43
+ assert_equal(1, filters.xpath('/a:feed/a:entry/apps:property[@name="hasTheWord"]',ns).length, "Should have exactly one 'has' property")
44
+ end
45
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gmail-britta
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 29
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 2
10
- version: 0.1.2
9
+ - 3
10
+ version: 0.1.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Andreas Fuchs
@@ -15,11 +15,10 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-10-12 00:00:00 Z
18
+ date: 2012-12-22 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- type: :runtime
22
- requirement: &id001 !ruby/object:Gem::Requirement
21
+ version_requirements: &id001 !ruby/object:Gem::Requirement
23
22
  none: false
24
23
  requirements:
25
24
  - - ~>
@@ -30,12 +29,12 @@ dependencies:
30
29
  - 1
31
30
  - 6
32
31
  version: 3.1.6
33
- version_requirements: *id001
34
- name: haml
35
32
  prerelease: false
33
+ type: :runtime
34
+ name: haml
35
+ requirement: *id001
36
36
  - !ruby/object:Gem::Dependency
37
- type: :development
38
- requirement: &id002 !ruby/object:Gem::Requirement
37
+ version_requirements: &id002 !ruby/object:Gem::Requirement
39
38
  none: false
40
39
  requirements:
41
40
  - - ">="
@@ -44,12 +43,12 @@ dependencies:
44
43
  segments:
45
44
  - 0
46
45
  version: "0"
47
- version_requirements: *id002
48
- name: shoulda
49
46
  prerelease: false
50
- - !ruby/object:Gem::Dependency
51
47
  type: :development
52
- requirement: &id003 !ruby/object:Gem::Requirement
48
+ name: shoulda
49
+ requirement: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ version_requirements: &id003 !ruby/object:Gem::Requirement
53
52
  none: false
54
53
  requirements:
55
54
  - - ~>
@@ -59,28 +58,28 @@ dependencies:
59
58
  - 3
60
59
  - 12
61
60
  version: "3.12"
62
- version_requirements: *id003
63
- name: rdoc
64
61
  prerelease: false
65
- - !ruby/object:Gem::Dependency
66
62
  type: :development
67
- requirement: &id004 !ruby/object:Gem::Requirement
63
+ name: rdoc
64
+ requirement: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ version_requirements: &id004 !ruby/object:Gem::Requirement
68
67
  none: false
69
68
  requirements:
70
69
  - - ~>
71
70
  - !ruby/object:Gem::Version
72
- hash: 19
71
+ hash: 31
73
72
  segments:
74
73
  - 1
75
- - 1
74
+ - 2
76
75
  - 0
77
- version: 1.1.0
78
- version_requirements: *id004
79
- name: bundler
76
+ version: 1.2.0
80
77
  prerelease: false
81
- - !ruby/object:Gem::Dependency
82
78
  type: :development
83
- requirement: &id005 !ruby/object:Gem::Requirement
79
+ name: bundler
80
+ requirement: *id004
81
+ - !ruby/object:Gem::Dependency
82
+ version_requirements: &id005 !ruby/object:Gem::Requirement
84
83
  none: false
85
84
  requirements:
86
85
  - - ~>
@@ -91,12 +90,40 @@ dependencies:
91
90
  - 8
92
91
  - 4
93
92
  version: 1.8.4
94
- version_requirements: *id005
93
+ prerelease: false
94
+ type: :development
95
95
  name: jeweler
96
+ requirement: *id005
97
+ - !ruby/object:Gem::Dependency
98
+ version_requirements: &id006 !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ hash: 3
104
+ segments:
105
+ - 0
106
+ version: "0"
96
107
  prerelease: false
108
+ type: :development
109
+ name: rcov
110
+ requirement: *id006
97
111
  - !ruby/object:Gem::Dependency
112
+ version_requirements: &id007 !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ hash: 3
118
+ segments:
119
+ - 0
120
+ version: "0"
121
+ prerelease: false
98
122
  type: :development
99
- requirement: &id006 !ruby/object:Gem::Requirement
123
+ name: minitest
124
+ requirement: *id007
125
+ - !ruby/object:Gem::Dependency
126
+ version_requirements: &id008 !ruby/object:Gem::Requirement
100
127
  none: false
101
128
  requirements:
102
129
  - - ">="
@@ -105,9 +132,10 @@ dependencies:
105
132
  segments:
106
133
  - 0
107
134
  version: "0"
108
- version_requirements: *id006
109
- name: rcov
110
135
  prerelease: false
136
+ type: :development
137
+ name: nokogiri
138
+ requirement: *id008
111
139
  description: This gem helps create large (>50) gmail filter chains by writing xml compatible with gmail's "import/export filters" feature.
112
140
  email: asf@boinkor.net
113
141
  executables: []
@@ -127,6 +155,10 @@ files:
127
155
  - VERSION
128
156
  - gmail-britta.gemspec
129
157
  - lib/gmail-britta.rb
158
+ - lib/gmail-britta/delegate.rb
159
+ - lib/gmail-britta/filter.rb
160
+ - lib/gmail-britta/single_write_accessors.rb
161
+ - test/test_gmail-britta.rb
130
162
  homepage: http://github.com/antifuchs/gmail-britta
131
163
  licenses:
132
164
  - MIT