vmail 1.4.7 → 1.4.8
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.
- 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