vmail 2.8.7 → 2.8.9

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.
@@ -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