imap-filter 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/.semver +5 -0
- data/Gemfile +24 -0
- data/Gemfile.lock +122 -0
- data/LICENSE.txt +20 -0
- data/README.org +321 -0
- data/Rakefile +58 -0
- data/bin/imap-filter +11 -0
- data/examples/default.imap +56 -0
- data/imap-filter.gemspec +110 -0
- data/lib/imap-filter.rb +17 -0
- data/lib/imap-filter/cli.rb +24 -0
- data/lib/imap-filter/dsl.rb +321 -0
- data/lib/imap-filter/functionality.rb +128 -0
- data/lib/imap-filter/imap-filter.rb +108 -0
- data/lib/imap-filter/monkeypatches.rb +37 -0
- data/spec/imap-filter_spec.rb +7 -0
- data/spec/spec_helper.rb +29 -0
- metadata +311 -0
data/Rakefile
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
require 'semver'
|
14
|
+
|
15
|
+
def s_version
|
16
|
+
SemVer.find.format "%M.%m.%p%s"
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'juwelier'
|
20
|
+
Juwelier::Tasks.new do |gem|
|
21
|
+
# gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
|
22
|
+
gem.name = "imap-filter"
|
23
|
+
gem.homepage = "http://github.com/flajann2/imap-filter"
|
24
|
+
gem.license = "MIT"
|
25
|
+
gem.summary = %Q{IMAP Scriptable filter for one or multiple Email accounts.}
|
26
|
+
gem.description = %Q{
|
27
|
+
imap-filter is a Ruby implementation of an IMAP filtering application.
|
28
|
+
it can handle multiple IMAP accounts, and create IMAP folders automatically
|
29
|
+
where none exists.
|
30
|
+
|
31
|
+
The imap-filter DSL makes it easy to filter. You can also do "dry-runs"
|
32
|
+
to make sure what happens is what is expected.}
|
33
|
+
|
34
|
+
gem.email = "fred.mitchell@gmx.de"
|
35
|
+
gem.authors = ["Fred Mitchell"]
|
36
|
+
gem.version = s_version
|
37
|
+
gem.required_ruby_version = '>= 2.2'
|
38
|
+
|
39
|
+
# dependencies defined in Gemfile
|
40
|
+
end
|
41
|
+
Juwelier::RubygemsDotOrgTasks.new
|
42
|
+
|
43
|
+
require 'rspec/core'
|
44
|
+
require 'rspec/core/rake_task'
|
45
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
46
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
47
|
+
end
|
48
|
+
|
49
|
+
desc "Code coverage detail"
|
50
|
+
task :simplecov do
|
51
|
+
ENV['COVERAGE'] = "true"
|
52
|
+
Rake::Task['spec'].execute
|
53
|
+
end
|
54
|
+
|
55
|
+
task :default => :spec
|
56
|
+
|
57
|
+
require 'yard'
|
58
|
+
YARD::Rake::YardocTask.new
|
data/bin/imap-filter
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# My Email accounts
|
2
|
+
account :gmx do
|
3
|
+
login ENV['GMX_EMAIL'], ENV['GMX_PASS']
|
4
|
+
serv "imap.gmx.net"
|
5
|
+
ssl true
|
6
|
+
auth :login
|
7
|
+
port 993
|
8
|
+
end
|
9
|
+
|
10
|
+
account :yahoo do
|
11
|
+
login ENV['YAHOO_EMAIL'], ENV['YAHOO_PASS']
|
12
|
+
serv 'imap.mail.yahoo.com'
|
13
|
+
auth :login
|
14
|
+
end
|
15
|
+
|
16
|
+
account :google do
|
17
|
+
login ENV['GOOGLE_EMAIL'], ENV['GOOGLE_PASS']
|
18
|
+
serv "imap.gmail.com"
|
19
|
+
auth :plain
|
20
|
+
end
|
21
|
+
|
22
|
+
filter :slashdot, 'gmx:INBOX', from: 'slashdot' do
|
23
|
+
mark :seen
|
24
|
+
cp 'google:INBOX'
|
25
|
+
mv 'gmx:Slashdot'
|
26
|
+
end
|
27
|
+
|
28
|
+
filter :github, 'gmx:INBOX' do
|
29
|
+
search do
|
30
|
+
from 'github.com'
|
31
|
+
unseen
|
32
|
+
end
|
33
|
+
|
34
|
+
cp 'google:news/Github'
|
35
|
+
mv 'gmx:Github'
|
36
|
+
end
|
37
|
+
|
38
|
+
filter :gitter, 'gmx:INBOX', from: 'gitter' do
|
39
|
+
mv 'gmx:Gitter'
|
40
|
+
end
|
41
|
+
|
42
|
+
filter :xing, 'gmx:INBOX', from: 'xing.com' do
|
43
|
+
mv 'gmx:XING'
|
44
|
+
unmark :seen
|
45
|
+
end
|
46
|
+
|
47
|
+
filter :neat, 'yahoo:NEAT', :unseen do
|
48
|
+
cp 'gmx:Lists/NEAT'
|
49
|
+
mark :seen
|
50
|
+
end
|
51
|
+
|
52
|
+
filter :spam, 'gmx:INBOX', from: ['news.brgmedia.com', 'travel.hoteltravel-email.com'] do
|
53
|
+
delete
|
54
|
+
end
|
55
|
+
|
56
|
+
activate :all
|
data/imap-filter.gemspec
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
# Generated by juwelier
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: imap-filter 0.0.2 ruby lib
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "imap-filter"
|
9
|
+
s.version = "0.0.2"
|
10
|
+
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib"]
|
13
|
+
s.authors = ["Fred Mitchell"]
|
14
|
+
s.date = "2016-09-25"
|
15
|
+
s.description = "\n imap-filter is a Ruby implementation of an IMAP filtering application.\n it can handle multiple IMAP accounts, and create IMAP folders automatically\n where none exists.\n\n The imap-filter DSL makes it easy to filter. You can also do \"dry-runs\"\n to make sure what happens is what is expected."
|
16
|
+
s.email = "fred.mitchell@gmx.de"
|
17
|
+
s.executables = ["imap-filter"]
|
18
|
+
s.extra_rdoc_files = [
|
19
|
+
"LICENSE.txt",
|
20
|
+
"README.org"
|
21
|
+
]
|
22
|
+
s.files = [
|
23
|
+
".document",
|
24
|
+
".rspec",
|
25
|
+
".ruby-version",
|
26
|
+
".semver",
|
27
|
+
"Gemfile",
|
28
|
+
"Gemfile.lock",
|
29
|
+
"LICENSE.txt",
|
30
|
+
"README.org",
|
31
|
+
"Rakefile",
|
32
|
+
"bin/imap-filter",
|
33
|
+
"examples/default.imap",
|
34
|
+
"imap-filter.gemspec",
|
35
|
+
"lib/imap-filter.rb",
|
36
|
+
"lib/imap-filter/cli.rb",
|
37
|
+
"lib/imap-filter/dsl.rb",
|
38
|
+
"lib/imap-filter/functionality.rb",
|
39
|
+
"lib/imap-filter/imap-filter.rb",
|
40
|
+
"lib/imap-filter/monkeypatches.rb",
|
41
|
+
"spec/imap-filter_spec.rb",
|
42
|
+
"spec/spec_helper.rb"
|
43
|
+
]
|
44
|
+
s.homepage = "http://github.com/flajann2/imap-filter"
|
45
|
+
s.licenses = ["MIT"]
|
46
|
+
s.required_ruby_version = Gem::Requirement.new(">= 2.2")
|
47
|
+
s.rubygems_version = "2.5.1"
|
48
|
+
s.summary = "IMAP Scriptable filter for one or multiple Email accounts."
|
49
|
+
|
50
|
+
if s.respond_to? :specification_version then
|
51
|
+
s.specification_version = 4
|
52
|
+
|
53
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
54
|
+
s.add_runtime_dependency(%q<semver>, ["~> 1"])
|
55
|
+
s.add_runtime_dependency(%q<awesome_print>, ["~> 1"])
|
56
|
+
s.add_runtime_dependency(%q<text-table>, ["~> 1"])
|
57
|
+
s.add_runtime_dependency(%q<thor>, ["~> 0"])
|
58
|
+
s.add_runtime_dependency(%q<colorize>, ["~> 0"])
|
59
|
+
s.add_development_dependency(%q<rspec>, ["~> 2"])
|
60
|
+
s.add_development_dependency(%q<yard>, ["~> 0"])
|
61
|
+
s.add_development_dependency(%q<rdoc>, ["~> 3"])
|
62
|
+
s.add_development_dependency(%q<bundler>, ["~> 1"])
|
63
|
+
s.add_development_dependency(%q<juwelier>, ["~> 2"])
|
64
|
+
s.add_development_dependency(%q<simplecov>, ["~> 0"])
|
65
|
+
s.add_development_dependency(%q<pry>, ["~> 0"])
|
66
|
+
s.add_development_dependency(%q<pry-byebug>, ["~> 3"])
|
67
|
+
s.add_development_dependency(%q<pry-doc>, ["~> 0"])
|
68
|
+
s.add_development_dependency(%q<pry-remote>, ["~> 0"])
|
69
|
+
s.add_development_dependency(%q<pry-rescue>, ["~> 1"])
|
70
|
+
s.add_development_dependency(%q<pry-stack_explorer>, ["~> 0"])
|
71
|
+
else
|
72
|
+
s.add_dependency(%q<semver>, ["~> 1"])
|
73
|
+
s.add_dependency(%q<awesome_print>, ["~> 1"])
|
74
|
+
s.add_dependency(%q<text-table>, ["~> 1"])
|
75
|
+
s.add_dependency(%q<thor>, ["~> 0"])
|
76
|
+
s.add_dependency(%q<colorize>, ["~> 0"])
|
77
|
+
s.add_dependency(%q<rspec>, ["~> 2"])
|
78
|
+
s.add_dependency(%q<yard>, ["~> 0"])
|
79
|
+
s.add_dependency(%q<rdoc>, ["~> 3"])
|
80
|
+
s.add_dependency(%q<bundler>, ["~> 1"])
|
81
|
+
s.add_dependency(%q<juwelier>, ["~> 2"])
|
82
|
+
s.add_dependency(%q<simplecov>, ["~> 0"])
|
83
|
+
s.add_dependency(%q<pry>, ["~> 0"])
|
84
|
+
s.add_dependency(%q<pry-byebug>, ["~> 3"])
|
85
|
+
s.add_dependency(%q<pry-doc>, ["~> 0"])
|
86
|
+
s.add_dependency(%q<pry-remote>, ["~> 0"])
|
87
|
+
s.add_dependency(%q<pry-rescue>, ["~> 1"])
|
88
|
+
s.add_dependency(%q<pry-stack_explorer>, ["~> 0"])
|
89
|
+
end
|
90
|
+
else
|
91
|
+
s.add_dependency(%q<semver>, ["~> 1"])
|
92
|
+
s.add_dependency(%q<awesome_print>, ["~> 1"])
|
93
|
+
s.add_dependency(%q<text-table>, ["~> 1"])
|
94
|
+
s.add_dependency(%q<thor>, ["~> 0"])
|
95
|
+
s.add_dependency(%q<colorize>, ["~> 0"])
|
96
|
+
s.add_dependency(%q<rspec>, ["~> 2"])
|
97
|
+
s.add_dependency(%q<yard>, ["~> 0"])
|
98
|
+
s.add_dependency(%q<rdoc>, ["~> 3"])
|
99
|
+
s.add_dependency(%q<bundler>, ["~> 1"])
|
100
|
+
s.add_dependency(%q<juwelier>, ["~> 2"])
|
101
|
+
s.add_dependency(%q<simplecov>, ["~> 0"])
|
102
|
+
s.add_dependency(%q<pry>, ["~> 0"])
|
103
|
+
s.add_dependency(%q<pry-byebug>, ["~> 3"])
|
104
|
+
s.add_dependency(%q<pry-doc>, ["~> 0"])
|
105
|
+
s.add_dependency(%q<pry-remote>, ["~> 0"])
|
106
|
+
s.add_dependency(%q<pry-rescue>, ["~> 1"])
|
107
|
+
s.add_dependency(%q<pry-stack_explorer>, ["~> 0"])
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
data/lib/imap-filter.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'semver'
|
3
|
+
require 'pp'
|
4
|
+
require 'ap'
|
5
|
+
require 'colorize'
|
6
|
+
require 'awesome_print'
|
7
|
+
require 'net/imap'
|
8
|
+
require 'forwardable'
|
9
|
+
|
10
|
+
module ImapFilter
|
11
|
+
end
|
12
|
+
|
13
|
+
require_relative 'imap-filter/monkeypatches'
|
14
|
+
require_relative 'imap-filter/dsl'
|
15
|
+
require_relative 'imap-filter/functionality'
|
16
|
+
require_relative 'imap-filter/imap-filter'
|
17
|
+
require_relative 'imap-filter/cli'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'imap-filter'
|
3
|
+
|
4
|
+
include ImapFilter::DSL
|
5
|
+
|
6
|
+
module ImapFilter
|
7
|
+
module Cli
|
8
|
+
class Main < Thor
|
9
|
+
class_option :verbose, type: :numeric, banner: '[1|2|3|4]', aliases: '-v', default: 0
|
10
|
+
@@default_script = ENV['IMAPF_IMAP_FILE'] || 'default.imap'
|
11
|
+
|
12
|
+
desc 'filter [script]', "Run the powerplay script. Default #{@@default_script}"
|
13
|
+
option :dryrun, type: :boolean, aliases: '-u', desc: "Dry run, do not actually execute."
|
14
|
+
option :test, type: :boolean, aliases: '-t', desc: "Test IMAP accounts only."
|
15
|
+
option :filters, type: :array, aliases: '-f', banner: %(<FILT1>[ FILT2 FILT3...]),
|
16
|
+
desc: "Run specified filters. The default is to run all of them."
|
17
|
+
def filter(script = @@default_script)
|
18
|
+
_global[:options] = options
|
19
|
+
puts "script %s " % [script] if _options[:verbose] >= 1
|
20
|
+
load script, true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,321 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'imap-filter'
|
3
|
+
|
4
|
+
module ImapFilter
|
5
|
+
module DSL
|
6
|
+
@@global_config = {}
|
7
|
+
|
8
|
+
def _global
|
9
|
+
@@global_config
|
10
|
+
end
|
11
|
+
|
12
|
+
def _options
|
13
|
+
DSL::_global[:options]
|
14
|
+
end
|
15
|
+
|
16
|
+
def _accounts
|
17
|
+
DSL::_global[:accounts] ||= {}
|
18
|
+
end
|
19
|
+
|
20
|
+
def _filters
|
21
|
+
DSL::_global[:filters] ||= {}
|
22
|
+
end
|
23
|
+
|
24
|
+
class Dsl
|
25
|
+
attr :name, :desc
|
26
|
+
|
27
|
+
def initialize(name, desc=nil, &ignore)
|
28
|
+
@name = name
|
29
|
+
@desc = desc
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Account < Dsl
|
34
|
+
attr :name, :userid, :pass, :fqdn, :use_ssl, :use_port, :auth_type
|
35
|
+
attr :imap, :delim
|
36
|
+
|
37
|
+
def login userid, password
|
38
|
+
@userid = userid
|
39
|
+
@pass = password
|
40
|
+
@use_ssl = true
|
41
|
+
@use_port = nil
|
42
|
+
@auth_type = 'PLAIN'
|
43
|
+
end
|
44
|
+
|
45
|
+
def serv fqdn
|
46
|
+
@fqdn = fqdn
|
47
|
+
end
|
48
|
+
|
49
|
+
def ssl t
|
50
|
+
@use_ssl = t
|
51
|
+
end
|
52
|
+
|
53
|
+
def port p
|
54
|
+
@use_port = p
|
55
|
+
end
|
56
|
+
|
57
|
+
def auth type
|
58
|
+
@auth_type = type.to_s.upcase
|
59
|
+
end
|
60
|
+
|
61
|
+
def initialize(name, &block)
|
62
|
+
super
|
63
|
+
@name = name
|
64
|
+
instance_eval( &block )
|
65
|
+
_accounts[name] = self
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_s
|
69
|
+
"SERV #{fqdn} USER #{userid} SSL #{use_ssl} PORT #{ use_port ? use_port : '<default>'} AUTH #{auth_type} >DELIM #{delim}"
|
70
|
+
end
|
71
|
+
|
72
|
+
# connects and logs in
|
73
|
+
def _open_connection
|
74
|
+
print "\n *** connect #{fqdn} port '#{use_port}' ssl #{use_ssl}".light_cyan unless _options[:verbose] < 2
|
75
|
+
unless use_port.nil?
|
76
|
+
@imap = Net::IMAP.new(fqdn, port: use_port, ssl: use_ssl)
|
77
|
+
else
|
78
|
+
@imap = Net::IMAP.new(fqdn, ssl: use_ssl)
|
79
|
+
end
|
80
|
+
|
81
|
+
print "\n *** auth #{userid} pass #{pass}...".light_cyan unless _options[:verbose] < 2
|
82
|
+
imap.authenticate(auth_type, userid, pass)
|
83
|
+
@delim = imap.list('', '').first.delim
|
84
|
+
end
|
85
|
+
|
86
|
+
def _close_connection
|
87
|
+
imap.close
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
class Filter < Dsl
|
92
|
+
attr :mbox, :directives, :actions
|
93
|
+
OPS = [:or, :not, :new]
|
94
|
+
MARKS = {
|
95
|
+
seen: :Seen,
|
96
|
+
read: :Seen,
|
97
|
+
unread: :Unseen,
|
98
|
+
unseen: :Unseen,
|
99
|
+
deleted: :Deleted,
|
100
|
+
flagged: :Flagged
|
101
|
+
}
|
102
|
+
DIRECTIVES = {
|
103
|
+
all: 'ALL',
|
104
|
+
new: 'NEW',
|
105
|
+
recent: 'RECENT',
|
106
|
+
seen: 'SEEN',
|
107
|
+
read: 'SEEN',
|
108
|
+
unseen: 'UNSEEN',
|
109
|
+
unread: 'UNSEEN',
|
110
|
+
answered: 'ANSWERED',
|
111
|
+
unanswered: 'UNANSWERED',
|
112
|
+
deleted: 'DELETED',
|
113
|
+
undeleted: 'UNDELETED',
|
114
|
+
draft: 'DRAFT',
|
115
|
+
undraft: 'UNDRAFT',
|
116
|
+
flagged: 'FLAGGED',
|
117
|
+
unflagged: 'UNFLAGGED',
|
118
|
+
}
|
119
|
+
|
120
|
+
def list *a, **h
|
121
|
+
@actions << [:list, a, h]
|
122
|
+
end
|
123
|
+
|
124
|
+
def move to_mbox
|
125
|
+
@actions << [:move, to_mbox]
|
126
|
+
end
|
127
|
+
alias mv move
|
128
|
+
|
129
|
+
def copy to_mbox
|
130
|
+
@actions << [:copy, to_mbox]
|
131
|
+
end
|
132
|
+
alias cp copy
|
133
|
+
|
134
|
+
def delete
|
135
|
+
@actions << [:delete]
|
136
|
+
end
|
137
|
+
|
138
|
+
def mark *flags, custom: false
|
139
|
+
flags.each do |f|
|
140
|
+
raise "Illegal flag #{f}" unless MARKS.member? f
|
141
|
+
end unless custom
|
142
|
+
@actions << [:mark] + flags.map{ |f| MARKS[f] || f }
|
143
|
+
end
|
144
|
+
alias store mark
|
145
|
+
|
146
|
+
def unmark *flags, custom: false
|
147
|
+
flags.each do |f|
|
148
|
+
raise "Illegal flag #{f}" unless MARKS.member? f
|
149
|
+
end unless custom
|
150
|
+
@actions << [:unmark] + flags.map{ |f| MARKS[f] || f }
|
151
|
+
end
|
152
|
+
alias unstore unmark
|
153
|
+
|
154
|
+
def search &block
|
155
|
+
def before d
|
156
|
+
directives << 'BEFORE' << d
|
157
|
+
end
|
158
|
+
|
159
|
+
def body s
|
160
|
+
directives << 'BODY'<< s
|
161
|
+
end
|
162
|
+
|
163
|
+
def cc s
|
164
|
+
directives << 'CC' << s
|
165
|
+
end
|
166
|
+
|
167
|
+
def bcc s
|
168
|
+
directives << 'BCC' << s
|
169
|
+
end
|
170
|
+
|
171
|
+
def from s
|
172
|
+
directives << 'FROM' << s
|
173
|
+
end
|
174
|
+
|
175
|
+
def op *a
|
176
|
+
a.each { |x|
|
177
|
+
raise "illegal operator #{x}" unless OPS.member? x
|
178
|
+
directives << x.to_s.upcase
|
179
|
+
}
|
180
|
+
end
|
181
|
+
|
182
|
+
def on d
|
183
|
+
directives << 'ON' << d
|
184
|
+
end
|
185
|
+
|
186
|
+
def since d
|
187
|
+
directives << 'SINCE' << d
|
188
|
+
end
|
189
|
+
|
190
|
+
def senton d
|
191
|
+
directives << 'SENTON' << d
|
192
|
+
end
|
193
|
+
|
194
|
+
def sentsince d
|
195
|
+
directives << 'SENTSINCE' << d
|
196
|
+
end
|
197
|
+
|
198
|
+
def sentbefore d
|
199
|
+
directives << 'SENTBEFORE' << d
|
200
|
+
end
|
201
|
+
|
202
|
+
def smaller n
|
203
|
+
directives << 'SMALLER' << n
|
204
|
+
end
|
205
|
+
|
206
|
+
def subject s
|
207
|
+
directives << 'SUBJECT' << s
|
208
|
+
end
|
209
|
+
|
210
|
+
def text s
|
211
|
+
directives << 'TEXT' << s
|
212
|
+
end
|
213
|
+
|
214
|
+
def to s
|
215
|
+
directives << 'TO' << s
|
216
|
+
end
|
217
|
+
|
218
|
+
def all
|
219
|
+
directives << 'ALL'
|
220
|
+
end
|
221
|
+
|
222
|
+
def answered
|
223
|
+
directives << 'ANSWERED'
|
224
|
+
end
|
225
|
+
|
226
|
+
def unanswered
|
227
|
+
directives << 'UNANSWERED'
|
228
|
+
end
|
229
|
+
|
230
|
+
def deleted
|
231
|
+
directives << 'DELETED'
|
232
|
+
end
|
233
|
+
|
234
|
+
def undeleted
|
235
|
+
directives << 'UNDELETED'
|
236
|
+
end
|
237
|
+
|
238
|
+
def draft
|
239
|
+
directives << 'DRAFT'
|
240
|
+
end
|
241
|
+
|
242
|
+
def undraft
|
243
|
+
directives << 'UNDRAFT'
|
244
|
+
end
|
245
|
+
|
246
|
+
def flagged
|
247
|
+
directives << 'FLAGGED'
|
248
|
+
end
|
249
|
+
|
250
|
+
def unflagged
|
251
|
+
directives << 'UNFLAGGED'
|
252
|
+
end
|
253
|
+
|
254
|
+
def seen
|
255
|
+
directives << 'SEEN'
|
256
|
+
end
|
257
|
+
alias red seen
|
258
|
+
|
259
|
+
def unseen
|
260
|
+
directives << 'UNSEEN'
|
261
|
+
end
|
262
|
+
alias unread unseen
|
263
|
+
|
264
|
+
def keyword key
|
265
|
+
directives << 'KEYWORD' << key
|
266
|
+
end
|
267
|
+
|
268
|
+
def unkeyword key
|
269
|
+
directives << 'UNKEYWORD' << key
|
270
|
+
end
|
271
|
+
|
272
|
+
instance_eval &block
|
273
|
+
end
|
274
|
+
|
275
|
+
def massage directives
|
276
|
+
if directives.is_a?(Hash)
|
277
|
+
directives.map{ |k, v|
|
278
|
+
unless v.is_a? Array
|
279
|
+
[k.to_s.upcase, v]
|
280
|
+
else
|
281
|
+
['OR',
|
282
|
+
v.map{ |va|
|
283
|
+
[k.to_s.upcase, va]
|
284
|
+
}].flatten
|
285
|
+
end
|
286
|
+
}.flatten
|
287
|
+
elsif directives.is_a?(Symbol)
|
288
|
+
DIRECTIVES[directives]
|
289
|
+
else
|
290
|
+
directives
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
# note that directives can be either a hash or a single symbol
|
295
|
+
def initialize(name, mbox, directives=[], &block)
|
296
|
+
super(name)
|
297
|
+
@mbox = mbox
|
298
|
+
@directives = massage directives
|
299
|
+
@actions = []
|
300
|
+
instance_eval &block
|
301
|
+
_filters[name] = self
|
302
|
+
end
|
303
|
+
|
304
|
+
def to_s
|
305
|
+
"MBOX #{mbox} DIRECTIVES #{directives}"
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
def account name, &block
|
310
|
+
Account.new name, &block
|
311
|
+
end
|
312
|
+
|
313
|
+
def filter name, mbox, singledir=nil, **directives, &block
|
314
|
+
Filter.new name, mbox, (singledir || directives), &block
|
315
|
+
end
|
316
|
+
|
317
|
+
def activate filters
|
318
|
+
Functionality.run_filters filters
|
319
|
+
end
|
320
|
+
end
|
321
|
+
end
|