sakura-cli 0.1.3 → 0.2.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 +5 -5
- data/.gitignore +2 -0
- data/LICENSE.txt +1 -1
- data/README.md +12 -16
- 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 +49 -18
- data/lib/sakura/mail_address.rb +159 -72
- data/lib/sakura.rb +1 -1
- data/sakura-cli.gemspec +3 -3
- metadata +15 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: f4bd482e0d86c365ea75946bc6831c56d30390b30121e289ad5ccdf7daeab02a
|
|
4
|
+
data.tar.gz: e864d3491596ca9919c9a6e5001664e7affdef7281976a50f375bc8817cdbc5d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7594da6f2ca11dae4251fe0aba8d61f3860505adcb7005d5ce631c13e61ed8b2e23e93a5ee61404ec87ec812771f4cf031a228a6ea59e50ce84ac1e278770890
|
|
7
|
+
data.tar.gz: '01519f5f2a7aa79001e770700ee4ef6abc80509dc21c405418c565bccc5b6945502ad32fe60f6ac1f3ed767fb088d379d85dec69405b06a5cd18629d8cc9ce3a'
|
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) 2015-2022 Shintaro Kojima. Code released under the [MIT license](LICENSE).
|
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
|
@@ -1,58 +1,77 @@
|
|
|
1
1
|
require 'capybara/dsl'
|
|
2
|
-
require '
|
|
2
|
+
require 'selenium-webdriver'
|
|
3
|
+
|
|
3
4
|
require 'sakura'
|
|
4
5
|
require 'sakura/cli/version'
|
|
5
6
|
|
|
6
|
-
Capybara.default_driver = :
|
|
7
|
-
Capybara.current_session.driver.headers = {'User-Agent' => "sakura-cli/#{Sakura::Cli::VERSION}"}
|
|
7
|
+
Capybara.default_driver = :selenium_chrome_headless
|
|
8
8
|
|
|
9
9
|
module Sakura
|
|
10
10
|
class Client
|
|
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
|
|
41
|
+
|
|
42
|
+
wait_for_loading
|
|
33
43
|
|
|
34
|
-
|
|
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,93 +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(:
|
|
25
|
-
|
|
26
|
-
MailAddress.new(*arguments)
|
|
29
|
+
page.all(:css, '.entity-lists .entity-lists-row').map { |element|
|
|
30
|
+
MailAddress.new_from_element(element)
|
|
27
31
|
}
|
|
28
32
|
end
|
|
29
33
|
|
|
30
34
|
def find(local_part)
|
|
31
|
-
|
|
35
|
+
page = Client.current_session.get(MAIL_URL, /メールアドレス一覧/)
|
|
36
|
+
page.first('.input-text').select '300件'
|
|
37
|
+
|
|
38
|
+
element = page.find(:xpath, "//div[contains(@class, \"entity-lists-row\")]//div[@class=\"username\" and contains(text(), \"#{local_part}\")]/../../..")
|
|
39
|
+
MailAddress.new_from_element(element)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def new_from_element(element)
|
|
43
|
+
MailAddress.new(
|
|
44
|
+
element.find('.username').text.split('@').first,
|
|
45
|
+
element.find('.capacity').text
|
|
46
|
+
)
|
|
32
47
|
end
|
|
33
48
|
|
|
34
49
|
def header
|
|
35
|
-
str = tabularize('address', '
|
|
36
|
-
"#{str}\n#{'-' * (str.size+1)}"
|
|
50
|
+
str = tabularize('address', 'usage', 'quota', '%')
|
|
51
|
+
"#{str}\n#{'-' * (str.size + 1)}"
|
|
37
52
|
end
|
|
38
53
|
|
|
39
54
|
def tabularize(*args)
|
|
40
55
|
args[0].ljust(20) <<
|
|
41
|
-
args[1].to_s.rjust(
|
|
42
|
-
|
|
43
|
-
args[3].to_s.rjust(
|
|
44
|
-
" (#{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)})"
|
|
45
59
|
end
|
|
46
60
|
end
|
|
47
61
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
@
|
|
51
|
-
@virus_scan = virus_scan == '○'
|
|
52
|
-
@usage = usage
|
|
53
|
-
@quota = quota
|
|
54
|
-
@link = link
|
|
55
|
-
@link_to_delete = link_to_delete
|
|
62
|
+
def initialize(address, usage)
|
|
63
|
+
@address = address
|
|
64
|
+
@usage, @quota = usage.split(/\s*\/\s*/)
|
|
56
65
|
end
|
|
57
66
|
|
|
58
67
|
def delete
|
|
59
|
-
|
|
60
|
-
Client.current_session.process(MAIL_URL) do
|
|
61
|
-
|
|
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.is-dangerous').click
|
|
72
|
+
end
|
|
62
73
|
end
|
|
63
74
|
|
|
64
75
|
true
|
|
65
76
|
end
|
|
66
77
|
|
|
67
78
|
def quota=(value)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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
|
|
72
97
|
|
|
73
|
-
|
|
74
|
-
|
|
98
|
+
page.find(:xpath, '//button[text() = "保存する"]').click
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
@quota = value
|
|
75
102
|
end
|
|
76
103
|
|
|
77
104
|
def password=(value)
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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'
|
|
82
119
|
end
|
|
120
|
+
|
|
121
|
+
@virus_scan
|
|
83
122
|
end
|
|
84
123
|
|
|
85
124
|
def virus_scan=(value)
|
|
86
|
-
|
|
87
|
-
Client.current_session.process(MAIL_URL + @
|
|
88
|
-
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
|
|
89
129
|
end
|
|
90
130
|
|
|
91
|
-
@virus_scan = value
|
|
131
|
+
@virus_scan = value
|
|
92
132
|
end
|
|
93
133
|
|
|
94
134
|
def enable_virus_scan
|
|
@@ -99,22 +139,24 @@ module Sakura
|
|
|
99
139
|
virus_scan = false
|
|
100
140
|
end
|
|
101
141
|
|
|
102
|
-
def keep(page=nil)
|
|
142
|
+
def keep(page = nil)
|
|
103
143
|
if @keep.nil?
|
|
104
|
-
|
|
105
|
-
|
|
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'
|
|
106
147
|
end
|
|
107
148
|
|
|
108
149
|
@keep
|
|
109
150
|
end
|
|
110
151
|
|
|
111
152
|
def keep=(value)
|
|
112
|
-
|
|
113
|
-
Client.current_session.process(MAIL_URL + @
|
|
114
|
-
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
|
|
115
157
|
end
|
|
116
158
|
|
|
117
|
-
@keep = value
|
|
159
|
+
@keep = value
|
|
118
160
|
end
|
|
119
161
|
|
|
120
162
|
def enable_keep
|
|
@@ -125,59 +167,104 @@ module Sakura
|
|
|
125
167
|
keep = false
|
|
126
168
|
end
|
|
127
169
|
|
|
128
|
-
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)
|
|
129
214
|
if @forward_list.nil?
|
|
130
|
-
|
|
131
|
-
|
|
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,]+/)
|
|
132
218
|
end
|
|
133
219
|
|
|
134
220
|
@forward_list
|
|
135
221
|
end
|
|
136
222
|
|
|
137
223
|
def forward_to(mail)
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
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
|
|
145
230
|
end
|
|
146
231
|
|
|
147
|
-
@forward_list ||= []
|
|
148
232
|
@forward_list << mail
|
|
149
233
|
end
|
|
150
234
|
|
|
151
235
|
def delete_forward_to(mail)
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
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
|
|
155
242
|
end
|
|
156
243
|
|
|
157
|
-
@forward_list ||= []
|
|
158
244
|
@forward_list.delete mail
|
|
159
245
|
end
|
|
160
246
|
|
|
161
247
|
def to_s
|
|
162
|
-
self.class.tabularize(@address, @
|
|
248
|
+
self.class.tabularize(@address, @usage, @quota, percentage(@usage, @quota))
|
|
163
249
|
end
|
|
164
250
|
|
|
165
251
|
def detail
|
|
166
|
-
|
|
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}の設定/)
|
|
167
254
|
|
|
168
255
|
<<-EOS
|
|
169
256
|
usage / quota: #{usage} / #{quota} (#{percentage(@usage, @quota)})
|
|
170
257
|
forward_to: #{forward_list(page).join(' ')}
|
|
171
|
-
keep mail
|
|
172
|
-
|
|
258
|
+
keep mail: #{keep(page)}
|
|
259
|
+
virus scan: #{virus_scan(page)}
|
|
260
|
+
spam filter: #{spam_filter(page)}
|
|
173
261
|
EOS
|
|
174
262
|
end
|
|
175
263
|
|
|
176
|
-
|
|
177
264
|
private
|
|
178
265
|
|
|
179
266
|
def percentage(usage, quota)
|
|
180
|
-
usage, quota = [usage, quota].map {|i|
|
|
267
|
+
usage, quota = [usage, quota].map { |i|
|
|
181
268
|
case i
|
|
182
269
|
when /([\d.]+)TB$/
|
|
183
270
|
$1.to_f * 1000000000000
|
|
@@ -192,7 +279,7 @@ virus_scan?: #{virus_scan}
|
|
|
192
279
|
end
|
|
193
280
|
}
|
|
194
281
|
|
|
195
|
-
"#{(usage*100/quota).to_i}%"
|
|
282
|
+
"#{(usage * 100 / quota).to_i}%"
|
|
196
283
|
end
|
|
197
284
|
end
|
|
198
285
|
end
|
data/lib/sakura.rb
CHANGED
data/sakura-cli.gemspec
CHANGED
|
@@ -20,9 +20,9 @@ Gem::Specification.new do |spec|
|
|
|
20
20
|
spec.require_paths = ["lib"]
|
|
21
21
|
|
|
22
22
|
spec.add_runtime_dependency "capybara"
|
|
23
|
-
spec.add_runtime_dependency "
|
|
23
|
+
spec.add_runtime_dependency "selenium-webdriver"
|
|
24
24
|
spec.add_runtime_dependency "thor"
|
|
25
|
-
spec.add_development_dependency "bundler"
|
|
26
|
-
spec.add_development_dependency "rake"
|
|
25
|
+
spec.add_development_dependency "bundler"
|
|
26
|
+
spec.add_development_dependency "rake"
|
|
27
27
|
spec.required_ruby_version = '>= 2.0.0'
|
|
28
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.1
|
|
4
|
+
version: 0.2.1
|
|
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: 2022-06-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: capybara
|
|
@@ -25,7 +25,7 @@ dependencies:
|
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '0'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
28
|
+
name: selenium-webdriver
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
31
|
- - ">="
|
|
@@ -56,30 +56,30 @@ dependencies:
|
|
|
56
56
|
name: bundler
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
58
58
|
requirements:
|
|
59
|
-
- - "
|
|
59
|
+
- - ">="
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
61
|
+
version: '0'
|
|
62
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
|
-
version: '
|
|
68
|
+
version: '0'
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
70
|
name: rake
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
72
72
|
requirements:
|
|
73
|
-
- - "
|
|
73
|
+
- - ">="
|
|
74
74
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '
|
|
75
|
+
version: '0'
|
|
76
76
|
type: :development
|
|
77
77
|
prerelease: false
|
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
79
|
requirements:
|
|
80
|
-
- - "
|
|
80
|
+
- - ">="
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '
|
|
82
|
+
version: '0'
|
|
83
83
|
description: Command-line tool and client library to control the dashboard of Sakura
|
|
84
84
|
Rental Server.
|
|
85
85
|
email:
|
|
@@ -106,7 +106,7 @@ homepage: https://github.com/codeout/sakura-cli
|
|
|
106
106
|
licenses:
|
|
107
107
|
- MIT
|
|
108
108
|
metadata: {}
|
|
109
|
-
post_install_message:
|
|
109
|
+
post_install_message:
|
|
110
110
|
rdoc_options: []
|
|
111
111
|
require_paths:
|
|
112
112
|
- lib
|
|
@@ -121,9 +121,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
121
121
|
- !ruby/object:Gem::Version
|
|
122
122
|
version: '0'
|
|
123
123
|
requirements: []
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
signing_key:
|
|
124
|
+
rubygems_version: 3.3.7
|
|
125
|
+
signing_key:
|
|
127
126
|
specification_version: 4
|
|
128
127
|
summary: Command-line tool for Sakura's Rental Server.
|
|
129
128
|
test_files: []
|