vmail 2.8.7 → 2.8.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -17,7 +17,7 @@ module Vmail
17
17
  end
18
18
 
19
19
  vim = ENV['VMAIL_VIM'] || 'vim'
20
- ENV['VMAIL_BROWSER'] ||= if RUBY_PLATFORM.downcase.include?('linux')
20
+ ENV['VMAIL_BROWSER'] ||= if RUBY_PLATFORM.downcase.include?('linux')
21
21
  tools = ['gnome-open', 'kfmclient-exec', 'xdg-open', 'konqueror']
22
22
  tool = tools.detect { |tool|
23
23
  `which #{tool}`.size > 0
@@ -65,9 +65,9 @@ module Vmail
65
65
  # require after the working dir is set
66
66
  require 'vmail/imap_client'
67
67
 
68
- drb_uri = begin
68
+ drb_uri = begin
69
69
  Vmail::ImapClient.daemon config
70
- rescue
70
+ rescue
71
71
  puts "Failure:", $!
72
72
  exit(1)
73
73
  end
@@ -79,14 +79,16 @@ module Vmail
79
79
  server.select_mailbox mailbox
80
80
 
81
81
  STDERR.puts "Mailbox: #{mailbox}"
82
- STDERR.puts "Query: #{query.inspect}"
82
+ STDERR.puts "Query: #{query.inspect}"
83
83
  STDERR.puts "Query String: #{String.shellescape(query_string)}"
84
-
84
+
85
85
  buffer_file = "vmailbuffer"
86
86
  # invoke vim
87
87
  vimscript = File.expand_path("../vmail.vim", __FILE__)
88
88
  vimopts = config['vim_opts']
89
- vim_command = "DRB_URI=#{drb_uri} VMAIL_CONTACTS_FILE=#{contacts_file} VMAIL_MAILBOX=#{String.shellescape(mailbox)} VMAIL_QUERY=\"#{query_string}\" #{vim} -S #{vimscript} -c '#{vimopts}' #{buffer_file}"
89
+ $drb_uri = drb_uri
90
+ server_name = "VMAIL:#{ config['username'] }"
91
+ vim_command = "DRB_URI=#{drb_uri} VMAIL_CONTACTS_FILE=#{contacts_file} VMAIL_MAILBOX=#{String.shellescape(mailbox)} VMAIL_QUERY=\"#{query_string}\" #{vim} --servername #{ server_name } -S #{vimscript} -c '#{vimopts}' #{buffer_file}"
90
92
  STDERR.puts vim_command
91
93
  STDERR.puts "Using buffer file: #{buffer_file}"
92
94
  File.open(buffer_file, "w") do |file|
@@ -102,9 +104,9 @@ module Vmail
102
104
 
103
105
  File.delete(buffer_file)
104
106
 
105
- STDERR.puts "Closing imap connection"
107
+ STDERR.puts "Closing imap connection"
106
108
  begin
107
- Timeout::timeout(10) do
109
+ Timeout::timeout(10) do
108
110
  $gmail.close
109
111
  end
110
112
  rescue Timeout::Error
@@ -129,10 +131,10 @@ module Vmail
129
131
  end
130
132
 
131
133
  def parse_query
132
- if ARGV[0] =~ /^\d+/
134
+ if ARGV[0] =~ /^\d+/
133
135
  ARGV.shift
134
136
  end
135
- mailbox = ARGV.shift || 'INBOX'
137
+ mailbox = ARGV.shift || 'INBOX'
136
138
  query = Vmail::Query.parse(ARGV)
137
139
  [mailbox, query]
138
140
  end
@@ -282,7 +282,7 @@ function! s:mark_as_read_unread(read) range
282
282
  setlocal nomodifiable
283
283
  write
284
284
  redraw
285
- echom nummsgs ." conversation(s) have been marked as unread."
285
+ echom nummsgs ." conversation(s) have been marked as " . (a:read ? "read" : "unread") . "."
286
286
  endfunction
287
287
 
288
288
  function! s:toggle_star() range
@@ -684,6 +684,42 @@ function! s:send_message()
684
684
  redraw
685
685
  endfunction
686
686
 
687
+ " --------------------------------------------------------------------------------
688
+ " Update message list with new emails.
689
+
690
+ func! UPDATE_MESSAGE_LIST(filename)
691
+ if s:mailbox == 'INBOX'
692
+ if bufnr('%') == s:listbufnr
693
+ call s:update_and_redraw_message_list(a:filename)
694
+
695
+ " If current_message is open with message list in another split.
696
+ elseif bufname('%') == s:message_bufname && index(tabpagebuflist(), s:listbufnr) >= 0
697
+ let message_bufnr = bufnr('%')
698
+
699
+ " Switch to message list window and update it.
700
+ while bufnr('%') != s:listbufnr | wincmd w | endwhile
701
+ call s:update_and_redraw_message_list(a:filename)
702
+
703
+ while bufnr('%') != message_bufnr | wincmd w | endwhile
704
+ else
705
+ call s:update_message_list(a:filename)
706
+ endif
707
+ endif
708
+ endfunc
709
+
710
+ func! s:update_and_redraw_message_list(filename)
711
+ call s:update_message_list(a:filename)
712
+ edit!
713
+ redraw!
714
+ endfunc
715
+
716
+ func! s:update_message_list(filename)
717
+ let newer_contents = readfile(a:filename)
718
+ let older_contents = readfile(s:listbufname)
719
+ let updated_contents = extend(newer_contents, older_contents)
720
+ call writefile(updated_contents, s:listbufname)
721
+ endfunc
722
+
687
723
  " --------------------------------------------------------------------------------
688
724
 
689
725
  " call from inside message window with <Leader>h
@@ -16,17 +16,17 @@ module Vmail
16
16
  savebin = part + ", "
17
17
  end
18
18
  end
19
-
19
+
20
20
  #Quote the names
21
- addrs.map { |addr|
21
+ addrs.map { |addr|
22
22
  # a little hackish
23
23
  if addr =~ /"/
24
24
  addr
25
25
  else
26
- addr.gsub(/^(.*) (<.*)/, '"\1" \2')
26
+ addr.gsub(/^(.*) (<.*)/, '"\1" \2')
27
27
  end
28
28
  }.join(', ')
29
29
  end
30
-
30
+
31
31
  end
32
32
  end
@@ -11,7 +11,7 @@ class ContactsExtractor
11
11
  @imap = Net::IMAP.new('imap.gmail.com', 993, true, nil, false)
12
12
  puts @imap.login(@username, @password)
13
13
  yield @imap
14
- @imap.close
14
+ @imap.close
15
15
  @imap.disconnect
16
16
  end
17
17
 
@@ -31,10 +31,10 @@ class ContactsExtractor
31
31
  recipients = fetch_data.attr["ENVELOPE"].to
32
32
  next unless recipients
33
33
  recipients.each do |address_struct|
34
- email = [address_struct.mailbox, address_struct.host].join('@')
34
+ email = [address_struct.mailbox, address_struct.host].join('@')
35
35
  name = address_struct.name
36
- if name
37
- name = Mail::Encodings.unquote_and_convert_to(name, 'UTF-8')
36
+ if name
37
+ name = Mail::Encodings.unquote_and_convert_to(name, 'UTF-8')
38
38
  yield %Q("#{name}" <#{email}>)
39
39
  else
40
40
  yield email
@@ -46,7 +46,7 @@ class ContactsExtractor
46
46
 
47
47
  def set_mailbox_prefix
48
48
  mailboxes = ((@imap.list("[#@prefix]/", "%") || []) + (@imap.list("", "*")) || []).map {|struct| struct.name}
49
- @prefix = mailboxes.detect {|m| m =~ /^\[Google Mail\]/} ? "Google Mail" : "Gmail"
49
+ @prefix = mailboxes.detect {|m| m =~ /^\[Google Mail\]/} ? "Google Mail" : "Gmail"
50
50
  end
51
51
  end
52
52
  end
@@ -5,8 +5,8 @@ require 'sequel'
5
5
  CREATE_TABLE_SCRIPT = File.expand_path("../../../db/create.sql", __FILE__)
6
6
  print "Checking vmail.db version... "
7
7
  db = Sequel.connect 'sqlite://vmail.db'
8
- if db.tables.include?(:version) &&
9
- (r = db[:version].first) &&
8
+ if db.tables.include?(:version) &&
9
+ (r = db[:version].first) &&
10
10
  r[:vmail_version] != Vmail::VERSION
11
11
 
12
12
  print "Vmail database version is outdated. Recreating.\n"
@@ -17,7 +17,7 @@ module Vmail
17
17
  log "Deleting uid_set: #{uid_set.inspect}"
18
18
  decrement_max_seqno(uid_set.size)
19
19
  # for delete, do in a separate thread because deletions are slow
20
- spawn_thread_if_tty do
20
+ spawn_thread_if_tty do
21
21
  unless @mailbox == mailbox_aliases['trash']
22
22
  log "imap.uid_copy #{uid_set.inspect} to #{mailbox_aliases['trash']}"
23
23
  log @imap.uid_copy(uid_set, mailbox_aliases['trash'])
@@ -27,12 +27,12 @@ module Vmail
27
27
  reload_mailbox
28
28
  clear_cached_message
29
29
  end
30
- elsif flg == 'spam' || flg == mailbox_aliases['spam']
30
+ elsif flg == 'spam' || flg == mailbox_aliases['spam']
31
31
  log "Marking as spam uid_set: #{uid_set.inspect}"
32
32
  decrement_max_seqno(uid_set.size)
33
- spawn_thread_if_tty do
33
+ spawn_thread_if_tty do
34
34
  log "imap.uid_copy #{uid_set.inspect} to #{mailbox_aliases['spam']}"
35
- log @imap.uid_copy(uid_set, mailbox_aliases['spam'])
35
+ log @imap.uid_copy(uid_set, mailbox_aliases['spam'])
36
36
  log "imap.uid_store #{uid_set.inspect} #{action} [:Deleted]"
37
37
  log @imap.uid_store(uid_set, action, [:Deleted])
38
38
  reload_mailbox
@@ -61,7 +61,7 @@ module Vmail
61
61
  end
62
62
  create_if_necessary mailbox
63
63
  log "Moving uid_set: #{uid_set.inspect} to #{mailbox}"
64
- spawn_thread_if_tty do
64
+ spawn_thread_if_tty do
65
65
  log @imap.uid_copy(uid_set, mailbox)
66
66
  log @imap.uid_store(uid_set, '+FLAGS', [:Deleted])
67
67
  reload_mailbox
@@ -79,7 +79,7 @@ module Vmail
79
79
  end
80
80
  create_if_necessary mailbox
81
81
  log "Copying #{uid_set.inspect} to #{mailbox}"
82
- spawn_thread_if_tty do
82
+ spawn_thread_if_tty do
83
83
  log @imap.uid_copy(uid_set, mailbox)
84
84
  log "Copied uid_set #{uid_set.inspect} to #{mailbox}"
85
85
  end
@@ -26,7 +26,7 @@ module Vmail
26
26
  "#{number}#{unit}"
27
27
  end
28
28
  end
29
-
29
+
30
30
 
31
31
  def divider(str)
32
32
  str * DIVIDER_WIDTH
@@ -6,6 +6,7 @@ require 'mail'
6
6
  require 'net/imap'
7
7
  require 'time'
8
8
  require 'logger'
9
+ require 'tempfile'
9
10
  require 'vmail/helpers'
10
11
  require 'vmail/address_quoter'
11
12
  require 'vmail/database'
@@ -32,8 +33,8 @@ module Vmail
32
33
  #load user-specified value for from field
33
34
  @from = config['from'] || config['username']
34
35
  @name = config['name']
35
- @signature = config['signature']
36
- @signature_script = config['signature_script']
36
+ @signature = config['signature']
37
+ @signature_script = config['signature_script']
37
38
  @always_cc = config['always_cc']
38
39
  @always_bcc = config['always_bcc']
39
40
  @mailbox = nil
@@ -49,7 +50,7 @@ module Vmail
49
50
  @authentication = config['authentication'] || 'plain'
50
51
  @width = 100
51
52
 
52
- @date_formatter_this_year = config['date_format'] || '%b %d %I:%M%P'
53
+ @date_formatter_this_year = config['date_format'] || '%b %d %I:%M%P'
53
54
  @date_formatter_prev_years = config['date_format_previous_years'] || '%b %d %Y'
54
55
  @date_width = DateTime.parse("12/12/2012 12:12:12").strftime(@date_formatter_this_year).length
55
56
  current_message = nil
@@ -60,7 +61,7 @@ module Vmail
60
61
  @imap = Net::IMAP.new(@imap_server, @imap_port, true, nil, false)
61
62
  log @imap.login(@username, @password)
62
63
  list_mailboxes # prefetch mailbox list
63
- rescue
64
+ rescue
64
65
  puts "VMAIL_ERROR: #{[$!.message, $!.backtrace].join("\n")}"
65
66
  end
66
67
 
@@ -86,7 +87,7 @@ module Vmail
86
87
  mailbox = mailbox_aliases[mailbox]
87
88
  end
88
89
  log "Selecting mailbox #{mailbox.inspect}"
89
- reconnect_if_necessary(30) do
90
+ reconnect_if_necessary(30) do
90
91
  log @imap.select(Net::IMAP.encode_utf7(mailbox))
91
92
  end
92
93
  log "Done"
@@ -106,7 +107,7 @@ module Vmail
106
107
  select_mailbox(@mailbox, true)
107
108
  end
108
109
 
109
- # TODO no need for this if all shown messages are stored in SQLITE3
110
+ # TODO no need for this if all shown messages are stored in SQLITE3
110
111
  # and keyed by UID.
111
112
  def clear_cached_message
112
113
  return unless STDIN.tty?
@@ -142,23 +143,23 @@ module Vmail
142
143
 
143
144
  def prime_connection
144
145
  return if @ids.nil? || @ids.empty?
145
- reconnect_if_necessary(4) do
146
+ reconnect_if_necessary(4) do
146
147
  # this is just to prime the IMAP connection
147
- # It's necessary for some reason before update and deliver.
148
+ # It's necessary for some reason before update and deliver.
148
149
  log "Priming connection"
149
150
  res = @imap.fetch(@ids[-1], ["ENVELOPE"])
150
151
  if res.nil?
151
152
  # just go ahead, just log
152
153
  log "Priming connection didn't work, connection seems broken, but still going ahead..."
153
154
  end
154
- end
155
+ end
155
156
  end
156
157
 
157
158
  def list_mailboxes
158
159
  log 'loading mailboxes...'
159
160
  @mailboxes ||= (@imap.list("", "*") || []).
160
161
  select {|struct| struct.attr.none? {|a| a == :Noselect} }.
161
- map {|struct|
162
+ map {|struct|
162
163
  Net::IMAP.decode_utf7(struct.name)
163
164
  }.uniq
164
165
  @mailboxes.delete("INBOX")
@@ -217,7 +218,7 @@ module Vmail
217
218
  # set a new range filter
218
219
  # this may generate a negative rane, e.g., "19893:19992" but that seems harmless
219
220
  update_query[0] = "#{old_num_messages}:#{@num_messages}"
220
- ids = reconnect_if_necessary {
221
+ ids = reconnect_if_necessary {
221
222
  log "Search #update_query"
222
223
  @imap.search(Vmail::Query.args2string(update_query))
223
224
  }
@@ -228,12 +229,24 @@ module Vmail
228
229
  self.max_seqno = ids.max
229
230
  log "- setting max_seqno to #{self.max_seqno}"
230
231
  log "- new uids found: #{new_ids.inspect}"
232
+ update_message_list(new_ids) unless new_ids.empty?
231
233
  new_ids
232
234
  end
233
235
 
236
+ def update_message_list(new_ids)
237
+ new_emails = DRbObject.new_with_uri($drb_uri).update
238
+ return if new_emails.empty?
239
+
240
+ tempfile_path = Tempfile.new('vmail-').path
241
+ File.open(tempfile_path, 'w') { |file| file.write(new_emails) }
242
+ server_name = "VMAIL:#{ @username }"
243
+
244
+ system(%[vim --servername #{ server_name } --remote-expr 'UPDATE_MESSAGE_LIST("#{ tempfile_path }")'])
245
+ end
246
+
234
247
  def update
235
248
  prime_connection
236
- new_ids = check_for_new_messages
249
+ new_ids = check_for_new_messages
237
250
  if !new_ids.empty?
238
251
  @ids = @ids + new_ids
239
252
  message_ids = fetch_and_cache_headers(new_ids)
@@ -260,9 +273,9 @@ module Vmail
260
273
  with_more_message_line(res)
261
274
  end
262
275
 
263
- def spawn_thread_if_tty(&block)
276
+ def spawn_thread_if_tty(&block)
264
277
  if STDIN.tty?
265
- Thread.new do
278
+ Thread.new do
266
279
  reconnect_if_necessary(10, &block)
267
280
  end
268
281
  else
@@ -275,7 +288,7 @@ module Vmail
275
288
  if !current_mailboxes.include?(mailbox)
276
289
  log "Current mailboxes: #{current_mailboxes.inspect}"
277
290
  log "Creating mailbox #{mailbox}"
278
- log @imap.create(mailbox)
291
+ log @imap.create(mailbox)
279
292
  @mailboxes = nil # force reload ...
280
293
  list_mailboxes
281
294
  end
@@ -338,7 +351,7 @@ module Vmail
338
351
  subject = "Fwd: #{subject}"
339
352
  end
340
353
 
341
- new_message_template(subject, false) +
354
+ new_message_template(subject, false) +
342
355
  "\n---------- Forwarded message ----------\n" +
343
356
  original_body + signature
344
357
  end
@@ -447,7 +460,7 @@ EOF
447
460
  log "Open_html_part"
448
461
  log current_mail.parts.inspect
449
462
  multipart = current_mail.parts.detect {|part| part.multipart?}
450
- html_part = if multipart
463
+ html_part = if multipart
451
464
  multipart.parts.detect {|part| part.header["Content-Type"].to_s =~ /text\/html/}
452
465
  elsif ! current_mail.parts.empty?
453
466
  current_mail.parts.detect {|part| part.header["Content-Type"].to_s =~ /text\/html/}
@@ -465,7 +478,7 @@ EOF
465
478
  @width = width.to_i
466
479
  log "Setting window width to #{width}"
467
480
  end
468
-
481
+
469
482
  def smtp_settings
470
483
  [:smtp, {:address => @smtp_server,
471
484
  :port => @smtp_port,
@@ -499,7 +512,7 @@ EOF
499
512
  close
500
513
  log(revive_connection)
501
514
  # hope this isn't an endless loop
502
- reconnect_if_necessary do
515
+ reconnect_if_necessary do
503
516
  block.call
504
517
  end
505
518
  rescue
@@ -525,11 +538,11 @@ EOF
525
538
  end
526
539
  end
527
540
 
528
- trap("INT") {
541
+ trap("INT") {
529
542
  require 'timeout'
530
- puts "Closing imap connection"
543
+ puts "Closing imap connection"
531
544
  begin
532
- #Timeout::timeout(2) do
545
+ #Timeout::timeout(2) do
533
546
  # just try to quit
534
547
  # $gmail.close
535
548
  #end
@@ -3,9 +3,8 @@ require "vmail/imap_client"
3
3
  module Vmail
4
4
  class InboxPoller < ImapClient
5
5
 
6
-
7
6
  # This is a second IMAP client operating in a separate process
8
-
7
+
9
8
  def start_polling
10
9
  n = [`which notify-send`.chomp, `which growlnotify`.chomp].detect {|c| c != ''}
11
10
  if n
@@ -20,7 +19,7 @@ module Vmail
20
19
  log "No notification tool detected. INBOX polling aborted."
21
20
  return
22
21
  end
23
-
22
+
24
23
  sleep 30
25
24
  log "INBOX POLLER: started polling"
26
25
  @mailboxes.unshift "INBOX"
@@ -34,12 +33,88 @@ module Vmail
34
33
  end
35
34
 
36
35
  def update
37
- new_ids = check_for_new_messages
36
+ new_ids = check_for_new_messages
38
37
  if !new_ids.empty?
39
38
  @ids = @ids + new_ids
40
- # remove '<>' from email. libnotify can't print '<'
41
- res = uncached_headers(new_ids).map {|m| m[:sender] }.join(", ").tr('<>','')
42
- @notifier.call "Vmail: new email", "from " + res
39
+
40
+ notification_title = "Vmail: "
41
+ notification_body = ""
42
+
43
+ if new_ids.size == 1
44
+ # If there is a single email, message is more descriptive about the
45
+ # received email.
46
+ #
47
+ # Example:
48
+ #
49
+ # (title) Vmail: Colin Sullivan
50
+ # (body) New Pull request received!
51
+ #
52
+ log "single new message received!"
53
+ new_message = uncached_headers(new_ids)[0]
54
+
55
+ # Extract just sender's name from sender field
56
+ notification_title += new_message[:sender].gsub(/\<.*\>/, "").strip()
57
+
58
+ # Truncate message subject if necessary
59
+ if new_message[:subject].length > 128
60
+ # Extract first 128 characters from subject of email
61
+ notification_body += new_message[:subject][0..128] + "..."
62
+ else
63
+ notification_body += new_message[:subject]
64
+ end
65
+
66
+ else
67
+ # If there are multiple new messages, notification is just a brief
68
+ # listing.
69
+ #
70
+ # Example:
71
+ #
72
+ # (title) Vmail: 3 new messages
73
+ # (body) Colin Sullivan: New Pull request rec...
74
+ # Henry Cowell: I am back from the dead!
75
+ # ...
76
+ #
77
+ log "multiple new messages received!"
78
+
79
+ notification_title += new_ids.size.to_s() + " new messages"
80
+
81
+ # for each message
82
+ for i in 0...new_ids.size
83
+ new_message = uncached_headers(new_ids)[i]
84
+
85
+ # Create message line
86
+ message_line = ""
87
+
88
+ # Extract just sender's name from sender field
89
+ message_line += new_message[:sender].gsub(/\<.*\>/, "").strip()
90
+
91
+ # Extract subject
92
+ message_line += ": " + new_message[:subject]
93
+
94
+ # Concatenate line if necessary
95
+ if message_line.length > 32
96
+ message_line = message_line[0...29] + "..."
97
+ end
98
+
99
+ # Add to notification body
100
+ notification_body += message_line + "\n"
101
+
102
+ end
103
+
104
+ # Concatenate entire notification body if necessary
105
+ if notification_body.length > 128
106
+ notification_body = notification_body[0...125] + "..."
107
+ end
108
+
109
+ end
110
+
111
+ # Remove any '<>' characters from notification just incase, libnotify
112
+ # can't print '<'
113
+ notification_title = notification_title.tr('<>', '')
114
+ notification_body = notification_body.tr('<>', '')
115
+
116
+ @notifier.call notification_title, notification_body
117
+
43
118
  end
44
119
  rescue
45
120
  log "VMAIL_ERROR: #{[$!.message, $!.backtrace].join("\n")}"
@@ -48,10 +123,10 @@ module Vmail
48
123
  # doesn't try to access Sequel / sqlite3
49
124
  def uncached_headers(id_set)
50
125
  log "Fetching headers for #{id_set.size} messages"
51
- results = reconnect_if_necessary do
126
+ results = reconnect_if_necessary do
52
127
  @imap.fetch(id_set, ["FLAGS", "ENVELOPE", "RFC822.SIZE", "UID"])
53
128
  end
54
- results.reverse.map do |x|
129
+ results.reverse.map do |x|
55
130
  envelope = x.attr["ENVELOPE"]
56
131
  message_id = envelope.message_id
57
132
  subject = Mail::Encodings.unquote_and_convert_to((envelope.subject || ''), 'UTF-8')
@@ -32,13 +32,13 @@ module Vmail
32
32
 
33
33
  # helper method
34
34
  def find_text_part2(part, content_type)
35
- if part.multipart?
35
+ if part.multipart?
36
36
  part.parts.
37
37
  map {|p| find_text_part2(p, p.content_type)}.
38
38
  compact.
39
39
  select {|p| !p.attachment?}.
40
40
  first
41
- elsif content_type =~ %r[^text/plain] ||
41
+ elsif content_type =~ %r[^text/plain] ||
42
42
  content_type =~ %r[text/plain] ||
43
43
  content_type =~ %r[message/rfc]
44
44
  part
@@ -47,18 +47,18 @@ module Vmail
47
47
 
48
48
  def format_part(part)
49
49
  if part && part.respond_to?(:header)
50
- case part.header["Content-Type"].to_s
50
+ case part.header["Content-Type"].to_s
51
51
  when /text\/html/
52
- format_html_body(part)
52
+ format_html_body(part)
53
53
  when /text\/plain/
54
- format_text_body(part)
54
+ format_text_body(part)
55
55
  when /message\/rfc/
56
56
  m = Mail.new(part.body.decoded)
57
57
  plaintext_part(m)
58
58
  else # just format_text on it anyway
59
- format_text_body(part)
59
+ format_text_body(part)
60
60
  end
61
- else
61
+ else
62
62
  part.decoded.gsub("\r", '')
63
63
  end
64
64
  rescue
@@ -73,7 +73,7 @@ module Vmail
73
73
  # depend on VMAIL_HTML_PART_READER
74
74
  # variable
75
75
  def format_html_body(part)
76
- html_tool = ENV['VMAIL_HTML_PART_READER']
76
+ html_tool = ENV['VMAIL_HTML_PART_READER']
77
77
  html = part.body.decoded.gsub("\r", '')
78
78
  stdin, stdout, stderr = Open3.popen3(html_tool)
79
79
  stdin.puts html
@@ -107,10 +107,10 @@ module Vmail
107
107
 
108
108
  def utf8(string, this_encoding = encoding)
109
109
  return '' unless string
110
- out = if this_encoding && this_encoding.upcase != 'UTF-8'
110
+ out = if this_encoding && this_encoding.upcase != 'UTF-8'
111
111
  string.encode!('utf-8', this_encoding, undef: :replace, invalid: :replace)
112
- elsif this_encoding.upcase == 'UTF-8'
113
- string
112
+ elsif this_encoding.upcase == 'UTF-8'
113
+ string
114
114
  else
115
115
  # assume UTF-8 and convert to ascii
116
116
  string.encode!('us-ascii', 'utf-8', undef: :replace, invalid: :replace)
@@ -20,10 +20,10 @@ module Vmail
20
20
 
21
21
  def parse(argv)
22
22
  OptionParser.new do |opts|
23
- opts.banner = "Usage: vmail [ options ] [ limit ] [ imap search query ]"
23
+ opts.banner = "Usage: vmail [ options ] [ limit ] [ imap search query ]"
24
24
  opts.separator ""
25
25
  opts.separator "Specific options:"
26
- opts.on("-g[n]", "--getcontacts[n]", Integer, "Generate contacts file. n is number of emails to scan (default 500).") do |n|
26
+ opts.on("-g[n]", "--getcontacts[n]", Integer, "Generate contacts file. n is number of emails to scan (default 500).") do |n|
27
27
  @get_contacts = true
28
28
  @max_messages_to_scan = n || 500
29
29
  end
@@ -46,7 +46,7 @@ module Vmail
46
46
  else
47
47
  STDERR.puts <<EOF
48
48
 
49
- Missing config file!
49
+ Missing config file!
50
50
 
51
51
  #{INSTRUCTIONS}
52
52
  EOF
@@ -75,16 +75,16 @@ EOF
75
75
  require 'vmail/contacts_extractor'
76
76
  extractor = ContactsExtractor.new(@config['username'], @config['password'])
77
77
  File.open(DEFAULT_CONTACTS_FILENAME, 'w') do |file|
78
- extractor.extract(@max_messages_to_scan) do |address|
78
+ extractor.extract(@max_messages_to_scan) do |address|
79
79
  STDERR.print '.'
80
80
  file.puts(address.strip)
81
- STDERR.flush
81
+ STDERR.flush
82
82
  end
83
83
  end
84
84
  STDERR.print "\n"
85
85
  puts "Saved file to #{DEFAULT_CONTACTS_FILENAME}"
86
86
  puts "Sorting address..."
87
- cmd = "sort #{DEFAULT_CONTACTS_FILENAME} | uniq > vmail-tmp.txt"
87
+ cmd = "sort #{DEFAULT_CONTACTS_FILENAME} | uniq > vmail-tmp.txt"
88
88
  cmd2 = "mv vmail-tmp.txt #{DEFAULT_CONTACTS_FILENAME}"
89
89
  `#{cmd}`
90
90
  `#{cmd2}`
@@ -10,7 +10,7 @@ module Vmail
10
10
  if args.size > 0 && args.first =~ /^\d+/
11
11
  args.shift
12
12
  end
13
- query = if args.empty?
13
+ query = if args.empty?
14
14
  ['ALL']
15
15
  else
16
16
  args
@@ -22,17 +22,17 @@ module Vmail
22
22
  sender = current_message.sender
23
23
  reply_quote_header = date ? "On #{date.strftime('%a, %b %d, %Y at %I:%M %p')}, #{sender} wrote:\n\n" : "#{sender} wrote:\n"
24
24
 
25
- reply_body = reply_quote_header +
25
+ reply_body = reply_quote_header +
26
26
  ( current_message.plaintext.split(/^-+$/,2)[1].strip.gsub(/^(?=>)/, ">").gsub(/^(?!>)/, "> ") )
27
27
 
28
28
  {
29
29
  'references' => current_message.message_id,
30
30
  # set 'from' to user-specified value
31
- 'from' => "#@name <#@from>",
32
- 'to' => reply_recipient,
33
- 'cc' => reply_cc,
31
+ 'from' => "#@name <#@from>",
32
+ 'to' => reply_recipient,
33
+ 'cc' => reply_cc,
34
34
  'bcc' => @always_bcc,
35
- 'subject' => reply_subject,
35
+ 'subject' => reply_subject,
36
36
  'body' => reply_body
37
37
  }
38
38
  rescue
@@ -52,12 +52,12 @@ module Vmail
52
52
  []
53
53
  end
54
54
  xs = xs.select {|x|
55
- email = (x[/<([^>]+)>/, 1] || x)
55
+ email = (x[/<([^>]+)>/, 1] || x)
56
56
  email !~ /#{reply_recipient}/ \
57
57
  && email !~ /#@username/ \
58
- && (@always_cc ? (email !~ /#{@always_cc}/) : true)
58
+ && (@always_cc ? (email !~ /#{@always_cc}/) : true)
59
59
  }
60
- if @always_cc
60
+ if @always_cc
61
61
  xs << @always_cc
62
62
  end
63
63
  xs.uniq.select {|x| x != reply_recipient }.join(', ')
@@ -3,7 +3,7 @@ module Vmail
3
3
  # The main function called by the client to retrieve messages
4
4
  def search(query)
5
5
  log "#search: #{query.inspect}"
6
- @query = Vmail::Query.parse(query)
6
+ @query = Vmail::Query.parse(query)
7
7
  # customizable @limit is Deprecated
8
8
  @limit = 100
9
9
 
@@ -13,10 +13,10 @@ module Vmail
13
13
  @ids = reconnect_if_necessary(180) do # timeout of 3 minutes
14
14
  @imap.search(query_string)
15
15
  end
16
- @start_index = [@ids.size - @limit, 0].max
16
+ @start_index = [@ids.size - @limit, 0].max
17
17
  else
18
18
  # set the target range to the whole set, unless it is too big
19
- @start_index = [@num_messages - @limit, 0].max
19
+ @start_index = [@num_messages - @limit, 0].max
20
20
  @query.unshift "#{@start_index + 1}:#{@num_messages}"
21
21
  query_string = Vmail::Query.args2string(@query)
22
22
  log "Query: #{query_string.inspect}"
@@ -30,7 +30,7 @@ module Vmail
30
30
  end
31
31
 
32
32
  self.max_seqno = @ids[-1] # this is a instance var
33
- log "- Query got #{@ids.size} results; max seqno: #{self.max_seqno}"
33
+ log "- Query got #{@ids.size} results; max seqno: #{self.max_seqno}"
34
34
  clear_cached_message
35
35
 
36
36
  select_ids = (search_query? ? @ids[[-@limit, 0].max, @limit] : @ids)
@@ -51,7 +51,7 @@ module Vmail
51
51
  rescue
52
52
  log "ERROR:\n#{$!.inspect}\n#{$!.backtrace.join("\n")}"
53
53
  "Sorry there was an error. Please check vmail.log."
54
- end
54
+ end
55
55
 
56
56
  def search_query?
57
57
  x = @query[-1] != 'all'
@@ -5,7 +5,7 @@ module Vmail
5
5
 
6
6
  def parse(argv)
7
7
  OptionParser.new do |opts|
8
- opts.banner = "Usage: vmailsend"
8
+ opts.banner = "Usage: vmailsend"
9
9
  opts.separator ""
10
10
  opts.separator "Specific options:"
11
11
  opts.on("-c", "--config path", String, "Path to config file") do |config_file|
@@ -30,7 +30,7 @@ module Vmail
30
30
  else
31
31
  puts <<EOF
32
32
 
33
- Missing config file!
33
+ Missing config file!
34
34
 
35
35
  #{INSTRUCTIONS}
36
36
  EOF
@@ -3,7 +3,7 @@ module Vmail
3
3
  module ShowingHeaders
4
4
 
5
5
  def get_message_headers(message_ids)
6
- messages = message_ids.map {|message_id|
6
+ messages = message_ids.map {|message_id|
7
7
  m = Message[message_id]
8
8
  if m.nil?
9
9
  raise "Message #{message_id} not found"
@@ -16,10 +16,10 @@ module Vmail
16
16
 
17
17
  def fetch_and_cache_headers(id_set)
18
18
  log "Fetching headers for #{id_set.size} messages"
19
- results = reconnect_if_necessary do
19
+ results = reconnect_if_necessary do
20
20
  @imap.fetch(id_set, ["FLAGS", "ENVELOPE", "RFC822.SIZE", "UID"])
21
21
  end
22
- results.reverse.map do |x|
22
+ results.reverse.map do |x|
23
23
  envelope = x.attr["ENVELOPE"]
24
24
  message_id = envelope.message_id
25
25
  begin
@@ -60,10 +60,10 @@ module Vmail
60
60
  def extract_address(address_struct)
61
61
  address = if address_struct.nil?
62
62
  "Unknown"
63
- else
64
- email = [ (address_struct.mailbox ? Mail::Encodings.unquote_and_convert_to(address_struct.mailbox, 'UTF-8') : ""),
63
+ else
64
+ email = [ (address_struct.mailbox ? Mail::Encodings.unquote_and_convert_to(address_struct.mailbox, 'UTF-8') : ""),
65
65
  (address_struct.host ? Mail::Encodings.unquote_and_convert_to(address_struct.host, 'UTF-8'): "")
66
- ].join('@')
66
+ ].join('@')
67
67
  if address_struct.name
68
68
  "#{Mail::Encodings.unquote_and_convert_to((address_struct.name || ''), 'UTF-8')} <#{email}>"
69
69
  else
@@ -77,7 +77,7 @@ module Vmail
77
77
  date = DateTime.parse(message.date)
78
78
  formatted_date = if date.year != Time.now.year
79
79
  date.strftime @date_formatter_prev_years
80
- else
80
+ else
81
81
  date.strftime @date_formatter_this_year
82
82
  end
83
83
  address = if @mailbox == mailbox_aliases['sent']
@@ -92,8 +92,8 @@ module Vmail
92
92
  row_text = [ format_flags(message.flags).col(2),
93
93
  (formatted_date || '').col(@date_width),
94
94
  address.col(address_col_width),
95
- message.subject.col(subject_col_width),
96
- number_to_human_size(message.size).rcol(7),
95
+ message.subject.col(subject_col_width),
96
+ number_to_human_size(message.size).rcol(7),
97
97
  message.message_id ].join(' | ')
98
98
  end
99
99
 
@@ -108,11 +108,11 @@ module Vmail
108
108
  end
109
109
 
110
110
  def with_more_message_line(res)
111
- remaining = @start_index
111
+ remaining = @start_index
112
112
  if remaining <= 1
113
113
  return res
114
114
  end
115
- res + "\n> Load #{[100, remaining].min} more messages. #{remaining} remaining."
115
+ res + "\n> Load #{[100, remaining].min} more messages. #{remaining} remaining."
116
116
  end
117
117
 
118
118
  end
@@ -26,7 +26,7 @@ module Vmail
26
26
  def show_message(message_id, raw=false)
27
27
  message_id = message_id.strip.gsub('\\', '')
28
28
  log "Show message: #{message_id.inspect}"
29
- return current_message.rfc822 if raw
29
+ return current_message.rfc822 if raw
30
30
  res = retry_if_needed { fetch_and_cache(message_id) }
31
31
  log "Showing message message_id: #{message_id}"
32
32
  @cur_message_id = message_id
@@ -35,10 +35,10 @@ module Vmail
35
35
 
36
36
  def fetch_and_cache(message_id)
37
37
  if message = cached_full_message?(message_id)
38
- log "- full message cache hit"
38
+ log "- full message cache hit"
39
39
  return message.plaintext
40
40
  end
41
- log "- full message cache miss"
41
+ log "- full message cache miss"
42
42
  params = {message_id: message_id, label_id: @label.label_id}
43
43
  labeling = Labeling[params] || Labeling.create(params)
44
44
  unless (labeling && labeling.uid)
@@ -48,13 +48,13 @@ module Vmail
48
48
  end
49
49
  uid = labeling.uid
50
50
 
51
- log "- fetching message uid #{uid}"
52
- fetch_data = reconnect_if_necessary do
51
+ log "- fetching message uid #{uid}"
52
+ fetch_data = reconnect_if_necessary do
53
53
  res = retry_if_needed do
54
54
  @imap.uid_fetch(uid, ["FLAGS", "RFC822", "RFC822.SIZE"])
55
55
  end
56
56
  raise "Message uid #{uid} could not be fetched from server" if res.nil?
57
- res[0]
57
+ res[0]
58
58
  end
59
59
  seqno = fetch_data.seqno
60
60
  rfc822 = Mail.new(fetch_data.attr['RFC822'])
@@ -63,7 +63,7 @@ module Vmail
63
63
  message = Message[message_id]
64
64
  parts_list = format_parts_info(formatter.list_parts)
65
65
  headers_hash = formatter.extract_headers
66
- headers_hash['date']
66
+ headers_hash['date']
67
67
  headers = format_headers headers_hash
68
68
  # replace the date value with the one derived from the envelope
69
69
  body = formatter.plaintext_part
@@ -88,7 +88,7 @@ EOF
88
88
  end
89
89
 
90
90
  begin
91
- message.update(:plaintext => message_text)
91
+ message.update(:plaintext => message_text)
92
92
  rescue
93
93
  log message_text.encoding
94
94
  #log message_text
@@ -96,7 +96,7 @@ EOF
96
96
  end
97
97
  message_text
98
98
  rescue
99
- msg = "Error encountered in fetch_and_cache(), message_id #{message_id} [#{@mailbox}]:\n#{$!}\n#{$!.backtrace.join("\n")}"
99
+ msg = "Error encountered in fetch_and_cache(), message_id #{message_id} [#{@mailbox}]:\n#{$!}\n#{$!.backtrace.join("\n")}"
100
100
  log msg
101
101
  msg
102
102
  end
@@ -1,3 +1,3 @@
1
1
  module Vmail
2
- VERSION = '2.8.7'
2
+ VERSION = '2.8.9'
3
3
  end
@@ -15,20 +15,20 @@ class AddressQuoterTest < MiniTest::Unit::TestCase
15
15
  assert_equal @expected, quote_addresses(@string) #=> "Bob Smith" <bobsmith@gmail.com>, "Jones, Rich A." <richjones@gmail.com>
16
16
  assert_equal @expected2, quote_addresses(@string2) #=> "Bob Smith" <bobsmith@gmail.com>, "Jones, Rich A." <richjones@gmail.com>
17
17
  end
18
-
18
+
19
19
  def test_quoting_with_bare_email_address
20
20
  string = "richjones@gmail.com"
21
- assert_equal string, quote_addresses(string)
21
+ assert_equal string, quote_addresses(string)
22
22
 
23
23
  string = "Bob Smith <bobsmith@gmail.com>, Jones, Rich A. <richjones@gmail.com>, peterbaker@gmail.com"
24
24
  expected = %q("Bob Smith" <bobsmith@gmail.com>, "Jones, Rich A." <richjones@gmail.com>, peterbaker@gmail.com)
25
- assert_equal expected, quote_addresses(string)
25
+ assert_equal expected, quote_addresses(string)
26
26
  end
27
27
 
28
28
  def test_quoting_already_quoted
29
29
  string = %q(Bob Smith <bobsmith@gmail.com>, "Jones, Rich A." <richjones@gmail.com>, peterbaker@gmail.com)
30
30
  expected = %q("Bob Smith" <bobsmith@gmail.com>, "Jones, Rich A." <richjones@gmail.com>, peterbaker@gmail.com)
31
- assert_equal expected, quote_addresses(string)
31
+ assert_equal expected, quote_addresses(string)
32
32
  end
33
33
 
34
34
  end
@@ -19,7 +19,7 @@ describe Vmail::MessageFormatter do
19
19
  end
20
20
 
21
21
  describe "message has a text body but no Content-Type" do
22
- before do
22
+ before do
23
23
  @raw = File.read(File.expand_path('../fixtures/textbody-nocontenttype.eml', __FILE__))
24
24
  @mail = Mail.new(@raw)
25
25
  @formatter = Vmail::MessageFormatter.new(@mail)
@@ -52,12 +52,12 @@ describe Vmail::MessageFormatter do
52
52
  end
53
53
  it "should format the subject line in UTF-8" do
54
54
  match = "독특닷컴과"
55
- assert_match match, @formatter.extract_headers['subject']
55
+ assert_match match, @formatter.extract_headers['subject']
56
56
  end
57
57
  end
58
58
 
59
59
  describe "when message has only an HTML body and no encoding info" do
60
- before do
60
+ before do
61
61
  @raw = File.read(File.expand_path('../fixtures/moleskine-html.eml', __FILE__))
62
62
  @mail = Mail.new(@raw)
63
63
  @formatter = Vmail::MessageFormatter.new(@mail)
@@ -69,12 +69,12 @@ describe Vmail::MessageFormatter do
69
69
 
70
70
  describe "when message has two attachments" do
71
71
  before do
72
- @raw = read_fixture('with-attachments.eml')
72
+ @raw = read_fixture('with-attachments.eml')
73
73
  @mail = Mail.new(@raw)
74
74
  end
75
75
 
76
76
  it "should extract two attachments" do
77
- attachments = @mail.attachments
77
+ attachments = @mail.attachments
78
78
  assert_equal 2, attachments.size
79
79
  assert_equal ['image/png', 'image/gif'], attachments.map(&:mime_type)
80
80
  end
@@ -88,7 +88,7 @@ describe Vmail::MessageFormatter do
88
88
  end
89
89
 
90
90
  it 'should extract the message/rfc822 part' do
91
- assert_match /I hope everyone is having a great holiday season/,
91
+ assert_match /I hope everyone is having a great holiday season/,
92
92
  @formatter.process_body
93
93
  end
94
94
  end
@@ -0,0 +1,35 @@
1
+ gem "minitest"
2
+ require 'minitest/autorun'
3
+ require 'vmail/version'
4
+ require 'vmail/options'
5
+ require 'vmail/inbox_poller'
6
+
7
+ describe Vmail::InboxPoller do
8
+ before do
9
+ working_dir = ENV['VMAIL_HOME'] || "#{ENV['HOME']}/.vmail/default"
10
+ Dir.chdir(working_dir)
11
+ opts = Vmail::Options.new(["--config", ".vmailrc"])
12
+ opts.config
13
+ config = opts.config
14
+ @inbox_poller = Vmail::InboxPoller.start config
15
+ @notifier = @inbox_poller.initialize_notifier
16
+ end
17
+
18
+ after do
19
+ @inbox_poller.close
20
+ end
21
+
22
+ describe "test notifications" do
23
+ it "does not fail" do
24
+ @notifier.call "This is a simple notification title", "This is a simple body"
25
+ end
26
+ end
27
+
28
+ describe "when a notification contains single quotes" do
29
+ it "does not fail" do
30
+ res = @notifier.call "Someone's notification", "Shouldn't fail with single quotes"
31
+
32
+ print "res: #{res}"
33
+ end
34
+ end
35
+ end
@@ -22,7 +22,7 @@ describe Vmail::ReplyTemplating do
22
22
  expected = "Draculette Ko <violinist.ko@gmail.com>, Cookiemonster Youn <cookiemonster@gmail.com>, Racoon <raycoon@gmail.com>"
23
23
  assert_equal expected, @rt.cc
24
24
  end
25
-
25
+
26
26
  def test_sender
27
27
  assert_equal "Chappy Youn <chappy1@gmail.com>", @rt.sender
28
28
  end
metadata CHANGED
@@ -1,83 +1,94 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vmail
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.8.7
4
+ version: 2.8.9
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Daniel Choi
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2013-07-24 00:00:00.000000000 Z
12
+ date: 2014-05-12 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: mail
15
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
- - - '>='
19
+ - - ! '>='
18
20
  - !ruby/object:Gem::Version
19
21
  version: 2.2.12
20
22
  type: :runtime
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
23
26
  requirements:
24
- - - '>='
27
+ - - ! '>='
25
28
  - !ruby/object:Gem::Version
26
29
  version: 2.2.12
27
30
  - !ruby/object:Gem::Dependency
28
31
  name: highline
29
32
  requirement: !ruby/object:Gem::Requirement
33
+ none: false
30
34
  requirements:
31
- - - '>='
35
+ - - ! '>='
32
36
  - !ruby/object:Gem::Version
33
37
  version: 1.6.1
34
38
  type: :runtime
35
39
  prerelease: false
36
40
  version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
37
42
  requirements:
38
- - - '>='
43
+ - - ! '>='
39
44
  - !ruby/object:Gem::Version
40
45
  version: 1.6.1
41
46
  - !ruby/object:Gem::Dependency
42
47
  name: sequel
43
48
  requirement: !ruby/object:Gem::Requirement
49
+ none: false
44
50
  requirements:
45
- - - '>='
51
+ - - ! '>='
46
52
  - !ruby/object:Gem::Version
47
53
  version: 3.24.1
48
54
  type: :runtime
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
51
58
  requirements:
52
- - - '>='
59
+ - - ! '>='
53
60
  - !ruby/object:Gem::Version
54
61
  version: 3.24.1
55
62
  - !ruby/object:Gem::Dependency
56
63
  name: sqlite3
57
64
  requirement: !ruby/object:Gem::Requirement
65
+ none: false
58
66
  requirements:
59
- - - '>='
67
+ - - ! '>='
60
68
  - !ruby/object:Gem::Version
61
69
  version: 1.3.3
62
70
  type: :runtime
63
71
  prerelease: false
64
72
  version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
65
74
  requirements:
66
- - - '>='
75
+ - - ! '>='
67
76
  - !ruby/object:Gem::Version
68
77
  version: 1.3.3
69
78
  - !ruby/object:Gem::Dependency
70
79
  name: versionomy
71
80
  requirement: !ruby/object:Gem::Requirement
81
+ none: false
72
82
  requirements:
73
- - - '>='
83
+ - - ! '>='
74
84
  - !ruby/object:Gem::Version
75
85
  version: 0.4.4
76
86
  type: :runtime
77
87
  prerelease: false
78
88
  version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
79
90
  requirements:
80
- - - '>='
91
+ - - ! '>='
81
92
  - !ruby/object:Gem::Version
82
93
  version: 0.4.4
83
94
  description: Manage your email with Vim
@@ -134,47 +145,34 @@ files:
134
145
  - test/fixtures/textbody-nocontenttype.eml
135
146
  - test/fixtures/with-attachments.eml
136
147
  - test/message_formatter_test.rb
148
+ - test/notifier_test.rb
137
149
  - test/reply_template_test.rb
138
150
  - test/test_helper.rb
139
151
  - test/time_format_test.rb
140
152
  - vmail.gemspec
141
153
  homepage: http://danielchoi.com/software/vmail.html
142
154
  licenses: []
143
- metadata: {}
144
155
  post_install_message:
145
156
  rdoc_options: []
146
157
  require_paths:
147
158
  - lib
148
159
  required_ruby_version: !ruby/object:Gem::Requirement
160
+ none: false
149
161
  requirements:
150
- - - '>='
162
+ - - ! '>='
151
163
  - !ruby/object:Gem::Version
152
164
  version: 1.9.0
153
165
  required_rubygems_version: !ruby/object:Gem::Requirement
166
+ none: false
154
167
  requirements:
155
- - - '>='
168
+ - - ! '>='
156
169
  - !ruby/object:Gem::Version
157
170
  version: '0'
158
171
  requirements: []
159
172
  rubyforge_project: vmail
160
- rubygems_version: 2.0.3
173
+ rubygems_version: 1.8.25
161
174
  signing_key:
162
- specification_version: 4
175
+ specification_version: 3
163
176
  summary: A Vim interface to Gmail
164
- test_files:
165
- - test/address_quoter_test.rb
166
- - test/base64_test.rb
167
- - test/fixtures/euc-kr-header.eml
168
- - test/fixtures/euc-kr-html.eml
169
- - test/fixtures/google-affiliate.eml
170
- - test/fixtures/htmlbody.eml
171
- - test/fixtures/moleskine-html.eml
172
- - test/fixtures/reply-template-encoding-test.eml
173
- - test/fixtures/reply_all.eml
174
- - test/fixtures/rfc_part.eml
175
- - test/fixtures/textbody-nocontenttype.eml
176
- - test/fixtures/with-attachments.eml
177
- - test/message_formatter_test.rb
178
- - test/reply_template_test.rb
179
- - test/test_helper.rb
180
- - test/time_format_test.rb
177
+ test_files: []
178
+ has_rdoc:
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 3518bf85a7fa7234e20959f21d38d38673ccd756
4
- data.tar.gz: 074a00c8760160288c904d9307745315276d713b
5
- SHA512:
6
- metadata.gz: a3e3c4c7d7328851e93a2b42c3c925a88d0cb587d736dc364e092e95d98ba58f57eda872fe9c8e964e23eba0f7699ee5e7579c48d8b8b9afdc88253d8b4f5a9b
7
- data.tar.gz: 3890f56ce913f779e89e5d6155dc4e6381c670359926e1929e95b38570f42d145999540e57ee76bbc581fe6020839ad942e7e1e628ace978f70307e1755a8a18