sup_tag 0.1.2 → 0.2.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.
data/README.markdown CHANGED
@@ -6,37 +6,102 @@ A gem to make tagging messages in sup cleaner.
6
6
  Usage
7
7
  =====
8
8
 
9
- This currently supports two methods to add tags, tag and archive. Tag adds tags
10
- but does not remove the inbox tag. Archive will add a tag and remove the inbox
11
- tag.
9
+ Messages are tagged using by either the tag or archive block. The tag block will
10
+ add the labels while archive adds labels and removes the inbox tag. Each block
11
+ consists of methods of the message to call, what they should match against and
12
+ the tags to add if the messages match. Tags must always be a symbol, while the
13
+ queries may be either strings or regular expressions. It's easiest to see with
14
+ an example:
12
15
 
13
- Example
14
- -------
15
-
16
- My before-add-message.rb looks like:
16
+ tag do
17
+ from 'blake', :self
18
+ end
17
19
 
18
- require 'sup_tag'
19
- require 'sup_tag/extensions/object'
20
+ This would tag any message from 'blake' with self. If no tag is provided then
21
+ the given queries are converted to strings and used as labels. For example:
20
22
 
21
- # Tag messages
22
23
  tag do
23
- from /jnls.cust.serv@oxfordjournals.org/i, :oxford
24
- from /some_email/i, :tag1, :tag2
24
+ from /blake/i
25
+ end
26
+
27
+ Here if a message is from 'blake' the message would be tagged as 'blake'. It is
28
+ possible to use several queries in one rule as well.
29
+
30
+ archive do
31
+ from /blake/, /sweeney/, :self
32
+ end
33
+
34
+ This would archive any message where the from matches both 'blake' and
35
+ 'sweeney' as self and the inbox tag would be removed. If the self tag had not
36
+ been provided then the message would have been tagged as both 'blake' and
37
+ 'sweeney'. Tag and archive blocks may have many rules. For example:
38
+
39
+ tag
40
+ from /blake/, :self
41
+ subj /sup-talk/i
42
+ end
43
+
44
+ Here messages from 'blake' are marked as self, while messages with 'sup-talk' in
45
+ the subject line are marked as sup talk.
46
+
47
+ If you wish to tag against several different fields then simply use a multi
48
+ block. A multi block will require that all rules in the block hit in order to
49
+ tag.
50
+
51
+ tag
52
+ multi :ann, 'ruby-talk'.to_sym do
53
+ recipients /ruby-talk/
54
+ subj /ANN/
55
+ end
25
56
  end
26
57
 
27
- # Archive messages
58
+ This would tag any messages going to 'ruby-talk' with 'ANN' in the subject line.
59
+ If tags are provided to the rules in the multi block they will be ignored.
60
+
61
+ There are some other probably less useful options. It is possible to archive a
62
+ message directly without adding any tags. To do this provide a nil as the tag.
63
+
28
64
  archive do
29
- subj /sup-talk/i # Tag messages with sup-talk in subject as sup-talk
65
+ from /Boring/i, nil
30
66
  end
31
67
 
32
- This tags messages from jnls as oxford and leaves them in my inbox. Messages
33
- from some\_email are given tag1, tag2. Messages from sup-talk are given the
34
- sup-talk label and the inbox label is removed.
68
+ This will archive any message from 'Boring' without adding any tags.
69
+
70
+ Example
71
+ -------
72
+
73
+ My before-add-message.rb looks something like:
74
+
75
+ require 'sup_tag'
76
+ require "sup_tag/extensions/object"
77
+
78
+ archive do
79
+ subj /sup-talk/i
80
+ subj /MongoMapper/i, :MM
81
+ subj /easyb-users/i, :easyb
82
+ recipients /ruby-talk/i
83
+ recipients /vim(_|-)mac/i, :vim
84
+ recipients /buildr.apache.org/i, :buildr
85
+
86
+ multi :ann do
87
+ recipients /ruby-talk/i
88
+ subj /ANN/i
89
+ end
90
+ end
35
91
 
