imap_processor 1.3 → 1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
Binary file
data.tar.gz.sig CHANGED
Binary file
File without changes
@@ -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
+
@@ -1,15 +1,24 @@
1
1
  .autotest
2
- History.txt
2
+ History.rdoc
3
3
  Manifest.txt
4
- README.txt
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
@@ -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
- IMAPProcessor ships with the executables imap_keywords which can query an IMAP
12
- server for keywords set on messages in mailboxes, imap_idle which can show new
13
- messages in a mailbox and imap_archive which will archive old messages to a
14
- new mailbox.
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
- See IMAPProcessor and IMAPProcessor::Keywords for details
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) 2009 Eric Hodel
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 |ip|
9
- ip.rubyforge_name = 'seattlerb'
10
- ip.developer 'Eric Hodel', 'drbrain@segment7.net'
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
@@ -0,0 +1,5 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ require 'imap_processor/cleanse'
4
+
5
+ IMAPProcessor::Cleanse.run ARGV
@@ -0,0 +1,5 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ require 'imap_processor/flag'
4
+
5
+ IMAPProcessor::Flag.run
@@ -0,0 +1,5 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ require 'imap_processor/learn'
4
+
5
+ IMAPProcessor::Learn.run
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'imap_processor/mkdir'
4
+
5
+ IMAPProcessor::Mkdir.run ARGV
@@ -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 = '1.3'
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
- # super __FILE__, args, required_options do |opts, options|
97
- # opts.banner << "Explain my_processor's executable"
98
- #
99
- # opts.on( "--move=MAILBOX",
100
- # "Mailbox to move message to",
101
- # "Default: #{options[:MoveTo].inspect}",
102
- # "Options file name: :MoveTo") do |mailbox|
103
- # options[:MoveTo] = mailbox
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 opts_file_name =~ /^imap_/
114
- opts_file = File.expand_path "~/.#{opts_file_name}"
115
- options = @@options.dup
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
- options.merge! YAML.load_file(opts_file)
140
+ defaults = YAML.load_file(opts_file)
141
+ defaults = [defaults] unless Array === defaults
133
142
  end
134
143
 
135
- options[:SSL] = true unless options.key? :SSL
136
- options[:Username] ||= ENV['USER']
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
- required_options.each do |k,(v,m)|
142
- options[k] ||= v
143
- end
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
- op = OptionParser.new do |opts|
146
- opts.program_name = File.basename $0
147
- opts.banner = "Usage: #{opts.program_name} [options]\n\n"
153
+ required_options.each do |k,(v,_)|
154
+ options[k] ||= v
155
+ end
148
156
 
149
- opts.separator ''
150
- opts.separator 'Connection options:'
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
- opts.on("-H", "--host HOST",
153
- "IMAP server host",
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
- opts.on("-P", "--port PORT",
160
- "IMAP server port",
161
- "Default: The correct port SSL/non-SSL mode",
162
- "Options file name: :Port") do |port|
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
- opts.on("-s", "--[no-]ssl",
167
- "Use SSL for IMAP connection",
168
- "Default: #{options[:SSL].inspect}",
169
- "Options file name: :SSL") do |ssl|
170
- options[:SSL] = ssl
171
- end
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
- opts.on( "--[no-]debug",
174
- "Display Net::IMAP debugging info",
175
- "Default: #{options[:Debug].inspect}",
176
- "Options file name: :Debug") do |debug|
177
- options[:Debug] = debug
178
- end
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
- opts.separator ''
181
- opts.separator 'Login options:'
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
- opts.on("-u", "--username USERNAME",
184
- "IMAP username",
185
- "Default: #{options[:Username].inspect}",
186
- "Options file name: :Username") do |username|
187
- options[:Username] = username
188
- end
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
- opts.on("-p", "--password PASSWORD",
191
- "IMAP password",
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
- authenticators = Net::IMAP.send :class_variable_get, :@@authenticators
198
- auth_types = authenticators.keys.sort.join ', '
199
- opts.on("-a", "--auth AUTH", auth_types,
200
- "IMAP authentication type override",
201
- "Authentication type will be auto-",
202
- "discovered",
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
- opts.separator ''
209
- opts.separator "IMAP options:"
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
- opts.on("-r", "--root ROOT",
212
- "Root of mailbox hierarchy",
213
- "Default: #{options[:Root].inspect}",
214
- "Options file name: :Root") do |root|
215
- options[:Root] = root
216
- end
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
- opts.on("-b", "--boxes BOXES", Array,
219
- "Comma-separated list of mailbox names",
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
- opts.on("-v", "--[no-]verbose",
227
- "Be verbose",
228
- "Default: #{options[:Verbose].inspect}",
229
- "Options file name: :Verbose") do |verbose|
230
- options[:Verbose] = verbose
231
- end
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
- opts.on("-q", "--quiet",
234
- "Be quiet") do
235
- options[:Verbose] = false
236
- end
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
- if block_given? then
239
- opts.separator ''
240
- opts.separator "#{self} options:"
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
- yield opts, options if block_given?
243
- end
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
- @@extra_options.each do |block|
246
- block.call opts, options
247
- end
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
- opts.separator ''
274
+ opts.separator ''
250
275
 
251
- opts.banner << <<-EOF
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
- EOF
260
- end
284
+ EOF
285
+
286
+ end # OptionParser.new do
261
287
 
262
- op.parse! args
263
-
264
- options[:Port] ||= options[:SSL] ? 993 : 143
265
-
266
- if options[:Host].nil? or
267
- options[:Password].nil? or
268
- options[:Boxes].nil? or
269
- required_options.any? { |k,(v,m)| options[k].nil? } then
270
- $stderr.puts op
271
- $stderr.puts
272
- $stderr.puts "Host name not set" if options[:Host].nil?
273
- $stderr.puts "Password not set" if options[:Password].nil?
274
- $stderr.puts "Boxes not set" if options[:Boxes].nil?
275
- required_options.each do |option_name, (option_value, missing_message)|
276
- $stderr.puts missing_message if options[option_name].nil?
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
- return options
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
- options = process_args args
289
- client = new(options, &block)
290
- client.run
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
- # logs in as +username+ with +password+. IMAPProcessor is only known to
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
- capability = imap.capability
378
+ capabilities = capability imap, imap.greeting
332
379
 
333
- log "Capabilities: #{capability.join ', '}"
380
+ log "Capabilities: #{capabilities.join ', '}"
334
381
 
335
- auth_caps = capability.select { |c| c =~ /^AUTH/ }
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
- auth = auth.upcase
343
- log "Trying #{auth} authentication"
344
- imap.authenticate auth, username, password
345
- log "Logged in as #{username}"
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, capability
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 => e
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
-