vmail 1.2.3 → 1.2.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +5 -0
- data/bin/vmail +7 -1
- data/lib/vmail.rb +85 -24
- data/lib/vmail.vim +7 -16
- data/lib/vmail/imap_client.rb +55 -21
- data/lib/vmail/options.rb +9 -7
- data/lib/vmail/query.rb +28 -0
- data/lib/vmail/version.rb +1 -1
- metadata +4 -3
data/README.markdown
CHANGED
@@ -120,6 +120,11 @@ this number by passing in a number after the mailbox name:
|
|
120
120
|
|
121
121
|
vmail inbox 700 subject unix
|
122
122
|
|
123
|
+
Passing in 0 as the number of messages returns all messages that match
|
124
|
+
the query:
|
125
|
+
|
126
|
+
vmail inbox 0 subject unix # => returns all matching messages
|
127
|
+
|
123
128
|
## Viewing messages
|
124
129
|
|
125
130
|
The first screen vmail shows you is a list of messages. You can view a message
|
data/bin/vmail
CHANGED
data/lib/vmail.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'vmail/version'
|
2
2
|
require 'vmail/options'
|
3
3
|
require 'vmail/imap_client'
|
4
|
+
require 'vmail/query'
|
4
5
|
require 'vmail/message_formatter'
|
5
6
|
require 'vmail/reply_template'
|
6
7
|
|
@@ -11,18 +12,14 @@ module Vmail
|
|
11
12
|
puts "starting vmail #{Vmail::VERSION}"
|
12
13
|
|
13
14
|
vim = ENV['VMAIL_VIM'] || 'vim'
|
14
|
-
|
15
15
|
ENV['VMAIL_BROWSER'] ||= 'open'
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
puts "You need to install lynx on your system in order to see html-only messages"
|
20
|
-
sleep 3
|
21
|
-
end
|
17
|
+
check_lynx
|
18
|
+
|
22
19
|
opts = Vmail::Options.new(ARGV)
|
23
20
|
opts.config
|
24
|
-
|
25
21
|
config = opts.config
|
22
|
+
|
26
23
|
contacts_file = opts.contacts_file
|
27
24
|
|
28
25
|
logfile = (vim == 'mvim') ? STDERR : 'vmail.log'
|
@@ -39,33 +36,25 @@ module Vmail
|
|
39
36
|
|
40
37
|
server = DRbObject.new_with_uri drb_uri
|
41
38
|
|
42
|
-
mailbox =
|
43
|
-
|
44
|
-
else
|
45
|
-
ARGV.shift || 'INBOX'
|
46
|
-
end
|
47
|
-
|
39
|
+
mailbox, query = parse_query
|
40
|
+
query_string = Vmail::Query.args2string query
|
48
41
|
server.select_mailbox mailbox
|
49
42
|
|
50
|
-
|
51
|
-
|
52
|
-
query << "ALL"
|
53
|
-
end
|
54
|
-
puts "mailbox: #{mailbox}"
|
55
|
-
puts "query: #{query.inspect}"
|
43
|
+
STDERR.puts "mailbox: #{mailbox}"
|
44
|
+
STDERR.puts "query: #{query.inspect} => #{query_string}"
|
56
45
|
|
57
46
|
buffer_file = "vmailbuffer"
|
58
47
|
# invoke vim
|
59
48
|
vimscript = File.expand_path("../vmail.vim", __FILE__)
|
60
|
-
vim_command = "DRB_URI=#{drb_uri} VMAIL_CONTACTS_FILE=#{contacts_file} VMAIL_MAILBOX=#{String.shellescape(mailbox)} VMAIL_QUERY=#{String.shellescape(
|
61
|
-
puts vim_command
|
49
|
+
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}"
|
50
|
+
STDERR.puts vim_command
|
62
51
|
|
63
|
-
puts "using buffer file: #{buffer_file}"
|
52
|
+
STDERR.puts "using buffer file: #{buffer_file}"
|
64
53
|
File.open(buffer_file, "w") do |file|
|
65
54
|
file.puts "vmail starting with values:"
|
66
55
|
file.puts "- drb uri: #{drb_uri}"
|
67
56
|
file.puts "- mailbox: #{mailbox}"
|
68
|
-
file.puts "- query: #{
|
57
|
+
file.puts "- query: #{query_string}"
|
69
58
|
file.puts
|
70
59
|
file.puts "fetching messages. please wait..."
|
71
60
|
end
|
@@ -78,7 +67,7 @@ module Vmail
|
|
78
67
|
|
79
68
|
File.delete(buffer_file)
|
80
69
|
|
81
|
-
puts "closing imap connection"
|
70
|
+
STDERR.puts "closing imap connection"
|
82
71
|
begin
|
83
72
|
Timeout::timeout(10) do
|
84
73
|
$gmail.close
|
@@ -89,5 +78,77 @@ module Vmail
|
|
89
78
|
puts "bye"
|
90
79
|
exit
|
91
80
|
end
|
81
|
+
|
82
|
+
# non-interactive mode
|
83
|
+
def noninteractive_list_messages
|
84
|
+
check_lynx
|
85
|
+
opts = Vmail::Options.new(ARGV)
|
86
|
+
opts.config
|
87
|
+
config = opts.config.merge 'logfile' => 'vmail.log'
|
88
|
+
mailbox, query = parse_query
|
89
|
+
query_string = Vmail::Query.args2string query
|
90
|
+
imap_client = Vmail::ImapClient.new config
|
91
|
+
imap_client.with_open do |vmail|
|
92
|
+
vmail.select_mailbox mailbox
|
93
|
+
vmail.search query_string
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# batch processing mode
|
98
|
+
def batch_run
|
99
|
+
check_lynx
|
100
|
+
opts = Vmail::Options.new(ARGV)
|
101
|
+
opts.config
|
102
|
+
config = opts.config.merge 'logfile' => 'vmail.log'
|
103
|
+
# no search query args, but command args
|
104
|
+
imap_client = Vmail::ImapClient.new config
|
105
|
+
lines = STDIN.readlines# .reverse
|
106
|
+
mailbox = lines.shift.chomp
|
107
|
+
puts "mailbox: #{mailbox}"
|
108
|
+
uid_set = lines.map do |line|
|
109
|
+
line[/(\d+)\s*$/,1].to_i
|
110
|
+
end
|
111
|
+
commands = {
|
112
|
+
'rm' => ["flag", "+FLAGS", "Deleted"],
|
113
|
+
'spam' => ["flag", "+FLAGS", "spam"],
|
114
|
+
'mv' => ["move_to"],
|
115
|
+
'cp' => ["copy_to"],
|
116
|
+
'cat' => ["append_to_file"]
|
117
|
+
}
|
118
|
+
args = commands[ARGV.first]
|
119
|
+
if args.nil?
|
120
|
+
abort "command '#{args.inspect}' not recognized"
|
121
|
+
end
|
122
|
+
command = args.shift
|
123
|
+
imap_client.with_open do |vmail|
|
124
|
+
puts "selecting mailbox: #{mailbox}"
|
125
|
+
vmail.select_mailbox mailbox
|
126
|
+
uid_set.each_slice(5) do |uid_set|
|
127
|
+
params = [uid_set.join(',')] + args + ARGV[1..-1]
|
128
|
+
puts "executing: #{command} #{params.join(' ')}"
|
129
|
+
vmail.send command, *params
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
private
|
135
|
+
|
136
|
+
def check_lynx
|
137
|
+
# TODO check for elinks, or firefox (how do we parse VMAIL_HTML_PART_REDAER to determine?)
|
138
|
+
if `which lynx` == ''
|
139
|
+
STDERR.puts "You need to install lynx on your system in order to see html-only messages"
|
140
|
+
sleep 3
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def parse_query
|
145
|
+
mailbox = if ARGV[0] =~ /^\d+/
|
146
|
+
"INBOX"
|
147
|
+
else
|
148
|
+
ARGV.shift || 'INBOX'
|
149
|
+
end
|
150
|
+
query = Vmail::Query.parse(ARGV)
|
151
|
+
[mailbox, query]
|
152
|
+
end
|
92
153
|
end
|
93
154
|
|
data/lib/vmail.vim
CHANGED
@@ -286,7 +286,7 @@ function! s:toggle_star() range
|
|
286
286
|
endif
|
287
287
|
endfunction
|
288
288
|
|
289
|
-
" flag can be Deleted or
|
289
|
+
" flag can be Deleted or spam
|
290
290
|
func! s:delete_messages(flag) range
|
291
291
|
let uid_set = s:collect_uids(a:firstline, a:lastline)
|
292
292
|
let nummsgs = len(uid_set)
|
@@ -339,7 +339,7 @@ func! s:append_messages_to_file() range
|
|
339
339
|
return
|
340
340
|
endif
|
341
341
|
let s:append_file = append_file
|
342
|
-
let command = s:append_to_file_command .
|
342
|
+
let command = s:append_to_file_command . join(uid_set, ',') . ' ' . s:append_file
|
343
343
|
echo "appending " . nummsgs . " message" . (nummsgs == 1 ? '' : 's') . " to " . s:append_file . ". please wait..."
|
344
344
|
let res = system(command)
|
345
345
|
echo res
|
@@ -497,7 +497,7 @@ function! s:select_mailbox()
|
|
497
497
|
" now get latest 100 messages
|
498
498
|
call s:focus_list_window()
|
499
499
|
setlocal modifiable
|
500
|
-
let command = s:search_command . "100 all"
|
500
|
+
let command = s:search_command . shellescape("100 all")
|
501
501
|
echo "loading messages..."
|
502
502
|
let res = system(command)
|
503
503
|
1,$delete
|
@@ -527,16 +527,7 @@ function! s:do_search()
|
|
527
527
|
" close message window if open
|
528
528
|
call s:focus_message_window()
|
529
529
|
close
|
530
|
-
|
531
|
-
let limit = 100
|
532
|
-
let imap_query = s:query
|
533
|
-
if match(s:query, '^\d') == 0
|
534
|
-
let query_chunks = split(s:query, '\s')
|
535
|
-
let limit = remove(query_chunks, 0)
|
536
|
-
let imap_query = join(query_chunks, ' ')
|
537
|
-
end
|
538
|
-
let s:query = limit . ' ' . imap_query
|
539
|
-
let command = s:search_command . limit . ' ' . shellescape(imap_query)
|
530
|
+
let command = s:search_command . shellescape(s:query)
|
540
531
|
redraw
|
541
532
|
call s:focus_list_window()
|
542
533
|
setlocal modifiable
|
@@ -778,7 +769,7 @@ func! s:message_window_mappings()
|
|
778
769
|
|
779
770
|
nnoremap <silent> <buffer> <leader># :close<cr>:call <SID>focus_list_window()<cr>:call <SID>delete_messages("Deleted")<cr>
|
780
771
|
nnoremap <silent> <buffer> <leader>* :call <SID>focus_list_window()<cr>:call <SID>toggle_star()<cr>
|
781
|
-
noremap <silent> <buffer> <leader>! :call <SID>focus_list_window()<cr>:call <SID>delete_messages("
|
772
|
+
noremap <silent> <buffer> <leader>! :call <SID>focus_list_window()<cr>:call <SID>delete_messages("spam")<CR>
|
782
773
|
noremap <silent> <buffer> <leader>e :call <SID>focus_list_window()<cr>:call <SID>archive_messages()<CR>
|
783
774
|
" alt mappings for lazy hands
|
784
775
|
nmap <silent> <buffer> <leader>8 <leader>*
|
@@ -805,12 +796,12 @@ func! s:message_list_window_mappings()
|
|
805
796
|
|
806
797
|
noremap <silent> <buffer> <leader>* :call <SID>toggle_star()<CR>
|
807
798
|
noremap <silent> <buffer> <leader># :call <SID>delete_messages("Deleted")<CR>
|
808
|
-
noremap <silent> <buffer> <leader>! :call <SID>delete_messages("
|
799
|
+
noremap <silent> <buffer> <leader>! :call <SID>delete_messages("spam")<CR>
|
809
800
|
noremap <silent> <buffer> <leader>e :call <SID>archive_messages()<CR>
|
810
801
|
" alt mappings for lazy hands
|
811
802
|
noremap <silent> <buffer> <leader>8 :call <SID>toggle_star()<CR>
|
812
803
|
noremap <silent> <buffer> <leader>3 :call <SID>delete_messages("Deleted")<CR>
|
813
|
-
noremap <silent> <buffer> <leader>1 :call <SID>delete_messages("
|
804
|
+
noremap <silent> <buffer> <leader>1 :call <SID>delete_messages("spam")<CR>
|
814
805
|
" nmap <silent> <buffer> <leader>8 <leader>*
|
815
806
|
" nmap <silent> <buffer> <leader>3 <leader>#
|
816
807
|
" nmap <silent> <buffer> <leader>1 <leader>!
|
data/lib/vmail/imap_client.rb
CHANGED
@@ -33,6 +33,7 @@ module Vmail
|
|
33
33
|
@imap_port = config['port'] || 993
|
34
34
|
@current_mail = nil
|
35
35
|
@current_message_uid = nil
|
36
|
+
@width = 140
|
36
37
|
end
|
37
38
|
|
38
39
|
# holds mail objects keyed by [mailbox, uid]
|
@@ -52,6 +53,14 @@ module Vmail
|
|
52
53
|
list_mailboxes # prefetch mailbox list
|
53
54
|
end
|
54
55
|
|
56
|
+
# expects a block, closes on finish
|
57
|
+
def with_open
|
58
|
+
@imap = Net::IMAP.new(@imap_server, @imap_port, true, nil, false)
|
59
|
+
log @imap.login(@username, @password)
|
60
|
+
yield self
|
61
|
+
close
|
62
|
+
end
|
63
|
+
|
55
64
|
def close
|
56
65
|
log "closing connection"
|
57
66
|
Timeout::timeout(10) do
|
@@ -82,10 +91,12 @@ module Vmail
|
|
82
91
|
end
|
83
92
|
|
84
93
|
def reload_mailbox
|
94
|
+
return unless STDIN.tty?
|
85
95
|
select_mailbox(@mailbox, true)
|
86
96
|
end
|
87
97
|
|
88
98
|
def clear_cached_message
|
99
|
+
return unless STDIN.tty?
|
89
100
|
log "CLEARING CACHED MESSAGE"
|
90
101
|
@current_mail = nil
|
91
102
|
@current_message_uid = nil
|
@@ -164,6 +175,9 @@ module Vmail
|
|
164
175
|
end
|
165
176
|
new_message_rows = fetch_envelopes(id_set, are_uids, is_update)
|
166
177
|
new_message_rows.map {|x| x[:row_text]}.join("\n")
|
178
|
+
rescue # Encoding::CompatibilityError (only in 1.9.2)
|
179
|
+
log "Error in fetch_row_text:\n#{$!}\n#{$!.backtrace}"
|
180
|
+
new_message_rows.map {|x| Iconv.conv('US-ASCII//TRANSLIT//IGNORE', 'UTF-8', x[:row_text])}.join("\n")
|
167
181
|
end
|
168
182
|
|
169
183
|
def fetch_envelopes(id_set, are_uids, is_update)
|
@@ -226,7 +240,7 @@ module Vmail
|
|
226
240
|
mid_width = @width - 38
|
227
241
|
address_col_width = (mid_width * 0.3).ceil
|
228
242
|
subject_col_width = (mid_width * 0.7).floor
|
229
|
-
identifier = [
|
243
|
+
identifier = [seqno.to_i, uid.to_i].join(':')
|
230
244
|
row_text = [ flags.col(2),
|
231
245
|
(date_formatted || '').col(14),
|
232
246
|
address.col(address_col_width),
|
@@ -267,13 +281,16 @@ module Vmail
|
|
267
281
|
flags.join('')
|
268
282
|
end
|
269
283
|
|
270
|
-
def search(
|
271
|
-
|
272
|
-
limit =
|
273
|
-
|
284
|
+
def search(query)
|
285
|
+
query = Vmail::Query.parse(query)
|
286
|
+
@limit = query.shift.to_i
|
287
|
+
# a limit of zero is effectively no limit
|
288
|
+
if @limit == 0
|
289
|
+
@limit = @num_messages
|
290
|
+
end
|
274
291
|
if query.size == 1 && query[0].downcase == 'all'
|
275
292
|
# form a sequence range
|
276
|
-
query.unshift [[@num_messages - limit
|
293
|
+
query.unshift [[@num_messages - @limit + 1 , 1].max, @num_messages].join(':')
|
277
294
|
@all_search = true
|
278
295
|
else # this is a special query search
|
279
296
|
# set the target range to the whole set
|
@@ -281,28 +298,36 @@ module Vmail
|
|
281
298
|
@all_search = false
|
282
299
|
end
|
283
300
|
@query = query.map {|x| x.to_s.downcase}
|
284
|
-
|
285
|
-
log "search query: #{@query.inspect}"
|
301
|
+
query_string = Vmail::Query.args2string(@query)
|
302
|
+
log "search query: #{@query} > #{query_string.inspect}"
|
286
303
|
log "- @all_search #{@all_search}"
|
287
304
|
@query = query
|
288
305
|
@ids = reconnect_if_necessary(180) do # increase timeout to 3 minutes
|
289
|
-
@imap.search(
|
306
|
+
@imap.search(query_string)
|
290
307
|
end
|
291
308
|
# save ids in @ids, because filtered search relies on it
|
292
309
|
fetch_ids = if @all_search
|
293
310
|
@ids
|
294
311
|
else #filtered search
|
295
|
-
@start_index = [@ids.length - limit, 0].max
|
312
|
+
@start_index = [@ids.length - @limit, 0].max
|
296
313
|
@ids[@start_index..-1]
|
297
314
|
end
|
298
315
|
self.max_seqno = @ids[-1]
|
299
316
|
log "- search query got #{@ids.size} results; max seqno: #{self.max_seqno}"
|
300
317
|
clear_cached_message
|
301
318
|
res = fetch_row_text(fetch_ids)
|
302
|
-
|
319
|
+
if STDOUT.tty?
|
320
|
+
add_more_message_line(res, fetch_ids[0])
|
321
|
+
else
|
322
|
+
# non interactive mode
|
323
|
+
puts [@mailbox, res].join("\n")
|
324
|
+
end
|
325
|
+
rescue
|
326
|
+
log "ERROR:\n#{$!.inspect}\n#{$!.backtrace.join("\n")}"
|
303
327
|
end
|
304
328
|
|
305
329
|
def decrement_max_seqno(num)
|
330
|
+
return unless STDIN.tty?
|
306
331
|
log "Decremented max seqno from #{self.max_seqno} to #{self.max_seqno - num}"
|
307
332
|
self.max_seqno -= num
|
308
333
|
end
|
@@ -318,7 +343,7 @@ module Vmail
|
|
318
343
|
update_query[0] = "#{old_num_messages}:#{@num_messages}"
|
319
344
|
ids = reconnect_if_necessary {
|
320
345
|
log "search #update_query"
|
321
|
-
@imap.search(
|
346
|
+
@imap.search(Vmail::Query.args2string(update_query))
|
322
347
|
}
|
323
348
|
log "- got seqnos: #{ids.inspect}"
|
324
349
|
log "- getting seqnos > #{self.max_seqno}"
|
@@ -462,13 +487,13 @@ EOF
|
|
462
487
|
# id_set is a string comming from the vim client
|
463
488
|
# action is -FLAGS or +FLAGS
|
464
489
|
def flag(uid_set, action, flg)
|
490
|
+
log "flag #{uid_set} #{flg} #{action}"
|
465
491
|
uid_set = uid_set.split(',').map(&:to_i)
|
466
|
-
log "flag #{uid_set.inspect} #{flg} #{action}"
|
467
492
|
if flg == 'Deleted'
|
468
493
|
log "Deleting uid_set: #{uid_set.inspect}"
|
469
494
|
decrement_max_seqno(uid_set.size)
|
470
495
|
# for delete, do in a separate thread because deletions are slow
|
471
|
-
|
496
|
+
spawn_thread_if_tty do
|
472
497
|
unless @mailbox == '[Gmail]/Trash'
|
473
498
|
log "@imap.uid_copy #{uid_set.inspect} to trash"
|
474
499
|
log @imap.uid_copy(uid_set, "[Gmail]/Trash")
|
@@ -478,10 +503,10 @@ EOF
|
|
478
503
|
reload_mailbox
|
479
504
|
clear_cached_message
|
480
505
|
end
|
481
|
-
elsif flg == '[Gmail]/Spam'
|
506
|
+
elsif flg == 'spam' || flg == '[Gmail]/Spam'
|
482
507
|
log "Marking as spam uid_set: #{uid_set.inspect}"
|
483
508
|
decrement_max_seqno(uid_set.size)
|
484
|
-
|
509
|
+
spawn_thread_if_tty do
|
485
510
|
log "@imap.uid_copy #{uid_set.inspect} to spam"
|
486
511
|
log @imap.uid_copy(uid_set, "[Gmail]/Spam")
|
487
512
|
log "@imap.uid_store #{uid_set.inspect} #{action} [:Deleted]"
|
@@ -489,10 +514,9 @@ EOF
|
|
489
514
|
reload_mailbox
|
490
515
|
clear_cached_message
|
491
516
|
end
|
492
|
-
"#{id} deleted"
|
493
517
|
else
|
494
518
|
log "Flagging uid_set: #{uid_set.inspect}"
|
495
|
-
|
519
|
+
spawn_thread_if_tty do
|
496
520
|
log "@imap.uid_store #{uid_set.inspect} #{action} [#{flg.to_sym}]"
|
497
521
|
log @imap.uid_store(uid_set, action, [flg.to_sym])
|
498
522
|
end
|
@@ -511,7 +535,7 @@ EOF
|
|
511
535
|
end
|
512
536
|
create_if_necessary mailbox
|
513
537
|
log "moving uid_set: #{uid_set.inspect} to #{mailbox}"
|
514
|
-
|
538
|
+
spawn_thread_if_tty do
|
515
539
|
log @imap.uid_copy(uid_set, mailbox)
|
516
540
|
log @imap.uid_store(uid_set, '+FLAGS', [:Deleted])
|
517
541
|
reload_mailbox
|
@@ -527,12 +551,22 @@ EOF
|
|
527
551
|
end
|
528
552
|
create_if_necessary mailbox
|
529
553
|
log "copying #{uid_set.inspect} to #{mailbox}"
|
530
|
-
|
554
|
+
spawn_thread_if_tty do
|
531
555
|
log @imap.uid_copy(uid_set, mailbox)
|
532
556
|
log "copied uid_set #{uid_set.inspect} to #{mailbox}"
|
533
557
|
end
|
534
558
|
end
|
535
559
|
|
560
|
+
def spawn_thread_if_tty
|
561
|
+
if STDIN.tty?
|
562
|
+
Thread.new do
|
563
|
+
yield
|
564
|
+
end
|
565
|
+
else
|
566
|
+
yield
|
567
|
+
end
|
568
|
+
end
|
569
|
+
|
536
570
|
def create_if_necessary(mailbox)
|
537
571
|
current_mailboxes = mailboxes.map {|m| MailboxAliases[m] || m}
|
538
572
|
if !current_mailboxes.include?(mailbox)
|
@@ -544,7 +578,7 @@ EOF
|
|
544
578
|
end
|
545
579
|
end
|
546
580
|
|
547
|
-
def append_to_file(
|
581
|
+
def append_to_file(uid_set, file)
|
548
582
|
uid_set = uid_set.split(',').map(&:to_i)
|
549
583
|
log "append to file uid set #{uid_set.inspect} to file: #{file}"
|
550
584
|
uid_set.each do |uid|
|
data/lib/vmail/options.rb
CHANGED
@@ -48,9 +48,9 @@ module Vmail
|
|
48
48
|
begin
|
49
49
|
opts.parse!(argv)
|
50
50
|
if @config_file && File.exists?(@config_file)
|
51
|
-
puts "using config file: #{@config_file}"
|
51
|
+
STDERR.puts "using config file: #{@config_file}"
|
52
52
|
else
|
53
|
-
puts <<EOF
|
53
|
+
STDERR.puts <<EOF
|
54
54
|
|
55
55
|
Missing config file!
|
56
56
|
|
@@ -59,11 +59,13 @@ EOF
|
|
59
59
|
exit(1)
|
60
60
|
end
|
61
61
|
|
62
|
-
if
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
62
|
+
if STDOUT.tty?
|
63
|
+
if @contacts_file.nil?
|
64
|
+
STDERR.puts "No contacts file found for auto-completion. See help for how to generate it."
|
65
|
+
sleep 0.5
|
66
|
+
else
|
67
|
+
STDERR.puts "using contacts file: #{@contacts_file}"
|
68
|
+
end
|
67
69
|
end
|
68
70
|
|
69
71
|
@config = YAML::load(File.read(@config_file))
|
data/lib/vmail/query.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'shellwords'
|
2
|
+
module Vmail
|
3
|
+
class Query
|
4
|
+
# args is an array like ARGV
|
5
|
+
def self.parse(args)
|
6
|
+
if args.is_a?(String)
|
7
|
+
args = Shellwords.shellwords args
|
8
|
+
end
|
9
|
+
query = if args.empty?
|
10
|
+
[100, 'ALL']
|
11
|
+
elsif args.size == 1 && args[0] =~ /^\d+/
|
12
|
+
[args.shift, "ALL"]
|
13
|
+
elsif args[0] =~ /^\d+/
|
14
|
+
args
|
15
|
+
else
|
16
|
+
[100] + args
|
17
|
+
end
|
18
|
+
query
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.args2string(array)
|
22
|
+
array.map {|x|
|
23
|
+
x.to_s.split(/\s+/).size > 1 ? "\"#{x}\"" : x.to_s
|
24
|
+
}.join(' ')
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
data/lib/vmail/version.rb
CHANGED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
version: 1.2.
|
8
|
+
- 4
|
9
|
+
version: 1.2.4
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Daniel Choi
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-01-
|
17
|
+
date: 2011-01-08 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -73,6 +73,7 @@ files:
|
|
73
73
|
- lib/vmail/imap_client.rb
|
74
74
|
- lib/vmail/message_formatter.rb
|
75
75
|
- lib/vmail/options.rb
|
76
|
+
- lib/vmail/query.rb
|
76
77
|
- lib/vmail/reply_template.rb
|
77
78
|
- lib/vmail/send_options.rb
|
78
79
|
- lib/vmail/sender.rb
|