92
+ tag do
93
+ subj /BIOL\.1010/, :ta
94
+ subj /BIOL\.5870/, :ta
95
+ from /Mbuthia/, :ta
96
+ subj /Nucl. Acids Res/, :nar
97
+ subj /Database Table of Contents/, :biodb
98
+ from /rna@faseb.org/i, :rna
99
+ from /jnls.cust.serv@oxfordjournals.org/, :oxford
100
+ end
36
101
 
37
102
  Note on Patches/Pull Requests
38
103
  =============================
39
-
104
+
40
105
  * Fork the project.
41
106
  * Make your feature addition or bug fix.
42
107
  * Add tests for it. This is important so I don't break it in a
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.2.1
data/lib/sup_tag.rb CHANGED
@@ -6,6 +6,7 @@ class SupTag
6
6
  # @param [Redwood::Message] message A Message to tag.
7
7
  def initialize(message)
8
8
  @message = message
9
+ @add = true
9
10
  end
10
11
 
11
12
  # Remove the given tags from the message.
@@ -23,9 +24,8 @@ class SupTag
23
24
  # @param [Block] block Block to add tags.
24
25
  # @return [Array] Tags on the message.
25
26
  def archive(&block)
26
- @match = false
27
- cloaker(&block).bind(self).call
28
- remove(:inbox) if @match
27
+ tag(&block)
28
+ remove(:inbox) if @labels
29
29
  return @message.labels
30
30
  end
31
31
 
@@ -34,8 +34,27 @@ class SupTag
34
34
  # @param [Block] Block for adding tags.
35
35
  # @return [Array] The tags on the message.
36
36
  def tag(&block)
37
+ @labels = nil
37
38
  cloaker(&block).bind(self).call
38
- @message.labels
39
+ @labels.each { |l| @message.add_label(l) } if @labels
40
+ return @message.labels
41
+ end
42
+
43
+ # Test queries across several feilds to add tags.
44
+ #
45
+ # @param [Symbol, Array] labels Labels to add.
46
+ # @param [Block] Block for adding tags.
47
+ # @return [Array] The tags on the message
48
+ def multi(*labels, &block)
49
+ @multi = true
50
+ @add = false
51
+ cloaker(&block).bind(self).call
52
+ @add = true
53
+ if @multi
54
+ @labels.concat(labels)
55
+ @match = true
56
+ end
57
+ return @message.labels
39
58
  end
40
59
 
41
60
  # Instance eval for blocks stolen from Trollop. Orignally from:
@@ -54,21 +73,52 @@ class SupTag
54
73
  end
55
74
  end
56
75
 
76
+ # Override to include methods from messages.
57
77
  def respond_to?(method, include_private = false)
58
78
  return @message.respond_to?(method) || super
59
79
  end
60
80
 
61
- def method_missing(method, *args)
81
+ # Override method missing to allow for matching the results of
82
+ # a method on message against some queries.
83
+ def method_missing(method, *args, &block)
62
84
  super if !respond_to?(method)
63
-
64
- match = args.shift
65
- match_string = (match.is_a?(Regexp) ? match.source : match.to_s)
66
- tags = (args.empty? ? [match_string.downcase] : args).compact
67
- query = @message.send(method)
68
- if (!query.is_a?(Array) && query.to_s.match(match)) ||
69
- (query.is_a?(Array) && query.any? { |q| q.to_s.match(match) } )
70
- @match = true
71
- tags.map { |t| @message.add_label(t) }
85
+ parts = split_args(args)
86
+ queries = parts.first
87
+ results = Array(@message.send(method))
88
+ count = match_args(results, queries)
89
+ if count.size == queries.size
90
+ @labels ||= []
91
+ @multi &= true
92
+ @labels.concat(parts.last.compact) if @add
93
+ else
94
+ @multi = false
72
95
  end
