imap_processor 1.3 → 1.5
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.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.gemtest +0 -0
- data/History.rdoc +83 -0
- data/Manifest.txt +11 -2
- data/{README.txt → README.rdoc} +13 -6
- data/Rakefile +6 -3
- data/bin/imap_cleanse +5 -0
- data/bin/imap_flag +5 -0
- data/bin/imap_learn +5 -0
- data/bin/imap_mkdir +5 -0
- data/lib/imap_processor.rb +206 -150
- data/lib/imap_processor/archive.rb +58 -13
- data/lib/imap_processor/cleanse.rb +67 -0
- data/lib/imap_processor/client.rb +145 -0
- data/lib/imap_processor/flag.rb +121 -0
- data/lib/imap_processor/learn.rb +231 -0
- data/lib/imap_processor/mkdir.rb +25 -0
- data/test/test_imap_processor.rb +37 -0
- metadata +121 -72
- metadata.gz.sig +0 -0
- data/History.txt +0 -43
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7ebadbaa317cabbc2b15ca821a55739a5689c614
|
4
|
+
data.tar.gz: 3fb713f7d17b9b04dd1d5f081725734fa90fad97
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 027324815a2b2a44928ba687d74c23f06a66eef0470cdbfab5f5fe604b84a0b2b7b12ffd2cbc40202b4dd76a55083b8b42eb2806d0bb886980638015c63ee235
|
7
|
+
data.tar.gz: ee70746ac80bcac8339abcfb7281bdb6464a6eb6d384aeabff4873e96f460f41b18c9ef1475e371613c016edf8bb068f47ff52bb817405270c31e46527c4a995
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/.gemtest
ADDED
File without changes
|
data/History.rdoc
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
=== 1.5 / 2014-08-06
|
2
|
+
|
3
|
+
* 3 major enhancements:
|
4
|
+
|
5
|
+
* IMAPProcessor#process_args now returns an array of option hashes.
|
6
|
+
* IMAPProcessor.run now enumerates the array returned from process_args.
|
7
|
+
* You can now specify multiple host configs w/ an array of hashes in your config files.
|
8
|
+
|
9
|
+
* 4 minor enhancements:
|
10
|
+
|
11
|
+
* Added --merge to imap_archive.
|
12
|
+
* Added --noop/-n to manually disable destructive actions. (needs to propagate down).
|
13
|
+
* Added imap_cleanse, imap_flag, imap_learn; migrated from IMAPCleanse.
|
14
|
+
* Added support for LOGIN. (bleything)
|
15
|
+
|
16
|
+
* 7 bug fixes:
|
17
|
+
|
18
|
+
* Fixed initializers in flag and cleanse.
|
19
|
+
* Fixed odd bug w/ running on empty folders. Never saw that before. odd...
|
20
|
+
* Handle unparsable date entries. Stupid spammers...
|
21
|
+
* Now calculating latest month when not splitting directly from the date
|
22
|
+
* Removed 1.9/2.0 warnings.
|
23
|
+
* Removed dead rubyforge setting in Rakefile
|
24
|
+
* Split was still defaulting to true.
|
25
|
+
|
26
|
+
=== 1.4 / 2011-01-10
|
27
|
+
|
28
|
+
* 6 minor enhancements:
|
29
|
+
|
30
|
+
* Added explicit help option (-h didn't work)
|
31
|
+
* Added folder separator support (osx server uses '.' not '/')
|
32
|
+
* Added imap_mkdir command
|
33
|
+
* Added opts_file_name class var so subclass option processing can refer to file
|
34
|
+
* Extended imap_archive to archive multiple months per box, as necessary. Allowing easy archiving of big mailboxes
|
35
|
+
* Handles server-provided CAPABILITY to avoid an extra round-trip
|
36
|
+
|
37
|
+
* 1 bug fix:
|
38
|
+
|
39
|
+
* Fixed doco.
|
40
|
+
|
41
|
+
=== 1.3 / 2009-08-04
|
42
|
+
|
43
|
+
* 1 major enhancement
|
44
|
+
* IMAP IDLE support now matches ruby trunk's support. See Net::IMAP#idle
|
45
|
+
and Net::IMAP#idle_done
|
46
|
+
|
47
|
+
=== 1.2 / 2009-06-02
|
48
|
+
|
49
|
+
* 2 major enhancements
|
50
|
+
* imap_archive which archives old mail to dated mailboxes
|
51
|
+
* imap_idle which lists messages that were added or expunged from a mailbox
|
52
|
+
|
53
|
+
* 4 minor enhancements
|
54
|
+
* Added IMAPProcessor#create_mailbox
|
55
|
+
* Added IMAPProcessor#delete_messages
|
56
|
+
* Added IMAPProcessor#move_messages
|
57
|
+
* Disabled verification of SSL certs for 1.9
|
58
|
+
|
59
|
+
* 1 bug fix
|
60
|
+
* Fixed options file names, they should be Symbol keys
|
61
|
+
|
62
|
+
=== 1.1.1 / 2009-05-19
|
63
|
+
|
64
|
+
* 1 bug fix
|
65
|
+
* Got the skip test backwards
|
66
|
+
|
67
|
+
=== 1.1 / 2009-05-18
|
68
|
+
|
69
|
+
* 1 minor enhancement
|
70
|
+
* IMAPProcessor#each_message allows messages to be omitted from the returned
|
71
|
+
uid list (skipped)
|
72
|
+
|
73
|
+
=== 1.0.1 / 2009-05-15
|
74
|
+
|
75
|
+
* 2 bug fix
|
76
|
+
* Show correct name of options file for --password help
|
77
|
+
* Fix --quiet
|
78
|
+
|
79
|
+
=== 1.0.0 / 2009-05-12
|
80
|
+
|
81
|
+
* 1 major enhancement
|
82
|
+
* Birthday!
|
83
|
+
|
data/Manifest.txt
CHANGED
@@ -1,15 +1,24 @@
|
|
1
1
|
.autotest
|
2
|
-
History.
|
2
|
+
History.rdoc
|
3
3
|
Manifest.txt
|
4
|
-
README.
|
4
|
+
README.rdoc
|
5
5
|
Rakefile
|
6
6
|
bin/imap_archive
|
7
|
+
bin/imap_cleanse
|
8
|
+
bin/imap_flag
|
7
9
|
bin/imap_idle
|
8
10
|
bin/imap_keywords
|
11
|
+
bin/imap_learn
|
12
|
+
bin/imap_mkdir
|
9
13
|
lib/imap_processor.rb
|
10
14
|
lib/imap_processor/archive.rb
|
15
|
+
lib/imap_processor/cleanse.rb
|
16
|
+
lib/imap_processor/client.rb
|
17
|
+
lib/imap_processor/flag.rb
|
11
18
|
lib/imap_processor/idle.rb
|
12
19
|
lib/imap_processor/keywords.rb
|
20
|
+
lib/imap_processor/learn.rb
|
21
|
+
lib/imap_processor/mkdir.rb
|
13
22
|
lib/imap_sasl_plain.rb
|
14
23
|
lib/net/imap/date.rb
|
15
24
|
lib/net/imap/idle.rb
|
data/{README.txt → README.rdoc}
RENAMED
@@ -8,10 +8,17 @@ IMAPProcessor is a client for processing messages on an IMAP server. It
|
|
8
8
|
provides some basic mechanisms for connecting to an IMAP server, determining
|
9
9
|
capabilities and handling messages.
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
|
12
|
+
IMAPProcessor ships with several executables which can query and
|
13
|
+
manipulate IMAP mailboxes in several different ways:
|
14
|
+
|
15
|
+
imap_archive :: Archives old messages to a new dated mailbox.
|
16
|
+
imap_cleanse :: Delete messages older than a certain age in specified mailboxes.
|
17
|
+
imap_flag :: Flag messages to/from certain people.
|
18
|
+
imap_idle :: Shows new messages in a mailbox.
|
19
|
+
imap_keywords :: Queries an IMAP server for keywords set on messages
|
20
|
+
imap_learn :: Flags messages based on what you've flagged before.
|
21
|
+
imap_mkdir :: Ensures that certain mailboxes exist.
|
15
22
|
|
16
23
|
== FEATURES/PROBLEMS:
|
17
24
|
|
@@ -21,7 +28,7 @@ new mailbox.
|
|
21
28
|
|
22
29
|
== SYNOPSIS:
|
23
30
|
|
24
|
-
|
31
|
+
Run any command with --help for details.
|
25
32
|
|
26
33
|
== REQUIREMENTS:
|
27
34
|
|
@@ -35,7 +42,7 @@ See IMAPProcessor and IMAPProcessor::Keywords for details
|
|
35
42
|
|
36
43
|
(The MIT License)
|
37
44
|
|
38
|
-
Copyright (c)
|
45
|
+
Copyright (c) Eric Hodel, Ryan Davis, Seattle.rb
|
39
46
|
|
40
47
|
Permission is hereby granted, free of charge, to any person obtaining
|
41
48
|
a copy of this software and associated documentation files (the
|
data/Rakefile
CHANGED
@@ -4,10 +4,13 @@ require 'rubygems'
|
|
4
4
|
require 'hoe'
|
5
5
|
|
6
6
|
Hoe.plugin :seattlerb
|
7
|
+
Hoe.plugin :rdoc
|
7
8
|
|
8
|
-
Hoe.spec 'imap_processor' do
|
9
|
-
|
10
|
-
|
9
|
+
Hoe.spec 'imap_processor' do
|
10
|
+
developer 'Eric Hodel', 'drbrain@segment7.net'
|
11
|
+
developer 'Ryan Davis', 'ryand-ruby@zenspider.com'
|
12
|
+
|
13
|
+
license "MIT"
|
11
14
|
end
|
12
15
|
|
13
16
|
# vim: syntax=Ruby
|
data/bin/imap_cleanse
ADDED
data/bin/imap_flag
ADDED
data/bin/imap_learn
ADDED
data/bin/imap_mkdir
ADDED
data/lib/imap_processor.rb
CHANGED
@@ -15,13 +15,18 @@ require 'yaml'
|
|
15
15
|
# * An initialize method that connects to an IMAP server and sets the @imap
|
16
16
|
# instance variable
|
17
17
|
# * A run method that uses the IMAP connection to process messages.
|
18
|
+
#
|
19
|
+
# Reference:
|
20
|
+
#
|
21
|
+
# email: http://www.ietf.org/rfc/rfc0822.txt
|
22
|
+
# imap: http://www.ietf.org/rfc/rfc3501.txt
|
18
23
|
|
19
24
|
class IMAPProcessor
|
20
25
|
|
21
26
|
##
|
22
27
|
# The version of IMAPProcessor you are using
|
23
28
|
|
24
|
-
VERSION =
|
29
|
+
VERSION = "1.5"
|
25
30
|
|
26
31
|
##
|
27
32
|
# Base IMAPProcessor error class
|
@@ -92,15 +97,16 @@ class IMAPProcessor
|
|
92
97
|
# required_options = {
|
93
98
|
# :MoveTo => [nil, "MoveTo not set"],
|
94
99
|
# }
|
95
|
-
#
|
96
|
-
#
|
97
|
-
#
|
98
|
-
#
|
99
|
-
#
|
100
|
-
#
|
101
|
-
#
|
102
|
-
#
|
103
|
-
#
|
100
|
+
#
|
101
|
+
# super __FILE__, args, required_options do |opts, options|
|
102
|
+
# opts.banner << "Explain my_processor's executable"
|
103
|
+
#
|
104
|
+
# opts.on( "--move=MAILBOX",
|
105
|
+
# "Mailbox to move message to",
|
106
|
+
# "Default: #{options[:MoveTo].inspect}",
|
107
|
+
# "Options file name: :MoveTo") do |mailbox|
|
108
|
+
# options[:MoveTo] = mailbox
|
109
|
+
# end
|
104
110
|
# end
|
105
111
|
# end
|
106
112
|
# end
|
@@ -109,10 +115,10 @@ class IMAPProcessor
|
|
109
115
|
|
110
116
|
def self.process_args(processor_file, args,
|
111
117
|
required_options = {}) # :yield: OptionParser
|
112
|
-
opts_file_name = File.basename processor_file, '.rb'
|
113
|
-
opts_file_name = "imap_#{opts_file_name}" unless
|
114
|
-
|
115
|
-
|
118
|
+
@@opts_file_name = File.basename processor_file, '.rb'
|
119
|
+
@@opts_file_name = "imap_#{@@opts_file_name}" unless
|
120
|
+
@@opts_file_name =~ /^imap_/
|
121
|
+
opts_file = File.expand_path "~/.#{@@opts_file_name}"
|
116
122
|
|
117
123
|
if required_options then
|
118
124
|
required_options.each do |option, (default, message)|
|
@@ -122,6 +128,8 @@ class IMAPProcessor
|
|
122
128
|
end
|
123
129
|
end
|
124
130
|
|
131
|
+
defaults = [{}]
|
132
|
+
|
125
133
|
if File.exist? opts_file then
|
126
134
|
unless File.stat(opts_file).mode & 077 == 0 then
|
127
135
|
$stderr.puts "WARNING! #{opts_file} is group/other readable or writable!"
|
@@ -129,165 +137,187 @@ class IMAPProcessor
|
|
129
137
|
exit 1
|
130
138
|
end
|
131
139
|
|
132
|
-
|
140
|
+
defaults = YAML.load_file(opts_file)
|
141
|
+
defaults = [defaults] unless Array === defaults
|
133
142
|
end
|
134
143
|
|
135
|
-
|
136
|
-
|
137
|
-
options[:Root] ||= nil
|
138
|
-
options[:Verbose] ||= false
|
139
|
-
options[:Debug] ||= false
|
144
|
+
defaults.map { |default|
|
145
|
+
options = default.merge @@options.dup
|
140
146
|
|
141
|
-
|
142
|
-
options[
|
143
|
-
|
147
|
+
options[:SSL] = true unless options.key? :SSL
|
148
|
+
options[:Username] ||= ENV['USER']
|
149
|
+
options[:Root] ||= nil
|
150
|
+
options[:Verbose] ||= false
|
151
|
+
options[:Debug] ||= false
|
144
152
|
|
145
|
-
|
146
|
-
|
147
|
-
|
153
|
+
required_options.each do |k,(v,_)|
|
154
|
+
options[k] ||= v
|
155
|
+
end
|
148
156
|
|
149
|
-
|
150
|
-
|
157
|
+
op = OptionParser.new do |opts|
|
158
|
+
opts.program_name = File.basename $0
|
159
|
+
opts.banner = "Usage: #{opts.program_name} [options]\n\n"
|
151
160
|
|
152
|
-
|
153
|
-
|
154
|
-
"Default: #{options[:Host].inspect}",
|
155
|
-
"Options file name: :Host") do |host|
|
156
|
-
options[:Host] = host
|
157
|
-
end
|
161
|
+
opts.separator ''
|
162
|
+
opts.separator 'Connection options:'
|
158
163
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
options[:Port] = port
|
164
|
-
end
|
164
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
165
|
+
puts opts
|
166
|
+
exit
|
167
|
+
end
|
165
168
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
169
|
+
opts.on("-H", "--host HOST",
|
170
|
+
"IMAP server host",
|
171
|
+
"Default: #{options[:Host].inspect}",
|
172
|
+
"Options file name: :Host") do |host|
|
173
|
+
options[:Host] = host
|
174
|
+
end
|
172
175
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
176
|
+
opts.on("-P", "--port PORT",
|
177
|
+
"IMAP server port",
|
178
|
+
"Default: The correct port SSL/non-SSL mode",
|
179
|
+
"Options file name: :Port") do |port|
|
180
|
+
options[:Port] = port
|
181
|
+
end
|
179
182
|
|
180
|
-
|
181
|
-
|
183
|
+
opts.on("-s", "--[no-]ssl",
|
184
|
+
"Use SSL for IMAP connection",
|
185
|
+
"Default: #{options[:SSL].inspect}",
|
186
|
+
"Options file name: :SSL") do |ssl|
|
187
|
+
options[:SSL] = ssl
|
188
|
+
end
|
182
189
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
190
|
+
opts.on( "--[no-]debug",
|
191
|
+
"Display Net::IMAP debugging info",
|
192
|
+
"Default: #{options[:Debug].inspect}",
|
193
|
+
"Options file name: :Debug") do |debug|
|
194
|
+
options[:Debug] = debug
|
195
|
+
end
|
189
196
|
|
190
|
-
|
191
|
-
|
192
|
-
"Default: Read from ~/.#{opts_file_name}",
|
193
|
-
"Options file name: :Password") do |password|
|
194
|
-
options[:Password] = password
|
195
|
-
end
|
197
|
+
opts.separator ''
|
198
|
+
opts.separator 'Login options:'
|
196
199
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
"Default: #{options[:Auth].inspect}",
|
204
|
-
"Options file name: :Auth") do |auth|
|
205
|
-
options[:Auth] = auth
|
206
|
-
end
|
200
|
+
opts.on("-u", "--username USERNAME",
|
201
|
+
"IMAP username",
|
202
|
+
"Default: #{options[:Username].inspect}",
|
203
|
+
"Options file name: :Username") do |username|
|
204
|
+
options[:Username] = username
|
205
|
+
end
|
207
206
|
|
208
|
-
|
209
|
-
|
207
|
+
opts.on("-p", "--password PASSWORD",
|
208
|
+
"IMAP password",
|
209
|
+
"Default: Read from ~/.#{@@opts_file_name}",
|
210
|
+
"Options file name: :Password") do |password|
|
211
|
+
options[:Password] = password
|
212
|
+
end
|
210
213
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
214
|
+
authenticators = Net::IMAP.send :class_variable_get, :@@authenticators
|
215
|
+
auth_types = authenticators.keys.sort.join ', '
|
216
|
+
opts.on("-a", "--auth AUTH", auth_types,
|
217
|
+
"IMAP authentication type override",
|
218
|
+
"Authentication type will be auto-",
|
219
|
+
"discovered",
|
220
|
+
"Default: #{options[:Auth].inspect}",
|
221
|
+
"Options file name: :Auth") do |auth|
|
222
|
+
options[:Auth] = auth
|
223
|
+
end
|
217
224
|
|
218
|
-
|
219
|
-
|
220
|
-
"to search",
|
221
|
-
"Default: #{options[:Boxes].inspect}",
|
222
|
-
"Options file name: :Boxes") do |boxes|
|
223
|
-
options[:Boxes] = boxes
|
224
|
-
end
|
225
|
+
opts.separator ''
|
226
|
+
opts.separator "IMAP options:"
|
225
227
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
228
|
+
opts.on("-r", "--root ROOT",
|
229
|
+
"Root of mailbox hierarchy",
|
230
|
+
"Default: #{options[:Root].inspect}",
|
231
|
+
"Options file name: :Root") do |root|
|
232
|
+
options[:Root] = root
|
233
|
+
end
|
232
234
|
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
235
|
+
opts.on("-b", "--boxes BOXES", Array,
|
236
|
+
"Comma-separated list of mailbox names",
|
237
|
+
"to search",
|
238
|
+
"Default: #{options[:Boxes].inspect}",
|
239
|
+
"Options file name: :Boxes") do |boxes|
|
240
|
+
options[:Boxes] = boxes
|
241
|
+
end
|
237
242
|
|
238
|
-
|
239
|
-
|
240
|
-
|
243
|
+
opts.on("-v", "--[no-]verbose",
|
244
|
+
"Be verbose",
|
245
|
+
"Default: #{options[:Verbose].inspect}",
|
246
|
+
"Options file name: :Verbose") do |verbose|
|
247
|
+
options[:Verbose] = verbose
|
248
|
+
end
|
241
249
|
|
242
|
-
|
243
|
-
|
250
|
+
opts.on("-n", "--noop",
|
251
|
+
"Perform no destructive operations",
|
252
|
+
"Best used with the verbose option",
|
253
|
+
"Default: #{options[:Noop].inspect}",
|
254
|
+
"Options file name: Noop") do |noop|
|
255
|
+
options[:Noop] = noop
|
256
|
+
end
|
244
257
|
|
245
|
-
|
246
|
-
|
247
|
-
|
258
|
+
opts.on("-q", "--quiet",
|
259
|
+
"Be quiet") do
|
260
|
+
options[:Verbose] = false
|
261
|
+
end
|
262
|
+
|
263
|
+
if block_given? then
|
264
|
+
opts.separator ''
|
265
|
+
opts.separator "#{self} options:"
|
266
|
+
|
267
|
+
yield opts, options if block_given?
|
268
|
+
end
|
269
|
+
|
270
|
+
@@extra_options.each do |block|
|
271
|
+
block.call opts, options
|
272
|
+
end
|
248
273
|
|
249
|
-
|
274
|
+
opts.separator ''
|
250
275
|
|
251
|
-
|
276
|
+
opts.banner << <<-EOF
|
252
277
|
|
253
|
-
Options may also be set in the options file ~/.#{opts_file_name}
|
278
|
+
Options may also be set in the options file ~/.#{@@opts_file_name}
|
254
279
|
|
255
|
-
Example ~/.#{opts_file_name}:
|
280
|
+
Example ~/.#{@@opts_file_name}:
|
256
281
|
\tHost=mail.example.com
|
257
282
|
\tPassword=my password
|
258
283
|
|
259
|
-
|
260
|
-
|
284
|
+
EOF
|
285
|
+
|
286
|
+
end # OptionParser.new do
|
261
287
|
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
288
|
+
op.parse! args
|
289
|
+
|
290
|
+
options[:Port] ||= options[:SSL] ? 993 : 143
|
291
|
+
|
292
|
+
# HACK: removed :Boxes -- push down
|
293
|
+
required_keys = [:Host, :Password] + required_options.keys
|
294
|
+
if required_keys.any? { |k| options[k].nil? } then
|
295
|
+
$stderr.puts op
|
296
|
+
$stderr.puts
|
297
|
+
$stderr.puts "Host name not set" if options[:Host].nil?
|
298
|
+
$stderr.puts "Password not set" if options[:Password].nil?
|
299
|
+
$stderr.puts "Boxes not set" if options[:Boxes].nil?
|
300
|
+
required_options.each do |option_name, (_, missing_message)|
|
301
|
+
$stderr.puts missing_message if options[option_name].nil?
|
302
|
+
end
|
303
|
+
exit 1
|
277
304
|
end
|
278
|
-
exit 1
|
279
|
-
end
|
280
305
|
|
281
|
-
|
306
|
+
options
|
307
|
+
} # defaults.map
|
282
308
|
end
|
283
309
|
|
284
310
|
##
|
285
311
|
# Sets up an IMAP processor's options then calls its \#run method.
|
286
312
|
|
287
313
|
def self.run(args = ARGV, &block)
|
288
|
-
|
289
|
-
|
290
|
-
|
314
|
+
client = nil
|
315
|
+
multi_options = process_args args
|
316
|
+
|
317
|
+
multi_options.each do |options|
|
318
|
+
client = new(options, &block)
|
319
|
+
client.run
|
320
|
+
end
|
291
321
|
rescue Interrupt
|
292
322
|
exit
|
293
323
|
rescue SystemExit
|
@@ -312,10 +342,27 @@ Example ~/.#{opts_file_name}:
|
|
312
342
|
Net::IMAP.debug = options[:Debug]
|
313
343
|
end
|
314
344
|
|
345
|
+
##
|
346
|
+
# Extracts capability information for +imap+ from +res+ or by contacting the
|
347
|
+
# server.
|
348
|
+
|
349
|
+
def capability imap, res = nil
|
350
|
+
return imap.capability unless res
|
351
|
+
|
352
|
+
data = res.data
|
353
|
+
|
354
|
+
if data.code and data.code.name == 'CAPABILITY' then
|
355
|
+
data.code.data.split ' '
|
356
|
+
else
|
357
|
+
imap.capability
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
315
361
|
##
|
316
362
|
# Connects to IMAP server +host+ at +port+ using ssl if +ssl+ is true then
|
317
|
-
#
|
318
|
-
# work with PLAIN auth on SSL sockets.
|
363
|
+
# authenticates with +username+ and +password+. IMAPProcessor is only known
|
364
|
+
# to work with PLAIN auth on SSL sockets. IMAPProcessor does not support
|
365
|
+
# LOGIN.
|
319
366
|
#
|
320
367
|
# Returns a Connection object.
|
321
368
|
|
@@ -328,23 +375,35 @@ Example ~/.#{opts_file_name}:
|
|
328
375
|
imap = Net::IMAP.new host, port, ssl, nil, false
|
329
376
|
log "Connected to imap://#{host}:#{port}/"
|
330
377
|
|
331
|
-
|
378
|
+
capabilities = capability imap, imap.greeting
|
332
379
|
|
333
|
-
log "Capabilities: #{
|
380
|
+
log "Capabilities: #{capabilities.join ', '}"
|
334
381
|
|
335
|
-
auth_caps =
|
382
|
+
auth_caps = capabilities.select { |c| c =~ /^AUTH/ }
|
336
383
|
|
337
384
|
if auth.nil? then
|
338
385
|
raise "Couldn't find a supported auth type" if auth_caps.empty?
|
339
386
|
auth = auth_caps.first.sub(/AUTH=/, '')
|
340
387
|
end
|
341
388
|
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
389
|
+
# Net::IMAP supports using AUTHENTICATE with LOGIN, PLAIN, and
|
390
|
+
# CRAM-MD5... if the server reports a different AUTH method, then we
|
391
|
+
# should fall back to using LOGIN
|
392
|
+
if %w( LOGIN PLAIN CRAM-MD5 ).include?( auth.upcase )
|
393
|
+
auth = auth.upcase
|
394
|
+
log "Trying #{auth} authentication"
|
395
|
+
res = imap.authenticate auth, username, password
|
396
|
+
log "Logged in as #{username} using AUTHENTICATE"
|
397
|
+
else
|
398
|
+
log "Trying to authenticate via LOGIN"
|
399
|
+
res = imap.login username, password
|
400
|
+
log "Logged in as #{username} using LOGIN"
|
401
|
+
end
|
402
|
+
|
403
|
+
# CAPABILITY may have changed
|
404
|
+
capabilities = capability imap, res
|
346
405
|
|
347
|
-
connection = Connection.new imap,
|
406
|
+
connection = Connection.new imap, capabilities
|
348
407
|
|
349
408
|
if block_given? then
|
350
409
|
begin
|
@@ -399,8 +458,6 @@ Example ~/.#{opts_file_name}:
|
|
399
458
|
uids = []
|
400
459
|
|
401
460
|
each_part parts, true do |uid, message|
|
402
|
-
skip = false
|
403
|
-
|
404
461
|
mail = TMail::Mail.parse message
|
405
462
|
|
406
463
|
begin
|
@@ -498,7 +555,7 @@ Example ~/.#{opts_file_name}:
|
|
498
555
|
|
499
556
|
begin
|
500
557
|
imap.copy uids, destination
|
501
|
-
rescue Net::IMAP::NoResponseError
|
558
|
+
rescue Net::IMAP::NoResponseError
|
502
559
|
# ruby-lang bug #1713
|
503
560
|
#raise unless e.response.data.code.name == 'TRYCREATE'
|
504
561
|
create_mailbox destination
|
@@ -531,4 +588,3 @@ Example ~/.#{opts_file_name}:
|
|
531
588
|
end
|
532
589
|
|
533
590
|
end
|
534
|
-
|