mournmail 0.3.2 → 1.0.0
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.
- checksums.yaml +4 -4
- data/README.md +6 -2
- data/lib/mournmail/commands.rb +11 -2
- data/lib/mournmail/config.rb +8 -0
- data/lib/mournmail/draft_mode.rb +23 -2
- data/lib/mournmail/message_mode.rb +16 -10
- data/lib/mournmail/message_rendering.rb +78 -18
- data/lib/mournmail/summary.rb +2 -1
- data/lib/mournmail/summary_mode.rb +19 -12
- data/lib/mournmail/utils.rb +26 -4
- data/lib/mournmail/version.rb +1 -1
- data/mournmail.gemspec +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8cbf82ccf54ab48f7596d24aaacb4673ca8f8271f304264df7aa96a932dac2fb
|
4
|
+
data.tar.gz: facbe695e21c68a1b5c50a9bb9d50894f948e09bab2a436b2174656953b809bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49c6ba544f435ea5eb150b510e26d18ab0bcd0fddd1a1a147dc0aee84bde05656bb153f44628ee0828b2e02c8f6ccc27b75c7e61b34ca0511c0eb2f074240e1e
|
7
|
+
data.tar.gz: 43accf4207ec48914c79940d2c45ce931beab826759b3e64174257891bf70d741913800aa976b41c19a2b47d1a0c8e32a00215995889058fdee5c82b4bc6e5e0
|
data/README.md
CHANGED
@@ -33,7 +33,11 @@ CONFIG[:mournmail_accounts] = {
|
|
33
33
|
},
|
34
34
|
spam_mailbox: "spam",
|
35
35
|
outbox_mailbox: "outbox",
|
36
|
-
archive_mailbox_format: "archive/%Y"
|
36
|
+
archive_mailbox_format: "archive/%Y",
|
37
|
+
signature: <<~EOF
|
38
|
+
--
|
39
|
+
Shugo Maeda <shugo@example.com>
|
40
|
+
EOF
|
37
41
|
},
|
38
42
|
"gmail.com" => {
|
39
43
|
from: "Example <example@gmail.com>",
|
@@ -54,7 +58,7 @@ CONFIG[:mournmail_accounts] = {
|
|
54
58
|
password: File.read(File.expand_path("~/.textbringer/gmail_passwd")).chomp,
|
55
59
|
ssl: true
|
56
60
|
},
|
57
|
-
spam_mailbox: "
|
61
|
+
spam_mailbox: "[Gmail]/迷惑メール",
|
58
62
|
archive_mailbox_format: false
|
59
63
|
},
|
60
64
|
}
|
data/lib/mournmail/commands.rb
CHANGED
@@ -11,6 +11,14 @@ define_command(:mournmail_visit_mailbox, doc: "Visit mailbox") do
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
+
define_command(:mournmail_visit_spam_mailbox, doc: "Visit spam mailbox") do
|
15
|
+
mailbox = Mournmail.account_config[:spam_mailbox]
|
16
|
+
if mailbox.nil?
|
17
|
+
raise EditorError, "spam_mailbox is not specified"
|
18
|
+
end
|
19
|
+
mournmail_visit_mailbox(Net::IMAP.encode_utf7(mailbox))
|
20
|
+
end
|
21
|
+
|
14
22
|
define_command(:mournmail_summary_sync, doc: "Sync summary.") do
|
15
23
|
|mailbox = (Mournmail.current_mailbox || "INBOX"),
|
16
24
|
all = current_prefix_arg|
|
@@ -61,9 +69,10 @@ define_command(:mail, doc: "Write a new mail.") do
|
|
61
69
|
User-Agent: Mournmail/#{Mournmail::VERSION} Textbringer/#{Textbringer::VERSION} Ruby/#{RUBY_VERSION}
|
62
70
|
--text follows this line--
|
63
71
|
EOF
|
64
|
-
|
65
|
-
|
72
|
+
beginning_of_buffer
|
73
|
+
re_search_forward(/^To: */)
|
66
74
|
if run_hooks
|
75
|
+
Mournmail.insert_signature
|
67
76
|
run_hooks(:mournmail_draft_setup_hook)
|
68
77
|
end
|
69
78
|
end
|
data/lib/mournmail/config.rb
CHANGED
@@ -14,6 +14,13 @@ module Textbringer
|
|
14
14
|
"X-Mailer",
|
15
15
|
"Content-Type"
|
16
16
|
]
|
17
|
+
CONFIG[:mournmail_quote_header_fields] = [
|
18
|
+
"Subject",
|
19
|
+
"Date",
|
20
|
+
"From",
|
21
|
+
"To",
|
22
|
+
"Cc"
|
23
|
+
]
|
17
24
|
CONFIG[:mournmail_imap_connect_timeout] = 10
|
18
25
|
CONFIG[:mournmail_keep_alive_interval] = 60
|
19
26
|
case RUBY_PLATFORM
|
@@ -28,4 +35,5 @@ module Textbringer
|
|
28
35
|
CONFIG[:mournmail_link_open_comamnd] = "xdg-open"
|
29
36
|
end
|
30
37
|
CONFIG[:mournmail_addresses_path] = File.expand_path("~/.addresses")
|
38
|
+
CONFIG[:mournmail_signature_regexp] = /^\n-- /
|
31
39
|
end
|
data/lib/mournmail/draft_mode.rb
CHANGED
@@ -8,6 +8,7 @@ module Mournmail
|
|
8
8
|
MAIL_MODE_MAP.define_key("\C-c\C-xv", :draft_pgp_sign_command)
|
9
9
|
MAIL_MODE_MAP.define_key("\C-c\C-xe", :draft_pgp_encrypt_command)
|
10
10
|
MAIL_MODE_MAP.define_key("\C-c\t", :insert_signature_command)
|
11
|
+
MAIL_MODE_MAP.define_key("\C-c@", :draft_change_account_command)
|
11
12
|
|
12
13
|
define_syntax :field_name, /^[A-Za-z\-]+: /
|
13
14
|
define_syntax :quotation, /^>.*/
|
@@ -68,12 +69,15 @@ module Mournmail
|
|
68
69
|
content: File.read(file),
|
69
70
|
encoding: "binary")
|
70
71
|
end
|
71
|
-
|
72
|
+
account = @buffer[:mournmail_delivery_account] ||
|
73
|
+
Mournmail.current_account
|
74
|
+
conf = CONFIG[:mournmail_accounts][account]
|
72
75
|
options = @buffer[:mournmail_delivery_options] ||
|
73
76
|
conf[:delivery_options]
|
74
77
|
if options[:authentication] == "gmail"
|
78
|
+
token = Mournmail.google_access_token(account)
|
75
79
|
options = options.merge(authentication: "xoauth2",
|
76
|
-
password:
|
80
|
+
password: token)
|
77
81
|
end
|
78
82
|
m.delivery_method(@buffer[:mournmail_delivery_method] ||
|
79
83
|
conf[:delivery_method],
|
@@ -186,6 +190,23 @@ module Mournmail
|
|
186
190
|
@buffer.insert(CONFIG[:signature])
|
187
191
|
end
|
188
192
|
|
193
|
+
define_local_command(:draft_change_account, doc: "Change account.") do
|
194
|
+
|account = Mournmail.read_account_name("Change account: ")|
|
195
|
+
from = CONFIG[:mournmail_accounts][account][:from]
|
196
|
+
@buffer[:mournmail_delivery_account] = account
|
197
|
+
@buffer.save_excursion do
|
198
|
+
@buffer.beginning_of_buffer
|
199
|
+
@buffer.re_search_forward(/^From:.*/)
|
200
|
+
@buffer.replace_match("From: " + from)
|
201
|
+
@buffer.end_of_buffer
|
202
|
+
if @buffer.re_search_backward(CONFIG[:mournmail_signature_regexp],
|
203
|
+
raise_error: false)
|
204
|
+
@buffer.delete_region(@buffer.point, @buffer.point_max)
|
205
|
+
end
|
206
|
+
Mournmail.insert_signature
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
189
210
|
private
|
190
211
|
|
191
212
|
def end_of_header
|
@@ -12,7 +12,7 @@ module Mournmail
|
|
12
12
|
|
13
13
|
# See http://nihongo.jp/support/mail_guide/dev_guide.txt
|
14
14
|
MAILTO_REGEXP = URI.regexp("mailto")
|
15
|
-
URI_REGEXP = /(https?|ftp):\/\/[^ \t\n>)"]*[
|
15
|
+
URI_REGEXP = /(https?|ftp):\/\/[^ \t\n>)"]*[^\] \t\n>.,:)"]+|#{MAILTO_REGEXP}/
|
16
16
|
MIME_REGEXP = /^\[(([0-9.]+) [A-Za-z._\-]+\/[A-Za-z._\-]+.*|PGP\/MIME .*)\]$/
|
17
17
|
URI_OR_MIME_REGEXP = /#{URI_REGEXP}|#{MIME_REGEXP}/
|
18
18
|
|
@@ -24,6 +24,7 @@ module Mournmail
|
|
24
24
|
def initialize(buffer)
|
25
25
|
super(buffer)
|
26
26
|
buffer.keymap = MESSAGE_MODE_MAP
|
27
|
+
@attached_file = nil
|
27
28
|
end
|
28
29
|
|
29
30
|
define_local_command(:message_open_link_or_part,
|
@@ -52,6 +53,9 @@ module Mournmail
|
|
52
53
|
|
53
54
|
define_local_command(:message_next_link_or_part,
|
54
55
|
doc: "Go to the next link or MIME part.") do
|
56
|
+
if @buffer.looking_at?(URI_OR_MIME_REGEXP)
|
57
|
+
@buffer.forward_char
|
58
|
+
end
|
55
59
|
if @buffer.re_search_forward(URI_OR_MIME_REGEXP, raise_error: false)
|
56
60
|
goto_char(@buffer.match_beginning(0))
|
57
61
|
else
|
@@ -76,8 +80,8 @@ module Mournmail
|
|
76
80
|
|
77
81
|
def part_file_name(part)
|
78
82
|
file_name =
|
79
|
-
part["content-disposition"]&.parameters&.[]("filename") ||
|
80
|
-
part["content-type"]&.parameters&.[]("name") ||
|
83
|
+
(part["content-disposition"]&.parameters&.[]("filename") rescue nil) ||
|
84
|
+
(part["content-type"]&.parameters&.[]("name") rescue nil) ||
|
81
85
|
part_default_file_name(part)
|
82
86
|
decoded_file_name = Mail::Encodings.decode_encode(file_name, :decode)
|
83
87
|
if /\A([A-Za-z0-9_\-]+)'(?:[A-Za-z0-9_\-])*'(.*)/ =~ decoded_file_name
|
@@ -130,18 +134,20 @@ module Mournmail
|
|
130
134
|
else
|
131
135
|
file_name = "mournmail"
|
132
136
|
end
|
133
|
-
|
137
|
+
@attached_file = Tempfile.open(file_name, binmode: true)
|
134
138
|
s = part.decoded
|
135
|
-
if part.
|
139
|
+
if part.content_type == "text/html"
|
140
|
+
s = s.sub(/<meta http-equiv="content-type".*?>/i, "")
|
141
|
+
elsif part.charset
|
136
142
|
s = s.encode(part.charset)
|
137
143
|
end
|
138
|
-
|
139
|
-
|
140
|
-
if
|
141
|
-
find_file(
|
144
|
+
@attached_file.write(s)
|
145
|
+
@attached_file.close
|
146
|
+
if part.main_type == "text" && part.sub_type != "html"
|
147
|
+
find_file(@attached_file.path)
|
142
148
|
else
|
143
149
|
background do
|
144
|
-
system(*CONFIG[:mournmail_file_open_comamnd],
|
150
|
+
system(*CONFIG[:mournmail_file_open_comamnd], @attached_file.path,
|
145
151
|
out: File::NULL, err: File::NULL)
|
146
152
|
end
|
147
153
|
end
|
@@ -8,8 +8,8 @@ module Mournmail
|
|
8
8
|
render_header + "\n" + render_body(indices)
|
9
9
|
end
|
10
10
|
|
11
|
-
def render_header
|
12
|
-
|
11
|
+
def render_header(fields = CONFIG[:mournmail_display_header_fields])
|
12
|
+
fields.map { |name|
|
13
13
|
val = self[name]&.to_s&.gsub(/\t/, " ")
|
14
14
|
val ? "#{name}: #{val}\n" : ""
|
15
15
|
}.join
|
@@ -41,11 +41,36 @@ module Mournmail
|
|
41
41
|
else
|
42
42
|
type = Mail::Encodings.decode_encode(self["content-type"].to_s,
|
43
43
|
:decode) rescue
|
44
|
-
|
44
|
+
"broken/type; error=\"#{$!} (#{$!.class})\""
|
45
45
|
"[0 #{type}]\n"
|
46
46
|
end + pgp_signature
|
47
47
|
end
|
48
48
|
|
49
|
+
def render_text(indices = [])
|
50
|
+
if HAVE_MAIL_GPG && encrypted?
|
51
|
+
mail = decrypt(verify: true)
|
52
|
+
return mail.render_text(indices)
|
53
|
+
end
|
54
|
+
if multipart?
|
55
|
+
parts.each_with_index.map { |part, i|
|
56
|
+
if sub_type == "alternative" && i > 0
|
57
|
+
""
|
58
|
+
else
|
59
|
+
part.render_text([*indices, i])
|
60
|
+
end
|
61
|
+
}.join("\n")
|
62
|
+
elsif main_type.nil? || main_type == "text"
|
63
|
+
s = Mournmail.to_utf8(body.decoded, charset)
|
64
|
+
if sub_type == "html"
|
65
|
+
Html2Text.convert(s)
|
66
|
+
else
|
67
|
+
s
|
68
|
+
end
|
69
|
+
else
|
70
|
+
""
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
49
74
|
def dig_part(i, *rest_indices)
|
50
75
|
if HAVE_MAIL_GPG && encrypted?
|
51
76
|
mail = decrypt(verify: true)
|
@@ -91,7 +116,39 @@ module Mournmail
|
|
91
116
|
:decode) rescue
|
92
117
|
"broken/type; error=\"#{$!} (#{$!.class})\""
|
93
118
|
"[#{index} #{type}]\n" +
|
94
|
-
|
119
|
+
render_content(indices, no_content)
|
120
|
+
end
|
121
|
+
|
122
|
+
def render_text(indices)
|
123
|
+
if multipart?
|
124
|
+
parts.each_with_index.map { |part, i|
|
125
|
+
if sub_type == "alternative" && i > 0
|
126
|
+
""
|
127
|
+
else
|
128
|
+
part.render_text([*indices, i])
|
129
|
+
end
|
130
|
+
}.join("\n")
|
131
|
+
else
|
132
|
+
if main_type == "message" && sub_type == "rfc822"
|
133
|
+
mail = Mail.new(body.raw_source)
|
134
|
+
mail.render_header(CONFIG[:mournmail_quote_header_fields]) +
|
135
|
+
"\n" + mail.render_text(indices)
|
136
|
+
elsif attachment?
|
137
|
+
""
|
138
|
+
else
|
139
|
+
if main_type == "text"
|
140
|
+
if sub_type == "html"
|
141
|
+
Html2Text.convert(decoded).sub(/(?<!\n)\z/, "\n")
|
142
|
+
else
|
143
|
+
decoded.sub(/(?<!\n)\z/, "\n").gsub(/\r\n/, "\n")
|
144
|
+
end
|
145
|
+
else
|
146
|
+
""
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
rescue => e
|
151
|
+
""
|
95
152
|
end
|
96
153
|
|
97
154
|
def dig_part(i, *rest_indices)
|
@@ -110,26 +167,29 @@ module Mournmail
|
|
110
167
|
|
111
168
|
private
|
112
169
|
|
113
|
-
def render_content(indices)
|
170
|
+
def render_content(indices, no_content)
|
114
171
|
if multipart?
|
115
172
|
parts.each_with_index.map { |part, i|
|
116
|
-
|
117
|
-
|
173
|
+
part.render([*indices, i],
|
174
|
+
no_content || sub_type == "alternative" && i > 0)
|
118
175
|
}.join
|
119
|
-
elsif main_type == "message" && sub_type == "rfc822"
|
120
|
-
mail = Mail.new(body.raw_source)
|
121
|
-
mail.render(indices)
|
122
|
-
elsif attachment?
|
123
|
-
""
|
124
176
|
else
|
125
|
-
|
126
|
-
|
127
|
-
|
177
|
+
return "" if no_content
|
178
|
+
if main_type == "message" && sub_type == "rfc822"
|
179
|
+
mail = Mail.new(body.raw_source)
|
180
|
+
mail.render(indices)
|
181
|
+
elsif attachment?
|
182
|
+
""
|
183
|
+
else
|
184
|
+
if main_type == "text"
|
185
|
+
if sub_type == "html"
|
186
|
+
Html2Text.convert(decoded).sub(/(?<!\n)\z/, "\n")
|
187
|
+
else
|
188
|
+
decoded.sub(/(?<!\n)\z/, "\n").gsub(/\r\n/, "\n")
|
189
|
+
end
|
128
190
|
else
|
129
|
-
|
191
|
+
""
|
130
192
|
end
|
131
|
-
else
|
132
|
-
""
|
133
193
|
end
|
134
194
|
end
|
135
195
|
rescue => e
|
data/lib/mournmail/summary.rb
CHANGED
@@ -141,7 +141,8 @@ module Mournmail
|
|
141
141
|
end
|
142
142
|
s = data[0].attr["BODY[]"]
|
143
143
|
mail = Mournmail.parse_mail(s)
|
144
|
-
|
144
|
+
spam_mailbox = Mournmail.account_config[:spam_mailbox]
|
145
|
+
if @mailbox != Net::IMAP.encode_utf7(spam_mailbox)
|
145
146
|
item.cache_id = Mournmail.write_mail_cache(s)
|
146
147
|
Mournmail.index_mail(item.cache_id, mail)
|
147
148
|
end
|
@@ -25,6 +25,7 @@ module Mournmail
|
|
25
25
|
SUMMARY_MODE_MAP.define_key("*t", :summary_mark_unflagged_command)
|
26
26
|
SUMMARY_MODE_MAP.define_key("y", :summary_archive_command)
|
27
27
|
SUMMARY_MODE_MAP.define_key("o", :summary_refile_command)
|
28
|
+
SUMMARY_MODE_MAP.define_key("!", :summary_refile_spam_command)
|
28
29
|
SUMMARY_MODE_MAP.define_key("p", :summary_prefetch_command)
|
29
30
|
SUMMARY_MODE_MAP.define_key("X", :summary_expunge_command)
|
30
31
|
SUMMARY_MODE_MAP.define_key("v", :summary_view_source_command)
|
@@ -33,6 +34,7 @@ module Mournmail
|
|
33
34
|
SUMMARY_MODE_MAP.define_key("k", :previous_line)
|
34
35
|
SUMMARY_MODE_MAP.define_key("j", :next_line)
|
35
36
|
SUMMARY_MODE_MAP.define_key("m", :mournmail_visit_mailbox)
|
37
|
+
SUMMARY_MODE_MAP.define_key("S", :mournmail_visit_spam_mailbox)
|
36
38
|
SUMMARY_MODE_MAP.define_key("/", :summary_search_command)
|
37
39
|
SUMMARY_MODE_MAP.define_key("t", :summary_show_thread_command)
|
38
40
|
SUMMARY_MODE_MAP.define_key("@", :summary_change_account_command)
|
@@ -98,7 +100,7 @@ module Mournmail
|
|
98
100
|
|reply_all = current_prefix_arg|
|
99
101
|
Mournmail.background do
|
100
102
|
mail = read_current_mail[0]
|
101
|
-
body = mail.
|
103
|
+
body = mail.render_text
|
102
104
|
foreground do
|
103
105
|
Window.current = Mournmail.message_window
|
104
106
|
Commands.mail(run_hooks: false)
|
@@ -137,6 +139,7 @@ module Mournmail
|
|
137
139
|
On #{mail['date']}
|
138
140
|
#{mail['from']} wrote:
|
139
141
|
EOF
|
142
|
+
Mournmail.insert_signature
|
140
143
|
exchange_point_and_mark
|
141
144
|
run_hooks(:mournmail_draft_setup_hook)
|
142
145
|
end
|
@@ -373,10 +376,23 @@ module Mournmail
|
|
373
376
|
end
|
374
377
|
end
|
375
378
|
|
379
|
+
define_local_command(:summary_refile_spam,
|
380
|
+
doc: "Refile marked mails as spam.") do
|
381
|
+
mailbox = Mournmail.account_config[:spam_mailbox]
|
382
|
+
if mailbox.nil?
|
383
|
+
raise EditorError, "spam_mailbox is not specified"
|
384
|
+
end
|
385
|
+
summary_refile(Net::IMAP.encode_utf7(mailbox))
|
386
|
+
end
|
387
|
+
|
376
388
|
define_local_command(:summary_prefetch,
|
377
389
|
doc: "Prefetch mails.") do
|
378
390
|
summary = Mournmail.current_summary
|
379
391
|
mailbox = Mournmail.current_mailbox
|
392
|
+
spam_mailbox = Mournmail.account_config[:spam_mailbox]
|
393
|
+
if mailbox == Net::IMAP.encode_utf7(spam_mailbox)
|
394
|
+
raise EditorError, "Can't prefetch spam"
|
395
|
+
end
|
380
396
|
target_uids = @buffer.to_s.scan(/^ *\d+/).map { |s|
|
381
397
|
s.to_i
|
382
398
|
}.select { |uid|
|
@@ -394,9 +410,7 @@ module Mournmail
|
|
394
410
|
s = i.attr["BODY[]"]
|
395
411
|
if s
|
396
412
|
cache_id = Mournmail.write_mail_cache(s)
|
397
|
-
|
398
|
-
Mournmail.index_mail(cache_id, Mail.new(s))
|
399
|
-
end
|
413
|
+
Mournmail.index_mail(cache_id, Mail.new(s))
|
400
414
|
summary[uid].cache_id = cache_id
|
401
415
|
end
|
402
416
|
end
|
@@ -450,7 +464,7 @@ module Mournmail
|
|
450
464
|
|
451
465
|
define_local_command(:summary_change_account,
|
452
466
|
doc: "Change the current account.") do
|
453
|
-
|account = read_account_name("Change account: ")|
|
467
|
+
|account = Mournmail.read_account_name("Change account: ")|
|
454
468
|
unless CONFIG[:mournmail_accounts].key?(account)
|
455
469
|
raise EditorError, "No such account: #{account}"
|
456
470
|
end
|
@@ -651,13 +665,6 @@ module Mournmail
|
|
651
665
|
message
|
652
666
|
end
|
653
667
|
|
654
|
-
def read_account_name(prompt, **opts)
|
655
|
-
f = ->(s) {
|
656
|
-
complete_for_minibuffer(s, CONFIG[:mournmail_accounts].keys)
|
657
|
-
}
|
658
|
-
read_from_minibuffer(prompt, completion_proc: f, **opts)
|
659
|
-
end
|
660
|
-
|
661
668
|
def delete_from_summary(summary, uids, msg)
|
662
669
|
summary.delete_item_if do |item|
|
663
670
|
uids.include?(item.uid)
|
data/lib/mournmail/utils.rb
CHANGED
@@ -225,15 +225,16 @@ module Mournmail
|
|
225
225
|
end
|
226
226
|
end
|
227
227
|
|
228
|
-
def self.google_access_token
|
229
|
-
auth_path = File.expand_path("cache/#{
|
228
|
+
def self.google_access_token(account = current_account)
|
229
|
+
auth_path = File.expand_path("cache/#{account}/google_auth.json",
|
230
230
|
CONFIG[:mournmail_directory])
|
231
231
|
FileUtils.mkdir_p(File.dirname(auth_path))
|
232
232
|
store = Google::APIClient::FileStore.new(auth_path)
|
233
233
|
storage = Google::APIClient::Storage.new(store)
|
234
234
|
storage.authorize
|
235
235
|
if storage.authorization.nil?
|
236
|
-
|
236
|
+
conf = CONFIG[:mournmail_accounts][account]
|
237
|
+
path = File.expand_path(conf[:client_secret_path])
|
237
238
|
client_secrets = Google::APIClient::ClientSecrets.load(path)
|
238
239
|
auth_client = client_secrets.to_authorization
|
239
240
|
auth_client.update!(
|
@@ -382,7 +383,8 @@ module Mournmail
|
|
382
383
|
dir = File.dirname(path)
|
383
384
|
base = File.basename(path)
|
384
385
|
begin
|
385
|
-
f = Tempfile.create(["#{base}-", ".tmp"], dir
|
386
|
+
f = Tempfile.create(["#{base}-", ".tmp"], dir,
|
387
|
+
external_encoding: "ASCII-8BIT", binmode: true)
|
386
388
|
begin
|
387
389
|
f.write(s)
|
388
390
|
ensure
|
@@ -554,4 +556,24 @@ module Mournmail
|
|
554
556
|
def self.parse_mail(s)
|
555
557
|
Mail.new(s.scrub("??"))
|
556
558
|
end
|
559
|
+
|
560
|
+
def self.read_account_name(prompt, **opts)
|
561
|
+
f = ->(s) {
|
562
|
+
complete_for_minibuffer(s, CONFIG[:mournmail_accounts].keys)
|
563
|
+
}
|
564
|
+
read_from_minibuffer(prompt, completion_proc: f, **opts)
|
565
|
+
end
|
566
|
+
|
567
|
+
def self.insert_signature
|
568
|
+
account = Buffer.current[:mournmail_delivery_account] ||
|
569
|
+
Mournmail.current_account
|
570
|
+
signature = CONFIG[:mournmail_accounts][account][:signature]
|
571
|
+
if signature
|
572
|
+
Buffer.current.save_excursion do
|
573
|
+
end_of_buffer
|
574
|
+
insert("\n")
|
575
|
+
insert(signature)
|
576
|
+
end
|
577
|
+
end
|
578
|
+
end
|
557
579
|
end
|
data/lib/mournmail/version.rb
CHANGED
data/mournmail.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mournmail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shugo Maeda
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-06-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: textbringer
|
@@ -126,14 +126,14 @@ dependencies:
|
|
126
126
|
name: rake
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
|
-
- - "
|
129
|
+
- - ">="
|
130
130
|
- !ruby/object:Gem::Version
|
131
131
|
version: '12.0'
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
|
-
- - "
|
136
|
+
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '12.0'
|
139
139
|
description: A message user agent for Textbringer.
|