73
96
  end
97
+
98
+ private
99
+ # Split the arguments into labels and queries.
100
+ #
101
+ # @param [Array] arguments Arguments to split.
102
+ def split_args(arguments)
103
+ parts = arguments.partition { |e| !e.is_a?(Symbol) && e }
104
+
105
+ # Generate labels if none given
106
+ if parts[1].empty?
107
+ parts[1] = parts[0].map do |part|
108
+ (part.is_a?(Regexp) ? part.source : part.to_s).downcase
109
+ end
110
+ end
111
+
112
+ return parts
113
+ end
114
+
115
+ # Match the results against the queries and count how many match.
116
+ #
117
+ # @param [Array] results Results to check.
118
+ # @param [Array] queries Queries to look for.
119
+ def match_args(results, queries)
120
+ queries.map do |query|
121
+ (results.any? { |r| r.to_s.match(query) } ? 1 : nil)
122
+ end.compact
123
+ end
74
124
  end
@@ -1,3 +1,4 @@
1
+ require 'sup_tag/extensions/binding'
1
2
  # Modify Object to support tag and archive methods.
2
3
 
3
4
  class Object
@@ -25,6 +26,6 @@ class Object
25
26
  # @param [Block] A Block to generate the tagger object with.
26
27
  # @return [SupTag] A SupTag object.
27
28
  def get_tagger(&block)
28
- return SupTag.new(eval("lambda { message }", block.binding).call)
29
+ return SupTag.new(block.binding[:message])
29
30
  end
30
31
  end
@@ -0,0 +1,12 @@
1
+ # Modify Binding to extract value.
2
+
3
+ class Binding
4
+
5
+ # Get the value of a variable of method in this binding.
6
+ #
7
+ # @param [Symbol, String] name Object to get value of.
8
+ # @return [Object] The value.
9
+ def [](name)
10
+ return eval("lambda { #{name.to_s} }", self).call
11
+ end
12
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,10 +1,10 @@
1
1
  $LOAD_PATH.unshift(File.dirname(__FILE__))
2
2
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
3
  require 'sup_tag'
4
+ require 'sup_tag/extensions/object'
5
+ require 'sup_tag/extensions/binding'
4
6
  require "rubygems"
5
7
  require "sup"
6
- require 'spec'
7
- require 'spec/autorun'
8
8
  require 'stringio'
9
9
  require 'rmail'
10
10
  require 'uri'
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Binding' do
4
+ context '[]' do
5
+ it 'can get the value of a variable' do
6
+ @message = 'hi'
7
+ binding[:@message].should == 'hi'
8
+ end
9
+ it 'can get the value of a method' do
10
+ def bob
11
+ return 'jones'
12
+ end
13
+ binding['bob'].should == 'jones'
14
+ end
15
+ end
16
+ end
@@ -1,5 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
- require 'sup_tag/extensions/object'
1
+ require 'spec_helper'
3
2
 
4
3
  describe 'Object' do
5
4
  before do
@@ -1,6 +1,11 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
1
+ require 'spec_helper'
2
2
 
3
3
  describe "SupTag" do
4
+ before do
5
+ @mess = get_short_message
6
+ @tagger = SupTag.new(@mess)
7
+ end
8
+
4
9
  context 'respond_to' do
5
10
  it 'responds to taggable methods' do
6
11
  [ :from, :subj, :to, :replyto ].each do |meth|
@@ -10,11 +15,6 @@ describe "SupTag" do
10
15
  end
11
16
 
12
17
  context 'tags' do
13
- before do
14
- @mess = get_short_message
15
- @tagger = SupTag.new(@mess)
16
- end
17
-
18
18
  context 'removing tags' do
19
19
  it 'can remove a given tag' do
20
20
  @mess.add_label(:t)
@@ -84,6 +84,51 @@ describe "SupTag" do
84
84
  end
