vmail 0.4.4 → 0.4.5
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 +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>
|