sakura-cli 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9b355454e8178df0c213c7137a6650081b9bbdc6d5a218210a8d3713265e705b
4
- data.tar.gz: dc95edb37d7b0aa8c4f77e61a2985a52e5f75a74b1a2a9fb62491b0092763fce
3
+ metadata.gz: 63e925b0d5771393ece520ba74ef24695fadf188e82980ae0cc59864a6b3abee
4
+ data.tar.gz: 2c65e42f350a073663eeb9f912b72b07eb9eb2236e839d29a0d910cd481fb483
5
5
  SHA512:
6
- metadata.gz: 3b333c99ee357eb70318390eae2d8497df12fe60488d2d6e593298a8a6d8d25d1566ad34cc0c3e5e433cc6565c7dd375b945b14df4933019f86fbf0a5f9b5bc6
7
- data.tar.gz: 1b2be0dcfb6fe150d2f92fc9f42ca110b5cd007a613f62978d96deff76656c9f8a36b7929ced3d04d43634a69451c240544bc75cffb659c93014850c3f5ea0d0
6
+ metadata.gz: d3b7c3668f914eefd3735d32370b2cd4031f45aef33a9e009a490a2b2a6569e59580ab66234426cd8e633163d31aec53945dd16d87068ce50b71b7ad6516d1f4
7
+ data.tar.gz: 259300757340ef237b273025a8438d841f16b65365004fbb60aaa07f6783de2a52daa0af884cf95cfcc33d6983f8695f01007c4877032603a2428e0d9411c35f
data/.gitignore CHANGED
@@ -7,3 +7,5 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+
11
+ /.idea/
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2018 Shintaro Kojima
3
+ Copyright (c) 2021 Shintaro Kojima
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -12,18 +12,13 @@ Sakura CLI をインストールします.
12
12
  gem install sakura-cli