85
85
  @mess.labels.should == Set[:old]
86
86
  end
87
+ it 'can tag using several criteria at once' do
88
+ @tagger.tag do
89
+ date /2/, /7/, :self
90
+ end
91
+ @mess.labels.should == Set[:self]
92
+ end
93
+ it 'requires all criteria to match' do
94
+ @tagger.tag do
95
+ date /2/, /blake/, :me
96
+ end
97
+ @mess.labels.should == Set.new
98
+ end
99
+ it 'uses all requirements as the labels if none given' do
100
+ @tagger.tag do
101
+ date /2/, /7/
102
+ end
103
+ @mess.labels.should == Set['2'.to_sym, '7'.to_sym]
104
+ end
105
+ it 'can use a multi tag block to specify requirements on several results' do
106
+ @tagger.tag do
107
+ multi :bob do
108
+ subj /test/i
109
+ date /2/
110
+ end
111
+ end
112
+ @mess.labels.should == Set[:bob]
113
+ end
114
+ it 'requires that all queries in the multi block match to tag' do
115
+ @tagger.tag do
116
+ multi :bob do
117
+ subj /test/i
118
+ date '-1'
119
+ end
120
+ end
121
+ @mess.labels.should == Set[]
122
+ end
123
+ it 'can add several tags with a multi block' do
124
+ @tagger.tag do
125
+ multi :jo, :bob do
126
+ subj /test/i
127
+ date /2/
128
+ end
129
+ end
130
+ @mess.labels.should == Set[:jo, :bob]
131
+ end
87
132
  end
88
133
 
89
134
  context 'adding tags' do
@@ -144,6 +189,15 @@ describe "SupTag" do
144
189
  end
145
190
  @mess.labels.should == Set[]
146
191
  end
192
+ it 'will archive if all querires in a multi block hit' do
193
+ @tagger.archive do
194
+ multi :me do
195
+ subj /Test/
196
+ date '2'
197
+ end
198
+ end
199
+ @mess.labels.should == Set[:me]
200
+ end
147
201
  end
148
202
 
149
203
  context 'archiving' do
@@ -180,5 +234,68 @@ describe "SupTag" do
180
234
  end
181
235
  @mess.labels.should == Set[:me]
182
236
  end
237
+ it 'archives if all queries hit' do
238
+ @tagger.archive do
239
+ subj /t/, /e/, :hi
240
+ end
241
+ @mess.labels.should == Set[:hi]
242
+ end
243
+ it 'will not archive if all queries do not hit' do
244
+ @tagger.archive do
245
+ subj /t/, /J/, :hi
246
+ end
247
+ @mess.labels.should == Set[:inbox]
248
+ end
249
+ end
250
+
251
+ context 'complex tests' do
252
+ it 'can properly tag a block with many rules' do
253
+ @tagger.tag do
254
+ subj /something/
255
+ from /BAD/
256
+ subj /test/i, :bob, :other
257
+ to /WHO/
258
+ end
259
+ @mess.labels.should == Set[:bob, :other]
260
+ end
261
+ it 'can properly tag a block with a multi block' do
262
+ @tagger.tag do
263
+ subj /something/
264
+ from /BAD/
265
+ subj /test/i, :bob, :other
266
+ to /WHO/
267
+ multi :ann do
268
+ subj /test/i
269
+ from /Sender/i
270
+ end
271
+ to /Bob/
272
+ end
273
+ @mess.labels.should == Set[:bob, :other, :ann]
274
+ end
275
+ it 'can properly archive with a block of many rules' do
276
+ @mess.add_label(:inbox)
277
+ @tagger.archive do
278
+ subj /something/
279
+ from /BAD/
280
+ subj /test/i, :bob, :other
281
+ to /WHO/
282
+ end
283
+ @mess.labels.should == Set[:bob, :other]
284
+ end
285
+ it 'can properly archive a block with a multiblock rule' do
286
+ @mess.add_label(:inbox)
287
+ @tagger.archive do
288
+ subj /something/
289
+ from /BAD/
290
+ subj /test/i, :bob, :other
291
+ to /WHO/
292
+ multi :ann do
293
+ subj /test/i
294
+ from /Sender/i
295
+ end
296
+ to /Bob/
297
+ end
298
+ @mess.labels.should == Set[:bob, :other, :ann]
299
+ end
183
300
  end
