vmail 1.4.7 → 1.4.8
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/vmail.rb +15 -17
- data/lib/vmail.vim +14 -23
- data/lib/vmail/contacts_extractor.rb +5 -5
- data/lib/vmail/imap_client.rb +57 -57
- data/lib/vmail/options.rb +5 -5
- data/lib/vmail/version.rb +1 -1
- metadata +2 -2
data/lib/vmail.rb
CHANGED
@@ -9,7 +9,7 @@ module Vmail
|
|
9
9
|
extend self
|
10
10
|
|
11
11
|
def start
|
12
|
-
puts "
|
12
|
+
puts "Starting vmail #{Vmail::VERSION}"
|
13
13
|
|
14
14
|
vim = ENV['VMAIL_VIM'] || 'vim'
|
15
15
|
ENV['VMAIL_BROWSER'] ||= if RUBY_PLATFORM.downcase.include?('linux')
|
@@ -26,7 +26,7 @@ module Vmail
|
|
26
26
|
'open'
|
27
27
|
end
|
28
28
|
|
29
|
-
puts "
|
29
|
+
puts "Setting VMAIL_BROWSER to '#{ENV['VMAIL_BROWSER']}'"
|
30
30
|
check_lynx
|
31
31
|
|
32
32
|
opts = Vmail::Options.new(ARGV)
|
@@ -38,7 +38,7 @@ module Vmail
|
|
38
38
|
logfile = (vim == 'mvim') ? STDERR : 'vmail.log'
|
39
39
|
config.merge! 'logfile' => logfile
|
40
40
|
|
41
|
-
puts "
|
41
|
+
puts "Starting vmail imap client for #{config['username']}"
|
42
42
|
|
43
43
|
drb_uri = begin
|
44
44
|
Vmail::ImapClient.daemon config
|
@@ -53,23 +53,21 @@ module Vmail
|
|
53
53
|
query_string = Vmail::Query.args2string query
|
54
54
|
server.select_mailbox mailbox
|
55
55
|
|
56
|
-
STDERR.puts "
|
57
|
-
STDERR.puts "
|
56
|
+
STDERR.puts "Mailbox: #{mailbox}"
|
57
|
+
STDERR.puts "Query: #{query.inspect} => #{query_string}"
|
58
58
|
|
59
59
|
buffer_file = "vmailbuffer"
|
60
60
|
# invoke vim
|
61
61
|
vimscript = File.expand_path("../vmail.vim", __FILE__)
|
62
62
|
vim_command = "DRB_URI=#{drb_uri} VMAIL_CONTACTS_FILE=#{contacts_file} VMAIL_MAILBOX=#{String.shellescape(mailbox)} VMAIL_QUERY=#{String.shellescape(query_string)} #{vim} -S #{vimscript} #{buffer_file}"
|
63
63
|
STDERR.puts vim_command
|
64
|
-
|
65
|
-
STDERR.puts "using buffer file: #{buffer_file}"
|
64
|
+
STDERR.puts "Using buffer file: #{buffer_file}"
|
66
65
|
File.open(buffer_file, "w") do |file|
|
67
|
-
file.puts "
|
66
|
+
file.puts "Vmail starting with values:\n"
|
68
67
|
file.puts "- drb uri: #{drb_uri}"
|
69
68
|
file.puts "- mailbox: #{mailbox}"
|
70
|
-
file.puts "- query: #{query_string}"
|
71
|
-
file.puts
|
72
|
-
file.puts "fetching messages. please wait..."
|
69
|
+
file.puts "- query: #{query_string}\n"
|
70
|
+
file.puts "Fetching messages. please wait..."
|
73
71
|
end
|
74
72
|
|
75
73
|
system(vim_command)
|
@@ -80,15 +78,15 @@ module Vmail
|
|
80
78
|
|
81
79
|
File.delete(buffer_file)
|
82
80
|
|
83
|
-
STDERR.puts "
|
81
|
+
STDERR.puts "Closing imap connection"
|
84
82
|
begin
|
85
83
|
Timeout::timeout(10) do
|
86
84
|
$gmail.close
|
87
85
|
end
|
88
86
|
rescue Timeout::Error
|
89
|
-
puts "
|
87
|
+
puts "Close connection attempt timed out"
|
90
88
|
end
|
91
|
-
puts "
|
89
|
+
puts "Bye"
|
92
90
|
exit
|
93
91
|
end
|
94
92
|
|
@@ -130,15 +128,15 @@ module Vmail
|
|
130
128
|
}
|
131
129
|
args = commands[ARGV.first]
|
132
130
|
if args.nil?
|
133
|
-
abort "
|
131
|
+
abort "Command '#{args.inspect}' not recognized"
|
134
132
|
end
|
135
133
|
command = args.shift
|
136
134
|
imap_client.with_open do |vmail|
|
137
|
-
puts "
|
135
|
+
puts "Selecting mailbox: #{mailbox}"
|
138
136
|
vmail.select_mailbox mailbox
|
139
137
|
uid_set.each_slice(5) do |uid_set|
|
140
138
|
params = [uid_set.join(',')] + args + ARGV[1..-1]
|
141
|
-
puts "
|
139
|
+
puts "Executing: #{command} #{params.join(' ')}"
|
142
140
|
vmail.send command, *params
|
143
141
|
end
|
144
142
|
end
|
data/lib/vmail.vim
CHANGED
@@ -289,20 +289,15 @@ func! s:delete_messages(flag) range
|
|
289
289
|
let nummsgs = len(uid_set)
|
290
290
|
let command = s:flag_command . join(uid_set, ',') . " +FLAGS " . a:flag
|
291
291
|
if nummsgs == 1
|
292
|
-
echom "
|
292
|
+
echom "Deleting message"
|
293
293
|
else
|
294
|
-
echom "
|
294
|
+
echom "Deleting " . nummsgs . " messages"
|
295
295
|
endif
|
296
296
|
let res = system(command)
|
297
297
|
setlocal modifiable
|
298
|
-
exec a:firstline . "," . a:lastline . "delete"
|
298
|
+
exec "silent " . a:firstline . "," . a:lastline . "delete"
|
299
299
|
setlocal nomodifiable
|
300
300
|
write
|
301
|
-
" if more than 2 lines change, vim forces us to look at a message.
|
302
|
-
" dismiss it.
|
303
|
-
if nummsgs > 2
|
304
|
-
" call feedkeys("\<cr>")
|
305
|
-
endif
|
306
301
|
redraw
|
307
302
|
echo nummsgs . " message" . (nummsgs == 1 ? '' : 's') . " marked " . a:flag
|
308
303
|
endfunc
|
@@ -311,15 +306,12 @@ func! s:archive_messages() range
|
|
311
306
|
let uid_set = s:collect_uids(a:firstline, a:lastline)
|
312
307
|
let nummsgs = len(uid_set)
|
313
308
|
let command = s:move_to_command . join(uid_set, ',') . ' ' . "all"
|
314
|
-
echo "
|
309
|
+
echo "Archiving message" . (nummsgs == 1 ? '' : 's')
|
315
310
|
let res = system(command)
|
316
311
|
setlocal modifiable
|
317
|
-
exec a:firstline . "," . a:lastline . "delete"
|
312
|
+
exec "silent " . a:firstline . "," . a:lastline . "delete"
|
318
313
|
setlocal nomodifiable
|
319
314
|
write
|
320
|
-
if nummsgs > 2
|
321
|
-
call feedkeys("\<cr>")
|
322
|
-
endif
|
323
315
|
redraw
|
324
316
|
echo nummsgs . " message" . (nummsgs == 1 ? '' : 's') . " archived"
|
325
317
|
endfunc
|
@@ -385,13 +377,10 @@ function! s:complete_move_to_mailbox()
|
|
385
377
|
let res = system(command)
|
386
378
|
setlocal modifiable
|
387
379
|
if !s:copy_to_mailbox
|
388
|
-
exec s:firstline . "," . s:lastline . "delete"
|
380
|
+
exec "silent " . s:firstline . "," . s:lastline . "delete"
|
389
381
|
end
|
390
382
|
setlocal nomodifiable
|
391
383
|
write
|
392
|
-
if s:nummsgs > 2
|
393
|
-
call feedkeys("\<cr>")
|
394
|
-
endif
|
395
384
|
redraw
|
396
385
|
echo s:nummsgs . " message" . (s:nummsgs == 1 ? '' : 's') . ' ' . (s:copy_to_mailbox ? 'copied' : 'moved') . ' to ' . mailbox
|
397
386
|
endfunction
|
@@ -497,7 +486,7 @@ function! s:select_mailbox()
|
|
497
486
|
let command = s:search_command . shellescape("100 all")
|
498
487
|
echo "loading messages..."
|
499
488
|
let res = system(command)
|
500
|
-
1,$delete
|
489
|
+
silent 1,$delete
|
501
490
|
silent! put! =res
|
502
491
|
execute "normal Gdd\<c-y>"
|
503
492
|
normal G
|
@@ -629,19 +618,21 @@ function! CompleteContact(findstart, base)
|
|
629
618
|
endif
|
630
619
|
endfun
|
631
620
|
|
632
|
-
|
621
|
+
func! s:close_and_focus_list_window()
|
633
622
|
call s:focus_list_window()
|
634
623
|
wincmd p
|
635
624
|
close!
|
636
625
|
normal z.
|
637
|
-
|
626
|
+
endfunc
|
627
|
+
|
638
628
|
|
639
629
|
function! s:send_message()
|
640
630
|
let mail = join(getline(1,'$'), "\n")
|
641
631
|
echo "sending message"
|
642
632
|
call system(s:deliver_command, mail)
|
643
633
|
redraw
|
644
|
-
|
634
|
+
call s:close_and_focus_list_window()
|
635
|
+
echom "Message sent!"
|
645
636
|
redraw
|
646
637
|
endfunction
|
647
638
|
|
@@ -771,7 +762,7 @@ func! s:message_window_mappings()
|
|
771
762
|
|
772
763
|
nnoremap <silent> <buffer> <leader># :close<cr>:call <SID>focus_list_window()<cr>:call <SID>delete_messages("Deleted")<cr>
|
773
764
|
nnoremap <silent> <buffer> <leader>* :call <SID>focus_list_window()<cr>:call <SID>toggle_star()<cr>
|
774
|
-
noremap <silent> <buffer> <leader>! :call <SID>focus_list_window()<cr>:call <SID>delete_messages("spam")<CR>
|
765
|
+
noremap <silent> <buffer> <leader>! :close<cr>:call <SID>focus_list_window()<cr>:call <SID>delete_messages("spam")<CR>
|
775
766
|
noremap <silent> <buffer> <leader>e :call <SID>focus_list_window()<cr>:call <SID>archive_messages()<CR>
|
776
767
|
" alt mappings for lazy hands
|
777
768
|
nmap <silent> <buffer> <leader>8 <leader>*
|
@@ -830,7 +821,7 @@ func! s:message_list_window_mappings()
|
|
830
821
|
endfunc
|
831
822
|
|
832
823
|
func! s:compose_window_mappings()
|
833
|
-
noremap <silent> <buffer> <leader>q :call <SID>
|
824
|
+
noremap <silent> <buffer> <leader>q :call <SID>close_and_focus_list_window()<cr>
|
834
825
|
setlocal ai
|
835
826
|
" setlocal textwidth=72
|
836
827
|
autocmd CursorMoved <buffer> call <SID>toggle_textwidth()
|
@@ -3,7 +3,7 @@ require 'net/imap'
|
|
3
3
|
module Vmail
|
4
4
|
class ContactsExtractor
|
5
5
|
def initialize(username, password)
|
6
|
-
puts "
|
6
|
+
puts "Logging as #{username}"
|
7
7
|
@username, @password = username, password
|
8
8
|
end
|
9
9
|
|
@@ -19,13 +19,13 @@ class ContactsExtractor
|
|
19
19
|
open do |imap|
|
20
20
|
set_mailbox_prefix
|
21
21
|
mailbox = "[#@prefix]/Sent Mail"
|
22
|
-
STDERR.puts "
|
22
|
+
STDERR.puts "Selecting #{mailbox}"
|
23
23
|
imap.select(mailbox)
|
24
|
-
STDERR.puts "
|
24
|
+
STDERR.puts "Fetching last #{limit} sent messages"
|
25
25
|
all_uids = imap.uid_search('ALL')
|
26
|
-
STDERR.puts "
|
26
|
+
STDERR.puts "Total messages: #{all_uids.size}"
|
27
27
|
limit = [limit, all_uids.size].min
|
28
|
-
STDERR.puts "
|
28
|
+
STDERR.puts "Extracting addresses from #{limit} of them"
|
29
29
|
uids = all_uids[-limit ,limit]
|
30
30
|
imap.uid_fetch(uids, ["FLAGS", "ENVELOPE"]).each do |fetch_data|
|
31
31
|
recipients = fetch_data.attr["ENVELOPE"].to
|
data/lib/vmail/imap_client.rb
CHANGED
@@ -35,7 +35,7 @@ module Vmail
|
|
35
35
|
@message_cache ||= {}
|
36
36
|
size = @message_cache.values.reduce(0) {|sum, x| sum + x[:size]}
|
37
37
|
if size > 2_000_000 # TODO make this configurable
|
38
|
-
log "
|
38
|
+
log "Pruning message cache; message cache is consuming #{number_to_human_size size}"
|
39
39
|
@message_cache.keys[0, @message_cache.size / 2].each {|k| @message_cache.delete(k)}
|
40
40
|
end
|
41
41
|
@message_cache
|
@@ -56,7 +56,7 @@ module Vmail
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def close
|
59
|
-
log "
|
59
|
+
log "Closing connection"
|
60
60
|
Timeout::timeout(10) do
|
61
61
|
@imap.close rescue Net::IMAP::BadResponseError
|
62
62
|
@imap.disconnect rescue IOError
|
@@ -71,15 +71,15 @@ module Vmail
|
|
71
71
|
if mailbox == @mailbox && !force
|
72
72
|
return
|
73
73
|
end
|
74
|
-
log "
|
74
|
+
log "Selecting mailbox #{mailbox.inspect}"
|
75
75
|
reconnect_if_necessary(15) do
|
76
76
|
log @imap.select(mailbox)
|
77
77
|
end
|
78
|
-
log "
|
78
|
+
log "Done"
|
79
79
|
@mailbox = mailbox
|
80
|
-
log "
|
80
|
+
log "Getting mailbox status"
|
81
81
|
get_mailbox_status
|
82
|
-
log "
|
82
|
+
log "Getting highest message id"
|
83
83
|
get_highest_message_id
|
84
84
|
return "OK"
|
85
85
|
end
|
@@ -113,13 +113,13 @@ module Vmail
|
|
113
113
|
def get_mailbox_status
|
114
114
|
return
|
115
115
|
@status = @imap.status(@mailbox, ["MESSAGES", "RECENT", "UNSEEN"])
|
116
|
-
log "
|
116
|
+
log "Mailbox status: #{@status.inspect}"
|
117
117
|
end
|
118
118
|
|
119
119
|
def revive_connection
|
120
|
-
log "
|
120
|
+
log "Reviving connection"
|
121
121
|
open
|
122
|
-
log "
|
122
|
+
log "Reselecting mailbox #@mailbox"
|
123
123
|
@imap.select(@mailbox)
|
124
124
|
end
|
125
125
|
|
@@ -128,11 +128,11 @@ module Vmail
|
|
128
128
|
reconnect_if_necessary(4) do
|
129
129
|
# this is just to prime the IMAP connection
|
130
130
|
# It's necessary for some reason before update and deliver.
|
131
|
-
log "
|
131
|
+
log "Priming connection"
|
132
132
|
res = @imap.fetch(@ids[-1], ["ENVELOPE"])
|
133
133
|
if res.nil?
|
134
134
|
# just go ahead, just log
|
135
|
-
log "
|
135
|
+
log "Priming connection didn't work, connection seems broken, but still going ahead..."
|
136
136
|
end
|
137
137
|
end
|
138
138
|
end
|
@@ -144,7 +144,7 @@ module Vmail
|
|
144
144
|
map {|struct| struct.name}.uniq
|
145
145
|
@mailboxes.delete("INBOX")
|
146
146
|
@mailboxes.unshift("INBOX")
|
147
|
-
log "
|
147
|
+
log "Loaded mailboxes: #{@mailboxes.inspect}"
|
148
148
|
@mailboxes = @mailboxes.map {|name| mailbox_aliases.invert[name] || name}
|
149
149
|
@mailboxes.join("\n")
|
150
150
|
end
|
@@ -167,7 +167,7 @@ module Vmail
|
|
167
167
|
end
|
168
168
|
end
|
169
169
|
end
|
170
|
-
log "
|
170
|
+
log "Setting aliases to #{@mailbox_aliases.inspect}"
|
171
171
|
@mailbox_aliases
|
172
172
|
end
|
173
173
|
|
@@ -181,7 +181,7 @@ module Vmail
|
|
181
181
|
|
182
182
|
# id_set may be a range, array, or string
|
183
183
|
def fetch_row_text(id_set, are_uids=false, is_update=false)
|
184
|
-
log "
|
184
|
+
log "Fetch_row_text: #{id_set.inspect}"
|
185
185
|
if id_set.is_a?(String)
|
186
186
|
id_set = id_set.split(',')
|
187
187
|
end
|
@@ -205,7 +205,7 @@ module Vmail
|
|
205
205
|
end
|
206
206
|
end
|
207
207
|
if results.nil?
|
208
|
-
error = "
|
208
|
+
error = "Expected fetch results but got nil"
|
209
209
|
log(error) && raise(error)
|
210
210
|
end
|
211
211
|
log "- extracting headers"
|
@@ -229,7 +229,7 @@ module Vmail
|
|
229
229
|
envelope.from.first
|
230
230
|
end
|
231
231
|
address = if address_struct.nil?
|
232
|
-
"
|
232
|
+
"Unknown"
|
233
233
|
elsif address_struct.name
|
234
234
|
"#{Mail::Encodings.unquote_and_convert_to(address_struct.name, 'UTF-8')} <#{[address_struct.mailbox, address_struct.host].join('@')}>"
|
235
235
|
else
|
@@ -266,7 +266,7 @@ module Vmail
|
|
266
266
|
].join(' | ')
|
267
267
|
{:uid => uid, :seqno => seqno, :row_text => row_text}
|
268
268
|
rescue
|
269
|
-
log "
|
269
|
+
log "Error extracting header for uid #{uid} seqno #{seqno}: #$!\n#{$!.backtrace}"
|
270
270
|
row_text = "#{seqno.to_s} : error extracting this header"
|
271
271
|
{:uid => uid, :seqno => seqno, :row_text => row_text}
|
272
272
|
end
|
@@ -317,7 +317,7 @@ module Vmail
|
|
317
317
|
end
|
318
318
|
@query = query.map {|x| x.to_s.downcase}
|
319
319
|
query_string = Vmail::Query.args2string(@query)
|
320
|
-
log "
|
320
|
+
log "Search query: #{@query} > #{query_string.inspect}"
|
321
321
|
log "- @all_search #{@all_search}"
|
322
322
|
@query = query
|
323
323
|
@ids = reconnect_if_necessary(180) do # increase timeout to 3 minutes
|
@@ -360,7 +360,7 @@ module Vmail
|
|
360
360
|
# this may generate a negative rane, e.g., "19893:19992" but that seems harmless
|
361
361
|
update_query[0] = "#{old_num_messages}:#{@num_messages}"
|
362
362
|
ids = reconnect_if_necessary {
|
363
|
-
log "
|
363
|
+
log "Search #update_query"
|
364
364
|
@imap.search(Vmail::Query.args2string(update_query))
|
365
365
|
}
|
366
366
|
log "- got seqnos: #{ids.inspect}"
|
@@ -379,7 +379,7 @@ module Vmail
|
|
379
379
|
|
380
380
|
# gets 100 messages prior to id
|
381
381
|
def more_messages(message_id, limit=100)
|
382
|
-
log "
|
382
|
+
log "More_messages: message_id #{message_id}"
|
383
383
|
message_id = message_id.to_i
|
384
384
|
if @all_search
|
385
385
|
x = [(message_id - limit), 0].max
|
@@ -398,7 +398,7 @@ module Vmail
|
|
398
398
|
end
|
399
399
|
|
400
400
|
def add_more_message_line(res, start_seqno)
|
401
|
-
log "
|
401
|
+
log "Add_more_message_line for start_seqno #{start_seqno}"
|
402
402
|
if @all_search
|
403
403
|
return res if start_seqno.nil?
|
404
404
|
remaining = start_seqno - 1
|
@@ -406,15 +406,15 @@ module Vmail
|
|
406
406
|
remaining = (@ids.index(start_seqno) || 1) - 1
|
407
407
|
end
|
408
408
|
if remaining < 1
|
409
|
-
log "
|
410
|
-
return "
|
409
|
+
log "None remaining"
|
410
|
+
return "Showing all matches\n" + res
|
411
411
|
end
|
412
|
-
log "
|
412
|
+
log "Remaining messages: #{remaining}"
|
413
413
|
"> Load #{[100, remaining].min} more messages. #{remaining} remaining.\n" + res
|
414
414
|
end
|
415
415
|
|
416
416
|
def show_message(uid, raw=false)
|
417
|
-
log "
|
417
|
+
log "Show message: #{uid}"
|
418
418
|
return @current_mail.to_s if raw
|
419
419
|
uid = uid.to_i
|
420
420
|
if uid == @current_message_uid
|
@@ -427,7 +427,7 @@ module Vmail
|
|
427
427
|
# envelope_data[:row_text] = envelope_data[:row_text].gsub(/^\+ /, ' ').gsub(/^\*\+/, '* ') # mark as read in cache
|
428
428
|
#seqno = envelope_data[:seqno]
|
429
429
|
|
430
|
-
log "
|
430
|
+
log "Showing message uid: #{uid}"
|
431
431
|
data = if x = message_cache[[@mailbox, uid]]
|
432
432
|
log "- message cache hit"
|
433
433
|
x
|
@@ -448,7 +448,7 @@ module Vmail
|
|
448
448
|
@current_mail = mail # used later to show raw message or extract attachments if any
|
449
449
|
@current_message = data[:message_text]
|
450
450
|
rescue
|
451
|
-
log "
|
451
|
+
log "Parsing error"
|
452
452
|
"Error encountered parsing this message:\n#{$!}\n#{$!.backtrace.join("\n")}"
|
453
453
|
end
|
454
454
|
|
@@ -476,7 +476,7 @@ module Vmail
|
|
476
476
|
|
477
477
|
#{formatter.process_body}
|
478
478
|
EOF
|
479
|
-
# log "
|
479
|
+
# log "Storing message_cache[[#{@mailbox}, #{uid}]]"
|
480
480
|
d = {:mail => mail, :size => size, :message_text => message_text, :seqno => fetch_data.seqno, :flags => flags}
|
481
481
|
message_cache[[@mailbox, uid]] = d
|
482
482
|
rescue
|
@@ -506,7 +506,7 @@ EOF
|
|
506
506
|
# id_set is a string comming from the vim client
|
507
507
|
# action is -FLAGS or +FLAGS
|
508
508
|
def flag(uid_set, action, flg)
|
509
|
-
log "
|
509
|
+
log "Flag #{uid_set} #{flg} #{action}"
|
510
510
|
uid_set = uid_set.split(',').map(&:to_i)
|
511
511
|
if flg == 'Deleted'
|
512
512
|
log "Deleting uid_set: #{uid_set.inspect}"
|
@@ -545,21 +545,21 @@ EOF
|
|
545
545
|
def move_to(uid_set, mailbox)
|
546
546
|
uid_set = uid_set.split(',').map(&:to_i)
|
547
547
|
decrement_max_seqno(uid_set.size)
|
548
|
-
log "
|
548
|
+
log "Move #{uid_set.inspect} to #{mailbox}"
|
549
549
|
if mailbox == 'all'
|
550
|
-
log "
|
550
|
+
log "Archiving messages"
|
551
551
|
end
|
552
552
|
if mailbox_aliases[mailbox]
|
553
553
|
mailbox = mailbox_aliases[mailbox]
|
554
554
|
end
|
555
555
|
create_if_necessary mailbox
|
556
|
-
log "
|
556
|
+
log "Moving uid_set: #{uid_set.inspect} to #{mailbox}"
|
557
557
|
spawn_thread_if_tty do
|
558
558
|
log @imap.uid_copy(uid_set, mailbox)
|
559
559
|
log @imap.uid_store(uid_set, '+FLAGS', [:Deleted])
|
560
560
|
reload_mailbox
|
561
561
|
clear_cached_message
|
562
|
-
log "
|
562
|
+
log "Moved uid_set #{uid_set.inspect} to #{mailbox}"
|
563
563
|
end
|
564
564
|
end
|
565
565
|
|
@@ -569,10 +569,10 @@ EOF
|
|
569
569
|
mailbox = mailbox_aliases[mailbox]
|
570
570
|
end
|
571
571
|
create_if_necessary mailbox
|
572
|
-
log "
|
572
|
+
log "Copying #{uid_set.inspect} to #{mailbox}"
|
573
573
|
spawn_thread_if_tty do
|
574
574
|
log @imap.uid_copy(uid_set, mailbox)
|
575
|
-
log "
|
575
|
+
log "Copied uid_set #{uid_set.inspect} to #{mailbox}"
|
576
576
|
end
|
577
577
|
end
|
578
578
|
|
@@ -589,8 +589,8 @@ EOF
|
|
589
589
|
def create_if_necessary(mailbox)
|
590
590
|
current_mailboxes = mailboxes.map {|m| mailbox_aliases[m] || m}
|
591
591
|
if !current_mailboxes.include?(mailbox)
|
592
|
-
log "
|
593
|
-
log "
|
592
|
+
log "Current mailboxes: #{current_mailboxes.inspect}"
|
593
|
+
log "Creating mailbox #{mailbox}"
|
594
594
|
log @imap.create(mailbox)
|
595
595
|
@mailboxes = nil # force reload ...
|
596
596
|
list_mailboxes
|
@@ -599,14 +599,14 @@ EOF
|
|
599
599
|
|
600
600
|
def append_to_file(uid_set, file)
|
601
601
|
uid_set = uid_set.split(',').map(&:to_i)
|
602
|
-
log "
|
602
|
+
log "Append to file uid set #{uid_set.inspect} to file: #{file}"
|
603
603
|
uid_set.each do |uid|
|
604
604
|
message = show_message(uid)
|
605
605
|
File.open(file, 'a') {|f| f.puts(divider('=') + "\n" + message + "\n\n")}
|
606
606
|
subject = (message[/^subject:(.*)/,1] || '').strip
|
607
|
-
log "
|
607
|
+
log "Appended message '#{subject}'"
|
608
608
|
end
|
609
|
-
"
|
609
|
+
"Printed #{uid_set.size} message#{uid_set.size == 1 ? '' : 's'} to #{file.strip}"
|
610
610
|
end
|
611
611
|
|
612
612
|
def new_message_template(subject = nil, append_signature = true)
|
@@ -629,7 +629,7 @@ EOF
|
|
629
629
|
end
|
630
630
|
|
631
631
|
def reply_template(replyall=false)
|
632
|
-
log "
|
632
|
+
log "Sending reply template"
|
633
633
|
if @current_mail.nil?
|
634
634
|
log "- missing @current mail!"
|
635
635
|
return nil
|
@@ -673,9 +673,9 @@ EOF
|
|
673
673
|
log res.inspect
|
674
674
|
log "\n"
|
675
675
|
msg = if res.is_a?(Mail::Message)
|
676
|
-
"
|
676
|
+
"Message '#{mail.subject}' sent"
|
677
677
|
else
|
678
|
-
"
|
678
|
+
"Failed to deliver message '#{mail.subject}'"
|
679
679
|
end
|
680
680
|
log msg
|
681
681
|
msg
|
@@ -694,7 +694,7 @@ EOF
|
|
694
694
|
end
|
695
695
|
headers[key] = value
|
696
696
|
end
|
697
|
-
log "
|
697
|
+
log "Delivering message with headers: #{headers.to_yaml}"
|
698
698
|
mail.from = headers['from'] || @username
|
699
699
|
mail.to = headers['to'] #.split(/,\s+/)
|
700
700
|
mail.cc = headers['cc'] #&& headers['cc'].split(/,\s+/)
|
@@ -705,7 +705,7 @@ EOF
|
|
705
705
|
# after the headers, and followed by a blank line
|
706
706
|
if (attachments = raw_body.split(/\n\s*\n/, 2)[0]) =~ /^attach(ment|ments)*:/
|
707
707
|
files = YAML::load(attachments).values.flatten
|
708
|
-
log "
|
708
|
+
log "Attach: #{files}"
|
709
709
|
files.each do |file|
|
710
710
|
if File.directory?(file)
|
711
711
|
Dir.glob("#{file}/*").each {|f| mail.add_file(f) if File.size?(f)}
|
@@ -726,24 +726,24 @@ EOF
|
|
726
726
|
end
|
727
727
|
|
728
728
|
def save_attachments(dir)
|
729
|
-
log "
|
729
|
+
log "Save_attachments #{dir}"
|
730
730
|
if !@current_mail
|
731
|
-
log "
|
731
|
+
log "Missing a current message"
|
732
732
|
end
|
733
733
|
return unless dir && @current_mail
|
734
734
|
attachments = @current_mail.attachments
|
735
735
|
`mkdir -p #{dir}`
|
736
736
|
saved = attachments.map do |x|
|
737
737
|
path = File.join(dir, x.filename)
|
738
|
-
log "
|
738
|
+
log "Saving #{path}"
|
739
739
|
File.open(path, 'wb') {|f| f.puts x.decoded}
|
740
740
|
path
|
741
741
|
end
|
742
|
-
"
|
742
|
+
"Saved:\n" + saved.map {|x| "- #{x}"}.join("\n")
|
743
743
|
end
|
744
744
|
|
745
745
|
def open_html_part
|
746
|
-
log "
|
746
|
+
log "Open_html_part"
|
747
747
|
log @current_mail.parts.inspect
|
748
748
|
multipart = @current_mail.parts.detect {|part| part.multipart?}
|
749
749
|
html_part = if multipart
|
@@ -761,7 +761,7 @@ EOF
|
|
761
761
|
end
|
762
762
|
|
763
763
|
def window_width=(width)
|
764
|
-
log "
|
764
|
+
log "Setting window width to #{width}"
|
765
765
|
@width = width.to_i
|
766
766
|
end
|
767
767
|
|
@@ -790,8 +790,8 @@ EOF
|
|
790
790
|
block.call
|
791
791
|
end
|
792
792
|
rescue IOError, Errno::EADDRNOTAVAIL, Errno::ECONNRESET, Timeout::Error
|
793
|
-
log "
|
794
|
-
log "
|
793
|
+
log "Error: #{$!}"
|
794
|
+
log "Attempting to reconnect"
|
795
795
|
close
|
796
796
|
log(revive_connection)
|
797
797
|
# hope this isn't an endless loop
|
@@ -799,7 +799,7 @@ EOF
|
|
799
799
|
block.call
|
800
800
|
end
|
801
801
|
rescue
|
802
|
-
log "
|
802
|
+
log "Error: #{$!}"
|
803
803
|
raise
|
804
804
|
end
|
805
805
|
|
@@ -814,7 +814,7 @@ EOF
|
|
814
814
|
use_uri = config['drb_uri'] || nil # redundant but explicit
|
815
815
|
DRb.start_service(use_uri, $gmail)
|
816
816
|
uri = DRb.uri
|
817
|
-
puts "
|
817
|
+
puts "Starting gmail service at #{uri}"
|
818
818
|
uri
|
819
819
|
end
|
820
820
|
end
|
@@ -822,13 +822,13 @@ end
|
|
822
822
|
|
823
823
|
trap("INT") {
|
824
824
|
require 'timeout'
|
825
|
-
puts "
|
825
|
+
puts "Closing imap connection"
|
826
826
|
begin
|
827
827
|
Timeout::timeout(10) do
|
828
828
|
$gmail.close
|
829
829
|
end
|
830
830
|
rescue Timeout::Error
|
831
|
-
puts "
|
831
|
+
puts "Close connection attempt timed out"
|
832
832
|
end
|
833
833
|
exit
|
834
834
|
}
|
data/lib/vmail/options.rb
CHANGED
@@ -48,7 +48,7 @@ module Vmail
|
|
48
48
|
begin
|
49
49
|
opts.parse!(argv)
|
50
50
|
if @config_file && File.exists?(@config_file)
|
51
|
-
STDERR.puts "
|
51
|
+
STDERR.puts "Using config file: #{@config_file}"
|
52
52
|
else
|
53
53
|
STDERR.puts <<EOF
|
54
54
|
|
@@ -64,7 +64,7 @@ EOF
|
|
64
64
|
STDERR.puts "No contacts file found for auto-completion. See help for how to generate it."
|
65
65
|
sleep 0.5
|
66
66
|
else
|
67
|
-
STDERR.puts "
|
67
|
+
STDERR.puts "Using contacts file: #{@contacts_file}"
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
@@ -84,13 +84,13 @@ EOF
|
|
84
84
|
end
|
85
85
|
end
|
86
86
|
STDERR.print "\n"
|
87
|
-
puts "
|
88
|
-
puts "
|
87
|
+
puts "Saved file to #{DEFAULT_CONTACTS_FILENAME}"
|
88
|
+
puts "Sorting address..."
|
89
89
|
cmd = "sort #{DEFAULT_CONTACTS_FILENAME} | uniq > vmail-tmp.txt"
|
90
90
|
cmd2 = "mv vmail-tmp.txt #{DEFAULT_CONTACTS_FILENAME}"
|
91
91
|
`#{cmd}`
|
92
92
|
`#{cmd2}`
|
93
|
-
puts "
|
93
|
+
puts "Done"
|
94
94
|
exit
|
95
95
|
end
|
96
96
|
|
data/lib/vmail/version.rb
CHANGED