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 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: []