glima 0.3.1 → 0.3.2
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/.gitignore +1 -1
- data/Dockerfile +49 -0
- data/README.org +35 -0
- data/Rakefile +18 -0
- data/emacs/axman.el +156 -0
- data/exe/glima +37 -13
- data/exe/glima-docker.sh +6 -0
- data/glima.gemspec +1 -1
- data/lib/glima/gmail_client.rb +4 -1
- data/lib/glima/imap.rb +81 -39
- data/lib/glima/version.rb +1 -1
- metadata +9 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0260fea2c5f1589c7ea8cf305e1f77c724be667a
|
4
|
+
data.tar.gz: f6cc75417943bb19e01050dace7ac9af881962f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7249a0885cbcf95760e7204adbbf90c5f7a4b99dcd4e512110c358aa7cef23929b90e88d6366ac11339716e870741d5b489473bb499cc3fb0998cfe03daed75b
|
7
|
+
data.tar.gz: f745b82e4aa88c6e7493a9e47573cf03b035cd760ae7d6f22942e973c00593834a1ef9e75e5223f0667a10c64511310c62995decb72bd02df0af8b0aca78f88a
|
data/.gitignore
CHANGED
@@ -41,7 +41,7 @@ build/
|
|
41
41
|
# for a library or gem, you might want to ignore these files since the code is
|
42
42
|
# intended to run in multiple environments; otherwise, check them in:
|
43
43
|
# Gemfile.lock
|
44
|
-
|
44
|
+
.ruby-version
|
45
45
|
# .ruby-gemset
|
46
46
|
|
47
47
|
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
data/Dockerfile
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# * Dockerfile for glima
|
2
|
+
# https://github.com/yoshinari-nomura/glima
|
3
|
+
#
|
4
|
+
# * How to buld
|
5
|
+
# ** from command line
|
6
|
+
# bundle exec rake build
|
7
|
+
# docker build --build-arg GLIMA_VERSION=$(bundle exec glima version) -t nom4476/glima .
|
8
|
+
#
|
9
|
+
# ** from Rakefile
|
10
|
+
# bundle exec rake docker:build
|
11
|
+
#
|
12
|
+
# * How to run
|
13
|
+
# mkdir -p ~/.config/glima ~/.cache/glima
|
14
|
+
#
|
15
|
+
# docker run -it --rm \
|
16
|
+
# -v $HOME/.config/glima:/root/.config/glima \
|
17
|
+
# -v $HOME/.cache/glima:/root/.cache/glima \
|
18
|
+
# nom4476/glima init
|
19
|
+
#
|
20
|
+
# docker run -it --rm \
|
21
|
+
# -v $HOME/.config/glima:/root/.config/glima \
|
22
|
+
# -v $HOME/.cache/glima:/root/.cache/glima \
|
23
|
+
# nom4476/glima init
|
24
|
+
#
|
25
|
+
# * For debug
|
26
|
+
# docker run -it --rm -v $HOME/.config/glima:/root/.config/glima --entrypoint "sh" nom4476/glima
|
27
|
+
#
|
28
|
+
#
|
29
|
+
FROM alpine:3.6
|
30
|
+
|
31
|
+
MAINTAINER nom@quickhack.net
|
32
|
+
|
33
|
+
RUN mkdir -p $HOME/.config/glima
|
34
|
+
RUN mkdir -p $HOME/.cache/glima
|
35
|
+
|
36
|
+
RUN echo 'gem: --no-ri --no-rdoc' > $HOME/.gemrc
|
37
|
+
|
38
|
+
RUN apk --update add ruby ruby-json && rm -rf /var/cache/apk/*
|
39
|
+
|
40
|
+
ARG GLIMA_VERSION
|
41
|
+
ENV GLIMA_VERSION $GLIMA_VERSION
|
42
|
+
ENV RUBYOPT "-W0"
|
43
|
+
RUN test -n "$GLIMA_VERSION"
|
44
|
+
|
45
|
+
COPY pkg/glima-${GLIMA_VERSION}.gem /tmp
|
46
|
+
RUN gem install /tmp/glima-$GLIMA_VERSION.gem
|
47
|
+
|
48
|
+
ENTRYPOINT [ "glima" ]
|
49
|
+
CMD [ "help" ]
|
data/README.org
CHANGED
@@ -45,6 +45,15 @@
|
|
45
45
|
$ export PATH=/path/to/install/glima/exe:$PATH
|
46
46
|
#+END_SRC
|
47
47
|
|
48
|
+
** Install from Docker image
|
49
|
+
#+BEGIN_SRC sh
|
50
|
+
$ docker pull nom4476/glima
|
51
|
+
$ curl https://raw.githubusercontent.com/yoshinari-nomura/glima/master/exe/glima-docker.sh > glima
|
52
|
+
$ chmod +x glima
|
53
|
+
$ mkdir -p ~/.config/glima ~/.cache/glima
|
54
|
+
$ ./glima help
|
55
|
+
#+END_SRC
|
56
|
+
|
48
57
|
* Setup
|
49
58
|
1) Get OAuth CLIENT_ID/CLIENT_SECRET
|
50
59
|
|
@@ -89,3 +98,29 @@
|
|
89
98
|
2 09/27 14:00 15ec1b716bbb6bdc Yeah...
|
90
99
|
:
|
91
100
|
#+END_SRC
|
101
|
+
|
102
|
+
* Invoke decrypter from emacs mailer (Mew)
|
103
|
+
Minimum setup: add belows in your .emacs:
|
104
|
+
#+BEGIN_SRC emacs-lisp
|
105
|
+
(setq load-path
|
106
|
+
(cons "~/path/to/this/file load-path"))
|
107
|
+
(autoload 'axman-mew-decrypt-current-message-gmail "axman")
|
108
|
+
(autoload 'axman-mew-decrypt-current-message-local "axman")
|
109
|
+
#+END_SRC
|
110
|
+
|
111
|
+
How to use:
|
112
|
+
1) In mew-summary buffer (ie. %inbox),
|
113
|
+
point at an email with encrypted-ZIP attachment.
|
114
|
+
|
115
|
+
2) M-x axman-mew-decrypt-current-message-local
|
116
|
+
|
117
|
+
3) It will find the password from the current folder (%inbox)
|
118
|
+
inspecting in passwordish-emails.
|
119
|
+
|
120
|
+
axman-mew-decrypt-current-message-gmail is another version that works
|
121
|
+
with Gmail server. It would be useful if your email server is
|
122
|
+
Gmail with IMAP enabled.
|
123
|
+
|
124
|
+
* Japanese blog entry about glima xzip.
|
125
|
+
+ [[http://quickhack.net/nom/blog/2017-11-06-password-is-in-another-mail.html][「パスワードは別途お送りします」をなんとかしたい]]
|
126
|
+
+ [[http://quickhack.net/nom/blog/2017-11-29-mail-decrypter-for-mew.html][「パスワードは別途お送りします」を Mew でなんとかしたい]]
|
data/Rakefile
CHANGED
@@ -3,4 +3,22 @@ require "rspec/core/rake_task"
|
|
3
3
|
|
4
4
|
RSpec::Core::RakeTask.new(:spec)
|
5
5
|
|
6
|
+
|
7
|
+
|
8
|
+
namespace :docker do
|
9
|
+
tag = "nom4476/glima"
|
10
|
+
|
11
|
+
desc "Build Docker image from Dockerfile"
|
12
|
+
task :build do
|
13
|
+
version = Glima::VERSION
|
14
|
+
system "docker build --build-arg GLIMA_VERSION=#{version} -t #{tag} ."
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Push current Docker image to Docker Hub"
|
18
|
+
task :push do
|
19
|
+
system "docker push #{tag}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
task "docker:build" => "^build"
|
6
24
|
task :default => :spec
|
data/emacs/axman.el
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
;;; axman.el --- Automatic decrypter for attachments in emails.
|
2
|
+
|
3
|
+
;; Description: Automatic decrypter for attachments in emails.
|
4
|
+
;; Author: Yoshinari Nomura <nom@quickhack.net>
|
5
|
+
;; Created: 2016-08-24
|
6
|
+
;; Version: 0.1.0
|
7
|
+
;; Keywords: Mail Decrypter Zip
|
8
|
+
;; URL: https://github.com/yoshinari-nomura/axman
|
9
|
+
;; Package-Requires:
|
10
|
+
|
11
|
+
;;;
|
12
|
+
;;; Commentary:
|
13
|
+
;;;
|
14
|
+
|
15
|
+
;; Minimum setup:
|
16
|
+
;; 1) setup axzip ruby script in glima.
|
17
|
+
;; https://github.com/yoshinari-nomura/glima
|
18
|
+
;;
|
19
|
+
;; 2) add belows in your .emacs:
|
20
|
+
;; (setq load-path
|
21
|
+
;; (cons "~/path/to/this/file load-path"))
|
22
|
+
;; (autoload 'axman-mew-decrypt-current-message-gmail "axman")
|
23
|
+
;; (autoload 'axman-mew-decrypt-current-message-local "axman")
|
24
|
+
;;
|
25
|
+
;; How to use:
|
26
|
+
;; 1) In mew-summary buffer (ie. %inbox),
|
27
|
+
;; point at an email with encrypted-ZIP attachment.
|
28
|
+
;;
|
29
|
+
;; 2) M-x axman-mew-decrypt-current-message-local
|
30
|
+
;;
|
31
|
+
;; 3) It will find the password from the current folder (%inbox)
|
32
|
+
;; inspecting in passwordish-emails.
|
33
|
+
;;
|
34
|
+
;; axman-mew-decrypt-current-message-gmail is another version that works
|
35
|
+
;; with Gmail server. It would be useful if your email server is
|
36
|
+
;; Gmail with IMAP enabled.
|
37
|
+
;;
|
38
|
+
|
39
|
+
;;; Code:
|
40
|
+
|
41
|
+
(defcustom axman-attachment-store-directory "~/Downloads"
|
42
|
+
"Where to store unlocked zip file."
|
43
|
+
:group 'axman
|
44
|
+
:type 'directory)
|
45
|
+
|
46
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
47
|
+
;; Helper function works with Mew.
|
48
|
+
|
49
|
+
(defvar mew-regex-sumsyn-long)
|
50
|
+
(defvar mew-regex-sumsyn-short)
|
51
|
+
|
52
|
+
(declare-function mew-header-get-value "mew")
|
53
|
+
(declare-function mew-sumsyn-match "mew")
|
54
|
+
(declare-function mew-sumsyn-folder-name "mew")
|
55
|
+
(declare-function mew-sumsyn-message-number "mew")
|
56
|
+
(declare-function mew-msg-get-filename "mew")
|
57
|
+
(declare-function mew-expand-msg "mew")
|
58
|
+
(declare-function mew-expand-folder "mew")
|
59
|
+
(declare-function mew-summary-goto-message "mew")
|
60
|
+
(declare-function mew-summary-set-message-buffer "mew")
|
61
|
+
|
62
|
+
(defmacro mewx-with-current-message-buffer (&rest body)
|
63
|
+
"Eval BODY after switch from summary to message."
|
64
|
+
`(save-excursion
|
65
|
+
(mew-summary-goto-message)
|
66
|
+
(mew-sumsyn-match mew-regex-sumsyn-short)
|
67
|
+
(mew-summary-set-message-buffer
|
68
|
+
(mew-sumsyn-folder-name)
|
69
|
+
(mew-sumsyn-message-number))
|
70
|
+
,@body))
|
71
|
+
|
72
|
+
(defun mewx-current-info (property)
|
73
|
+
"Get PROPERTY of pointed messsage."
|
74
|
+
(when (mew-sumsyn-match mew-regex-sumsyn-long)
|
75
|
+
(let* ((folder (mew-sumsyn-folder-name))
|
76
|
+
(number (mew-sumsyn-message-number))
|
77
|
+
(path (mew-msg-get-filename (mew-expand-msg folder number)))
|
78
|
+
(directory (mew-expand-folder folder)))
|
79
|
+
(cdr (assoc
|
80
|
+
property
|
81
|
+
`((folder . ,folder)
|
82
|
+
(number . ,number)
|
83
|
+
(path . ,path)
|
84
|
+
(directory . ,directory)))))))
|
85
|
+
|
86
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
87
|
+
;; Decrypt attachments
|
88
|
+
|
89
|
+
(defmacro axman-with-decrypter-buffer (buffer message &rest body)
|
90
|
+
"Wrap decrypter in BUFFER with MESSAGE.
|
91
|
+
BODY should returns process object of ``start-process''."
|
92
|
+
`(let ((,buffer (get-buffer-create " *Axman*")))
|
93
|
+
(save-selected-window
|
94
|
+
(pop-to-buffer ,buffer)
|
95
|
+
(delete-region (point-min) (point-max))
|
96
|
+
(insert "Decrypting " (or ,message "") "...\n")
|
97
|
+
(recenter -1))
|
98
|
+
(set-process-sentinel
|
99
|
+
,@body
|
100
|
+
(lambda (proc event)
|
101
|
+
(let ((,buffer (process-buffer proc)))
|
102
|
+
(with-current-buffer ,buffer
|
103
|
+
(if (save-excursion
|
104
|
+
(re-search-backward "^Wrote to \\(.*\\)\\." nil t))
|
105
|
+
(start-process "open" ,buffer "open" "-R" (match-string 1)))))))))
|
106
|
+
|
107
|
+
(put 'axman-with-decrypter-buffer 'lisp-indent-function 2)
|
108
|
+
|
109
|
+
(defun axman-start-gmail-decrypter (target-mail extract-directory)
|
110
|
+
"Invoke Gmail decrypter process. Return process object.
|
111
|
+
It decrypts zip-attachments in TARGET-MAIL and stores the decrypted zip-files
|
112
|
+
into EXTRACT-DIRECTORY. TARGET-MAIL should be in the form of Gmail message-id
|
113
|
+
like: 15c5723f8d3dba57."
|
114
|
+
(axman-with-decrypter-buffer process-buffer target-mail
|
115
|
+
(start-process "glima" process-buffer
|
116
|
+
"glima" "dezip" target-mail extract-directory)))
|
117
|
+
|
118
|
+
(defun axman-start-mh-decrypter (target-mail password-source extract-directory)
|
119
|
+
"Invoke MH decrypter process. Return process object.
|
120
|
+
It decrypts zip-attachments in TARGET-MAIL using PASSWORD-SOURCE,
|
121
|
+
and stores the decrypted zip-files into EXTRACT-DIRECTORY.
|
122
|
+
TARGET-MAIL a filename of MHC-style mail.
|
123
|
+
MH decrypter takes PASSWORD-SOURCE as a MH-style folder directory
|
124
|
+
from where piking password mails."
|
125
|
+
(axman-with-decrypter-buffer process-buffer target-mail
|
126
|
+
(start-process "axezip" process-buffer
|
127
|
+
"axezip" target-mail password-source extract-directory)))
|
128
|
+
|
129
|
+
;;;###autoload
|
130
|
+
(defun axman-mew-decrypt-current-message-gmail ()
|
131
|
+
"Decrypt attachment from Gmail."
|
132
|
+
(interactive)
|
133
|
+
(let ((message-id
|
134
|
+
(mewx-with-current-message-buffer
|
135
|
+
(mew-header-get-value "X-GM-MSGID:"))))
|
136
|
+
(if message-id
|
137
|
+
(axman-start-gmail-decrypter
|
138
|
+
message-id
|
139
|
+
axman-attachment-store-directory)
|
140
|
+
(message "No message found."))))
|
141
|
+
|
142
|
+
;;;###autoload
|
143
|
+
(defun axman-mew-decrypt-current-message-local ()
|
144
|
+
"Decrypt current zip attachments."
|
145
|
+
(interactive)
|
146
|
+
(let ((path (mewx-current-info 'path))
|
147
|
+
(password-source (mewx-current-info 'directory)))
|
148
|
+
(if path
|
149
|
+
(axman-start-mh-decrypter
|
150
|
+
path password-source
|
151
|
+
axman-attachment-store-directory)
|
152
|
+
(message "No message found."))))
|
153
|
+
|
154
|
+
(provide 'axman)
|
155
|
+
|
156
|
+
;;; axman.el ends here
|
data/exe/glima
CHANGED
@@ -30,6 +30,18 @@ require "logger"
|
|
30
30
|
|
31
31
|
Encoding.default_external="UTF-8"
|
32
32
|
|
33
|
+
# For debug
|
34
|
+
Signal.trap('USR2') do
|
35
|
+
pid = Process.pid
|
36
|
+
STDERR.puts "[#{pid}] Received USR2 at #{Time.now}. Dumping threads:"
|
37
|
+
Thread.list.each do |t|
|
38
|
+
trace = t.backtrace.join("\n[#{pid}] ")
|
39
|
+
STDERR.puts "[#{pid}] #{trace}"
|
40
|
+
STDERR.puts "[#{pid}] ---"
|
41
|
+
end
|
42
|
+
STDERR.puts "[#{pid}] -------------------"
|
43
|
+
end
|
44
|
+
|
33
45
|
class GlimaCLI < Clian::Cli
|
34
46
|
package_name 'GLIMA'
|
35
47
|
remove_command :configuration
|
@@ -238,9 +250,9 @@ class GlimaCLI < Clian::Cli
|
|
238
250
|
|
239
251
|
error_count = 0
|
240
252
|
begin
|
253
|
+
timestamp = Time.now
|
241
254
|
ql = parse_label_names(queue_label).first
|
242
255
|
ml = parse_label_names(mark_label).first
|
243
|
-
timestamp = Time.now
|
244
256
|
Glima::Command::Watch.new(ql, ml, default_passwords)
|
245
257
|
rescue => err
|
246
258
|
@logger.info err
|
@@ -317,28 +329,31 @@ class GlimaCLI < Clian::Cli
|
|
317
329
|
$GLIMA_DEBUG_FOR_DEVELOPER = true if ENV["GLIMA_DEBUG_FOR_DEVELOPER"]
|
318
330
|
end
|
319
331
|
|
320
|
-
@logger
|
321
|
-
|
322
|
-
|
332
|
+
unless @logger
|
333
|
+
@logger = ::Logger.new($stderr)
|
334
|
+
@logger.formatter = proc {|severity, datetime, progname, msg| "#{datetime} #{msg}\n"}
|
335
|
+
Glima::Command.logger = @logger
|
336
|
+
end
|
323
337
|
|
324
338
|
@config_path = options[:config] || DEFAULT_CONFIG_PATH
|
325
339
|
|
326
340
|
return true if ["init", "help"].member?(command.name)
|
327
341
|
|
328
|
-
@config
|
329
|
-
@datastore
|
342
|
+
@config ||= Glima::Config.create_from_file(@config_path)
|
343
|
+
@datastore ||= Glima::DataStore.new(File.expand_path(config.general.cache_directory))
|
330
344
|
@user = options[:user] || config.general.default_user
|
331
|
-
@context
|
332
|
-
@client
|
333
|
-
|
334
|
-
|
335
|
-
|
345
|
+
@context ||= Glima::Context.new(File.expand_path(DEFAULT_CONFIG_HOME))
|
346
|
+
@client ||= Glima::GmailClient.new(config.general.client_id,
|
347
|
+
config.general.client_secret,
|
348
|
+
File.expand_path("token_store.yml", File.dirname(@config_path)),
|
349
|
+
@user, @datastore, @logger)
|
336
350
|
|
337
|
-
Glima::Command.client
|
351
|
+
Glima::Command.client ||= @client
|
338
352
|
|
339
353
|
unless ["auth"].member?(command.name)
|
340
354
|
begin
|
341
|
-
@client.auth
|
355
|
+
@client.auth unless @client_already_authorized
|
356
|
+
@client_already_authorized = true
|
342
357
|
rescue Glima::GmailClient::AuthorizationError
|
343
358
|
Thor.new.say "ERROR: access token expired? try: glima auth --user=#{@user}", :red
|
344
359
|
exit(1)
|
@@ -346,6 +361,15 @@ class GlimaCLI < Clian::Cli
|
|
346
361
|
end
|
347
362
|
end
|
348
363
|
end
|
364
|
+
|
365
|
+
def custom_completion_for_banner(banner)
|
366
|
+
case banner
|
367
|
+
when /^USER/
|
368
|
+
"(#{config.general.default_user})"
|
369
|
+
else
|
370
|
+
nil
|
371
|
+
end
|
372
|
+
end
|
349
373
|
end
|
350
374
|
|
351
375
|
GlimaCLI.start(ARGV)
|
data/exe/glima-docker.sh
ADDED
data/glima.gemspec
CHANGED
@@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.required_ruby_version = ">= 2.3.0"
|
28
28
|
|
29
29
|
spec.add_runtime_dependency "thor", ">= 0.19.1"
|
30
|
-
spec.add_runtime_dependency "clian", ">= 0.
|
30
|
+
spec.add_runtime_dependency "clian", ">= 0.4.0"
|
31
31
|
spec.add_runtime_dependency "mail"
|
32
32
|
spec.add_runtime_dependency "rubyzip"
|
33
33
|
|
data/lib/glima/gmail_client.rb
CHANGED
@@ -265,9 +265,12 @@ module Glima
|
|
265
265
|
|
266
266
|
begin
|
267
267
|
@imap.wait(label&.name, timeout_sec)
|
268
|
-
|
268
|
+
|
269
|
+
rescue => err
|
269
270
|
@imap = nil
|
270
271
|
@logger.info "[#{self.class}#wait] imap connection error. abandon current imap connection."
|
272
|
+
@logger.info err
|
273
|
+
@logger.info err.backtrace
|
271
274
|
end
|
272
275
|
@logger.info "[#{self.class}#wait] Exit"
|
273
276
|
end
|
data/lib/glima/imap.rb
CHANGED
@@ -12,6 +12,42 @@ module Glima
|
|
12
12
|
usessl = false, certs = nil, verify = true)
|
13
13
|
super
|
14
14
|
@parser = Glima::IMAP::ResponseParser.new
|
15
|
+
|
16
|
+
set_keepalive(@sock, 30) # set *TCP* Keepalive
|
17
|
+
end
|
18
|
+
|
19
|
+
# https://www.winehq.org/pipermail/wine-devel/2015-July/108583.html
|
20
|
+
# TCP_KEEPALIVE on Darwin corresponds to Linux TCP_KEEPIDLE, not TCP_KEEPINTVL.
|
21
|
+
#
|
22
|
+
# * Darwin (macOS)
|
23
|
+
# /usr/include/netinet/tcp.h:
|
24
|
+
# : #define TCP_KEEPALIVE 0x10 /* idle time used when SO_KEEPALIVE is enabled */
|
25
|
+
# : TCP_KEEPALIVE = 0x10
|
26
|
+
# : TCP_KEEPCNT = 0x102
|
27
|
+
# : TCP_KEEPINTVL = 0x101
|
28
|
+
# * Linux
|
29
|
+
# : TCP_KEEPIDLE
|
30
|
+
# : TCP_KEEPCNT
|
31
|
+
# : TCP_KEEPINTVL
|
32
|
+
#
|
33
|
+
# Configurable TCP keepalives by normelton: PR #262 redis/redis-rb
|
34
|
+
# https://github.com/redis/redis-rb/pull/262
|
35
|
+
#
|
36
|
+
def set_keepalive(sock, sec)
|
37
|
+
xTCP_KEEPIDLE = if RUBY_PLATFORM =~ /darwin/ then 0x10 else :TCP_KEEPIDLE end
|
38
|
+
|
39
|
+
idle, interval, probes = if sec >= 60
|
40
|
+
[sec - 20, 10, 2]
|
41
|
+
elsif sec >= 30
|
42
|
+
[sec - 10, 5, 2]
|
43
|
+
elsif sec >= 5
|
44
|
+
[sec - 2, 2, 1]
|
45
|
+
end
|
46
|
+
|
47
|
+
sock.setsockopt(:SOL_SOCKET, :SO_KEEPALIVE, true)
|
48
|
+
sock.setsockopt(:IPPROTO_TCP, xTCP_KEEPIDLE, idle)
|
49
|
+
sock.setsockopt(:IPPROTO_TCP, :TCP_KEEPINTVL, interval)
|
50
|
+
sock.setsockopt(:IPPROTO_TCP, :TCP_KEEPCNT, probes)
|
15
51
|
end
|
16
52
|
|
17
53
|
class Xoauth2Authenticator
|
@@ -89,63 +125,69 @@ module Glima
|
|
89
125
|
|
90
126
|
def_delegators :@imap,
|
91
127
|
:fetch,
|
92
|
-
:select,
|
93
128
|
:disconnected?
|
94
129
|
|
95
130
|
def initialize(imap_server, authorization, logger)
|
96
131
|
@imap_server, @authorization, @logger = imap_server, authorization, logger
|
132
|
+
@current_folder = nil
|
97
133
|
connect(imap_server, authorization)
|
98
134
|
end
|
99
135
|
|
100
136
|
def wait(folder = nil, timeout_sec = 60)
|
101
|
-
|
102
|
-
|
103
|
-
if folder
|
104
|
-
folder = Net::IMAP.encode_utf7(folder)
|
105
|
-
else
|
106
|
-
# select "[Gmail]/All Mail" or localized one like "[Gmail]/すべてのメール"
|
107
|
-
folder = @imap.list("", "[Gmail]/*").find {|f| f.attr.include?(:All)}.name
|
108
|
-
end
|
137
|
+
select(folder || :all) unless @current_folder
|
109
138
|
|
110
|
-
|
139
|
+
logger.info "[#{self.class}#wait] Enter"
|
111
140
|
begin
|
112
|
-
|
113
|
-
|
114
|
-
sleep timeout
|
115
|
-
ensure
|
116
|
-
imap.idle_done
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
@imap.idle do |resp|
|
141
|
+
logger.info "[#{self.class}#wait] IMAP IDLE start (timeout: #{timeout_sec})"
|
142
|
+
@imap.idle(timeout_sec) do |resp|
|
121
143
|
logger.info "[#{self.class}#wait] got event #{resp.name} in IMAP IDLE"
|
122
|
-
|
123
|
-
end
|
124
|
-
rescue Net::IMAP::Error => e
|
125
|
-
if e.inspect.include? "connection closed"
|
126
|
-
reconnect
|
127
|
-
else
|
128
|
-
raise
|
144
|
+
@imap.idle_done
|
129
145
|
end
|
146
|
+
logger.info "[#{self.class}#wait] IMAP IDLE done"
|
147
|
+
|
148
|
+
# rescue Net::IMAP::Error => e
|
149
|
+
# if e.inspect.include? "connection closed"
|
150
|
+
# reconnect
|
151
|
+
# else
|
152
|
+
# raise
|
153
|
+
# end
|
130
154
|
end
|
131
155
|
logger.info "[#{self.class}#wait] Exit"
|
132
156
|
end # def wait
|
133
157
|
|
134
158
|
private
|
135
159
|
|
160
|
+
def select(folder)
|
161
|
+
@current_folder = folder
|
162
|
+
|
163
|
+
if folder == :all
|
164
|
+
# select "[Gmail]/All Mail" or localized one like "[Gmail]/すべてのメール"
|
165
|
+
folder = @imap.list("", "[Gmail]/*").find {|f| f.attr.include?(:All)}.name
|
166
|
+
else
|
167
|
+
folder = Net::IMAP.encode_utf7(folder)
|
168
|
+
end
|
169
|
+
|
170
|
+
logger.info "[#{self.class}#wait] IMAP Selecting #{Net::IMAP.decode_utf7(folder)}..."
|
171
|
+
@imap.select(folder)
|
172
|
+
logger.info "[#{self.class}#wait] IMAP Selected #{Net::IMAP.decode_utf7(folder)}"
|
173
|
+
end
|
174
|
+
|
136
175
|
def connect(imap_server, authorization)
|
137
176
|
logger.info "[#{self.class}#connect] Enter"
|
138
177
|
retry_count = 0
|
139
178
|
|
140
179
|
begin
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
180
|
+
Timeout.timeout(10) do
|
181
|
+
# @imap = Glima::IMAP.new(imap_server, 993, true)
|
182
|
+
@imap = Glima::IMAP.new(imap_server, :port => 993, :ssl => {:timeout => 10})
|
183
|
+
|
184
|
+
@imap.authenticate('XOAUTH2',
|
185
|
+
authorization.username,
|
186
|
+
authorization.access_token)
|
187
|
+
logger.info "[#{self.class}#connect] connected"
|
188
|
+
end
|
189
|
+
rescue Timeout::Error, Net::IMAP::NoResponseError => e
|
190
|
+
logger.info "[#{self.class}#connect] rescue #{e}"
|
149
191
|
|
150
192
|
if e.inspect.include? "Invalid credentials" && retry_count < 2
|
151
193
|
logger.info "[#{self.class}#connect] Refreshing access token for #{imap_server}."
|
@@ -159,11 +201,11 @@ module Glima
|
|
159
201
|
logger.info "[#{self.class}#connect] Exit"
|
160
202
|
end
|
161
203
|
|
162
|
-
def reconnect
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
end
|
204
|
+
# def reconnect
|
205
|
+
# logger.info "[#{self.class}#reconnect] Enter"
|
206
|
+
# connect(@imap_server, @authorization)
|
207
|
+
# logger.info "[#{self.class}#reconnect] Exit"
|
208
|
+
# end
|
167
209
|
|
168
210
|
def logger
|
169
211
|
@logger
|
data/lib/glima/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glima
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yoshinari Nomura
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-04-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.4.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
40
|
+
version: 0.4.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: mail
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,20 +114,24 @@ email:
|
|
114
114
|
executables:
|
115
115
|
- axezip
|
116
116
|
- glima
|
117
|
+
- glima-docker.sh
|
117
118
|
extensions: []
|
118
119
|
extra_rdoc_files: []
|
119
120
|
files:
|
120
121
|
- ".gitignore"
|
121
122
|
- ".rspec"
|
122
123
|
- ".travis.yml"
|
124
|
+
- Dockerfile
|
123
125
|
- Gemfile
|
124
126
|
- LICENSE.txt
|
125
127
|
- README.org
|
126
128
|
- Rakefile
|
127
129
|
- bin/console
|
128
130
|
- bin/setup
|
131
|
+
- emacs/axman.el
|
129
132
|
- exe/axezip
|
130
133
|
- exe/glima
|
134
|
+
- exe/glima-docker.sh
|
131
135
|
- glima.gemspec
|
132
136
|
- lib/glima.rb
|
133
137
|
- lib/glima/command.rb
|
@@ -180,7 +184,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
180
184
|
version: '0'
|
181
185
|
requirements: []
|
182
186
|
rubyforge_project:
|
183
|
-
rubygems_version: 2.5.2
|
187
|
+
rubygems_version: 2.5.2.2
|
184
188
|
signing_key:
|
185
189
|
specification_version: 4
|
186
190
|
summary: Gmail CLI client
|