imapcli 0.0.1
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 +7 -0
- data/.gitignore +4 -0
- data/.rspec +1 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +117 -0
- data/Guardfile +65 -0
- data/README.md +227 -0
- data/Rakefile +45 -0
- data/bin/imapcli +131 -0
- data/imapcli.gemspec +21 -0
- data/imapcli.rdoc +5 -0
- data/lib/imapcli/client.rb +226 -0
- data/lib/imapcli/command.rb +100 -0
- data/lib/imapcli/mailbox.rb +108 -0
- data/lib/imapcli/version.rb +3 -0
- data/lib/imapcli.rb +4 -0
- data/spec/lib/imapcli/client_spec.rb +70 -0
- data/spec/lib/imapcli/mailbox_spec.rb +21 -0
- data/spec/spec_helper.rb +102 -0
- metadata +111 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a446b1918219fb961e61ddce7f63e260a05eefff
|
4
|
+
data.tar.gz: 0d571a1f5c46a1edee07ef7381d10b26c6a1b511
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 82a9caf9891f4814b4965f0c52d9c263d8cc33deab96f506c24918e1c91b2b29ccda53cb7e8d70d1ce873d4f1873c77930a0b20538e78a66773de64ba74e6d4d
|
7
|
+
data.tar.gz: 76850a1c35393bba6997a7fde9bf9ad0075367c40c63cd78e6f3ea6a17b9754fddc140bbeff2e580f10f3580808aac47b8ced4d6f713d84e6629532488bb5515
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/Gemfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
source "https://rubygems.org"
|
3
|
+
|
4
|
+
gemspec
|
5
|
+
gem 'dotenv'
|
6
|
+
gem 'gli'
|
7
|
+
gem 'tty-prompt'
|
8
|
+
gem 'tty-table'
|
9
|
+
gem 'descriptive_statistics'
|
10
|
+
gem 'filesize'
|
11
|
+
|
12
|
+
group :test do
|
13
|
+
gem 'rspec'
|
14
|
+
gem 'pry'
|
15
|
+
gem 'guard-rspec'
|
16
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
imapcli (0.0.1)
|
5
|
+
gli (= 2.17.0)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
coderay (1.1.2)
|
11
|
+
descriptive_statistics (2.5.1)
|
12
|
+
diff-lcs (1.3)
|
13
|
+
dotenv (2.2.1)
|
14
|
+
equatable (0.5.0)
|
15
|
+
ffi (1.9.18)
|
16
|
+
filesize (0.1.1)
|
17
|
+
formatador (0.2.5)
|
18
|
+
gli (2.17.0)
|
19
|
+
guard (2.14.1)
|
20
|
+
formatador (>= 0.2.4)
|
21
|
+
listen (>= 2.7, < 4.0)
|
22
|
+
lumberjack (~> 1.0)
|
23
|
+
nenv (~> 0.1)
|
24
|
+
notiffany (~> 0.0)
|
25
|
+
pry (>= 0.9.12)
|
26
|
+
shellany (~> 0.0)
|
27
|
+
thor (>= 0.18.1)
|
28
|
+
guard-compat (1.2.1)
|
29
|
+
guard-rspec (4.7.3)
|
30
|
+
guard (~> 2.1)
|
31
|
+
guard-compat (~> 1.1)
|
32
|
+
rspec (>= 2.99.0, < 4.0)
|
33
|
+
hitimes (1.2.6)
|
34
|
+
listen (3.1.5)
|
35
|
+
rb-fsevent (~> 0.9, >= 0.9.4)
|
36
|
+
rb-inotify (~> 0.9, >= 0.9.7)
|
37
|
+
ruby_dep (~> 1.2)
|
38
|
+
lumberjack (1.0.12)
|
39
|
+
method_source (0.9.0)
|
40
|
+
necromancer (0.4.0)
|
41
|
+
nenv (0.3.0)
|
42
|
+
notiffany (0.1.1)
|
43
|
+
nenv (~> 0.1)
|
44
|
+
shellany (~> 0.0)
|
45
|
+
pastel (0.7.1)
|
46
|
+
equatable (~> 0.5.0)
|
47
|
+
tty-color (~> 0.4.0)
|
48
|
+
pry (0.11.2)
|
49
|
+
coderay (~> 1.1.0)
|
50
|
+
method_source (~> 0.9.0)
|
51
|
+
rake (12.1.0)
|
52
|
+
rb-fsevent (0.10.2)
|
53
|
+
rb-inotify (0.9.10)
|
54
|
+
ffi (>= 0.5.0, < 2)
|
55
|
+
rdoc (5.1.0)
|
56
|
+
rspec (3.7.0)
|
57
|
+
rspec-core (~> 3.7.0)
|
58
|
+
rspec-expectations (~> 3.7.0)
|
59
|
+
rspec-mocks (~> 3.7.0)
|
60
|
+
rspec-core (3.7.0)
|
61
|
+
rspec-support (~> 3.7.0)
|
62
|
+
rspec-expectations (3.7.0)
|
63
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
64
|
+
rspec-support (~> 3.7.0)
|
65
|
+
rspec-mocks (3.7.0)
|
66
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
67
|
+
rspec-support (~> 3.7.0)
|
68
|
+
rspec-support (3.7.0)
|
69
|
+
ruby_dep (1.5.0)
|
70
|
+
shellany (0.0.1)
|
71
|
+
thor (0.20.0)
|
72
|
+
timers (4.1.2)
|
73
|
+
hitimes
|
74
|
+
tty-color (0.4.2)
|
75
|
+
tty-cursor (0.5.0)
|
76
|
+
tty-prompt (0.13.2)
|
77
|
+
necromancer (~> 0.4.0)
|
78
|
+
pastel (~> 0.7.0)
|
79
|
+
timers (~> 4.1.2)
|
80
|
+
tty-cursor (~> 0.5.0)
|
81
|
+
tty-reader (~> 0.1.0)
|
82
|
+
tty-reader (0.1.0)
|
83
|
+
wisper (~> 2.0.0)
|
84
|
+
tty-screen (0.6.2)
|
85
|
+
tty-table (0.9.0)
|
86
|
+
equatable (~> 0.5.0)
|
87
|
+
necromancer (~> 0.4.0)
|
88
|
+
pastel (~> 0.7.0)
|
89
|
+
tty-screen (~> 0.6.0)
|
90
|
+
unicode-display_width (~> 1.1.0)
|
91
|
+
verse (~> 0.5.0)
|
92
|
+
unicode-display_width (1.1.3)
|
93
|
+
unicode_utils (1.4.0)
|
94
|
+
verse (0.5.0)
|
95
|
+
unicode-display_width (~> 1.1.0)
|
96
|
+
unicode_utils (~> 1.4.0)
|
97
|
+
wisper (2.0.0)
|
98
|
+
|
99
|
+
PLATFORMS
|
100
|
+
ruby
|
101
|
+
|
102
|
+
DEPENDENCIES
|
103
|
+
descriptive_statistics
|
104
|
+
dotenv
|
105
|
+
filesize
|
106
|
+
gli
|
107
|
+
guard-rspec
|
108
|
+
imapcli!
|
109
|
+
pry
|
110
|
+
rake
|
111
|
+
rdoc
|
112
|
+
rspec
|
113
|
+
tty-prompt
|
114
|
+
tty-table
|
115
|
+
|
116
|
+
BUNDLED WITH
|
117
|
+
1.16.0
|
data/Guardfile
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
## Uncomment and set this to only include directories you want to watch
|
5
|
+
# directories %w(app lib config test spec features) \
|
6
|
+
# .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
|
7
|
+
|
8
|
+
## Note: if you are using the `directories` clause above and you are not
|
9
|
+
## watching the project directory ('.'), then you will want to move
|
10
|
+
## the Guardfile to a watched dir and symlink it back, e.g.
|
11
|
+
#
|
12
|
+
# $ mkdir config
|
13
|
+
# $ mv Guardfile config/
|
14
|
+
# $ ln -s config/Guardfile .
|
15
|
+
#
|
16
|
+
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
|
17
|
+
|
18
|
+
# Note: The cmd option is now required due to the increasing number of ways
|
19
|
+
# rspec may be run, below are examples of the most common uses.
|
20
|
+
# * bundler: 'bundle exec rspec'
|
21
|
+
# * bundler binstubs: 'bin/rspec'
|
22
|
+
# * spring: 'bin/rspec' (This will use spring if running and you have
|
23
|
+
# installed the spring binstubs per the docs)
|
24
|
+
# * zeus: 'zeus rspec' (requires the server to be started separately)
|
25
|
+
# * 'just' rspec: 'rspec'
|
26
|
+
|
27
|
+
guard :rspec, cmd: "bundle exec rspec" do
|
28
|
+
require "guard/rspec/dsl"
|
29
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
30
|
+
|
31
|
+
# Feel free to open issues for suggestions and improvements
|
32
|
+
|
33
|
+
# RSpec files
|
34
|
+
rspec = dsl.rspec
|
35
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
36
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
37
|
+
watch(rspec.spec_files)
|
38
|
+
|
39
|
+
# Ruby files
|
40
|
+
ruby = dsl.ruby
|
41
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
42
|
+
|
43
|
+
# Rails files
|
44
|
+
rails = dsl.rails(view_extensions: %w(erb haml slim))
|
45
|
+
dsl.watch_spec_files_for(rails.app_files)
|
46
|
+
dsl.watch_spec_files_for(rails.views)
|
47
|
+
|
48
|
+
watch(rails.controllers) do |m|
|
49
|
+
[
|
50
|
+
rspec.spec.call("routing/#{m[1]}_routing"),
|
51
|
+
rspec.spec.call("controllers/#{m[1]}_controller"),
|
52
|
+
rspec.spec.call("acceptance/#{m[1]}")
|
53
|
+
]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Capybara features specs
|
57
|
+
watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") }
|
58
|
+
watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") }
|
59
|
+
|
60
|
+
# Turnip features and steps
|
61
|
+
watch(%r{^spec/acceptance/(.+)\.feature$})
|
62
|
+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
|
63
|
+
Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
|
64
|
+
end
|
65
|
+
end
|
data/README.md
ADDED
@@ -0,0 +1,227 @@
|
|
1
|
+
**Heads up! Code contributions welcome. Please issue pull requests against the
|
2
|
+
`develop` branch.**
|
3
|
+
|
4
|
+
imapcli
|
5
|
+
=======
|
6
|
+
|
7
|
+
> Command-line interface (CLI) for IMAP servers
|
8
|
+
|
9
|
+
`imapcli` is a command-line tool that offers a convenient way to query an IMAP
|
10
|
+
server for configuration details and e-mail statistics. It can be used to gather
|
11
|
+
IMAP folder sizes.
|
12
|
+
|
13
|
+
|
14
|
+
Table of contents
|
15
|
+
-----------------
|
16
|
+
|
17
|
+
* [Motivation](#motivation)
|
18
|
+
* [Warning](#warning)
|
19
|
+
* [Installing and executing `imapcli`](#installing-and-executing-imapcli)
|
20
|
+
* [Terminology](#terminology)
|
21
|
+
* [Commands](#commands)
|
22
|
+
* [Alternative resources](#alternative-resources)
|
23
|
+
* [State of the project](#state-of-the-project)
|
24
|
+
* [Credits](#credits)
|
25
|
+
* [License](#license)
|
26
|
+
|
27
|
+
|
28
|
+
Motivation
|
29
|
+
----------
|
30
|
+
|
31
|
+
When my university mail account had almost reached the quota, I needed to find
|
32
|
+
out what the largest mail folders were (in terms of megabytes, not message
|
33
|
+
count). To my surprise, there was no easy way to accomplish this; or at least I
|
34
|
+
did not find one by searching the web. A couple of specialized IMAP-related
|
35
|
+
tools exist (see [below](#alternative-resources)), but when it comes to querying
|
36
|
+
an IMAP server for configuration and stats, you have to resort to communicating
|
37
|
+
with the server by telnet or OpenSSL.
|
38
|
+
|
39
|
+
`imapcli` offers a convenient way to query an IMAP server.
|
40
|
+
|
41
|
+
|
42
|
+
Warning
|
43
|
+
-------
|
44
|
+
|
45
|
+
Some servers are configured to detect malicious login attempts by the frequency
|
46
|
+
of connections from a given source. **It may happen that you get locked out of
|
47
|
+
a server if you use `imapcli` to issue too many queries in too short a time!**
|
48
|
+
|
49
|
+
If you happen to be the server administrator yourself, have
|
50
|
+
[fail2ban](https://www.fail2ban.org) running, and find your IP being denied
|
51
|
+
access to the IMAP port, you can SSH into your server and un-ban your IP like
|
52
|
+
this:
|
53
|
+
|
54
|
+
sudo fail2ban-client set dovecot unbanip <your-ip>
|
55
|
+
|
56
|
+
If your IMAP server is not [Dovecot](https://www.dovecot.org), you need to change
|
57
|
+
this command and provide the appropriate 'jail' name.
|
58
|
+
|
59
|
+
To prevent `fail2ban` from blocking your IP, you may want to add a network and
|
60
|
+
submask to `jail.local`:
|
61
|
+
|
62
|
+
# /etc/fail2ban/jail.local
|
63
|
+
[DEFAULT]
|
64
|
+
ignoreip = 127.0.0.1/8 123.123.123.0/24 # or whatever your net/mask are
|
65
|
+
|
66
|
+
Do not forget to reload the `jail2ban` configuration afterwards:
|
67
|
+
|
68
|
+
sudo service fail2ban reload
|
69
|
+
|
70
|
+
(On Ubuntu Linux, the [indicator-ip](https://github.com/bovender/indicator-ip)
|
71
|
+
applet may be useful to know your remote IP. Disclaimer: I am the author of this
|
72
|
+
tool.)
|
73
|
+
|
74
|
+
Installing and executing `imapcli`
|
75
|
+
--------------------------------
|
76
|
+
|
77
|
+
`imapcli` is a Ruby project and as such does not need to be compiled. You'll
|
78
|
+
need Ruby on your system.
|
79
|
+
|
80
|
+
|
81
|
+
### Run in the repository
|
82
|
+
|
83
|
+
Just clone this repository and run
|
84
|
+
|
85
|
+
bin/imapcli
|
86
|
+
|
87
|
+
|
88
|
+
### Gem
|
89
|
+
|
90
|
+
To follow.
|
91
|
+
|
92
|
+
Run:
|
93
|
+
|
94
|
+
imapcli
|
95
|
+
|
96
|
+
|
97
|
+
### .deb installer
|
98
|
+
|
99
|
+
To follow.
|
100
|
+
|
101
|
+
|
102
|
+
### Docker image
|
103
|
+
|
104
|
+
To follow. This will be an option if you don't have Ruby installed.
|
105
|
+
|
106
|
+
|
107
|
+
Terminology
|
108
|
+
-----------
|
109
|
+
|
110
|
+
`imapcli` attempts to use the typical IMAP terminology. I guess most people
|
111
|
+
have their mails organized in *folders*; in IMAP speak, a folder is a *maibox*.
|
112
|
+
|
113
|
+
|
114
|
+
Commands
|
115
|
+
--------
|
116
|
+
|
117
|
+
For basic usage instructions and possible options, run `imapcli` and examine
|
118
|
+
the output. Please note that `imapcli` distinguishes between global and
|
119
|
+
command-specific options. Global options *precede* and command-specific options
|
120
|
+
*follow* a `command`, see the output of `imapcli` (without command or options)
|
121
|
+
for more information.
|
122
|
+
|
123
|
+
|
124
|
+
### Commands
|
125
|
+
|
126
|
+
* `info`: Prints configuration information about the server.
|
127
|
+
* `examine`: Examines a mailbox (i.e., folder) and returns statistics about it.
|
128
|
+
|
129
|
+
|
130
|
+
### Command-line options
|
131
|
+
|
132
|
+
* `-s SERVER`: Set the server domain name (e.g., `imap.example.com`). May be
|
133
|
+
omitted if the information is given in the `IMAP_SERVER` environment variable
|
134
|
+
(see below).
|
135
|
+
* `-u USER`: Set the login (user) name (e.g., `john@example.com`). May be
|
136
|
+
omitted if the information is given in the `IMAP_USER` environment variable
|
137
|
+
(see below).
|
138
|
+
* `-p PASSWORD`: Set the password. May be omitted if the `-P` option is used
|
139
|
+
or if the information is given in the `IMAP_PASS` environment variable (see below).
|
140
|
+
* `-P`: Prompt for the password.
|
141
|
+
|
142
|
+
|
143
|
+
### Using environment variables for the server and authentication details
|
144
|
+
|
145
|
+
You can set the following environment variables to avoid having to type the
|
146
|
+
server information over and over again:
|
147
|
+
|
148
|
+
IMAP_SERVER="imap.example.com"
|
149
|
+
IMAP_USER="your_imap_login"
|
150
|
+
IMAP_PASS="your_imap_password"
|
151
|
+
|
152
|
+
If you put this in a file `.env` in the root directory of the repository, this
|
153
|
+
information will be used. `.env` is git-ignored, so your credentials won't end up
|
154
|
+
in the repository, but of course anyone on your system who has access to this file
|
155
|
+
will be able to read the clear-text credentials.
|
156
|
+
|
157
|
+
**Also, be aware that a clear-text password that is stored in an environment
|
158
|
+
variable can be easily accessed by any other code running under your account.**
|
159
|
+
|
160
|
+
For best security, *never* store your clear-text password anywhere. Use the `-P`
|
161
|
+
(prompt) global option to have `imapcli` prompt you for the password.
|
162
|
+
|
163
|
+
|
164
|
+
Alternative resources
|
165
|
+
---------------------
|
166
|
+
|
167
|
+
While researching command-line tools for IMAP servers, I came across the
|
168
|
+
following:
|
169
|
+
|
170
|
+
|
171
|
+
### IMAP folder size script
|
172
|
+
|
173
|
+
* <https://code.iamcal.com/pl/imap_folders>
|
174
|
+
|
175
|
+
Ad-hoc perl script that computes the sizes of each mailbox. `imapcli` was
|
176
|
+
inspired by this!
|
177
|
+
|
178
|
+
|
179
|
+
### IMAP synchronization and backup tools
|
180
|
+
|
181
|
+
* <https://github.com/OfflineIMAP/imapfw>
|
182
|
+
|
183
|
+
Framework to work with mails
|
184
|
+
|
185
|
+
* <https://github.com/polo2ro/imapbox>
|
186
|
+
|
187
|
+
Pull down e-mails from an IMAP server to your local disk
|
188
|
+
|
189
|
+
|
190
|
+
|
191
|
+
### IMAP via Telnet or OpenSSL
|
192
|
+
|
193
|
+
|
194
|
+
State of the project
|
195
|
+
--------------------
|
196
|
+
|
197
|
+
Please consider this an alpha version. It does what I needed it for most (collect
|
198
|
+
information about the folder sizes), but that's pretty much it. I'll be happy
|
199
|
+
to take **pull request**. Please issue those against the **develop** branch as
|
200
|
+
I like to follow *[a successful Git branching model](http://nvie.com/git-model)*.
|
201
|
+
|
202
|
+
### Versioning
|
203
|
+
|
204
|
+
This project is [semantically versioned](https://semver.org).
|
205
|
+
|
206
|
+
### To do
|
207
|
+
|
208
|
+
- Man page
|
209
|
+
- .deb installer
|
210
|
+
- More commands?
|
211
|
+
|
212
|
+
|
213
|
+
Credits
|
214
|
+
-------
|
215
|
+
|
216
|
+
This tool is build around the awesome [GLI](https://github.com/davetron5000/gli)
|
217
|
+
gem by [David Copeland](https://github.com/davetron5000) and makes extensive use
|
218
|
+
of [Piotr Murach's](https://github.com/piotrmurach) excellent `TTY` tools. See
|
219
|
+
the `Gemfile` for other work that this tool depends on.
|
220
|
+
|
221
|
+
|
222
|
+
License
|
223
|
+
-------
|
224
|
+
|
225
|
+
© 2017 Daniel Kraus (bovender)
|
226
|
+
|
227
|
+
Apache license.
|
data/Rakefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'rake/clean'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rubygems/package_task'
|
4
|
+
require 'rdoc/task'
|
5
|
+
# require 'cucumber'
|
6
|
+
# require 'cucumber/rake/task'
|
7
|
+
Rake::RDocTask.new do |rd|
|
8
|
+
rd.main = "README.md"
|
9
|
+
rd.rdoc_files.include("README.md","lib/**/*.rb","bin/**/*")
|
10
|
+
rd.title = 'imapcli'
|
11
|
+
end
|
12
|
+
|
13
|
+
spec = eval(File.read('imapcli.gemspec'))
|
14
|
+
|
15
|
+
Gem::PackageTask.new(spec) do |pkg|
|
16
|
+
end
|
17
|
+
|
18
|
+
# CUKE_RESULTS = 'results.html'
|
19
|
+
# CLEAN << CUKE_RESULTS
|
20
|
+
# desc 'Run features'
|
21
|
+
# Cucumber::Rake::Task.new(:features) do |t|
|
22
|
+
# opts = "features --format html -o #{CUKE_RESULTS} --format progress -x"
|
23
|
+
# opts += " --tags #{ENV['TAGS']}" if ENV['TAGS']
|
24
|
+
# t.cucumber_opts = opts
|
25
|
+
# t.fork = false
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# desc 'Run features tagged as work-in-progress (@wip)'
|
29
|
+
# Cucumber::Rake::Task.new('features:wip') do |t|
|
30
|
+
# tag_opts = ' --tags ~@pending'
|
31
|
+
# tag_opts = ' --tags @wip'
|
32
|
+
# t.cucumber_opts = "features --format html -o #{CUKE_RESULTS} --format pretty -x -s#{tag_opts}"
|
33
|
+
# t.fork = false
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# task :cucumber => :features
|
37
|
+
# task 'cucumber:wip' => 'features:wip'
|
38
|
+
# task :wip => 'features:wip'
|
39
|
+
# require 'rake/testtask'
|
40
|
+
# Rake::TestTask.new do |t|
|
41
|
+
# t.libs << "test"
|
42
|
+
# t.test_files = FileList['test/*_test.rb']
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# task :default => [:test,:features]
|
data/bin/imapcli
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'gli'
|
3
|
+
begin # XXX: Remove this begin/rescue before distributing your app
|
4
|
+
require 'imapcli'
|
5
|
+
rescue LoadError
|
6
|
+
STDERR.puts "In development, you need to use `bundle exec bin/imapcli` to run your app"
|
7
|
+
STDERR.puts "At install-time, RubyGems will make sure lib, etc. are in the load path"
|
8
|
+
STDERR.puts "Feel free to remove this message from bin/imapcli now"
|
9
|
+
exit 64
|
10
|
+
end
|
11
|
+
require 'dotenv'
|
12
|
+
require 'tty-prompt'
|
13
|
+
require 'tty-table'
|
14
|
+
# require 'pp'
|
15
|
+
|
16
|
+
Dotenv.load
|
17
|
+
|
18
|
+
include GLI::App
|
19
|
+
|
20
|
+
program_desc 'Command-line interface for IMAP servers'
|
21
|
+
|
22
|
+
version Imapcli::VERSION
|
23
|
+
|
24
|
+
subcommand_option_handling :normal
|
25
|
+
arguments :strict
|
26
|
+
sort_help :manually
|
27
|
+
wrap_help_text :tty_only
|
28
|
+
|
29
|
+
desc 'Domain name (FQDN) of the IMAP server'
|
30
|
+
default_value ENV['IMAP_SERVER']
|
31
|
+
arg_name 'imap.example.com'
|
32
|
+
flag [:s,:server]
|
33
|
+
|
34
|
+
desc 'Log-in name (username/email)'
|
35
|
+
default_value ENV['IMAP_USER']
|
36
|
+
arg_name 'user'
|
37
|
+
flag [:u,:user]
|
38
|
+
|
39
|
+
desc 'Log-in password'
|
40
|
+
# default_value ENV['IMAP_PASS']
|
41
|
+
arg_name 'password'
|
42
|
+
flag [:p,:password]
|
43
|
+
|
44
|
+
desc 'Prompt for password'
|
45
|
+
switch [:P, :prompt], negatable: false
|
46
|
+
|
47
|
+
desc 'Verbose output (e.g., response values from Ruby''s Net::IMAP)'
|
48
|
+
switch [:v,:verbose], negatable: false
|
49
|
+
|
50
|
+
desc 'Tests if the server is available and log-in succeeds with the credentials'
|
51
|
+
command :check do |c|
|
52
|
+
c.action do |global_options,options,args|
|
53
|
+
@command.check ? @prompt.ok('login successful') : @prompt.error('login failed')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
desc 'Prints information about the server'
|
58
|
+
command :info do |c|
|
59
|
+
c.action do |global_options,options,args|
|
60
|
+
@command.info.each { |line| @prompt.say line }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
desc 'Lists mailboxes (folders)'
|
65
|
+
command :list do |c|
|
66
|
+
c.action do |global_options,options,args|
|
67
|
+
@command.list.each { |line| @prompt.say line }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
desc 'Collects mailbox statistics'
|
72
|
+
arg_name :mailbox, optional: false, multiple: true
|
73
|
+
command :examine do |c|
|
74
|
+
c.action do |global_options,options,args|
|
75
|
+
body = @command.stats(args)
|
76
|
+
head = [ 'Mailbox', 'Count', 'Total size', 'Min', 'Q1', 'Median', 'Q3', 'Max' ]
|
77
|
+
table = TTY::Table.new(head, body)
|
78
|
+
@prompt.say table.render(:unicode, alignments: [:left] + Array.new(7, :right) )
|
79
|
+
if body.any? { |line| line[0].start_with? Imapcli::Command.unknown_mailbox_prefix }
|
80
|
+
@prompt.warn "#{Imapcli::Command.unknown_mailbox_prefix}unknown mailbox"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
pre do |global,command,options,args|
|
86
|
+
@prompt = TTY::Prompt.new
|
87
|
+
|
88
|
+
if global[:s].nil? || global[:s].empty?
|
89
|
+
raise 'missing server name (use -s option or set IMAP_SERVER environment variable)'
|
90
|
+
end
|
91
|
+
if global[:s].nil? || global[:s].empty?
|
92
|
+
raise 'missing server name (use -s option or set IMAP_SERVER environment variable)'
|
93
|
+
end
|
94
|
+
if global[:P] && global[:p]
|
95
|
+
raise '-p and -P options do not agree'
|
96
|
+
end
|
97
|
+
if global[:P]
|
98
|
+
global[:p] = @prompt.mask 'Enter password:'
|
99
|
+
end
|
100
|
+
global[:p] ||= ENV['IMAP_PASS']
|
101
|
+
|
102
|
+
client = Imapcli::Client.new(global[:s], global[:u], global[:p])
|
103
|
+
@prompt.say "server: #{global[:s]}"
|
104
|
+
@prompt.say "user: #{global[:u]}"
|
105
|
+
raise 'invalid server name' unless client.server_valid?
|
106
|
+
raise 'invalid user name' unless client.user_valid?
|
107
|
+
@prompt.warn 'warning: no password was provided (missing -p/-P option)' unless global[:p]
|
108
|
+
raise 'unable to connect to server' unless client.connection
|
109
|
+
@command = Imapcli::Command.new(client)
|
110
|
+
|
111
|
+
true
|
112
|
+
end
|
113
|
+
|
114
|
+
post do |global,command,options,args|
|
115
|
+
@client.logout if @client
|
116
|
+
if global[:v]
|
117
|
+
@prompt.say "\n>>> --verbose switch on, listing server responses <<<"
|
118
|
+
@client.responses.each do |response|
|
119
|
+
@prompt.say response
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
on_error do |exception|
|
125
|
+
@client.logout if @client
|
126
|
+
# Error logic here
|
127
|
+
# return false to skip default error handling
|
128
|
+
true
|
129
|
+
end
|
130
|
+
|
131
|
+
exit run(ARGV)
|
data/imapcli.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# Ensure we require the local version and not one we might have installed already
|
2
|
+
require File.join([File.dirname(__FILE__),'lib','imapcli','version.rb'])
|
3
|
+
spec = Gem::Specification.new do |s|
|
4
|
+
s.name = 'imapcli'
|
5
|
+
s.version = Imapcli::VERSION
|
6
|
+
s.author = 'Daniel Kraus (bovender)'
|
7
|
+
s.email = 'bovender@bovender.de'
|
8
|
+
s.homepage = 'https://github.com/bovender/imapcli'
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.summary = 'A description of your project'
|
11
|
+
s.files = `git ls-files`.split("\n")
|
12
|
+
s.require_paths << 'lib'
|
13
|
+
s.has_rdoc = true
|
14
|
+
s.extra_rdoc_files = ['README.md','imapcli.rdoc']
|
15
|
+
s.rdoc_options << '--title' << 'imapcli' << '--main' << 'README.md' << '-ri'
|
16
|
+
s.bindir = 'bin'
|
17
|
+
s.executables << 'imapcli'
|
18
|
+
s.add_development_dependency('rake')
|
19
|
+
s.add_development_dependency('rdoc')
|
20
|
+
s.add_runtime_dependency('gli','2.17.0')
|
21
|
+
end
|