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.
@@ -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
-