vmail 0.8.7 → 0.8.8
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/vmail/imap_client.rb +47 -12
- data/lib/vmail/version.rb +1 -1
- metadata +2 -2
data/lib/vmail/imap_client.rb
CHANGED
@@ -28,10 +28,16 @@ module Vmail
|
|
28
28
|
@mailbox = nil
|
29
29
|
@logger = Logger.new(config['logfile'] || STDERR)
|
30
30
|
@logger.level = Logger::DEBUG
|
31
|
-
@current_mail = nil
|
32
|
-
@current_message_index = nil
|
33
31
|
@imap_server = config['server'] || 'imap.gmail.com'
|
34
32
|
@imap_port = config['port'] || 993
|
33
|
+
@current_mail = nil
|
34
|
+
@current_message_index = nil
|
35
|
+
end
|
36
|
+
|
37
|
+
# holds mail objects keyed by [mailbox, uid]
|
38
|
+
# TODO don't cache a mail if too large; or come up with a way to purge
|
39
|
+
def message_cache
|
40
|
+
@message_cache ||= {}
|
35
41
|
end
|
36
42
|
|
37
43
|
def open
|
@@ -361,27 +367,34 @@ module Vmail
|
|
361
367
|
|
362
368
|
def show_message(index, raw=false)
|
363
369
|
return if index.to_i < 0
|
364
|
-
log "showing message at #{index}"
|
365
370
|
return @current_mail.to_s if raw
|
366
371
|
index = index.to_i
|
367
372
|
if index == @current_message_index
|
368
373
|
return @current_message
|
369
374
|
end
|
375
|
+
|
376
|
+
prefetch_adjacent(index)
|
377
|
+
|
370
378
|
envelope_data = @message_list[index]
|
371
379
|
seqno = envelope_data[:seqno]
|
372
380
|
uid = envelope_data[:uid]
|
373
|
-
log "showing message seqno: #{seqno} uid #{uid}"
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
381
|
+
log "showing message index: #{index} seqno: #{seqno} uid #{uid}"
|
382
|
+
|
383
|
+
data = if x = message_cache[[@mailbox, uid]]
|
384
|
+
log "- message cache hit"
|
385
|
+
x
|
386
|
+
else
|
387
|
+
log "- fetching and storing to message_cache[[#{@mailbox}, #{uid}]]"
|
388
|
+
fetch_and_cache(uid)
|
389
|
+
end
|
390
|
+
# pre-fetch prev and next
|
391
|
+
|
392
|
+
mail = data[:mail]
|
393
|
+
size = data[:size]
|
379
394
|
@current_message_index = index
|
380
395
|
@current_mail = mail # used later to show raw message or extract attachments if any
|
381
|
-
log "saving current mail with parts: #{@current_mail.parts.inspect}"
|
382
396
|
formatter = Vmail::MessageFormatter.new(mail)
|
383
397
|
out = formatter.process_body
|
384
|
-
size = fetch_data.attr["RFC822.SIZE"]
|
385
398
|
@current_message = <<-EOF
|
386
399
|
#{@mailbox} seqno:#{envelope_data[:seqno]} uid:#{uid} #{number_to_human_size size} #{format_parts_info(formatter.list_parts)}
|
387
400
|
#{divider '-'}
|
@@ -391,7 +404,29 @@ module Vmail
|
|
391
404
|
EOF
|
392
405
|
rescue
|
393
406
|
log "parsing error"
|
394
|
-
"Error encountered parsing this message:\n#{$!}"
|
407
|
+
"Error encountered parsing this message:\n#{$!}\n#{$!.backtrace.join("\n")}"
|
408
|
+
end
|
409
|
+
|
410
|
+
def fetch_and_cache(uid)
|
411
|
+
return if message_cache[[@mailbox, uid]]
|
412
|
+
fetch_data = reconnect_if_necessary do
|
413
|
+
@imap.uid_fetch(uid, ["FLAGS", "RFC822", "RFC822.SIZE"])[0]
|
414
|
+
end
|
415
|
+
d = {:mail => Mail.new(fetch_data.attr['RFC822']), :size => fetch_data.attr["RFC822.SIZE"]}
|
416
|
+
log "storing message_cache[[#{@mailbox}, #{uid}]]"
|
417
|
+
message_cache[[@mailbox, uid]] = d
|
418
|
+
d
|
419
|
+
end
|
420
|
+
|
421
|
+
def prefetch_adjacent(index)
|
422
|
+
Thread.new do
|
423
|
+
[index + 1, index - 1].each do |idx|
|
424
|
+
envelope_data = @message_list[idx]
|
425
|
+
next unless envelope_data
|
426
|
+
uid = envelope_data[:uid]
|
427
|
+
fetch_and_cache(uid)
|
428
|
+
end
|
429
|
+
end
|
395
430
|
end
|
396
431
|
|
397
432
|
def format_parts_info(parts)
|
data/lib/vmail/version.rb
CHANGED