vmail 0.4.4 → 0.4.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +0 -18
- data/Rakefile +0 -5
- data/bin/vmail +0 -0
- data/bin/vmail_client +0 -0
- data/lib/vmail.vim +2 -3
- data/lib/vmail/imap_client.rb +119 -175
- data/lib/vmail/version.rb +1 -1
- data/website/vmail-template.html +4 -4
- metadata +2 -2
data/README.markdown
CHANGED
@@ -63,8 +63,6 @@ You can omit the password key-value pair if you'd rather not have the password
|
|
63
63
|
saved in the file. In that case, you'll prompted for the password each time you
|
64
64
|
start vmail.
|
65
65
|
|
66
|
-
|
67
|
-
|
68
66
|
## Contacts autocompletion
|
69
67
|
|
70
68
|
vmail uses Vim autocompletion to help you auto-complete email addresses.
|
@@ -400,22 +398,6 @@ vmail gem is downloaded from).
|
|
400
398
|
[github]:https://github.com/danchoi/vmail
|
401
399
|
[rubygems]:https://rubygems.org/gems/vmail
|
402
400
|
|
403
|
-
## Additional configuration options
|
404
|
-
|
405
|
-
The default IMAP server vmail uses is 'imap.gmail.com` and the default port is
|
406
|
-
`993`. If you want to change these values, e.g, because you are behind a
|
407
|
-
firewall which blocks IMAP, you can change these values by specifying new ones
|
408
|
-
in your .vmailrc, like so:
|
409
|
-
|
410
|
-
server: localhost
|
411
|
-
port: 2999
|
412
|
-
|
413
|
-
Then you can create an SSH tunnel, e.g.
|
414
|
-
|
415
|
-
ssh -f user@example.com -L 2999:imap.gmail.com:993 -N
|
416
|
-
|
417
|
-
(Thanks to Dave Bolton for this patch.)
|
418
|
-
|
419
401
|
## Bug reports, feature requests
|
420
402
|
|
421
403
|
Please file bug reports and feature requests in the [vmail github issue tracker][tracker].
|
data/Rakefile
CHANGED
data/bin/vmail
CHANGED
File without changes
|
data/bin/vmail_client
CHANGED
File without changes
|
data/lib/vmail.vim
CHANGED
@@ -453,7 +453,6 @@ function! s:select_mailbox()
|
|
453
453
|
return
|
454
454
|
endif
|
455
455
|
let s:mailbox = mailbox
|
456
|
-
let s:query = "100 all"
|
457
456
|
let command = s:select_mailbox_command . shellescape(s:mailbox)
|
458
457
|
call system(command)
|
459
458
|
redraw
|
@@ -691,9 +690,9 @@ func! s:message_window_mappings()
|
|
691
690
|
nnoremap <silent> <buffer> q :close<cr>
|
692
691
|
|
693
692
|
nnoremap <silent> <buffer> <leader># :close<cr>:call <SID>focus_list_window()<cr>:call <SID>delete_messages("Deleted")<cr>
|
693
|
+
nmap <silent> <buffer> <leader>d <leader>#
|
694
694
|
nnoremap <silent> <buffer> <leader>* :call <SID>focus_list_window()<cr>:call <SID>toggle_star()<cr>
|
695
|
-
|
696
|
-
noremap <silent> <buffer> <leader>e :call <SID>focus_list_window()<cr>:call <SID>archive_messages()<CR>
|
695
|
+
nmap <silent> <buffer> s <leader>*
|
697
696
|
|
698
697
|
nnoremap <silent> <buffer> <Leader>b :call <SID>focus_list_window()<cr>call <SID>move_to_mailbox(0)<CR>
|
699
698
|
nnoremap <silent> <buffer> <Leader>B :call <SID>focus_list_window()<cr>call <SID>move_to_mailbox(1)<CR>
|
data/lib/vmail/imap_client.rb
CHANGED
@@ -27,13 +27,11 @@ module Vmail
|
|
27
27
|
@logger = Logger.new(config['logfile'] || STDERR)
|
28
28
|
@logger.level = Logger::DEBUG
|
29
29
|
@current_mail = nil
|
30
|
-
@
|
31
|
-
@imap_server = config['server'] || 'imap.gmail.com'
|
32
|
-
@imap_port = config['port'] || 993
|
30
|
+
@current_uid = nil
|
33
31
|
end
|
34
32
|
|
35
33
|
def open
|
36
|
-
@imap = Net::IMAP.new(
|
34
|
+
@imap = Net::IMAP.new('imap.gmail.com', 993, true, nil, false)
|
37
35
|
@imap.login(@username, @password)
|
38
36
|
end
|
39
37
|
|
@@ -43,11 +41,11 @@ module Vmail
|
|
43
41
|
@imap.disconnect
|
44
42
|
end
|
45
43
|
|
46
|
-
def select_mailbox(mailbox
|
44
|
+
def select_mailbox(mailbox)
|
47
45
|
if MailboxAliases[mailbox]
|
48
46
|
mailbox = MailboxAliases[mailbox]
|
49
47
|
end
|
50
|
-
if mailbox == @mailbox
|
48
|
+
if mailbox == @mailbox
|
51
49
|
return
|
52
50
|
end
|
53
51
|
log "selecting mailbox #{mailbox.inspect}"
|
@@ -55,23 +53,11 @@ module Vmail
|
|
55
53
|
log @imap.select(mailbox)
|
56
54
|
end
|
57
55
|
@mailbox = mailbox
|
58
|
-
|
59
|
-
|
56
|
+
@all_uids = []
|
57
|
+
@bad_uids = []
|
60
58
|
return "OK"
|
61
59
|
end
|
62
60
|
|
63
|
-
def get_highest_message_id
|
64
|
-
# get highest message ID
|
65
|
-
res = @imap.fetch([1,"*"], ["ENVELOPE"])
|
66
|
-
@num_messages = res[-1].seqno
|
67
|
-
log "HIGHEST ID: #@num_messages"
|
68
|
-
end
|
69
|
-
|
70
|
-
def get_mailbox_status
|
71
|
-
@status = @imap.status(@mailbox, ["MESSAGES", "RECENT", "UNSEEN"])
|
72
|
-
log "mailbox status: #{@status.inspect}"
|
73
|
-
end
|
74
|
-
|
75
61
|
def revive_connection
|
76
62
|
log "reviving connection"
|
77
63
|
open
|
@@ -79,18 +65,6 @@ module Vmail
|
|
79
65
|
@imap.select(@mailbox)
|
80
66
|
end
|
81
67
|
|
82
|
-
def prime_connection
|
83
|
-
reconnect_if_necessary(4) do
|
84
|
-
# this is just to prime the IMAP connection
|
85
|
-
# It's necessary for some reason before update and deliver.
|
86
|
-
log "priming connection for delivering"
|
87
|
-
res = @imap.fetch(@ids[-1], ["ENVELOPE"])
|
88
|
-
if res.nil?
|
89
|
-
raise IOError, "IMAP connection seems broken"
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
68
|
def list_mailboxes
|
95
69
|
@mailboxes ||= (@imap.list("[Gmail]/", "%") + @imap.list("", "%")).
|
96
70
|
select {|struct| struct.attr.none? {|a| a == :Noselect} }.
|
@@ -109,19 +83,20 @@ module Vmail
|
|
109
83
|
@mailboxes
|
110
84
|
end
|
111
85
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
86
|
+
def fetch_headers(uid_set)
|
87
|
+
if uid_set.is_a?(String)
|
88
|
+
uid_set = uid_set.split(",").map(&:to_i)
|
89
|
+
elsif uid_set.is_a?(Integer)
|
90
|
+
uid_set = [uid_set]
|
117
91
|
end
|
118
|
-
|
119
|
-
|
92
|
+
max_uid = uid_set.max
|
93
|
+
log "fetch headers for #{uid_set.inspect}"
|
94
|
+
if uid_set.empty?
|
120
95
|
log "empty set"
|
121
96
|
return ""
|
122
97
|
end
|
123
98
|
results = reconnect_if_necessary do
|
124
|
-
@imap.
|
99
|
+
@imap.uid_fetch(uid_set, ["FLAGS", "ENVELOPE", "RFC822.SIZE" ])
|
125
100
|
end
|
126
101
|
log "extracting headers"
|
127
102
|
lines = results.
|
@@ -132,13 +107,13 @@ module Vmail
|
|
132
107
|
Time.now
|
133
108
|
end
|
134
109
|
}.
|
135
|
-
map {|x|
|
110
|
+
map {|x| format_header(x, max_uid)}
|
136
111
|
log "returning result"
|
137
112
|
return lines.join("\n")
|
138
113
|
end
|
139
114
|
|
140
|
-
def
|
141
|
-
|
115
|
+
def format_header(fetch_data, max_uid=nil)
|
116
|
+
uid = fetch_data.attr["UID"]
|
142
117
|
envelope = fetch_data.attr["ENVELOPE"]
|
143
118
|
size = fetch_data.attr["RFC822.SIZE"]
|
144
119
|
flags = fetch_data.attr["FLAGS"]
|
@@ -173,18 +148,18 @@ module Vmail
|
|
173
148
|
subject = envelope.subject || ''
|
174
149
|
subject = Mail::Encodings.unquote_and_convert_to(subject, 'UTF-8')
|
175
150
|
flags = format_flags(flags)
|
176
|
-
first_col_width =
|
151
|
+
first_col_width = max_uid.to_s.length
|
177
152
|
mid_width = @width - (first_col_width + 33)
|
178
153
|
address_col_width = (mid_width * 0.3).ceil
|
179
154
|
subject_col_width = (mid_width * 0.7).floor
|
180
|
-
[
|
155
|
+
[uid.to_s.col(first_col_width),
|
181
156
|
(date_formatted || '').col(14),
|
182
157
|
address.col(address_col_width),
|
183
158
|
subject.col(subject_col_width),
|
184
159
|
number_to_human_size(size).rcol(6),
|
185
160
|
flags.rcol(7)].join(' ')
|
186
161
|
rescue
|
187
|
-
"#{
|
162
|
+
"#{uid.to_s} : error extracting this header"
|
188
163
|
end
|
189
164
|
|
190
165
|
UNITS = [:b, :kb, :mb, :gb].freeze
|
@@ -214,119 +189,83 @@ module Vmail
|
|
214
189
|
end
|
215
190
|
|
216
191
|
def search(limit, *query)
|
217
|
-
limit
|
218
|
-
limit =
|
192
|
+
log "uid_search limit: #{limit} query: #{@query.inspect}"
|
193
|
+
limit = 25 if limit.to_s !~ /^\d+$/
|
219
194
|
query = ['ALL'] if query.empty?
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
@
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
@all_search = false
|
229
|
-
end
|
230
|
-
log "@all_search #{@all_search}"
|
231
|
-
@query = query
|
232
|
-
log "search query: #@query.inspect"
|
233
|
-
@ids = reconnect_if_necessary do
|
234
|
-
@imap.search(@query.join(' '))
|
235
|
-
end
|
236
|
-
# save ids in @ids, because filtered search relies on it
|
237
|
-
fetch_ids = if @all_search
|
238
|
-
@ids
|
239
|
-
else #filtered search
|
240
|
-
@start_index = [@ids.length - limit, 0].max
|
241
|
-
@ids[@start_index..-1]
|
242
|
-
end
|
243
|
-
log "search query got #{@ids.size} results"
|
244
|
-
res = fetch_envelopes(fetch_ids)
|
245
|
-
add_more_message_line(res, fetch_ids[0])
|
195
|
+
@query = query.join(' ')
|
196
|
+
log "uid_search #@query #{limit}"
|
197
|
+
@all_uids = reconnect_if_necessary do
|
198
|
+
@imap.uid_search(@query)
|
199
|
+
end
|
200
|
+
uids = @all_uids[-([limit.to_i, @all_uids.size].min)..-1] || []
|
201
|
+
res = fetch_headers(uids)
|
202
|
+
add_more_message_line(res, uids)
|
246
203
|
end
|
247
204
|
|
248
205
|
def update
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
206
|
+
reconnect_if_necessary(4) do
|
207
|
+
# this is just to prime the IMAP connection
|
208
|
+
# It's necessary for some reason.
|
209
|
+
log "priming connection for update"
|
210
|
+
res = @imap.uid_fetch(@all_uids[-1], ["ENVELOPE"])
|
211
|
+
if res.nil?
|
212
|
+
raise IOError, "IMAP connection seems broken"
|
213
|
+
end
|
214
|
+
end
|
215
|
+
uids = reconnect_if_necessary {
|
216
|
+
log "uid_search #@query"
|
217
|
+
@imap.uid_search(@query)
|
259
218
|
}
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
res = fetch_envelopes(new_ids)
|
219
|
+
new_uids = uids - @all_uids
|
220
|
+
log "UPDATE: NEW UIDS: #{new_uids.inspect}"
|
221
|
+
if !new_uids.empty?
|
222
|
+
res = fetch_headers(new_uids)
|
223
|
+
@all_uids = uids
|
266
224
|
res
|
267
225
|
end
|
268
226
|
end
|
269
227
|
|
270
|
-
# gets 100 messages prior to
|
271
|
-
def more_messages(
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
res =
|
286
|
-
add_more_message_line(res, @ids[x])
|
287
|
-
end
|
288
|
-
end
|
289
|
-
|
290
|
-
def add_more_message_line(res, start_id)
|
291
|
-
log "add_more_message_line for start_id #{start_id}"
|
292
|
-
if @all_search
|
293
|
-
return res if start_id.nil?
|
294
|
-
if start_id <= 1
|
295
|
-
return res
|
296
|
-
end
|
297
|
-
remaining = start_id - 1
|
298
|
-
else # filter search
|
299
|
-
remaining = @ids.index(start_id) - 1
|
300
|
-
end
|
301
|
-
if remaining < 1
|
302
|
-
log "none remaining"
|
303
|
-
return res
|
228
|
+
# gets 100 messages prior to uid
|
229
|
+
def more_messages(uid, limit=100)
|
230
|
+
uid = uid.to_i
|
231
|
+
x = [(@all_uids.index(uid) - limit), 0].max
|
232
|
+
y = [@all_uids.index(uid) - 1, 0].max
|
233
|
+
uids = @all_uids[x..y]
|
234
|
+
res = fetch_headers(uids)
|
235
|
+
add_more_message_line(res, uids)
|
236
|
+
end
|
237
|
+
|
238
|
+
def add_more_message_line(res, uids)
|
239
|
+
return res if uids.empty?
|
240
|
+
start_index = @all_uids.index(uids[0])
|
241
|
+
if start_index > 0
|
242
|
+
remaining = start_index
|
243
|
+
res = "> Load #{[100, remaining].min} more messages. #{remaining} remaining.\n" + res
|
304
244
|
end
|
305
|
-
|
306
|
-
"> Load #{[100, remaining].min} more messages. #{remaining} remaining.\n" + res
|
245
|
+
res
|
307
246
|
end
|
308
247
|
|
309
|
-
def show_message(
|
310
|
-
|
248
|
+
def show_message(uid, raw=false, forwarded=false)
|
249
|
+
uid = uid.to_i
|
311
250
|
if forwarded
|
312
251
|
return @current_message.split(/\n-{20,}\n/, 2)[1]
|
313
252
|
end
|
314
253
|
return @current_mail.to_s if raw
|
315
|
-
return @current_message if
|
316
|
-
log "fetching #{
|
254
|
+
return @current_message if uid == @current_uid
|
255
|
+
log "fetching #{uid.inspect}"
|
317
256
|
fetch_data = reconnect_if_necessary do
|
318
|
-
@imap.
|
257
|
+
@imap.uid_fetch(uid, ["FLAGS", "RFC822", "RFC822.SIZE"])[0]
|
319
258
|
end
|
320
259
|
res = fetch_data.attr["RFC822"]
|
321
260
|
mail = Mail.new(res)
|
322
|
-
@
|
261
|
+
@current_uid = uid
|
323
262
|
@current_mail = mail # used later to show raw message or extract attachments if any
|
324
263
|
log "saving current mail with parts: #{@current_mail.parts.inspect}"
|
325
264
|
formatter = Vmail::MessageFormatter.new(mail)
|
326
265
|
out = formatter.process_body
|
327
266
|
size = fetch_data.attr["RFC822.SIZE"]
|
328
267
|
@current_message = <<-EOF
|
329
|
-
#{@mailbox} #{
|
268
|
+
#{@mailbox} #{uid} #{number_to_human_size size} #{format_parts_info(formatter.list_parts)}
|
330
269
|
---------------------------------------
|
331
270
|
#{format_headers(formatter.extract_headers)}
|
332
271
|
|
@@ -344,36 +283,36 @@ EOF
|
|
344
283
|
end
|
345
284
|
end
|
346
285
|
|
347
|
-
#
|
286
|
+
# uid_set is a string comming from the vim client
|
348
287
|
# action is -FLAGS or +FLAGS
|
349
|
-
def flag(
|
350
|
-
if
|
351
|
-
|
288
|
+
def flag(uid_set, action, flg)
|
289
|
+
if uid_set.is_a?(String)
|
290
|
+
uid_set = uid_set.split(",").map(&:to_i)
|
352
291
|
end
|
353
292
|
# #<struct Net::IMAP::FetchData seqno=17423, attr={"FLAGS"=>[:Seen, "Flagged"], "UID"=>83113}>
|
354
|
-
log "flag #{
|
293
|
+
log "flag #{uid_set} #{flg} #{action}"
|
355
294
|
if flg == 'Deleted'
|
356
295
|
# for delete, do in a separate thread because deletions are slow
|
357
296
|
Thread.new do
|
358
297
|
unless @mailbox == '[Gmail]/Trash'
|
359
|
-
@imap.
|
298
|
+
@imap.uid_copy(uid_set, "[Gmail]/Trash")
|
360
299
|
end
|
361
|
-
res = @imap.
|
300
|
+
res = @imap.uid_store(uid_set, action, [flg.to_sym])
|
362
301
|
end
|
363
|
-
|
302
|
+
uid_set.each { |uid| @all_uids.delete(uid) }
|
364
303
|
elsif flg == '[Gmail]/Spam'
|
365
|
-
@imap.
|
366
|
-
res = @imap.
|
367
|
-
"#{
|
304
|
+
@imap.uid_copy(uid_set, "[Gmail]/Spam")
|
305
|
+
res = @imap.uid_store(uid_set, action, [:Deleted])
|
306
|
+
"#{uid} deleted"
|
368
307
|
else
|
369
308
|
log "Flagging"
|
370
|
-
res = @imap.
|
309
|
+
res = @imap.uid_store(uid_set, action, [flg.to_sym])
|
371
310
|
# log res.inspect
|
372
|
-
|
311
|
+
fetch_headers(uid_set)
|
373
312
|
end
|
374
313
|
end
|
375
314
|
|
376
|
-
def move_to(
|
315
|
+
def move_to(uid_set, mailbox)
|
377
316
|
if mailbox == 'all'
|
378
317
|
log "archiving messages"
|
379
318
|
end
|
@@ -381,24 +320,24 @@ EOF
|
|
381
320
|
mailbox = MailboxAliases[mailbox]
|
382
321
|
end
|
383
322
|
create_if_necessary mailbox
|
384
|
-
if
|
385
|
-
|
323
|
+
if uid_set.is_a?(String)
|
324
|
+
uid_set = uid_set.split(",").map(&:to_i)
|
386
325
|
end
|
387
|
-
log "move_to #{
|
388
|
-
log @imap.
|
389
|
-
log @imap.
|
326
|
+
log "move_to #{uid_set.inspect} #{mailbox}"
|
327
|
+
log @imap.uid_copy(uid_set, mailbox)
|
328
|
+
log @imap.uid_store(uid_set, '+FLAGS', [:Deleted])
|
390
329
|
end
|
391
330
|
|
392
|
-
def copy_to(
|
331
|
+
def copy_to(uid_set, mailbox)
|
393
332
|
if MailboxAliases[mailbox]
|
394
333
|
mailbox = MailboxAliases[mailbox]
|
395
334
|
end
|
396
335
|
create_if_necessary mailbox
|
397
|
-
log "copy #{
|
398
|
-
if
|
399
|
-
|
336
|
+
log "copy #{uid_set.inspect} #{mailbox}"
|
337
|
+
if uid_set.is_a?(String)
|
338
|
+
uid_set = uid_set.split(",").map(&:to_i)
|
400
339
|
end
|
401
|
-
log @imap.
|
340
|
+
log @imap.uid_copy(uid_set, mailbox)
|
402
341
|
end
|
403
342
|
|
404
343
|
def create_if_necessary(mailbox)
|
@@ -411,18 +350,18 @@ EOF
|
|
411
350
|
end
|
412
351
|
end
|
413
352
|
|
414
|
-
def append_to_file(file,
|
415
|
-
if
|
416
|
-
|
353
|
+
def append_to_file(file, uid_set)
|
354
|
+
if uid_set.is_a?(String)
|
355
|
+
uid_set = uid_set.split(",").map(&:to_i)
|
417
356
|
end
|
418
357
|
log "append messages to file: #{file}"
|
419
|
-
|
420
|
-
message = show_message(
|
358
|
+
uid_set.each do |uid|
|
359
|
+
message = show_message(uid)
|
421
360
|
divider = "#{'=' * 39}\n"
|
422
361
|
File.open(file, 'a') {|f| f.puts(divider + message + "\n\n")}
|
423
|
-
log "appended
|
362
|
+
log "appended uid #{uid}"
|
424
363
|
end
|
425
|
-
"printed #{
|
364
|
+
"printed #{uid_set.size} message#{uid_set.size == 1 ? '' : 's'} to #{file.strip}"
|
426
365
|
end
|
427
366
|
|
428
367
|
|
@@ -445,9 +384,9 @@ EOF
|
|
445
384
|
lines.join("\n")
|
446
385
|
end
|
447
386
|
|
448
|
-
def reply_template(
|
449
|
-
log "sending reply template for #{
|
450
|
-
fetch_data = @imap.
|
387
|
+
def reply_template(uid, replyall=false)
|
388
|
+
log "sending reply template for #{uid}"
|
389
|
+
fetch_data = @imap.uid_fetch(uid.to_i, ["FLAGS", "ENVELOPE", "RFC822"])[0]
|
451
390
|
envelope = fetch_data.attr['ENVELOPE']
|
452
391
|
recipient = [envelope.reply_to, envelope.from].flatten.map {|x| address_to_string(x)}[0]
|
453
392
|
cc = [envelope.to, envelope.cc]
|
@@ -478,8 +417,8 @@ EOF
|
|
478
417
|
"\n\n#@signature"
|
479
418
|
end
|
480
419
|
|
481
|
-
def forward_template(
|
482
|
-
original_body = show_message(
|
420
|
+
def forward_template(uid)
|
421
|
+
original_body = show_message(uid, false, true)
|
483
422
|
new_message_template +
|
484
423
|
"\n---------- Forwarded message ----------\n" +
|
485
424
|
original_body + signature
|
@@ -488,7 +427,15 @@ EOF
|
|
488
427
|
def deliver(text)
|
489
428
|
# parse the text. The headers are yaml. The rest is text body.
|
490
429
|
require 'net/smtp'
|
491
|
-
|
430
|
+
reconnect_if_necessary(4) do
|
431
|
+
# this is just to prime the IMAP connection
|
432
|
+
# It's necessary for some reason.
|
433
|
+
log "priming connection for delivering"
|
434
|
+
res = @imap.uid_fetch(@all_uids[-1], ["ENVELOPE"])
|
435
|
+
if res.nil?
|
436
|
+
raise IOError, "IMAP connection seems broken"
|
437
|
+
end
|
438
|
+
end
|
492
439
|
mail = new_mail_from_input(text)
|
493
440
|
mail.delivery_method(*smtp_settings)
|
494
441
|
log mail.deliver!
|
@@ -571,8 +518,8 @@ EOF
|
|
571
518
|
"saved:\n" + saved.map {|x| "- #{x}"}.join("\n")
|
572
519
|
end
|
573
520
|
|
574
|
-
def open_html_part(
|
575
|
-
log "open_html_part #{
|
521
|
+
def open_html_part(uid)
|
522
|
+
log "open_html_part #{uid}"
|
576
523
|
log @current_mail.parts.inspect
|
577
524
|
multipart = @current_mail.parts.detect {|part| part.multipart?}
|
578
525
|
html_part = if multipart
|
@@ -624,9 +571,6 @@ EOF
|
|
624
571
|
log(revive_connection)
|
625
572
|
# try just once
|
626
573
|
block.call
|
627
|
-
rescue
|
628
|
-
log "error: #{$!}"
|
629
|
-
raise
|
630
574
|
end
|
631
575
|
|
632
576
|
def self.start(config)
|
data/lib/vmail/version.rb
CHANGED
data/website/vmail-template.html
CHANGED
@@ -23,6 +23,10 @@
|
|
23
23
|
|
24
24
|
<div class="sidebar">
|
25
25
|
|
26
|
+
<h4>share this</h4>
|
27
|
+
|
28
|
+
<span class="st_twitter_large" displayText="Tweet"></span><span class="st_facebook_large" displayText="Facebook"></span><span class="st_ybuzz_large" displayText="Yahoo! Buzz"></span><span class="st_gbuzz_large" displayText="Google Buzz"></span><span class="st_email_large" displayText="Email"></span><span class="st_sharethis_large" displayText="ShareThis"></span>
|
29
|
+
|
26
30
|
<h4>links</h4>
|
27
31
|
<ul>
|
28
32
|
<li><a href="https://github.com/danchoi/vmail">github repo</a></li>
|
@@ -30,10 +34,6 @@
|
|
30
34
|
<li><a href="https://github.com/danchoi/vmail/issues">issue tracker</a></li>
|
31
35
|
<li><a href="http://www.google.com/search?sourceid=chrome&ie=UTF-8&q=vmail+vim#hl=en&tbo=1&tbs=mbl:1,mbl_sv:0&q=link:http://danielchoi.com/software/vmail.html&sa=X&ei=iw0JTYnsPMT_lgfgvMC1AQ&ved=0CAUQ6QcwCg&fp=1&cad=b">web reactions</a></li>
|
32
36
|
</ul>
|
33
|
-
<h4>share this</h4>
|
34
|
-
|
35
|
-
<span class="st_twitter_large" displayText="Tweet"></span><span class="st_facebook_large" displayText="Facebook"></span><span class="st_ybuzz_large" displayText="Yahoo! Buzz"></span><span class="st_gbuzz_large" displayText="Google Buzz"></span><span class="st_email_large" displayText="Email"></span><span class="st_sharethis_large" displayText="ShareThis"></span>
|
36
|
-
|
37
37
|
</div>
|
38
38
|
|
39
39
|
</div>
|