sakura-cli 0.1.4 → 0.2.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/.gitignore +2 -0
- data/LICENSE.txt +1 -1
- data/README.md +12 -16
- data/lib/sakura.rb +1 -1
- data/lib/sakura/cli/mail.rb +85 -26
- data/lib/sakura/cli/root.rb +7 -0
- data/lib/sakura/cli/version.rb +1 -1
- data/lib/sakura/client.rb +46 -15
- data/lib/sakura/mail_address.rb +153 -73
- data/sakura-cli.gemspec +2 -3
- metadata +13 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 63e925b0d5771393ece520ba74ef24695fadf188e82980ae0cc59864a6b3abee
|
4
|
+
data.tar.gz: 2c65e42f350a073663eeb9f912b72b07eb9eb2236e839d29a0d910cd481fb483
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d3b7c3668f914eefd3735d32370b2cd4031f45aef33a9e009a490a2b2a6569e59580ab66234426cd8e633163d31aec53945dd16d87068ce50b71b7ad6516d1f4
|
7
|
+
data.tar.gz: 259300757340ef237b273025a8438d841f16b65365004fbb60aaa07f6783de2a52daa0af884cf95cfcc33d6983f8695f01007c4877032603a2428e0d9411c35f
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -12,18 +12,13 @@ Sakura CLI をインストールします.
|
|
12
12
|
gem install sakura-cli
|
13
13
|
```
|
14
14
|
|
15
|
-
Sakura CLI は[
|
15
|
+
Sakura CLI は[ChromeDriver](https://chromedriver.chromium.org/downloads) に依存しています.
|
16
16
|
お使いのOS に合った方法でインストールしてください.
|
17
17
|
|
18
18
|
Mac の場合は
|
19
19
|
|
20
20
|
```zsh
|
21
|
-
brew install
|
22
|
-
|
23
|
-
# Yosemite or newer
|
24
|
-
brew cask install phantomjs
|
25
|
-
brew install upx
|
26
|
-
upx -d /opt/homebrew-cask/Caskroom/phantomjs/2.0.0/phantomjs-2.0.0-macosx/bin/phantomjs
|
21
|
+
brew install chromedriver
|
27
22
|
```
|
28
23
|
|
29
24
|
でもインストールできます.
|
@@ -80,12 +75,12 @@ Commands:
|
|
80
75
|
```zsh
|
81
76
|
$ sakura mail list
|
82
77
|
# domain: example.com
|
83
|
-
address
|
78
|
+
address usage / quota ( %)
|
84
79
|
---------------------------------------------------------
|
85
|
-
dummy
|
86
|
-
dummy001
|
87
|
-
dummy002
|
88
|
-
postmaster
|
80
|
+
dummy 893KB / 200MB ( 0%)
|
81
|
+
dummy001 19.5MB / 200MB ( 9%)
|
82
|
+
dummy002 11.4MB / 200MB ( 5%)
|
83
|
+
postmaster 9.75MB / 200MB ( 4%)
|
89
84
|
```
|
90
85
|
|
91
86
|
### メールアドレス詳細
|
@@ -94,10 +89,11 @@ postmaster true 0B / 2GB
|
|
94
89
|
|
95
90
|
```zsh
|
96
91
|
$ sakura mail show dummy
|
97
|
-
usage / quota:
|
92
|
+
usage / quota: 893KB / 200MB ( 0%)
|
98
93
|
forward_to: foo@example.com
|
99
|
-
keep mail
|
100
|
-
|
94
|
+
keep mail: true
|
95
|
+
virus scan: false
|
96
|
+
spam filter: disable
|
101
97
|
```
|
102
98
|
|
103
99
|
### メールアドレス作成
|
@@ -185,4 +181,4 @@ dotenv -f ~/.sakura.env sakura
|
|
185
181
|
|
186
182
|
## Copyright and License
|
187
183
|
|
188
|
-
Copyright (c)
|
184
|
+
Copyright (c) 2021 Shintaro Kojima. Code released under the [MIT license](LICENSE).
|
data/lib/sakura.rb
CHANGED
data/lib/sakura/cli/mail.rb
CHANGED
@@ -7,41 +7,51 @@ module Sakura
|
|
7
7
|
module Cli
|
8
8
|
class Mail < Thor
|
9
9
|
desc 'list', 'List all mail addresses of the domain'
|
10
|
+
|
10
11
|
def list
|
12
|
+
preprocess
|
13
|
+
|
11
14
|
addrs = MailAddress.all
|
12
15
|
|
13
16
|
puts "# domain: #{Client.current_session.domain}"
|
14
17
|
puts MailAddress.header
|
15
|
-
addrs.each {|addr| puts addr.to_s }
|
18
|
+
addrs.each { |addr| puts addr.to_s }
|
16
19
|
end
|
17
20
|
|
18
21
|
desc 'create LOCAL_PART [PASSWORD]', 'Create a mail address'
|
19
|
-
|
22
|
+
|
23
|
+
def create(local_part, password = nil)
|
24
|
+
preprocess
|
25
|
+
|
20
26
|
password ||= ask_password
|
21
27
|
|
22
28
|
begin
|
23
29
|
MailAddress.create local_part, password
|
24
30
|
rescue
|
31
|
+
raise if options[:verbose]
|
25
32
|
abort $!
|
26
33
|
end
|
27
34
|
end
|
28
35
|
|
29
36
|
desc 'delete LOCAL_PART', 'Delete a mail address'
|
37
|
+
|
30
38
|
def delete(local_part)
|
31
|
-
|
32
|
-
abort %(No mail address: "#{local_part}") unless mail
|
39
|
+
preprocess
|
33
40
|
|
34
41
|
begin
|
35
|
-
|
42
|
+
find(local_part).delete
|
36
43
|
rescue
|
44
|
+
raise if options[:verbose]
|
37
45
|
abort $!
|
38
46
|
end
|
39
47
|
end
|
40
48
|
|
41
49
|
desc 'quota LOCAL_PART [VALUE]', 'Update or show quota of a mail address'
|
42
|
-
|
43
|
-
|
44
|
-
|
50
|
+
|
51
|
+
def quota(local_part, value = nil)
|
52
|
+
preprocess
|
53
|
+
|
54
|
+
mail = find(local_part)
|
45
55
|
|
46
56
|
begin
|
47
57
|
if value
|
@@ -50,29 +60,35 @@ module Sakura
|
|
50
60
|
puts mail.quota
|
51
61
|
end
|
52
62
|
rescue
|
63
|
+
raise if options[:verbose]
|
53
64
|
abort $!
|
54
65
|
end
|
55
66
|
end
|
56
67
|
|
57
68
|
desc 'password LOCAL_PART [PASSWORD]', 'Update password of a mail address'
|
58
|
-
|
69
|
+
|
70
|
+
def password(local_part, password = nil)
|
71
|
+
preprocess
|
72
|
+
|
59
73
|
password ||= ask_password
|
60
|
-
mail =
|
61
|
-
abort %(No mail address: "#{local_part}") unless mail
|
74
|
+
mail = find(local_part)
|
62
75
|
|
63
76
|
begin
|
64
77
|
mail.password = password
|
65
78
|
rescue
|
79
|
+
raise if options[:verbose]
|
66
80
|
abort $!
|
67
81
|
end
|
68
82
|
end
|
69
83
|
|
70
84
|
desc 'scan LOCAL_PART [enable|disable]', 'Switch virus scan configuration of a mail address'
|
71
|
-
|
85
|
+
|
86
|
+
def scan(local_part, value = nil)
|
87
|
+
preprocess
|
88
|
+
|
72
89
|
self.class.handle_argument_error if value && value !~ /enable|disable/
|
73
90
|
|
74
|
-
mail =
|
75
|
-
abort %(No mail address: "#{local_part}") unless mail
|
91
|
+
mail = find(local_part)
|
76
92
|
|
77
93
|
begin
|
78
94
|
case value
|
@@ -84,18 +100,21 @@ module Sakura
|
|
84
100
|
puts mail.virus_scan
|
85
101
|
end
|
86
102
|
rescue
|
103
|
+
raise if options[:verbose]
|
87
104
|
abort $!
|
88
105
|
end
|
89
106
|
end
|
90
107
|
|
91
108
|
desc 'forward LOCAL_PART [{add|remove} EMAIL]', 'Add, remove or show mail address(es) to forward'
|
92
|
-
|
109
|
+
|
110
|
+
def forward(local_part, operation = nil, mail_to_forward = nil)
|
111
|
+
preprocess
|
112
|
+
|
93
113
|
if (operation && operation !~ /add|remove/) || (!mail_to_forward && operation)
|
94
114
|
self.class.handle_argument_error
|
95
115
|
end
|
96
116
|
|
97
|
-
mail =
|
98
|
-
abort %(No mail address: "#{local_part}") unless mail
|
117
|
+
mail = find(local_part)
|
99
118
|
|
100
119
|
begin
|
101
120
|
case operation
|
@@ -104,19 +123,22 @@ module Sakura
|
|
104
123
|
when 'remove'
|
105
124
|
mail.delete_forward_to mail_to_forward
|
106
125
|
when nil
|
107
|
-
mail.forward_list.each {|m| puts m }
|
126
|
+
mail.forward_list.each { |m| puts m }
|
108
127
|
end
|
109
128
|
rescue
|
129
|
+
raise if options[:verbose]
|
110
130
|
abort $!
|
111
131
|
end
|
112
132
|
end
|
113
133
|
|
114
134
|
desc 'keep LOCAL_PART [enable|disable]', 'Switch keep or flush configuration of a mail address'
|
115
|
-
|
135
|
+
|
136
|
+
def keep(local_part, value = nil)
|
137
|
+
preprocess
|
138
|
+
|
116
139
|
self.class.handle_argument_error if value && value !~ /enable|disable/
|
117
140
|
|
118
|
-
mail =
|
119
|
-
abort %(No mail address: "#{local_part}") unless mail
|
141
|
+
mail = find(local_part)
|
120
142
|
|
121
143
|
begin
|
122
144
|
case value
|
@@ -128,25 +150,62 @@ module Sakura
|
|
128
150
|
puts mail.keep
|
129
151
|
end
|
130
152
|
rescue
|
153
|
+
raise if options[:verbose]
|
154
|
+
abort $!
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
desc 'filter LOCAL_PART [mark|disable|discard|quarantine]', 'Configure spam filter of a mail address'
|
159
|
+
|
160
|
+
def filter(local_part, value = nil)
|
161
|
+
preprocess
|
162
|
+
|
163
|
+
self.class.handle_argument_error if value && value !~ /mark|disable|discard|quarantine/
|
164
|
+
|
165
|
+
mail = find(local_part)
|
166
|
+
|
167
|
+
begin
|
168
|
+
case value
|
169
|
+
when nil
|
170
|
+
puts mail.spam_filter
|
171
|
+
else
|
172
|
+
mail.spam_filter = value.to_sym
|
173
|
+
end
|
174
|
+
rescue
|
175
|
+
raise if options[:verbose]
|
131
176
|
abort $!
|
132
177
|
end
|
133
178
|
end
|
134
179
|
|
135
180
|
desc 'show LOCAL_PART', 'Display information about a mail address'
|
181
|
+
|
136
182
|
def show(local_part)
|
137
|
-
|
138
|
-
abort %(No mail address: "#{local_part}") unless mail
|
183
|
+
preprocess
|
139
184
|
|
140
|
-
puts
|
185
|
+
puts find(local_part).detail
|
141
186
|
end
|
142
187
|
|
143
|
-
|
144
188
|
private
|
145
189
|
|
190
|
+
def preprocess
|
191
|
+
Client.verbose = true if options[:verbose]
|
192
|
+
end
|
193
|
+
|
194
|
+
def find(local_part)
|
195
|
+
begin
|
196
|
+
mail = MailAddress.find(local_part)
|
197
|
+
rescue Capybara::ElementNotFound
|
198
|
+
raise if options[:verbose]
|
199
|
+
abort %(No mail address: "#{local_part}")
|
200
|
+
end
|
201
|
+
|
202
|
+
mail
|
203
|
+
end
|
204
|
+
|
146
205
|
def ask_password
|
147
206
|
password = ask('password?', echo: false)
|
148
207
|
puts
|
149
|
-
confirm
|
208
|
+
confirm = ask('password(confirm)?', echo: false)
|
150
209
|
puts
|
151
210
|
abort "password doesn't match" unless password == confirm
|
152
211
|
|
data/lib/sakura/cli/root.rb
CHANGED
@@ -4,6 +4,13 @@ require 'sakura/cli/mail'
|
|
4
4
|
module Sakura
|
5
5
|
module Cli
|
6
6
|
class Root < Thor
|
7
|
+
class_option :verbose, type: :boolean
|
8
|
+
|
9
|
+
# Allow failed exit codes (see https://github.com/erikhuda/thor/issues/244)
|
10
|
+
def self.exit_on_failure?
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
7
14
|
desc 'mail', 'Manage mail addresses'
|
8
15
|
subcommand 'mail', Mail
|
9
16
|
end
|
data/lib/sakura/cli/version.rb
CHANGED
data/lib/sakura/client.rb
CHANGED
@@ -11,48 +11,67 @@ module Sakura
|
|
11
11
|
include Capybara::DSL
|
12
12
|
|
13
13
|
attr_reader :domain
|
14
|
+
@@verbose = false
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
class << self
|
17
|
+
def current_session
|
18
|
+
@current_session ||= new
|
19
|
+
end
|
18
20
|
|
21
|
+
def verbose=(bool)
|
22
|
+
@@verbose = !!bool
|
23
|
+
end
|
24
|
+
end
|
19
25
|
|
20
26
|
def initialize
|
21
27
|
@domain, @passwd = credentials
|
22
28
|
end
|
23
29
|
|
24
30
|
def login?
|
25
|
-
|
31
|
+
@logged_in
|
26
32
|
end
|
27
33
|
|
28
34
|
def login
|
35
|
+
$stderr.puts 'login' if @@verbose
|
36
|
+
|
29
37
|
visit BASE_URL
|
30
|
-
fill_in '
|
31
|
-
fill_in 'password', with: @passwd
|
32
|
-
find('form
|
38
|
+
fill_in 'login-username', with: @domain
|
39
|
+
fill_in 'login-password', with: @passwd
|
40
|
+
find('form button[type=submit]').click
|
33
41
|
|
34
|
-
|
42
|
+
wait_for_loading
|
43
|
+
|
44
|
+
if page.text =~ /サーバコントロールパネル ホーム/
|
45
|
+
@logged_in = true
|
46
|
+
end
|
35
47
|
|
36
48
|
raise_when_error
|
37
49
|
login?
|
38
50
|
end
|
39
51
|
|
40
|
-
def get(url)
|
52
|
+
def get(url, expected)
|
41
53
|
login unless login?
|
54
|
+
|
55
|
+
$stderr.puts "visit #{url}" if @@verbose
|
42
56
|
visit url
|
57
|
+
wait_for_loading
|
58
|
+
unless page.text =~ expected
|
59
|
+
raise Timeout::Error.new('Timed out')
|
60
|
+
end
|
61
|
+
|
43
62
|
page
|
44
63
|
end
|
45
64
|
|
46
|
-
def process(url, &block)
|
65
|
+
def process(url, expected, &block)
|
47
66
|
login unless login?
|
48
|
-
|
49
|
-
|
67
|
+
|
68
|
+
get url, expected
|
69
|
+
yield page
|
50
70
|
|
51
71
|
raise_when_error
|
52
72
|
page
|
53
73
|
end
|
54
74
|
|
55
|
-
|
56
75
|
private
|
57
76
|
|
58
77
|
def credentials
|
@@ -67,8 +86,20 @@ module Sakura
|
|
67
86
|
end
|
68
87
|
|
69
88
|
def raise_when_error
|
70
|
-
error
|
71
|
-
|
89
|
+
%w[.error .input-error].each do |cls|
|
90
|
+
error = page.all(cls)
|
91
|
+
raise error.first.text unless error.empty?
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def wait_for_loading
|
96
|
+
5.times do
|
97
|
+
if find_all('読み込み中').empty?
|
98
|
+
break
|
99
|
+
else
|
100
|
+
$stderr.puts 'still loading ...' if @@verbose
|
101
|
+
end
|
102
|
+
end
|
72
103
|
end
|
73
104
|
end
|
74
105
|
end
|
data/lib/sakura/mail_address.rb
CHANGED
@@ -2,100 +2,133 @@ require 'sakura/client'
|
|
2
2
|
|
3
3
|
module Sakura
|
4
4
|
class MailAddress
|
5
|
-
MAIL_URL = BASE_URL + '
|
5
|
+
MAIL_URL = BASE_URL + 'users/list/'
|
6
6
|
|
7
|
-
attr_reader :address, :
|
7
|
+
attr_reader :address, :usage, :quota, :link
|
8
8
|
|
9
9
|
class << self
|
10
10
|
def create(local_part, password)
|
11
|
-
Client.current_session.process(MAIL_URL) do
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
Client.current_session.process(MAIL_URL, /メールアドレス一覧/) do |page|
|
12
|
+
page.first(:xpath, '//a[text() = "新規追加"]').click
|
13
|
+
|
14
|
+
page.find(:xpath, '//label[contains(text(), "ユーザ名")]/..//input')
|
15
|
+
.fill_in with: local_part
|
16
|
+
page.find_all(:xpath, '//label[contains(text(), "パスワード")]/..//input').each do |e|
|
17
|
+
e.fill_in with: password
|
18
|
+
end
|
19
|
+
page.find(:xpath, '//button[text() = "作成する"]').click
|
16
20
|
end
|
17
21
|
|
18
22
|
true
|
19
23
|
end
|
20
24
|
|
21
25
|
def all
|
22
|
-
page = Client.current_session.get(MAIL_URL)
|
26
|
+
page = Client.current_session.get(MAIL_URL, /メールアドレス一覧/)
|
27
|
+
page.first('.input-text').select '300件'
|
23
28
|
|
24
|
-
page.all(:
|
29
|
+
page.all(:css, '.entity-lists .entity-lists-row').map { |element|
|
25
30
|
MailAddress.new_from_element(element)
|
26
31
|
}
|
27
32
|
end
|
28
33
|
|
29
34
|
def find(local_part)
|
30
|
-
page = Client.current_session.get(MAIL_URL)
|
35
|
+
page = Client.current_session.get(MAIL_URL, /メールアドレス一覧/)
|
36
|
+
page.first('.input-text').select '300件'
|
31
37
|
|
32
|
-
element = page.find(:xpath, "//
|
38
|
+
element = page.find(:xpath, "//div[contains(@class, \"entity-lists-row\")]//div[@class=\"username\" and contains(text(), \"#{local_part}\")]/../../..")
|
33
39
|
MailAddress.new_from_element(element)
|
34
40
|
end
|
35
41
|
|
36
42
|
def new_from_element(element)
|
37
|
-
|
38
|
-
|
43
|
+
MailAddress.new(
|
44
|
+
element.find('.username').text.split('@').first,
|
45
|
+
element.find('.capacity').text
|
46
|
+
)
|
39
47
|
end
|
40
48
|
|
41
49
|
def header
|
42
|
-
str = tabularize('address', '
|
43
|
-
"#{str}\n#{'-' * (str.size+1)}"
|
50
|
+
str = tabularize('address', 'usage', 'quota', '%')
|
51
|
+
"#{str}\n#{'-' * (str.size + 1)}"
|
44
52
|
end
|
45
53
|
|
46
54
|
def tabularize(*args)
|
47
55
|
args[0].ljust(20) <<
|
48
|
-
args[1].to_s.rjust(
|
49
|
-
|
50
|
-
args[3].to_s.rjust(
|
51
|
-
" (#{args[4].to_s.rjust(3)})"
|
56
|
+
"#{args[1]} /".to_s.rjust(15) <<
|
57
|
+
args[2].to_s.rjust(10) <<
|
58
|
+
" (#{args[3].to_s.rjust(3)})"
|
52
59
|
end
|
53
60
|
end
|
54
61
|
|
55
|
-
|
56
|
-
|
57
|
-
@
|
58
|
-
@virus_scan = virus_scan == '○'
|
59
|
-
@usage = usage
|
60
|
-
@quota = quota
|
61
|
-
@link = link
|
62
|
-
@link_to_delete = link_to_delete
|
62
|
+
def initialize(address, usage)
|
63
|
+
@address = address
|
64
|
+
@usage, @quota = usage.split(/\s*\/\s*/)
|
63
65
|
end
|
64
66
|
|
65
67
|
def delete
|
66
|
-
|
67
|
-
Client.current_session.process(MAIL_URL) do
|
68
|
-
|
68
|
+
# FIXME: The URL won't work when mail addresses are more than 300
|
69
|
+
Client.current_session.process(MAIL_URL + "1/edit/#{@address}", /#{@address}の設定/) do |page|
|
70
|
+
page.accept_confirm do
|
71
|
+
page.find('button.dangerous-button').click
|
72
|
+
end
|
69
73
|
end
|
70
74
|
|
71
75
|
true
|
72
76
|
end
|
73
77
|
|
74
78
|
def quota=(value)
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
+
# FIXME: The URL won't work when mail addresses are more than 300
|
80
|
+
Client.current_session.process(MAIL_URL + "1/edit/#{@address}", /#{@address}の設定/) do |page|
|
81
|
+
case value
|
82
|
+
when /(\d+)\s*GB$/
|
83
|
+
page.find(:xpath, '//label[contains(text(), "メール容量制限")]/..//input').fill_in with: $1
|
84
|
+
page.find(:xpath, '//label[contains(text(), "メール容量制限")]/..//select').select 'GB'
|
85
|
+
when /(\d+)\s*MB$/
|
86
|
+
page.find(:xpath, '//label[contains(text(), "メール容量制限")]/..//input').fill_in with: $1
|
87
|
+
page.find(:xpath, '//label[contains(text(), "メール容量制限")]/..//select').select 'MB'
|
88
|
+
when /(\d+)\s*KB$/
|
89
|
+
page.find(:xpath, '//label[contains(text(), "メール容量制限")]/..//input').fill_in with: $1
|
90
|
+
page.find(:xpath, '//label[contains(text(), "メール容量制限")]/..//select').select 'KB'
|
91
|
+
when /(\d+)\s*B$/
|
92
|
+
page.find(:xpath, '//label[contains(text(), "メール容量制限")]/..//input').fill_in with: $1
|
93
|
+
page.find(:xpath, '//label[contains(text(), "メール容量制限")]/..//select').select 'B'
|
94
|
+
else
|
95
|
+
raise %(Unsupported quota value "#{value}")
|
96
|
+
end
|
97
|
+
|
98
|
+
page.find(:xpath, '//button[text() = "保存する"]').click
|
99
|
+
end
|
79
100
|
|
80
|
-
|
81
|
-
@quota = $1
|
101
|
+
@quota = value
|
82
102
|
end
|
83
103
|
|
84
104
|
def password=(value)
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
105
|
+
# FIXME: The URL won't work when mail addresses are more than 300
|
106
|
+
Client.current_session.process(MAIL_URL + "1/password/#{@address}", /#{@address}のパスワード設定/) do |page|
|
107
|
+
page.find_all(:xpath, '//label[contains(text(), "パスワード")]/..//input').each do |e|
|
108
|
+
e.fill_in with: value
|
109
|
+
end
|
110
|
+
page.find(:xpath, '//button[text() = "変更する"]').click
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def virus_scan(page = nil)
|
115
|
+
if @virus_scan.nil?
|
116
|
+
# FIXME: The URL won't work when mail addresses are more than 300
|
117
|
+
page ||= Client.current_session.get(MAIL_URL + "1/edit/#{@address}", /#{@address}の設定/)
|
118
|
+
@virus_scan = page.find('[name="usesVirusCheck"]:checked').value == '1'
|
89
119
|
end
|
120
|
+
|
121
|
+
@virus_scan
|
90
122
|
end
|
91
123
|
|
92
124
|
def virus_scan=(value)
|
93
|
-
|
94
|
-
Client.current_session.process(MAIL_URL + @
|
95
|
-
find("
|
125
|
+
# FIXME: The URL won't work when mail addresses are more than 300
|
126
|
+
Client.current_session.process(MAIL_URL + "1/edit/#{@address}", /#{@address}の設定/) do |page|
|
127
|
+
page.find("[name='usesVirusCheck'][value='#{value ? 1 : 0}']").choose
|
128
|
+
page.find(:xpath, '//button[text() = "保存する"]').click
|
96
129
|
end
|
97
130
|
|
98
|
-
@virus_scan = value
|
131
|
+
@virus_scan = value
|
99
132
|
end
|
100
133
|
|
101
134
|
def enable_virus_scan
|
@@ -106,22 +139,24 @@ module Sakura
|
|
106
139
|
virus_scan = false
|
107
140
|
end
|
108
141
|
|
109
|
-
def keep(page=nil)
|
142
|
+
def keep(page = nil)
|
110
143
|
if @keep.nil?
|
111
|
-
|
112
|
-
|
144
|
+
# FIXME: The URL won't work when mail addresses are more than 300
|
145
|
+
page ||= Client.current_session.get(MAIL_URL + "1/edit/#{@address}", /#{@address}の設定/)
|
146
|
+
@keep = page.find('[name="receiveType"]:checked').value == '1'
|
113
147
|
end
|
114
148
|
|
115
149
|
@keep
|
116
150
|
end
|
117
151
|
|
118
152
|
def keep=(value)
|
119
|
-
|
120
|
-
Client.current_session.process(MAIL_URL + @
|
121
|
-
find("
|
153
|
+
# FIXME: The URL won't work when mail addresses are more than 300
|
154
|
+
Client.current_session.process(MAIL_URL + "1/edit/#{@address}", /#{@address}の設定/) do |page|
|
155
|
+
page.find("[name='receiveType'][value='#{value ? 1 : 2}']").choose
|
156
|
+
page.find(:xpath, '//button[text() = "保存する"]').click
|
122
157
|
end
|
123
158
|
|
124
|
-
@keep = value
|
159
|
+
@keep = value
|
125
160
|
end
|
126
161
|
|
127
162
|
def enable_keep
|
@@ -132,59 +167,104 @@ module Sakura
|
|
132
167
|
keep = false
|
133
168
|
end
|
134
169
|
|
135
|
-
def
|
170
|
+
def spam_filter(page = nil)
|
171
|
+
if @spam_filter.nil?
|
172
|
+
# FIXME: The URL won't work when mail addresses are more than 300
|
173
|
+
page ||= Client.current_session.get(MAIL_URL + "1/edit/#{@address}", /#{@address}の設定/)
|
174
|
+
|
175
|
+
case page.find(:xpath, '//label[contains(text(), "迷惑メールフィルタ")]/..//select').value
|
176
|
+
when "0"
|
177
|
+
@spam_filter = :disable
|
178
|
+
when "1"
|
179
|
+
@spam_filter = :quarantine
|
180
|
+
when "2"
|
181
|
+
@spam_filter = :discard
|
182
|
+
when "3"
|
183
|
+
@spam_filter = :mark
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
@spam_filter
|
188
|
+
end
|
189
|
+
|
190
|
+
def spam_filter=(value)
|
191
|
+
# FIXME: The URL won't work when mail addresses are more than 300
|
192
|
+
Client.current_session.process(MAIL_URL + "1/edit/#{@address}", /#{@address}の設定/) do |page|
|
193
|
+
select = page.find(:xpath, '//label[contains(text(), "迷惑メールフィルタ")]/..//select')
|
194
|
+
|
195
|
+
value = value.to_sym
|
196
|
+
case value
|
197
|
+
when :disable
|
198
|
+
select.select '利用しない'
|
199
|
+
when :quarantine
|
200
|
+
select.select '「迷惑メール」フォルダに保存'
|
201
|
+
when :discard
|
202
|
+
select.select 'メールを破棄'
|
203
|
+
when :mark
|
204
|
+
select.select 'フィルタの利用'
|
205
|
+
end
|
206
|
+
|
207
|
+
page.find(:xpath, '//button[text() = "保存する"]').click
|
208
|
+
end
|
209
|
+
|
210
|
+
@spam_filter = value
|
211
|
+
end
|
212
|
+
|
213
|
+
def forward_list(page = nil)
|
136
214
|
if @forward_list.nil?
|
137
|
-
|
138
|
-
|
215
|
+
# FIXME: The URL won't work when mail addresses are more than 300
|
216
|
+
page ||= Client.current_session.get(MAIL_URL + "1/edit/#{@address}", /#{@address}の設定/)
|
217
|
+
@forward_list = page.find(:xpath, '//label[contains(text(), "転送先アドレス")]/..//textarea').value.split(/[\n,]+/)
|
139
218
|
end
|
140
219
|
|
141
220
|
@forward_list
|
142
221
|
end
|
143
222
|
|
144
223
|
def forward_to(mail)
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
JS
|
224
|
+
# FIXME: The URL won't work when mail addresses are more than 300
|
225
|
+
Client.current_session.process(MAIL_URL + "1/edit/#{@address}", /#{@address}の設定/) do |page|
|
226
|
+
@forward_list = page.find(:xpath, '//label[contains(text(), "転送先アドレス")]/..//textarea').value.split(/[\n,]+/)
|
227
|
+
page.find(:xpath, '//label[contains(text(), "転送先アドレス")]/..//textarea')
|
228
|
+
.fill_in with: (@forward_list + [mail]).uniq.join("\n")
|
229
|
+
page.find(:xpath, '//button[text() = "保存する"]').click
|
152
230
|
end
|
153
231
|
|
154
|
-
@forward_list ||= []
|
155
232
|
@forward_list << mail
|
156
233
|
end
|
157
234
|
|
158
235
|
def delete_forward_to(mail)
|
159
|
-
|
160
|
-
|
161
|
-
find('
|
236
|
+
# FIXME: The URL won't work when mail addresses are more than 300
|
237
|
+
Client.current_session.process(MAIL_URL + "1/edit/#{@address}", /#{@address}の設定/) do |page|
|
238
|
+
@forward_list = page.find(:xpath, '//label[contains(text(), "転送先アドレス")]/..//textarea').value.split(/[\n,]+/)
|
239
|
+
page.find(:xpath, '//label[contains(text(), "転送先アドレス")]/..//textarea')
|
240
|
+
.fill_in with: (@forward_list - [mail]).uniq.join("\n")
|
241
|
+
page.find(:xpath, '//button[text() = "保存する"]').click
|
162
242
|
end
|
163
243
|
|
164
|
-
@forward_list ||= []
|
165
244
|
@forward_list.delete mail
|
166
245
|
end
|
167
246
|
|
168
247
|
def to_s
|
169
|
-
self.class.tabularize(@address, @
|
248
|
+
self.class.tabularize(@address, @usage, @quota, percentage(@usage, @quota))
|
170
249
|
end
|
171
250
|
|
172
251
|
def detail
|
173
|
-
|
252
|
+
# FIXME: The URL won't work when mail addresses are more than 300
|
253
|
+
page = Client.current_session.get(MAIL_URL + "1/edit/#{@address}", /#{@address}の設定/)
|
174
254
|
|
175
255
|
<<-EOS
|
176
256
|
usage / quota: #{usage} / #{quota} (#{percentage(@usage, @quota)})
|
177
257
|
forward_to: #{forward_list(page).join(' ')}
|
178
|
-
keep mail
|
179
|
-
|
258
|
+
keep mail: #{keep(page)}
|
259
|
+
virus scan: #{virus_scan(page)}
|
260
|
+
spam filter: #{spam_filter(page)}
|
180
261
|
EOS
|
181
262
|
end
|
182
263
|
|
183
|
-
|
184
264
|
private
|
185
265
|
|
186
266
|
def percentage(usage, quota)
|
187
|
-
usage, quota = [usage, quota].map {|i|
|
267
|
+
usage, quota = [usage, quota].map { |i|
|
188
268
|
case i
|
189
269
|
when /([\d.]+)TB$/
|
190
270
|
$1.to_f * 1000000000000
|
@@ -199,7 +279,7 @@ virus_scan?: #{virus_scan}
|
|
199
279
|
end
|
200
280
|
}
|
201
281
|
|
202
|
-
"#{(usage*100/quota).to_i}%"
|
282
|
+
"#{(usage * 100 / quota).to_i}%"
|
203
283
|
end
|
204
284
|
end
|
205
285
|
end
|
data/sakura-cli.gemspec
CHANGED
@@ -21,9 +21,8 @@ Gem::Specification.new do |spec|
|
|
21
21
|
|
22
22
|
spec.add_runtime_dependency "capybara"
|
23
23
|
spec.add_runtime_dependency "selenium-webdriver"
|
24
|
-
spec.add_runtime_dependency "chromedriver-helper"
|
25
24
|
spec.add_runtime_dependency "thor"
|
26
|
-
spec.add_development_dependency "bundler"
|
27
|
-
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "bundler"
|
26
|
+
spec.add_development_dependency "rake"
|
28
27
|
spec.required_ruby_version = '>= 2.0.0'
|
29
28
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sakura-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shintaro Kojima
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-04-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: capybara
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: thor
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
@@ -53,47 +53,33 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: bundler
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
|
-
type: :
|
62
|
+
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: bundler
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '1.9'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '1.9'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
70
|
name: rake
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
86
72
|
requirements:
|
87
|
-
- - "
|
73
|
+
- - ">="
|
88
74
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
75
|
+
version: '0'
|
90
76
|
type: :development
|
91
77
|
prerelease: false
|
92
78
|
version_requirements: !ruby/object:Gem::Requirement
|
93
79
|
requirements:
|
94
|
-
- - "
|
80
|
+
- - ">="
|
95
81
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
82
|
+
version: '0'
|
97
83
|
description: Command-line tool and client library to control the dashboard of Sakura
|
98
84
|
Rental Server.
|
99
85
|
email:
|
@@ -120,7 +106,7 @@ homepage: https://github.com/codeout/sakura-cli
|
|
120
106
|
licenses:
|
121
107
|
- MIT
|
122
108
|
metadata: {}
|
123
|
-
post_install_message:
|
109
|
+
post_install_message:
|
124
110
|
rdoc_options: []
|
125
111
|
require_paths:
|
126
112
|
- lib
|
@@ -135,9 +121,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
135
121
|
- !ruby/object:Gem::Version
|
136
122
|
version: '0'
|
137
123
|
requirements: []
|
138
|
-
|
139
|
-
|
140
|
-
signing_key:
|
124
|
+
rubygems_version: 3.2.15
|
125
|
+
signing_key:
|
141
126
|
specification_version: 4
|
142
127
|
summary: Command-line tool for Sakura's Rental Server.
|
143
128
|
test_files: []
|