vmail 2.9.4 → 2.9.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/lib/vmail.rb +105 -67
- data/lib/vmail/contacts_extractor.rb +6 -6
- data/lib/vmail/database.rb +2 -2
- data/lib/vmail/flagging_and_moving.rb +14 -14
- data/lib/vmail/helpers.rb +1 -1
- data/lib/vmail/imap_client.rb +39 -39
- data/lib/vmail/inbox_poller.rb +5 -5
- data/lib/vmail/message_formatter.rb +2 -2
- data/lib/vmail/options.rb +12 -12
- data/lib/vmail/query.rb +1 -1
- data/lib/vmail/reply_templating.rb +4 -4
- data/lib/vmail/searching.rb +5 -5
- data/lib/vmail/send_options.rb +3 -3
- data/lib/vmail/showing_headers.rb +5 -5
- data/lib/vmail/showing_message.rb +15 -15
- data/lib/vmail/version.rb +1 -1
- data/vmail.gemspec +6 -5
- metadata +34 -3
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MjBhZmJmZTlkMDU0NjcwYTk1N2VhNWQxYWY5MjEzYWM5NDFjN2JiYg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZWMxMDI3NDg1NTg5NDNkZmY5MTlmY2JhMWZiOTE2YWIzZmI4ZDUxNg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YWI4OTRkZjQ3MDg5YzQ2OThhYWM0MTUyODczNzRjOWMxNzU4OGI1NjFjNTU0
|
10
|
+
N2MzNDJmZDc0ZmQ3YmIwMTg3MjI1Mzk0NjY4NTc2NzU1MDE0MTFmZWUxODgw
|
11
|
+
MjkxYmQ2MmNlODU3ZThhMGIxNzA2ZGRmODc5MjI3NjA1YzBlMzM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NzY0MTUwZWViZDcyYzViNTA4ZDJjOWJlNGJlM2M1OGY3ZjFlZjliM2ZlMjhl
|
14
|
+
ZjFmZDNhMTVkODk0ZWQwMzM1MWI4MDNhNjJlY2IzYmExMDAxZWFiOGVmYmM3
|
15
|
+
M2E0MTBkMmJkMzI3OTUyM2QwOWM4ZWI4Y2JiYTdiMzU1MDg0NTk=
|
data/lib/vmail.rb
CHANGED
@@ -7,20 +7,102 @@ require 'versionomy'
|
|
7
7
|
module Vmail
|
8
8
|
extend self
|
9
9
|
|
10
|
+
BUFFER_FILE = 'vmailbuffer'
|
11
|
+
|
10
12
|
def start
|
11
|
-
puts "Starting vmail #{Vmail::VERSION}"
|
13
|
+
puts "Starting vmail #{ Vmail::VERSION }"
|
14
|
+
check_ruby_version
|
15
|
+
|
16
|
+
set_vmail_browser
|
17
|
+
check_html_reader
|
18
|
+
change_directory_to_vmail_home
|
19
|
+
|
20
|
+
logfile = (vim == 'mvim' || vim == 'gvim') ? STDERR : 'vmail.log'
|
21
|
+
config.merge! 'logfile' => logfile
|
22
|
+
|
23
|
+
puts "Starting vmail imap client for #{ config['username'] }"
|
24
|
+
|
25
|
+
set_inbox_poller
|
26
|
+
|
27
|
+
puts "Working directory: #{ Dir.pwd }"
|
28
|
+
|
29
|
+
server = start_imap_daemon
|
30
|
+
mailbox, query_string = select_mailbox(server)
|
31
|
+
|
32
|
+
start_vim(mailbox, query_string)
|
33
|
+
|
34
|
+
if vim == 'mvim' || vim == 'gvim'
|
35
|
+
DRb.thread.join
|
36
|
+
end
|
37
|
+
|
38
|
+
close_connection
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def options
|
44
|
+
@options ||= Vmail::Options.new(ARGV)
|
45
|
+
end
|
46
|
+
|
47
|
+
def config
|
48
|
+
@config ||= options.config
|
49
|
+
end
|
50
|
+
|
51
|
+
def change_directory_to_vmail_home
|
52
|
+
working_dir = ENV['VMAIL_HOME'] || "#{ ENV['HOME'] }/.vmail/default"
|
53
|
+
`mkdir -p #{ working_dir }`
|
54
|
+
puts "Changing working directory to #{ working_dir }"
|
55
|
+
Dir.chdir(working_dir)
|
56
|
+
end
|
57
|
+
|
58
|
+
def check_html_reader
|
59
|
+
return if ENV['VMAIL_HTML_PART_READER']
|
60
|
+
html_reader = %w( w3m elinks lynx ).detect {|x| `which #{ x }` != ''}
|
61
|
+
if html_reader
|
62
|
+
cmd = ['w3m -dump -T text/html -I utf-8 -O utf-8', 'lynx -stdin -dump', 'elinks -dump'].detect {|s| s.index(html_reader)}
|
63
|
+
STDERR.puts "Setting VMAIL_HTML_PART_READER to '#{ cmd }'"
|
64
|
+
ENV['VMAIL_HTML_PART_READER'] = cmd
|
65
|
+
else
|
66
|
+
abort "You need to install w3m, elinks, or lynx on your system in order to see html-only messages"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def parse_query
|
71
|
+
if ARGV[0] =~ /^\d+/
|
72
|
+
ARGV.shift
|
73
|
+
end
|
74
|
+
mailbox = ARGV.shift || 'INBOX'
|
75
|
+
query = Vmail::Query.parse(ARGV)
|
76
|
+
[mailbox, query]
|
77
|
+
end
|
78
|
+
|
79
|
+
def select_mailbox(server)
|
80
|
+
mailbox, query = parse_query
|
81
|
+
query_string = Vmail::Query.args2string query
|
82
|
+
server.select_mailbox mailbox
|
83
|
+
|
84
|
+
STDERR.puts "Mailbox: #{ mailbox }"
|
85
|
+
STDERR.puts "Query: #{ query.inspect }"
|
86
|
+
STDERR.puts "Query String: #{ String.shellescape(query_string) }"
|
87
|
+
|
88
|
+
[mailbox, query_string]
|
89
|
+
end
|
90
|
+
|
91
|
+
def check_ruby_version
|
12
92
|
required_version = Versionomy::create(:major => 1, :minor => 9, :tiny => 0)
|
13
93
|
ruby_version = Versionomy::parse(RUBY_VERSION)
|
94
|
+
|
14
95
|
if required_version > ruby_version
|
15
96
|
puts "This version of vmail requires Ruby version 1.9.0 or higher (1.9.2 is recommended)"
|
16
97
|
exit
|
17
98
|
end
|
99
|
+
end
|
18
100
|
|
19
|
-
|
101
|
+
def set_vmail_browser
|
20
102
|
ENV['VMAIL_BROWSER'] ||= if RUBY_PLATFORM.downcase.include?('linux')
|
21
103
|
tools = ['gnome-open', 'kfmclient-exec', 'xdg-open', 'konqueror']
|
22
104
|
tool = tools.detect { |tool|
|
23
|
-
`which #{tool}`.size > 0
|
105
|
+
`which #{ tool }`.size > 0
|
24
106
|
}
|
25
107
|
if tool.nil?
|
26
108
|
puts "Can't find a VMAIL_BROWSER tool on your system. Please report this issue."
|
@@ -31,25 +113,10 @@ module Vmail
|
|
31
113
|
'open'
|
32
114
|
end
|
33
115
|
|
34
|
-
puts "Setting VMAIL_BROWSER to '#{ENV['VMAIL_BROWSER']}'"
|
35
|
-
|
36
|
-
|
37
|
-
working_dir = ENV['VMAIL_HOME'] || "#{ENV['HOME']}/.vmail/default"
|
38
|
-
`mkdir -p #{working_dir}`
|
39
|
-
puts "Changing working directory to #{working_dir}"
|
40
|
-
Dir.chdir(working_dir)
|
41
|
-
opts = Vmail::Options.new(ARGV)
|
42
|
-
opts.config
|
43
|
-
config = opts.config
|
44
|
-
|
45
|
-
contacts_file = opts.contacts_file
|
46
|
-
|
47
|
-
logfile = (vim == 'mvim' || vim == 'gvim') ? STDERR : 'vmail.log'
|
48
|
-
config.merge! 'logfile' => logfile
|
49
|
-
|
50
|
-
puts "Starting vmail imap client for #{config['username']}"
|
116
|
+
puts "Setting VMAIL_BROWSER to '#{ ENV['VMAIL_BROWSER'] }'"
|
117
|
+
end
|
51
118
|
|
52
|
-
|
119
|
+
def set_inbox_poller
|
53
120
|
if config['polling'] == true
|
54
121
|
require 'vmail/inbox_poller'
|
55
122
|
inbox_poller = Vmail::InboxPoller.start config
|
@@ -59,60 +126,50 @@ module Vmail
|
|
59
126
|
else
|
60
127
|
puts "INBOX polling disabled."
|
61
128
|
end
|
129
|
+
end
|
62
130
|
|
63
|
-
|
64
|
-
|
131
|
+
def start_imap_daemon
|
65
132
|
# require after the working dir is set
|
66
133
|
require 'vmail/imap_client'
|
67
134
|
|
68
|
-
drb_uri = begin
|
135
|
+
$drb_uri = begin
|
69
136
|
Vmail::ImapClient.daemon config
|
70
137
|
rescue
|
71
138
|
puts "Failure:", $!
|
72
139
|
exit(1)
|
73
140
|
end
|
74
141
|
|
75
|
-
|
76
|
-
|
77
|
-
mailbox, query = parse_query
|
78
|
-
query_string = Vmail::Query.args2string query
|
79
|
-
server.select_mailbox mailbox
|
80
|
-
|
81
|
-
STDERR.puts "Mailbox: #{mailbox}"
|
82
|
-
STDERR.puts "Query: #{query.inspect}"
|
83
|
-
STDERR.puts "Query String: #{String.shellescape(query_string)}"
|
142
|
+
DRbObject.new_with_uri $drb_uri
|
143
|
+
end
|
84
144
|
|
85
|
-
|
86
|
-
# invoke vim
|
145
|
+
def start_vim(mailbox, query_string)
|
87
146
|
vimscript = File.expand_path("../vmail.vim", __FILE__)
|
88
147
|
vimopts = config['vim_opts']
|
89
|
-
$drb_uri = drb_uri
|
90
148
|
server_name = "VMAIL:#{ config['username'] }"
|
149
|
+
contacts_file = options.contacts_file
|
91
150
|
|
92
151
|
vim_options = {
|
93
|
-
'DRB_URI' => drb_uri,
|
152
|
+
'DRB_URI' => $drb_uri,
|
94
153
|
'VMAIL_CONTACTS_FILE' => contacts_file,
|
95
154
|
'VMAIL_MAILBOX' => String.shellescape(mailbox),
|
96
155
|
'VMAIL_QUERY' => %("#{ query_string }")
|
97
156
|
}
|
98
157
|
|
99
|
-
vim_command = "#{vim} --servername #{ server_name } -S #{vimscript} -c '#{vimopts}' #{
|
158
|
+
vim_command = "#{ vim } --servername #{ server_name } -S #{ vimscript } -c '#{ vimopts }' #{ BUFFER_FILE }"
|
100
159
|
|
101
160
|
STDERR.puts vim_options
|
102
161
|
STDERR.puts vim_command
|
103
|
-
STDERR.puts "Using buffer file: #{
|
104
|
-
File.open(
|
105
|
-
file.puts "\n\nVmail #{Vmail::VERSION}\n\n"
|
162
|
+
STDERR.puts "Using buffer file: #{ BUFFER_FILE }"
|
163
|
+
File.open(BUFFER_FILE, "w") do |file|
|
164
|
+
file.puts "\n\nVmail #{ Vmail::VERSION }\n\n"
|
106
165
|
file.puts "Please wait while I fetch your messages.\n\n\n"
|
107
166
|
end
|
108
167
|
|
109
168
|
system(vim_options, vim_command)
|
169
|
+
end
|
110
170
|
|
111
|
-
|
112
|
-
|
113
|
-
end
|
114
|
-
|
115
|
-
File.delete(buffer_file)
|
171
|
+
def close_connection
|
172
|
+
File.delete(BUFFER_FILE)
|
116
173
|
|
117
174
|
STDERR.puts "Closing imap connection"
|
118
175
|
begin
|
@@ -126,27 +183,8 @@ module Vmail
|
|
126
183
|
exit
|
127
184
|
end
|
128
185
|
|
129
|
-
|
130
|
-
|
131
|
-
def check_html_reader
|
132
|
-
return if ENV['VMAIL_HTML_PART_READER']
|
133
|
-
html_reader = %w( w3m elinks lynx ).detect {|x| `which #{x}` != ''}
|
134
|
-
if html_reader
|
135
|
-
cmd = ['w3m -dump -T text/html -I utf-8 -O utf-8', 'lynx -stdin -dump', 'elinks -dump'].detect {|s| s.index(html_reader)}
|
136
|
-
STDERR.puts "Setting VMAIL_HTML_PART_READER to '#{cmd}'"
|
137
|
-
ENV['VMAIL_HTML_PART_READER'] = cmd
|
138
|
-
else
|
139
|
-
abort "You need to install w3m, elinks, or lynx on your system in order to see html-only messages"
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
def parse_query
|
144
|
-
if ARGV[0] =~ /^\d+/
|
145
|
-
ARGV.shift
|
146
|
-
end
|
147
|
-
mailbox = ARGV.shift || 'INBOX'
|
148
|
-
query = Vmail::Query.parse(ARGV)
|
149
|
-
[mailbox, query]
|
186
|
+
def vim
|
187
|
+
ENV['VMAIL_VIM'] || 'vim'
|
150
188
|
end
|
151
189
|
end
|
152
190
|
|
@@ -4,7 +4,7 @@ require 'vmail/defaults'
|
|
4
4
|
module Vmail
|
5
5
|
class ContactsExtractor
|
6
6
|
def initialize(username, password, mailbox_config)
|
7
|
-
puts "Logging as #{username}"
|
7
|
+
puts "Logging as #{ username }"
|
8
8
|
@username, @password = username, password
|
9
9
|
|
10
10
|
@sent_mailbox = mailbox_config && mailbox_config['sent']
|
@@ -23,13 +23,13 @@ class ContactsExtractor
|
|
23
23
|
open do |imap|
|
24
24
|
set_mailbox_prefix
|
25
25
|
mailbox = "[#@prefix]/#@sent_mailbox"
|
26
|
-
STDERR.puts "Selecting #{mailbox}"
|
26
|
+
STDERR.puts "Selecting #{ mailbox }"
|
27
27
|
imap.select(mailbox)
|
28
|
-
STDERR.puts "Fetching last #{limit} sent messages"
|
28
|
+
STDERR.puts "Fetching last #{ limit } sent messages"
|
29
29
|
all_uids = imap.uid_search('ALL')
|
30
|
-
STDERR.puts "Total messages: #{all_uids.size}"
|
30
|
+
STDERR.puts "Total messages: #{ all_uids.size }"
|
31
31
|
limit = [limit, all_uids.size].min
|
32
|
-
STDERR.puts "Extracting addresses from #{limit} of them"
|
32
|
+
STDERR.puts "Extracting addresses from #{ limit } of them"
|
33
33
|
uids = all_uids[-limit ,limit]
|
34
34
|
imap.uid_fetch(uids, ["FLAGS", "ENVELOPE"]).each do |fetch_data|
|
35
35
|
recipients = fetch_data.attr["ENVELOPE"].to
|
@@ -39,7 +39,7 @@ class ContactsExtractor
|
|
39
39
|
name = address_struct.name
|
40
40
|
if name
|
41
41
|
name = Mail::Encodings.unquote_and_convert_to(name, 'UTF-8')
|
42
|
-
yield %Q("#{name}" <#{email}>)
|
42
|
+
yield %Q("#{ name }" <#{ email }>)
|
43
43
|
else
|
44
44
|
yield email
|
45
45
|
end
|
data/lib/vmail/database.rb
CHANGED
@@ -11,14 +11,14 @@ if db.tables.include?(:version) &&
|
|
11
11
|
|
12
12
|
print "Vmail database version is outdated. Recreating.\n"
|
13
13
|
`rm vmail.db`
|
14
|
-
`sqlite3 vmail.db < #{CREATE_TABLE_SCRIPT}`
|
14
|
+
`sqlite3 vmail.db < #{ CREATE_TABLE_SCRIPT }`
|
15
15
|
else
|
16
16
|
print "OK\n"
|
17
17
|
end
|
18
18
|
db.disconnect
|
19
19
|
|
20
20
|
if !File.size?('vmail.db')
|
21
|
-
puts `sqlite3 vmail.db < #{CREATE_TABLE_SCRIPT}`
|
21
|
+
puts `sqlite3 vmail.db < #{ CREATE_TABLE_SCRIPT }`
|
22
22
|
end
|
23
23
|
|
24
24
|
DB = Sequel.connect 'sqlite://vmail.db'
|
@@ -12,36 +12,36 @@ module Vmail
|
|
12
12
|
# action is -FLAGS or +FLAGS
|
13
13
|
def flag(message_ids, action, flg)
|
14
14
|
uid_set = convert_to_message_ids(message_ids)
|
15
|
-
log "Flag #{uid_set} #{flg} #{action}"
|
15
|
+
log "Flag #{ uid_set } #{ flg } #{ action }"
|
16
16
|
if flg == 'Deleted'
|
17
|
-
log "Deleting uid_set: #{uid_set.inspect}"
|
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
20
|
spawn_thread_if_tty do
|
21
21
|
unless @mailbox == mailbox_aliases['trash']
|
22
|
-
log "imap.uid_copy #{uid_set.inspect} to #{mailbox_aliases['trash']}"
|
22
|
+
log "imap.uid_copy #{ uid_set.inspect } to #{ mailbox_aliases['trash'] }"
|
23
23
|
log @imap.uid_copy(uid_set, mailbox_aliases['trash'])
|
24
24
|
end
|
25
|
-
log "imap.uid_store #{uid_set.inspect} #{action} [#{flg.to_sym}]"
|
25
|
+
log "imap.uid_store #{ uid_set.inspect } #{ action } [#{ flg.to_sym }]"
|
26
26
|
log @imap.uid_store(uid_set, action, [flg.to_sym])
|
27
27
|
reload_mailbox
|
28
28
|
clear_cached_message
|
29
29
|
end
|
30
30
|
elsif flg == 'spam' || flg == mailbox_aliases['spam']
|
31
|
-
log "Marking as spam uid_set: #{uid_set.inspect}"
|
31
|
+
log "Marking as spam uid_set: #{ uid_set.inspect }"
|
32
32
|
decrement_max_seqno(uid_set.size)
|
33
33
|
spawn_thread_if_tty do
|
34
|
-
log "imap.uid_copy #{uid_set.inspect} to #{mailbox_aliases['spam']}"
|
34
|
+
log "imap.uid_copy #{ uid_set.inspect } to #{ mailbox_aliases['spam'] }"
|
35
35
|
log @imap.uid_copy(uid_set, mailbox_aliases['spam'])
|
36
|
-
log "imap.uid_store #{uid_set.inspect} #{action} [:Deleted]"
|
36
|
+
log "imap.uid_store #{ uid_set.inspect } #{ action } [:Deleted]"
|
37
37
|
log @imap.uid_store(uid_set, action, [:Deleted])
|
38
38
|
reload_mailbox
|
39
39
|
clear_cached_message
|
40
40
|
end
|
41
41
|
else
|
42
|
-
log "Flagging uid_set: #{uid_set.inspect}"
|
42
|
+
log "Flagging uid_set: #{ uid_set.inspect }"
|
43
43
|
spawn_thread_if_tty do
|
44
|
-
log "imap.uid_store #{uid_set.inspect} #{action} [#{flg.to_sym}]"
|
44
|
+
log "imap.uid_store #{ uid_set.inspect } #{ action } [#{ flg.to_sym }]"
|
45
45
|
log @imap.uid_store(uid_set, action, [flg.to_sym])
|
46
46
|
end
|
47
47
|
end
|
@@ -52,7 +52,7 @@ module Vmail
|
|
52
52
|
def move_to(message_ids, mailbox)
|
53
53
|
uid_set = convert_to_message_ids(message_ids)
|
54
54
|
decrement_max_seqno(uid_set.size)
|
55
|
-
log "Move #{uid_set.inspect} to #{mailbox}"
|
55
|
+
log "Move #{ uid_set.inspect } to #{ mailbox }"
|
56
56
|
if mailbox == 'all'
|
57
57
|
log "Archiving messages"
|
58
58
|
end
|
@@ -60,13 +60,13 @@ module Vmail
|
|
60
60
|
mailbox = mailbox_aliases[mailbox]
|
61
61
|
end
|
62
62
|
create_if_necessary mailbox
|
63
|
-
log "Moving uid_set: #{uid_set.inspect} to #{mailbox}"
|
63
|
+
log "Moving uid_set: #{ uid_set.inspect } to #{ mailbox }"
|
64
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
|
68
68
|
clear_cached_message
|
69
|
-
log "Moved uid_set #{uid_set.inspect} to #{mailbox}"
|
69
|
+
log "Moved uid_set #{ uid_set.inspect } to #{ mailbox }"
|
70
70
|
end
|
71
71
|
rescue
|
72
72
|
log $!
|
@@ -78,10 +78,10 @@ module Vmail
|
|
78
78
|
mailbox = mailbox_aliases[mailbox]
|
79
79
|
end
|
80
80
|
create_if_necessary mailbox
|
81
|
-
log "Copying #{uid_set.inspect} to #{mailbox}"
|
81
|
+
log "Copying #{ uid_set.inspect } to #{ mailbox }"
|
82
82
|
spawn_thread_if_tty do
|
83
83
|
log @imap.uid_copy(uid_set, mailbox)
|
84
|
-
log "Copied uid_set #{uid_set.inspect} to #{mailbox}"
|
84
|
+
log "Copied uid_set #{ uid_set.inspect } to #{ mailbox }"
|
85
85
|
end
|
86
86
|
rescue
|
87
87
|
log $!
|
data/lib/vmail/helpers.rb
CHANGED
data/lib/vmail/imap_client.rb
CHANGED
@@ -92,7 +92,7 @@ module Vmail
|
|
92
92
|
if mailbox_aliases[mailbox]
|
93
93
|
mailbox = mailbox_aliases[mailbox]
|
94
94
|
end
|
95
|
-
log "Selecting mailbox #{mailbox.inspect}"
|
95
|
+
log "Selecting mailbox #{ mailbox.inspect }"
|
96
96
|
reconnect_if_necessary(30) do
|
97
97
|
log @imap.select(Net::IMAP.encode_utf7(mailbox))
|
98
98
|
end
|
@@ -137,7 +137,7 @@ module Vmail
|
|
137
137
|
def get_mailbox_status
|
138
138
|
return
|
139
139
|
@status = @imap.status(@mailbox, ["MESSAGES", "RECENT", "UNSEEN"])
|
140
|
-
log "Mailbox status:
|
140
|
+
log "Mailbox status: #@status.inspect"
|
141
141
|
end
|
142
142
|
|
143
143
|
def revive_connection
|
@@ -170,7 +170,7 @@ module Vmail
|
|
170
170
|
}.uniq
|
171
171
|
@mailboxes.delete("INBOX")
|
172
172
|
@mailboxes.unshift("INBOX")
|
173
|
-
log "Loaded mailboxes:
|
173
|
+
log "Loaded mailboxes: #@mailboxes.inspect"
|
174
174
|
@mailboxes = @mailboxes.map {|name| mailbox_aliases.invert[name] || name}
|
175
175
|
@mailboxes.join("\n")
|
176
176
|
end
|
@@ -182,13 +182,13 @@ module Vmail
|
|
182
182
|
@default_mailbox_aliases.each do |shortname, fullname_list|
|
183
183
|
fullname_list.each do |fullname|
|
184
184
|
[ "[Gmail]", "[Google Mail]" ].each do |prefix|
|
185
|
-
if self.mailboxes.include?( "#{prefix}/#{fullname}" )
|
186
|
-
@mailbox_aliases[shortname] = "#{prefix}/#{fullname}"
|
185
|
+
if self.mailboxes.include?( "#{ prefix }/#{ fullname }" )
|
186
|
+
@mailbox_aliases[shortname] = "#{ prefix }/#{ fullname }"
|
187
187
|
end
|
188
188
|
end
|
189
189
|
end
|
190
190
|
end
|
191
|
-
log "Setting aliases to #{@mailbox_aliases.inspect}"
|
191
|
+
log "Setting aliases to #{ @mailbox_aliases.inspect }"
|
192
192
|
@mailbox_aliases
|
193
193
|
end
|
194
194
|
|
@@ -202,14 +202,14 @@ module Vmail
|
|
202
202
|
|
203
203
|
def decrement_max_seqno(num)
|
204
204
|
return unless STDIN.tty?
|
205
|
-
log "Decremented max seqno from #{self.max_seqno} to #{self.max_seqno - num}"
|
205
|
+
log "Decremented max seqno from #{ self.max_seqno } to #{ self.max_seqno - num }"
|
206
206
|
self.max_seqno -= num
|
207
207
|
end
|
208
208
|
|
209
209
|
def check_for_new_messages
|
210
210
|
log "Checking for new messages"
|
211
211
|
if search_query?
|
212
|
-
log "Update aborted because query is search query: #{@query.inspect}"
|
212
|
+
log "Update aborted because query is search query: #{ @query.inspect }"
|
213
213
|
return ""
|
214
214
|
end
|
215
215
|
old_num_messages = @num_messages
|
@@ -218,18 +218,18 @@ module Vmail
|
|
218
218
|
update_query = @query.dup
|
219
219
|
# set a new range filter
|
220
220
|
# this may generate a negative rane, e.g., "19893:19992" but that seems harmless
|
221
|
-
update_query[0] = "#{old_num_messages}
|
221
|
+
update_query[0] = "#{ old_num_messages }:#@num_messages"
|
222
222
|
ids = reconnect_if_necessary {
|
223
223
|
log "Search #update_query"
|
224
224
|
@imap.search(Vmail::Query.args2string(update_query))
|
225
225
|
}
|
226
|
-
log "- got seqnos: #{ids.inspect}"
|
227
|
-
log "- getting seqnos > #{self.max_seqno}"
|
226
|
+
log "- got seqnos: #{ ids.inspect }"
|
227
|
+
log "- getting seqnos > #{ self.max_seqno }"
|
228
228
|
new_ids = ids.select {|seqno| seqno.to_i > self.max_seqno}
|
229
229
|
# reset the max_seqno
|
230
230
|
self.max_seqno = ids.max
|
231
|
-
log "- setting max_seqno to #{self.max_seqno}"
|
232
|
-
log "- new uids found: #{new_ids.inspect}"
|
231
|
+
log "- setting max_seqno to #{ self.max_seqno }"
|
232
|
+
log "- new uids found: #{ new_ids.inspect }"
|
233
233
|
update_message_list(new_ids) unless new_ids.empty?
|
234
234
|
new_ids
|
235
235
|
end
|
@@ -263,10 +263,10 @@ module Vmail
|
|
263
263
|
# gets 100 messages prior to id
|
264
264
|
def more_messages
|
265
265
|
log "Getting more_messages"
|
266
|
-
log "Old start_index:
|
266
|
+
log "Old start_index: #@start_index"
|
267
267
|
max = @start_index - 1
|
268
268
|
@start_index = [(max + 1 - @limit), 1].max
|
269
|
-
log "New start_index:
|
269
|
+
log "New start_index: #@start_index"
|
270
270
|
fetch_ids = search_query? ? @ids[@start_index..max] : (@start_index..max).to_a
|
271
271
|
log fetch_ids.inspect
|
272
272
|
message_ids = fetch_and_cache_headers(fetch_ids)
|
@@ -287,8 +287,8 @@ module Vmail
|
|
287
287
|
def create_if_necessary(mailbox)
|
288
288
|
current_mailboxes = mailboxes.map {|m| mailbox_aliases[m] || m}
|
289
289
|
if !current_mailboxes.include?(mailbox)
|
290
|
-
log "Current mailboxes: #{current_mailboxes.inspect}"
|
291
|
-
log "Creating mailbox #{mailbox}"
|
290
|
+
log "Current mailboxes: #{ current_mailboxes.inspect }"
|
291
|
+
log "Creating mailbox #{ mailbox }"
|
292
292
|
log @imap.create(mailbox)
|
293
293
|
@mailboxes = nil # force reload ...
|
294
294
|
list_mailboxes
|
@@ -297,19 +297,19 @@ module Vmail
|
|
297
297
|
|
298
298
|
def append_to_file(message_ids, file)
|
299
299
|
message_ids = message_ids.split(',')
|
300
|
-
log "Append to file uid set #{message_ids.inspect} to file: #{file}"
|
300
|
+
log "Append to file uid set #{ message_ids.inspect } to file: #{ file }"
|
301
301
|
message_ids.each do |message_id|
|
302
302
|
message = show_message(message_id)
|
303
303
|
File.open(file, 'a') {|f| f.puts(divider('=') + "\n" + message + "\n\n")}
|
304
304
|
subject = (message[/^subject:(.*)/,1] || '').strip
|
305
|
-
log "Appended message '#{subject}'"
|
305
|
+
log "Appended message '#{ subject }'"
|
306
306
|
end
|
307
|
-
"Printed #{message_ids.size} message#{message_ids.size == 1 ? '' : 's'} to #{file.strip}"
|
307
|
+
"Printed #{ message_ids.size } message#{ message_ids.size == 1 ? '' : 's' } to #{ file.strip }"
|
308
308
|
end
|
309
309
|
|
310
310
|
def new_message_template(subject = nil, append_signature = true)
|
311
311
|
#set from field to user-specified value
|
312
|
-
headers = {'from' => "
|
312
|
+
headers = {'from' => "#@name <#@from>",
|
313
313
|
'to' => nil,
|
314
314
|
'subject' => subject,
|
315
315
|
'cc' => @always_cc,
|
@@ -327,7 +327,7 @@ module Vmail
|
|
327
327
|
if value.is_a?(Array)
|
328
328
|
value = value.join(", ")
|
329
329
|
end
|
330
|
-
lines << "#{key.gsub("_", '-')}: #{value}"
|
330
|
+
lines << "#{ key.gsub("_", '-') }: #{ value }"
|
331
331
|
end
|
332
332
|
lines.join("\n")
|
333
333
|
end
|
@@ -340,7 +340,7 @@ module Vmail
|
|
340
340
|
|
341
341
|
def signature_script
|
342
342
|
return unless @signature_script
|
343
|
-
%x{ #{@signature_script.strip} }
|
343
|
+
%x{ #{ @signature_script.strip } }
|
344
344
|
end
|
345
345
|
|
346
346
|
def forward_template
|
@@ -349,7 +349,7 @@ module Vmail
|
|
349
349
|
headers = formatter.extract_headers
|
350
350
|
subject = headers['subject']
|
351
351
|
if subject !~ /Fwd: /
|
352
|
-
subject = "Fwd: #{subject}"
|
352
|
+
subject = "Fwd: #{ subject }"
|
353
353
|
end
|
354
354
|
|
355
355
|
new_message_template(subject, false) +
|
@@ -360,11 +360,11 @@ module Vmail
|
|
360
360
|
def format_sent_message(mail)
|
361
361
|
formatter = Vmail::MessageFormatter.new(mail)
|
362
362
|
message_text = <<-EOF
|
363
|
-
Sent Message #{self.format_parts_info(formatter.list_parts)}
|
363
|
+
Sent Message #{ self.format_parts_info(formatter.list_parts) }
|
364
364
|
|
365
|
-
#{format_headers(formatter.extract_headers)}
|
365
|
+
#{ format_headers(formatter.extract_headers) }
|
366
366
|
|
367
|
-
#{formatter.plaintext_part}
|
367
|
+
#{ formatter.plaintext_part }
|
368
368
|
EOF
|
369
369
|
end
|
370
370
|
|
@@ -378,9 +378,9 @@ EOF
|
|
378
378
|
log res.inspect
|
379
379
|
log "\n"
|
380
380
|
msg = if res.is_a?(Mail::Message)
|
381
|
-
"Message '#{mail.subject}' sent"
|
381
|
+
"Message '#{ mail.subject }' sent"
|
382
382
|
else
|
383
|
-
"Failed to deliver message '#{mail.subject}'!"
|
383
|
+
"Failed to deliver message '#{ mail.subject }'!"
|
384
384
|
end
|
385
385
|
log msg
|
386
386
|
msg
|
@@ -405,7 +405,7 @@ EOF
|
|
405
405
|
headers[key] = value
|
406
406
|
end
|
407
407
|
end
|
408
|
-
log "Delivering message with headers: #{headers.to_yaml}"
|
408
|
+
log "Delivering message with headers: #{ headers.to_yaml }"
|
409
409
|
mail.from = headers['from'] || @username
|
410
410
|
mail.to = headers['to'] #.split(/,\s+/)
|
411
411
|
mail.cc = headers['cc'] #&& headers['cc'].split(/,\s+/)
|
@@ -417,10 +417,10 @@ EOF
|
|
417
417
|
# after the headers, and followed by a blank line
|
418
418
|
if (attachments_section = raw_body.split(/\n\s*\n/, 2)[0]) =~ /^attach(ment|ments)*:/
|
419
419
|
files = attachments_section.split(/\n/).map {|line| line[/[-:]\s*(.*)\s*$/, 1]}.compact
|
420
|
-
log "Attach: #{files.inspect}"
|
420
|
+
log "Attach: #{ files.inspect }"
|
421
421
|
files.each do |file|
|
422
422
|
if File.directory?(file)
|
423
|
-
Dir.glob("#{file}/*").each {|f| mail.add_file(f) if File.size?(f)}
|
423
|
+
Dir.glob("#{ file }/*").each {|f| mail.add_file(f) if File.size?(f)}
|
424
424
|
else
|
425
425
|
mail.add_file(file) if File.size?(file)
|
426
426
|
end
|
@@ -441,20 +441,20 @@ EOF
|
|
441
441
|
end
|
442
442
|
|
443
443
|
def save_attachments(dir)
|
444
|
-
log "Save_attachments #{dir}"
|
444
|
+
log "Save_attachments #{ dir }"
|
445
445
|
if !current_mail
|
446
446
|
log "Missing a current message"
|
447
447
|
end
|
448
448
|
return unless dir && current_mail
|
449
449
|
attachments = current_mail.attachments
|
450
|
-
`mkdir -p #{dir}`
|
450
|
+
`mkdir -p #{ dir }`
|
451
451
|
saved = attachments.map do |x|
|
452
452
|
path = File.join(dir, x.filename)
|
453
|
-
log "Saving #{path}"
|
453
|
+
log "Saving #{ path }"
|
454
454
|
File.open(path, 'wb') {|f| f.puts x.decoded}
|
455
455
|
path
|
456
456
|
end
|
457
|
-
"Saved:\n" + saved.map {|x| "- #{x}"}.join("\n")
|
457
|
+
"Saved:\n" + saved.map {|x| "- #{ x }"}.join("\n")
|
458
458
|
end
|
459
459
|
|
460
460
|
def open_html_part
|
@@ -477,7 +477,7 @@ EOF
|
|
477
477
|
|
478
478
|
def window_width=(width)
|
479
479
|
@width = width.to_i
|
480
|
-
log "Setting window width to #{width}"
|
480
|
+
log "Setting window width to #{ width }"
|
481
481
|
end
|
482
482
|
|
483
483
|
def smtp_settings
|
@@ -528,12 +528,12 @@ EOF
|
|
528
528
|
end
|
529
529
|
|
530
530
|
def self.daemon(config)
|
531
|
-
puts "Starting Vmail::ImapClient in dir #{Dir.pwd}"
|
531
|
+
puts "Starting Vmail::ImapClient in dir #{ Dir.pwd }"
|
532
532
|
$gmail = self.start(config)
|
533
533
|
use_uri = config['drb_uri'] || nil # redundant but explicit
|
534
534
|
DRb.start_service(use_uri, $gmail)
|
535
535
|
uri = DRb.uri
|
536
|
-
puts "Starting gmail service at #{uri}"
|
536
|
+
puts "Starting gmail service at #{ uri }"
|
537
537
|
uri
|
538
538
|
end
|
539
539
|
end
|
data/lib/vmail/inbox_poller.rb
CHANGED
@@ -8,12 +8,12 @@ module Vmail
|
|
8
8
|
def start_polling
|
9
9
|
n = [`which notify-send`.chomp, `which growlnotify`.chomp].detect {|c| c != ''}
|
10
10
|
if n
|
11
|
-
log "Using notify tool: #{n}"
|
11
|
+
log "Using notify tool: #{ n }"
|
12
12
|
@notifier = case n
|
13
13
|
when /notify-send/
|
14
|
-
Proc.new {|t, m| `#{n} -t 6000000 '#{t}' '#{m}'` }
|
14
|
+
Proc.new {|t, m| `#{ n } -t 6000000 '#{ t }' '#{ m }'` }
|
15
15
|
when /growlnotify/
|
16
|
-
Proc.new {|t, m| `#{n} -t '#{t}' -m '#{m}'` }
|
16
|
+
Proc.new {|t, m| `#{ n } -t '#{ t }' -m '#{ m }'` }
|
17
17
|
end
|
18
18
|
else
|
19
19
|
log "No notification tool detected. INBOX polling aborted."
|
@@ -122,7 +122,7 @@ module Vmail
|
|
122
122
|
|
123
123
|
# doesn't try to access Sequel / sqlite3
|
124
124
|
def uncached_headers(id_set)
|
125
|
-
log "Fetching headers for #{id_set.size} messages"
|
125
|
+
log "Fetching headers for #{ id_set.size } messages"
|
126
126
|
results = reconnect_if_necessary do
|
127
127
|
@imap.fetch(id_set, ["FLAGS", "ENVELOPE", "RFC822.SIZE", "UID"])
|
128
128
|
end
|
@@ -148,7 +148,7 @@ module Vmail
|
|
148
148
|
if string.is_a?(::Net::IMAP::TaggedResponse)
|
149
149
|
string = string.raw_data
|
150
150
|
end
|
151
|
-
@logger.debug "[INBOX POLLER]: #{string}"
|
151
|
+
@logger.debug "[INBOX POLLER]: #{ string }"
|
152
152
|
end
|
153
153
|
|
154
154
|
|
@@ -15,7 +15,7 @@ module Vmail
|
|
15
15
|
list_parts(part.parts)
|
16
16
|
else
|
17
17
|
# part.charset could be used
|
18
|
-
"- #{part.content_type} #{part.attachment? ? part.filename : ''}"
|
18
|
+
"- #{ part.content_type } #{ part.attachment? ? part.filename : '' }"
|
19
19
|
end
|
20
20
|
end
|
21
21
|
lines.flatten
|
@@ -78,7 +78,7 @@ module Vmail
|
|
78
78
|
stdin, stdout, stderr = Open3.popen3(html_tool)
|
79
79
|
stdin.puts html
|
80
80
|
stdin.close
|
81
|
-
output = "[vmail: html part translated into plaintext by '#{html_tool}']\n\n" + stdout.read
|
81
|
+
output = "[vmail: html part translated into plaintext by '#{ html_tool }']\n\n" + stdout.read
|
82
82
|
charset = part.content_type_parameters && part.content_type_parameters['charset']
|
83
83
|
if charset && charset != 'UTF-8'
|
84
84
|
output.encode!('utf-8', charset, undef: :replace, invalid: :replace)
|
data/lib/vmail/options.rb
CHANGED
@@ -7,11 +7,11 @@ module Vmail
|
|
7
7
|
attr_accessor :config
|
8
8
|
attr_accessor :contacts_file
|
9
9
|
def initialize(argv)
|
10
|
-
config_file_locations = ['.vmailrc', "#{ENV['HOME']}/.vmailrc"]
|
10
|
+
config_file_locations = ['.vmailrc', "#{ ENV['HOME'] }/.vmailrc"]
|
11
11
|
@config_file = config_file_locations.detect do |path|
|
12
12
|
File.exists?(File.expand_path(path))
|
13
13
|
end
|
14
|
-
@contacts_file = [DEFAULT_CONTACTS_FILENAME, "#{ENV['HOME']}/#{DEFAULT_CONTACTS_FILENAME}"].detect do |path|
|
14
|
+
@contacts_file = [DEFAULT_CONTACTS_FILENAME, "#{ ENV['HOME'] }/#{ DEFAULT_CONTACTS_FILENAME }"].detect do |path|
|
15
15
|
File.exists?(File.expand_path(path))
|
16
16
|
end
|
17
17
|
@config = {}
|
@@ -29,7 +29,7 @@ module Vmail
|
|
29
29
|
end
|
30
30
|
opts.on("-v", "--version", "Show version") do
|
31
31
|
require 'vmail/version'
|
32
|
-
puts "vmail #{Vmail::VERSION}\nCopyright 2010 Daniel Choi under the MIT license"
|
32
|
+
puts "vmail #{ Vmail::VERSION }\nCopyright 2010 Daniel Choi under the MIT license"
|
33
33
|
exit
|
34
34
|
end
|
35
35
|
opts.on("-h", "--help", "Show this message") do
|
@@ -42,13 +42,13 @@ module Vmail
|
|
42
42
|
begin
|
43
43
|
opts.parse!(argv)
|
44
44
|
if @config_file && File.exists?(@config_file)
|
45
|
-
STDERR.puts "Using config file:
|
45
|
+
STDERR.puts "Using config file: #@config_file"
|
46
46
|
else
|
47
47
|
STDERR.puts <<EOF
|
48
48
|
|
49
49
|
Missing config file!
|
50
50
|
|
51
|
-
#{INSTRUCTIONS}
|
51
|
+
#{ INSTRUCTIONS }
|
52
52
|
EOF
|
53
53
|
exit(1)
|
54
54
|
end
|
@@ -58,7 +58,7 @@ EOF
|
|
58
58
|
STDERR.puts "No contacts file found for auto-completion. See help for how to generate it."
|
59
59
|
sleep 0.5
|
60
60
|
else
|
61
|
-
STDERR.puts "Using contacts file:
|
61
|
+
STDERR.puts "Using contacts file: #@contacts_file"
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
@@ -67,7 +67,7 @@ EOF
|
|
67
67
|
if @config['password_script'].nil?
|
68
68
|
@config['password'] = ask("Enter gmail password (won't be visible & won't be persisted):") {|q| q.echo = false}
|
69
69
|
else
|
70
|
-
@config['password'] = %x{
|
70
|
+
@config['password'] = %x{ #@config['password_script'].strip }.strip
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
@@ -83,12 +83,12 @@ EOF
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
STDERR.print "\n"
|
86
|
-
puts "Saved file to #{DEFAULT_CONTACTS_FILENAME}"
|
86
|
+
puts "Saved file to #{ DEFAULT_CONTACTS_FILENAME }"
|
87
87
|
puts "Sorting address..."
|
88
|
-
cmd = "sort #{DEFAULT_CONTACTS_FILENAME} | uniq > vmail-tmp.txt"
|
89
|
-
cmd2 = "mv vmail-tmp.txt #{DEFAULT_CONTACTS_FILENAME}"
|
90
|
-
`#{cmd}`
|
91
|
-
`#{cmd2}`
|
88
|
+
cmd = "sort #{ DEFAULT_CONTACTS_FILENAME } | uniq > vmail-tmp.txt"
|
89
|
+
cmd2 = "mv vmail-tmp.txt #{ DEFAULT_CONTACTS_FILENAME }"
|
90
|
+
`#{ cmd }`
|
91
|
+
`#{ cmd2 }`
|
92
92
|
puts "Done"
|
93
93
|
exit
|
94
94
|
end
|
data/lib/vmail/query.rb
CHANGED
@@ -16,11 +16,11 @@ module Vmail
|
|
16
16
|
def reply_headers
|
17
17
|
reply_subject = current_message.subject
|
18
18
|
if reply_subject !~ /Re: /
|
19
|
-
reply_subject = "Re: #{reply_subject}"
|
19
|
+
reply_subject = "Re: #{ reply_subject }"
|
20
20
|
end
|
21
21
|
date = DateTime.parse(current_message.date)
|
22
22
|
sender = current_message.sender
|
23
|
-
reply_quote_header = date ? "On #{date.strftime('%a, %b %d, %Y at %I:%M %p')}, #{sender} wrote:\n\n" : "#{sender} wrote:\n"
|
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
25
|
reply_body = reply_quote_header +
|
26
26
|
( current_message.plaintext.split(/^-+$/,2)[1].strip.gsub(/^(?=>)/, ">").gsub(/^(?!>)/, "> ") )
|
@@ -53,9 +53,9 @@ module Vmail
|
|
53
53
|
end
|
54
54
|
xs = xs.select {|x|
|
55
55
|
email = (x[/<([^>]+)>/, 1] || x)
|
56
|
-
email !~ /#{reply_recipient}/ \
|
56
|
+
email !~ /#{ reply_recipient }/ \
|
57
57
|
&& email !~ /#@username/ \
|
58
|
-
&& (@always_cc ? (email !~
|
58
|
+
&& (@always_cc ? (email !~ /#@always_cc/) : true)
|
59
59
|
}
|
60
60
|
if @always_cc
|
61
61
|
xs << @always_cc
|
data/lib/vmail/searching.rb
CHANGED
@@ -2,7 +2,7 @@ module Vmail
|
|
2
2
|
module Searching
|
3
3
|
# The main function called by the client to retrieve messages
|
4
4
|
def search(query)
|
5
|
-
log "#search: #{query.inspect}"
|
5
|
+
log "#search: #{ query.inspect }"
|
6
6
|
@query = Vmail::Query.parse(query)
|
7
7
|
# customizable @limit is Deprecated
|
8
8
|
@limit = 100
|
@@ -17,9 +17,9 @@ module Vmail
|
|
17
17
|
else
|
18
18
|
# set the target range to the whole set, unless it is too big
|
19
19
|
@start_index = [@num_messages - @limit, 0].max
|
20
|
-
@query.unshift "#{@start_index + 1}
|
20
|
+
@query.unshift "#{ @start_index + 1 }:#@num_messages"
|
21
21
|
query_string = Vmail::Query.args2string(@query)
|
22
|
-
log "Query: #{query_string.inspect}"
|
22
|
+
log "Query: #{ query_string.inspect }"
|
23
23
|
@ids = reconnect_if_necessary(180) do # timeout of 3 minutes
|
24
24
|
@imap.search(query_string)
|
25
25
|
end
|
@@ -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)
|
@@ -55,7 +55,7 @@ module Vmail
|
|
55
55
|
|
56
56
|
def search_query?
|
57
57
|
x = @query[-1] != 'all'
|
58
|
-
#log "Search query? #{x}"
|
58
|
+
#log "Search query? #{ x }"
|
59
59
|
x
|
60
60
|
end
|
61
61
|
end
|
data/lib/vmail/send_options.rb
CHANGED
@@ -13,7 +13,7 @@ module Vmail
|
|
13
13
|
end
|
14
14
|
opts.on("-v", "--version", "Show version (identical to vmail version)") do
|
15
15
|
require 'vmail/version'
|
16
|
-
puts "vmail #{Vmail::VERSION}\nCopyright 2010 Daniel Choi under the MIT license"
|
16
|
+
puts "vmail #{ Vmail::VERSION }\nCopyright 2010 Daniel Choi under the MIT license"
|
17
17
|
exit
|
18
18
|
end
|
19
19
|
opts.on("-h", "--help", "Show this message") do
|
@@ -26,13 +26,13 @@ module Vmail
|
|
26
26
|
begin
|
27
27
|
opts.parse!(argv)
|
28
28
|
if @config_file && File.exists?(@config_file)
|
29
|
-
puts "Using config file
|
29
|
+
puts "Using config file #@config_file"
|
30
30
|
else
|
31
31
|
puts <<EOF
|
32
32
|
|
33
33
|
Missing config file!
|
34
34
|
|
35
|
-
#{INSTRUCTIONS}
|
35
|
+
#{ INSTRUCTIONS }
|
36
36
|
EOF
|
37
37
|
exit(1)
|
38
38
|
end
|
@@ -6,7 +6,7 @@ module Vmail
|
|
6
6
|
messages = message_ids.map {|message_id|
|
7
7
|
m = Message[message_id]
|
8
8
|
if m.nil?
|
9
|
-
raise "Message #{message_id} not found"
|
9
|
+
raise "Message #{ message_id } not found"
|
10
10
|
end
|
11
11
|
m
|
12
12
|
}
|
@@ -15,7 +15,7 @@ module Vmail
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def fetch_and_cache_headers(id_set)
|
18
|
-
log "Fetching headers for #{id_set.size} messages"
|
18
|
+
log "Fetching headers for #{ id_set.size } messages"
|
19
19
|
results = reconnect_if_necessary do
|
20
20
|
@imap.fetch(id_set, ["FLAGS", "ENVELOPE", "RFC822.SIZE", "UID"])
|
21
21
|
end
|
@@ -49,7 +49,7 @@ module Vmail
|
|
49
49
|
message.update params
|
50
50
|
|
51
51
|
unless Vmail::Labeling[message_id: message_id, label_id: @label.label_id]
|
52
|
-
params = {message_id: message.message_id, uid: uid, label_id: @label.label_id}
|
52
|
+
params = { message_id: message.message_id, uid: uid, label_id: @label.label_id }
|
53
53
|
|
54
54
|
Labeling.create params
|
55
55
|
end
|
@@ -65,7 +65,7 @@ module Vmail
|
|
65
65
|
(address_struct.host ? Mail::Encodings.unquote_and_convert_to(address_struct.host, 'UTF-8'): "")
|
66
66
|
].join('@')
|
67
67
|
if address_struct.name
|
68
|
-
"#{Mail::Encodings.unquote_and_convert_to((address_struct.name || ''), 'UTF-8')} <#{email}>"
|
68
|
+
"#{ Mail::Encodings.unquote_and_convert_to((address_struct.name || ''), 'UTF-8') } <#{ email }>"
|
69
69
|
else
|
70
70
|
email
|
71
71
|
end
|
@@ -112,7 +112,7 @@ module Vmail
|
|
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
|
@@ -15,20 +15,20 @@ module Vmail
|
|
15
15
|
def cached_full_message?(message_id)
|
16
16
|
m = Message[message_id]
|
17
17
|
if m
|
18
|
-
log "- found message #{message_id}"
|
18
|
+
log "- found message #{ message_id }"
|
19
19
|
log "- message has plaintext? #{!m.plaintext.nil?}"
|
20
20
|
else
|
21
|
-
log "- could not find message #{message_id.inspect}"
|
21
|
+
log "- could not find message #{ message_id.inspect }"
|
22
22
|
end
|
23
23
|
m && !m.plaintext.nil? && m
|
24
24
|
end
|
25
25
|
|
26
26
|
def show_message(message_id, raw=false)
|
27
27
|
message_id = message_id.strip.gsub('\\', '')
|
28
|
-
log "Show message: #{message_id.inspect}"
|
28
|
+
log "Show message: #{ message_id.inspect }"
|
29
29
|
return current_message.rfc822 if raw
|
30
30
|
res = retry_if_needed { fetch_and_cache(message_id) }
|
31
|
-
log "Showing message message_id: #{message_id}"
|
31
|
+
log "Showing message message_id: #{ message_id }"
|
32
32
|
@cur_message_id = message_id
|
33
33
|
res
|
34
34
|
end
|
@@ -39,21 +39,21 @@ module Vmail
|
|
39
39
|
return message.plaintext
|
40
40
|
end
|
41
41
|
log "- full message cache miss"
|
42
|
-
params = {message_id: message_id, label_id: @label.label_id}
|
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)
|
45
|
-
log "- Labeling not found for #{params.inspect}"
|
45
|
+
log "- Labeling not found for #{ params.inspect }"
|
46
46
|
# break out early
|
47
|
-
return "\nUnable to get message for #{labeling.values}"
|
47
|
+
return "\nUnable to get message for #{ labeling.values }"
|
48
48
|
end
|
49
49
|
uid = labeling.uid
|
50
50
|
|
51
|
-
log "- fetching message uid #{uid}"
|
51
|
+
log "- fetching message uid #{ uid }"
|
52
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
|
-
raise "Message uid #{uid} could not be fetched from server" if res.nil?
|
56
|
+
raise "Message uid #{ uid } could not be fetched from server" if res.nil?
|
57
57
|
res[0]
|
58
58
|
end
|
59
59
|
seqno = fetch_data.seqno
|
@@ -75,11 +75,11 @@ module Vmail
|
|
75
75
|
body = body.encode!('us-ascii', 'utf-8', undef: :replace, invalid: :replace)
|
76
76
|
end
|
77
77
|
message_text = <<-EOF
|
78
|
-
#{message_id} #{number_to_human_size message.size} #{message.flags} #{parts_list}
|
79
|
-
#{divider '-'}
|
80
|
-
#{headers}
|
78
|
+
#{ message_id } #{ number_to_human_size message.size } #{ message.flags } #{ parts_list }
|
79
|
+
#{ divider '-' }
|
80
|
+
#{ headers }
|
81
81
|
|
82
|
-
#{body}
|
82
|
+
#{ body }
|
83
83
|
EOF
|
84
84
|
# 2 calls so we can see more fine grained exceptions
|
85
85
|
message.update(:rfc822 => rfc822)
|
@@ -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} [
|
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
|
@@ -104,7 +104,7 @@ EOF
|
|
104
104
|
def format_parts_info(parts)
|
105
105
|
lines = parts #.select {|part| part !~ %r{text/plain}}
|
106
106
|
if lines.size > 0
|
107
|
-
"\n#{lines.join("\n")}"
|
107
|
+
"\n#{ lines.join("\n") }"
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
data/lib/vmail/version.rb
CHANGED
data/vmail.gemspec
CHANGED
@@ -13,6 +13,7 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.homepage = "http://danielchoi.com/software/vmail.html"
|
14
14
|
s.summary = %q{A Vim interface to Gmail}
|
15
15
|
s.description = %q{Manage your email with Vim}
|
16
|
+
s.licenses = %w(MIT)
|
16
17
|
|
17
18
|
s.rubyforge_project = "vmail"
|
18
19
|
|
@@ -21,9 +22,9 @@ Gem::Specification.new do |s|
|
|
21
22
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
22
23
|
s.require_paths = ["lib"]
|
23
24
|
|
24
|
-
s.
|
25
|
-
s.
|
26
|
-
s.
|
27
|
-
s.
|
28
|
-
s.
|
25
|
+
s.add_runtime_dependency 'mail', '~> 2.2', '>= 2.2.12'
|
26
|
+
s.add_runtime_dependency 'highline', '~> 1.6', '>= 1.6.1'
|
27
|
+
s.add_runtime_dependency 'sequel', '~> 3.24', '>= 3.24.1'
|
28
|
+
s.add_runtime_dependency 'sqlite3', '~> 1.3', '>= 1.3.3'
|
29
|
+
s.add_runtime_dependency 'versionomy', '~> 0.4', '>= 0.4.4'
|
29
30
|
end
|
metadata
CHANGED
@@ -1,19 +1,22 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vmail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.9.
|
4
|
+
version: 2.9.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Choi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mail
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.2'
|
17
20
|
- - ! '>='
|
18
21
|
- !ruby/object:Gem::Version
|
19
22
|
version: 2.2.12
|
@@ -21,6 +24,9 @@ dependencies:
|
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.2'
|
24
30
|
- - ! '>='
|
25
31
|
- !ruby/object:Gem::Version
|
26
32
|
version: 2.2.12
|
@@ -28,6 +34,9 @@ dependencies:
|
|
28
34
|
name: highline
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
30
36
|
requirements:
|
37
|
+
- - ~>
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.6'
|
31
40
|
- - ! '>='
|
32
41
|
- !ruby/object:Gem::Version
|
33
42
|
version: 1.6.1
|
@@ -35,6 +44,9 @@ dependencies:
|
|
35
44
|
prerelease: false
|
36
45
|
version_requirements: !ruby/object:Gem::Requirement
|
37
46
|
requirements:
|
47
|
+
- - ~>
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '1.6'
|
38
50
|
- - ! '>='
|
39
51
|
- !ruby/object:Gem::Version
|
40
52
|
version: 1.6.1
|
@@ -42,6 +54,9 @@ dependencies:
|
|
42
54
|
name: sequel
|
43
55
|
requirement: !ruby/object:Gem::Requirement
|
44
56
|
requirements:
|
57
|
+
- - ~>
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '3.24'
|
45
60
|
- - ! '>='
|
46
61
|
- !ruby/object:Gem::Version
|
47
62
|
version: 3.24.1
|
@@ -49,6 +64,9 @@ dependencies:
|
|
49
64
|
prerelease: false
|
50
65
|
version_requirements: !ruby/object:Gem::Requirement
|
51
66
|
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '3.24'
|
52
70
|
- - ! '>='
|
53
71
|
- !ruby/object:Gem::Version
|
54
72
|
version: 3.24.1
|
@@ -56,6 +74,9 @@ dependencies:
|
|
56
74
|
name: sqlite3
|
57
75
|
requirement: !ruby/object:Gem::Requirement
|
58
76
|
requirements:
|
77
|
+
- - ~>
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '1.3'
|
59
80
|
- - ! '>='
|
60
81
|
- !ruby/object:Gem::Version
|
61
82
|
version: 1.3.3
|
@@ -63,6 +84,9 @@ dependencies:
|
|
63
84
|
prerelease: false
|
64
85
|
version_requirements: !ruby/object:Gem::Requirement
|
65
86
|
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.3'
|
66
90
|
- - ! '>='
|
67
91
|
- !ruby/object:Gem::Version
|
68
92
|
version: 1.3.3
|
@@ -70,6 +94,9 @@ dependencies:
|
|
70
94
|
name: versionomy
|
71
95
|
requirement: !ruby/object:Gem::Requirement
|
72
96
|
requirements:
|
97
|
+
- - ~>
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0.4'
|
73
100
|
- - ! '>='
|
74
101
|
- !ruby/object:Gem::Version
|
75
102
|
version: 0.4.4
|
@@ -77,6 +104,9 @@ dependencies:
|
|
77
104
|
prerelease: false
|
78
105
|
version_requirements: !ruby/object:Gem::Requirement
|
79
106
|
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0.4'
|
80
110
|
- - ! '>='
|
81
111
|
- !ruby/object:Gem::Version
|
82
112
|
version: 0.4.4
|
@@ -141,7 +171,8 @@ files:
|
|
141
171
|
- test/time_format_test.rb
|
142
172
|
- vmail.gemspec
|
143
173
|
homepage: http://danielchoi.com/software/vmail.html
|
144
|
-
licenses:
|
174
|
+
licenses:
|
175
|
+
- MIT
|
145
176
|
metadata: {}
|
146
177
|
post_install_message:
|
147
178
|
rdoc_options: []
|