vmail 1.2.3 → 1.2.4
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/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
|