13
13
  ```
14
14
 
15
- Sakura CLI は[PhantomJS](http://phantomjs.org/download.html) に依存しています.
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 phantomjs
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 virus_scan usage / quota
78
+ address usage / quota ( %)
84
79
  ---------------------------------------------------------
85
- dummy true 379.13KB / 200MB
86
- dummy001 true 1.79MB / 2GB
87
- dummy002 true 6.28KB / 2GB
88
- postmaster true 0B / 2GB
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: 379.13KB / 200MB
92
+ usage / quota: 893KB / 200MB ( 0%)
98
93
  forward_to: foo@example.com
99
- keep mail?: true
100
- virus_scan?: false
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) 2018 Shintaro Kojima. Code released under the [MIT license](LICENSE).
184
+ Copyright (c) 2021 Shintaro Kojima. Code released under the [MIT license](LICENSE).
data/lib/sakura.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'uri'
2
2
 
3
3
  module Sakura
4
- BASE_URL = URI('https://secure.sakura.ad.jp/rscontrol/')
4
+ BASE_URL = URI('https://secure.sakura.ad.jp/rs/cp/')
5
5
  end
@@ -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
- def create(local_part, password=nil)
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
- mail = MailAddress.find(local_part)
32
- abort %(No mail address: "#{local_part}") unless mail
39
+ preprocess
33
40
 
34
41
  begin
35
- mail.delete
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
- def quota(local_part, value=nil)
43
- mail = MailAddress.find(local_part)
44
- abort %(No mail address: "#{local_part}") unless mail
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
- def password(local_part, password=nil)
69
+
70
+ def password(local_part, password = nil)
71
+ preprocess
72
+
59
73
  password ||= ask_password
60
- mail = MailAddress.find(local_part)
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
- def scan(local_part, value=nil)
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 = MailAddress.find(local_part)
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
- def forward(local_part, operation=nil, mail_to_forward=nil)
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 = MailAddress.find(local_part)
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
- def keep(local_part, value=nil)
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 = MailAddress.find(local_part)
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
- mail = MailAddress.find(local_part)
138
- abort %(No mail address: "#{local_part}") unless mail
183
+ preprocess
139
184
 
140
- puts mail.detail
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 = ask('password(confirm)?', echo: false)
208
+ confirm = ask('password(confirm)?', echo: false)
150
209
  puts
151
210
  abort "password doesn't match" unless password == confirm
152
211
 
@@ -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
@@ -1,5 +1,5 @@
1
1
  module Sakura
2
2
  module Cli
3
- VERSION = "0.1.4"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
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
- def self.current_session
16
- @current_session ||= new
17
- end
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
- !@last_login.nil?
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 'domain', with: @domain
31
- fill_in 'password', with: @passwd
32
- find('form input[type=image]').click
38
+ fill_in 'login-username', with: @domain
39
+ fill_in 'login-password', with: @passwd
40
+ find('form button[type=submit]').click
33
41
 
34
- @last_login = Time.now if page.text =~ /ログインドメイン: #{@domain}/
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
- visit url
49
- instance_eval &block
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 = page.all('.error-message')
71
- raise error.first.text unless error.empty?
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
@@ -2,100 +2,133 @@ require 'sakura/client'
2
2
 
3
3
  module Sakura
4
4
  class MailAddress
5
- MAIL_URL = BASE_URL + 'rs/mail'
5
+ MAIL_URL = BASE_URL + 'users/list/'
6
6
 
7
- attr_reader :address, :virus_scan, :usage, :quota, :link, :link_to_delete
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
- fill_in 'NewUsername', with: local_part
13
- fill_in 'Password1', with: password
14
- fill_in 'Password2', with: password
15
- find('input[name="Submit_useradd"]').click
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(:xpath, '//a[contains(@href, "mail?Username=")]/../..').map{|element|
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, "//a[@href=\"mail?Username=#{local_part}\"]/../..")
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
- arguments = element.all('td').map(&:text)[0..-2] + element.all('a').map{|i| i[:href] }
38
- MailAddress.new(*arguments)
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', 'virus_scan', 'usage', 'quota', '%')
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(11) <<
49
- "#{args[2]} /".to_s.rjust(15) <<
50
- args[3].to_s.rjust(10) <<
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
- def initialize(address, virus_scan, usage, quota, link, link_to_delete=nil)
57
- @address = address
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
- link = @link_to_delete
67
- Client.current_session.process(MAIL_URL) do
68
- find("a[href=\"#{link}\"]").click
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
- page = Client.current_session.process(MAIL_URL + @link) {
76
- fill_in 'MailQuota', with: value
77
- find('input[name="Submit_quotaedit"]').click
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
- page.text =~ /利用中のディスク領域: \S+ \/ (\S+)/
81
- @quota = $1
101
+ @quota = value
82
102
  end
83
103
 
84
104
  def password=(value)
85
- Client.current_session.process(MAIL_URL + @link) do
86
- fill_in 'Password1', with: value
87
- fill_in 'Password2', with: value
88
- find('input[name="Submit_password"]').click
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
- value = value ? 1 : 0
94
- Client.current_session.process(MAIL_URL + @link) do
95
- find("input[name='VirusScan'][value='#{value}']").click
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 == 1
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
- page ||= Client.current_session.get(MAIL_URL + @link)
112
- @keep = page.find('input[name="Save"]:checked').value == '1'
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
- value = value ? 1 : 0
120
- Client.current_session.process(MAIL_URL + @link) do
121
- find("input[name='Save'][value='#{value}']").click
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 == 1
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 forward_list(page=nil)
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
- page ||= Client.current_session.get(MAIL_URL + @link)
138
- @forward_list = page.all('select[name="DeleteAddress[]"] option').map(&:text)
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
- Client.current_session.process(MAIL_URL + @link) do
146
- execute_script <<-JS
147
- var f = document.Transfer;
148
- f.Address.value = '#{mail}';
149
- f.SubAction.value = 'add';
150
- f.submit();
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
- Client.current_session.process(MAIL_URL + @link) do
160
- find_field('DeleteAddress[]').select(mail)
161
- find('a[href="javascript:tr_delete();"]').click
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, @virus_scan, @usage, @quota, percentage(@usage, @quota))
248
+ self.class.tabularize(@address, @usage, @quota, percentage(@usage, @quota))
170
249
  end
171
250
 
172
251
  def detail
173
- page = Client.current_session.get(MAIL_URL + @link)
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?: #{keep(page)}
179
- virus_scan?: #{virus_scan}
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", "~> 1.9"
27
- spec.add_development_dependency "rake", "~> 10.0"
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.1.4
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: 2018-11-04 00:00:00.000000000 Z
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: chromedriver-helper
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: thor
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: :runtime
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: '10.0'
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: '10.0'
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
- rubyforge_project:
139
- rubygems_version: 2.7.6
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: []