184
301
  end
data/sup_tag.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{sup_tag}
8
- s.version = "0.1.2"
8
+ s.version = "0.2.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Blake Sweeney"]
12
- s.date = %q{2010-10-19}
12
+ s.date = %q{2010-11-08}
13
13
  s.description = %q{SupTag lets you clean up the before-add-hook script by providing a clean DSL}
14
14
  s.email = %q{blakes.85@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -25,11 +25,13 @@ Gem::Specification.new do |s|
25
25
  "VERSION",
26
26
  "lib/sup_tag.rb",
27
27
  "lib/sup_tag/extensions/Object.rb",
28
+ "lib/sup_tag/extensions/binding.rb",
28
29
  "spec/dummy_source.rb",
29
- "spec/object_spec.rb",
30
30
  "spec/spec.opts",
31
31
  "spec/spec_helper.rb",
32
- "spec/sup_tag_spec.rb",
32
+ "spec/sup_tag/extensions/binding_spec.rb",
33
+ "spec/sup_tag/extensions/object_spec.rb",
34
+ "spec/sup_tag/sup_tag_spec.rb",
33
35
  "sup_tag.gemspec"
34
36
  ]
35
37
  s.homepage = %q{http://github.com/blakesweeney/sup_tag}
@@ -39,9 +41,10 @@ Gem::Specification.new do |s|
39
41
  s.summary = %q{Make tagging messages in sup pretty}
40
42
  s.test_files = [
41
43
  "spec/dummy_source.rb",
42
- "spec/object_spec.rb",
43
44
  "spec/spec_helper.rb",
44
- "spec/sup_tag_spec.rb"
45
+ "spec/sup_tag/extensions/binding_spec.rb",
46
+ "spec/sup_tag/extensions/object_spec.rb",
47
+ "spec/sup_tag/sup_tag_spec.rb"
45
48
  ]
46
49
 
47
50
  if s.respond_to? :specification_version then
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
8
7
  - 2
9
- version: 0.1.2
8
+ - 1
9
+ version: 0.2.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Blake Sweeney
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-10-19 00:00:00 -04:00
17
+ date: 2010-11-08 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -74,11 +74,13 @@ files:
74
74
  - VERSION
75
75
  - lib/sup_tag.rb
76
76
  - lib/sup_tag/extensions/Object.rb
77
+ - lib/sup_tag/extensions/binding.rb
77
78
  - spec/dummy_source.rb
78
- - spec/object_spec.rb
79
79
  - spec/spec.opts
80
80
  - spec/spec_helper.rb
81
- - spec/sup_tag_spec.rb
81
+ - spec/sup_tag/extensions/binding_spec.rb
82
+ - spec/sup_tag/extensions/object_spec.rb
83
+ - spec/sup_tag/sup_tag_spec.rb
82
84
  - sup_tag.gemspec
83
85
  has_rdoc: true
84
86
  homepage: http://github.com/blakesweeney/sup_tag
@@ -112,6 +114,7 @@ specification_version: 3
112
114
  summary: Make tagging messages in sup pretty
113
115
  test_files:
114
116
  - spec/dummy_source.rb
115
- - spec/object_spec.rb
116
117
  - spec/spec_helper.rb
117
- - spec/sup_tag_spec.rb
118
+ - spec/sup_tag/extensions/binding_spec.rb
119
+ - spec/sup_tag/extensions/object_spec.rb
120
+ - spec/sup_tag/sup_tag_spec.rb