kobot 1.0.0 → 1.2.3
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/CHANGELOG.md +22 -0
- data/README.md +30 -19
- data/bin/console +1 -0
- data/exe/kobot +10 -1
- data/kobot.gemspec +1 -1
- data/lib/kobot.rb +1 -2
- data/lib/kobot/config.rb +2 -2
- data/lib/kobot/credential.rb +7 -8
- data/lib/kobot/engine.rb +56 -24
- data/lib/kobot/exception.rb +2 -1
- data/lib/kobot/mailer.rb +0 -2
- data/lib/kobot/option.rb +17 -7
- data/lib/kobot/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3eba14b1e3b076a368dd700c2ac46a9db4fd13bf57a58e29797de7db7eb16fc3
|
4
|
+
data.tar.gz: 1926333cefbaf4272ae117cc7afb12284ed85d6ff41aa96a02094904599b5312
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '08ad9cb2d55c2931a34ed4243884a7e16c189d1d914e5aa935cfd4d32fc3d3d7567cdaecdb53de54e980e84ec4c6e696761b7f9b15fb65e3a0eef11f829370e5'
|
7
|
+
data.tar.gz: f8662e41fe53d35df04b1b530f946621330124684d6bd955e6b18e53830efaef74c22db66818a8a3958aa8a4745b4d37090419f538962c3a4876e8dbb9b6c1d7
|
data/CHANGELOG.md
CHANGED
@@ -1,2 +1,24 @@
|
|
1
1
|
### v1.0.0
|
2
2
|
- Initial release
|
3
|
+
|
4
|
+
### v1.1.0
|
5
|
+
- Deprecated lower-case environment variables for credentials configuration
|
6
|
+
- Updated option help doc to indicate weekends and public holidays are skipped by default
|
7
|
+
- Updated required_ruby_version to be >= 2.4.0 to align with the webdrivers dependency
|
8
|
+
|
9
|
+
### v1.2.0
|
10
|
+
- Added an option to allow forcibly running regardless of weekends or public holidays
|
11
|
+
- Added an ENV flag to allow requiring lib in local workspace for development purpose
|
12
|
+
|
13
|
+
### v1.2.1
|
14
|
+
- Improved logging for better readability in logs
|
15
|
+
- Switched to builtin Logger#deprecate from Logger#warn for deprecations
|
16
|
+
- Renamed internal method to skip? from holiday? as it was meant for skipping any specified date
|
17
|
+
|
18
|
+
### v1.2.2
|
19
|
+
- Improved login screen wait and logging
|
20
|
+
- Applied fix for offenses about empty lines and long lines reported by Rubocop
|
21
|
+
|
22
|
+
### v1.2.3
|
23
|
+
- Improved validation logic to skip running due to weekend or intentional skips
|
24
|
+
- Refactored engine by reducing methods length based on reports by Rubocop
|
data/README.md
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
# Kobot
|
1
|
+
# Kobot [](https://badge.fury.io/rb/kobot)
|
2
2
|
|
3
3
|
Kobot is a simple tool to automate the clock in or clock out operation on the web service
|
4
|
-
provided by [KING OF TIME](kingtime.jp) by leveraging [Selenium WebDriver](
|
5
|
-
and with Google Gmail service email
|
4
|
+
provided by [KING OF TIME](https://www.kingtime.jp/) by leveraging [Selenium WebDriver](
|
5
|
+
https://www.selenium.dev/), and with Google Gmail service email notifications can also be
|
6
|
+
sent to notify the results.
|
6
7
|
|
7
8
|
It is meant for use only by one working under the discretionary labor system or flexible
|
8
9
|
hours where the daily record is still required regardless of the actual start or end time
|
@@ -21,10 +22,11 @@ Tested on macOS Catelina and runs on Heroku platform so it works on unix-like sy
|
|
21
22
|
#### Configuration
|
22
23
|
|
23
24
|
By default it uses `~/.kobot` file locally to persist credentials for reuse, but all credentials
|
24
|
-
can be overridden by
|
25
|
-
|
26
|
-
|
27
|
-
so there is no need to manually prepare the file beforehand
|
25
|
+
can also be supplied or overridden by runtime environment variables, which is the recommended way
|
26
|
+
of running as scheduled jobs on platforms like Heroku. When running for the first time, if neither
|
27
|
+
the configuration file nor ENV satisfies all required credentials, `an interactive prompt will be
|
28
|
+
displayed for initial setting, so there is no need to manually prepare the file beforehand`. The
|
29
|
+
content looks something like:
|
28
30
|
```property
|
29
31
|
kot_id=xxx
|
30
32
|
kot_password=xxx
|
@@ -34,6 +36,7 @@ Gmail account and password (or `app` password if MFA is on) are asked when notif
|
|
34
36
|
gmail_id=xxx
|
35
37
|
gmail_password=xxx
|
36
38
|
```
|
39
|
+
Note: use all upper-case letters for the above variables if using environment variables, e.g. `KOT_ID`.
|
37
40
|
|
38
41
|
#### Google Chrome browser
|
39
42
|
|
@@ -51,17 +54,20 @@ $ gem install kobot
|
|
51
54
|
## Usage
|
52
55
|
|
53
56
|
Get help doc:
|
54
|
-
```
|
57
|
+
```
|
55
58
|
$ kobot -h
|
56
59
|
Usage: kobot [options]
|
57
|
-
-c, --clock CLOCK
|
58
|
-
-l, --loglevel [LEVEL] Specify log level: debug, info, warn, error
|
60
|
+
-c, --clock CLOCK Required; the clock action option: in, out
|
61
|
+
-l, --loglevel [LEVEL] Specify log level: debug, info, warn, error; default is info
|
59
62
|
-s, --skip [D1,D2,D3] Specify dates to skip clock in/out with date format YYYY-MM-DD and
|
60
|
-
multiple values separated by comma, such as: 2020-05-01,2020-12-31
|
61
|
-
|
63
|
+
multiple values separated by comma, such as: 2020-05-01,2020-12-31;
|
64
|
+
weekends and public holidays in Japan will be skipped by default
|
65
|
+
-t, --to [TO] Email address to send notification to; by default it is sent to
|
62
66
|
the same self email account used in SMTP config as the sender
|
63
67
|
-n, --notify Enable email notification
|
64
68
|
-d, --dryrun Run the process without actual clock in/out
|
69
|
+
-f, --force Run the process forcibly regardless of weekends or public holidays;
|
70
|
+
must be used together with --dryrun to prevent mistaken operations
|
65
71
|
-x, --headless Start browser in headless mode
|
66
72
|
-g, --geolocation Allow browser to use geolocation
|
67
73
|
-h, --help Show this help message
|
@@ -69,20 +75,25 @@ Usage: kobot [options]
|
|
69
75
|
```
|
70
76
|
|
71
77
|
Dryrun to try out:
|
72
|
-
```
|
73
|
-
$ kobot --clock in --dryrun
|
78
|
+
```
|
79
|
+
$ kobot --clock in --notify --dryrun
|
74
80
|
```
|
75
81
|
|
76
82
|
Clock in/out with email notification
|
77
|
-
```
|
78
|
-
$ kobot --clock in --notify
|
79
|
-
$ kobot --clock out --notify
|
83
|
+
```
|
84
|
+
$ kobot --clock in --notify --headless
|
85
|
+
$ kobot --clock out --notify --headless
|
80
86
|
```
|
81
87
|
|
82
88
|
Run the task with crontab
|
83
89
|
```cron
|
84
|
-
|
85
|
-
30
|
90
|
+
# Weekend and public holidays will be skipped by default
|
91
|
+
30 09 * * * user kobot --cin -n -x
|
92
|
+
30 18 * * * user kobot --cout -n -x
|
93
|
+
|
94
|
+
# Skip for weekdays planned to take leave for example
|
95
|
+
30 09 * * * user kobot --cin -n -x -s 2020-09-01,2020-11-11
|
96
|
+
30 18 * * * user kobot --cout -n -x -s 2020-09-01,2020-11-11
|
86
97
|
```
|
87
98
|
On platforms like Heroku, an add-on called [Heroku Scheduler](https://elements.heroku.com/addons/scheduler) makes
|
88
99
|
running scheduled tasks much easier. Tips: either clock in or clock out task can be scheduled multiple times in
|
data/bin/console
CHANGED
data/exe/kobot
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
4
|
+
begin
|
5
|
+
# For quickly tryout in local development
|
6
|
+
# without installing to system gems path
|
7
|
+
raise LoadError if ENV['KOBOT_DEV']
|
8
|
+
|
9
|
+
require 'kobot'
|
10
|
+
rescue LoadError
|
11
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __dir__)
|
12
|
+
require 'kobot'
|
13
|
+
end
|
5
14
|
|
6
15
|
Kobot.run
|
data/kobot.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
|
|
17
17
|
|
18
18
|
spec.homepage = 'https://github.com/yuan-jiang/kobot'
|
19
19
|
spec.license = 'MIT'
|
20
|
-
spec.required_ruby_version = Gem::Requirement.new('>= 2.
|
20
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.4.0')
|
21
21
|
|
22
22
|
spec.metadata['allowed_push_host'] = 'https://rubygems.org/'
|
23
23
|
spec.metadata['homepage_uri'] = spec.homepage
|
data/lib/kobot.rb
CHANGED
@@ -14,8 +14,6 @@ require 'kobot/engine'
|
|
14
14
|
# and with Google Gmail service email notification can also be sent to notify the results.
|
15
15
|
module Kobot
|
16
16
|
class << self
|
17
|
-
|
18
|
-
# The entrance to run Kobot.
|
19
17
|
def run
|
20
18
|
configure
|
21
19
|
Engine.new.start
|
@@ -33,6 +31,7 @@ module Kobot
|
|
33
31
|
config.clock = options[:clock].to_sym
|
34
32
|
config.loglevel = options[:loglevel]&.to_sym || :info
|
35
33
|
config.dryrun = options[:dryrun]
|
34
|
+
config.force = options[:force]
|
36
35
|
config.skip = options[:skip] || []
|
37
36
|
|
38
37
|
config.kot_url = 'https://s2.kingtime.jp/independent/recorder/personal/'
|
data/lib/kobot/config.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Kobot
|
4
|
-
|
5
4
|
# Configuration definition includes static ones hardcoded and
|
6
5
|
# dynamic ones that can be specified by command line options.
|
7
6
|
class Config
|
@@ -9,7 +8,8 @@ module Kobot
|
|
9
8
|
attr_accessor :clock,
|
10
9
|
:loglevel,
|
11
10
|
:skip,
|
12
|
-
:dryrun
|
11
|
+
:dryrun,
|
12
|
+
:force
|
13
13
|
|
14
14
|
attr_accessor :kot_url,
|
15
15
|
:kot_timezone_offset,
|
data/lib/kobot/credential.rb
CHANGED
@@ -4,7 +4,6 @@ module Kobot
|
|
4
4
|
# Credentials include id and password to login to KOT and
|
5
5
|
# Gmail SMTP id and password to send email notifications.
|
6
6
|
class Credential
|
7
|
-
|
8
7
|
class << self
|
9
8
|
attr_accessor :kot_id,
|
10
9
|
:kot_password,
|
@@ -30,7 +29,7 @@ module Kobot
|
|
30
29
|
@credentials.each do |attr, value|
|
31
30
|
send("#{attr}=".to_sym, value)
|
32
31
|
end
|
33
|
-
Kobot.logger.info('
|
32
|
+
Kobot.logger.info('Load credentials successful')
|
34
33
|
Kobot.logger.debug(@credentials)
|
35
34
|
end
|
36
35
|
|
@@ -41,18 +40,18 @@ module Kobot
|
|
41
40
|
if File.exist? Config.credentials_file
|
42
41
|
File.open(Config.credentials_file) do |file|
|
43
42
|
file.each do |line|
|
44
|
-
attr, value = line.
|
43
|
+
attr, value = line.strip.split('=')
|
45
44
|
@credentials[attr] = value
|
46
45
|
end
|
47
46
|
end
|
48
47
|
end
|
49
|
-
@credentials['kot_id'] = ENV['kot_id'] if ENV['kot_id']
|
50
|
-
@credentials['kot_password'] = ENV['kot_password'] if ENV['kot_password']
|
51
|
-
@credentials['gmail_id'] = ENV['gmail_id'] if ENV['gmail_id']
|
52
|
-
@credentials['gmail_password'] = ENV['gmail_password'] if ENV['gmail_password']
|
53
|
-
|
54
48
|
required_credentials = %w[kot_id kot_password]
|
55
49
|
required_credentials.concat %w[gmail_id gmail_password] if Config.gmail_notify_enabled
|
50
|
+
required_credentials.each do |attr|
|
51
|
+
Kobot.logger.deprecate(attr, attr.upcase) if ENV[attr]
|
52
|
+
env_attr_value = ENV[attr.upcase] || ENV[attr]
|
53
|
+
@credentials[attr] = env_attr_value if env_attr_value
|
54
|
+
end
|
56
55
|
required_credentials.none? do |attr|
|
57
56
|
credential = @credentials[attr]
|
58
57
|
!credential || credential.strip.empty?
|
data/lib/kobot/engine.rb
CHANGED
@@ -6,7 +6,6 @@ module Kobot
|
|
6
6
|
# The core class that launches browser, logins to KOT, reads today
|
7
7
|
# record, and conducts clock in or clock out action based on config.
|
8
8
|
class Engine
|
9
|
-
|
10
9
|
def initialize
|
11
10
|
@now = Time.now.getlocal(Config.kot_timezone_offset)
|
12
11
|
@today = @now.strftime(Config.kot_date_format)
|
@@ -25,28 +24,19 @@ module Kobot
|
|
25
24
|
# System errors or any unknown exceptions occurred if any are
|
26
25
|
# to be popped up and should be handled by the outside caller.
|
27
26
|
def start
|
28
|
-
|
29
|
-
Kobot.logger.info("Today=#{@today} is weekend.")
|
30
|
-
return
|
31
|
-
end
|
32
|
-
if holiday?
|
33
|
-
Kobot.logger.info("Today=#{@today} is holiday.")
|
34
|
-
return
|
35
|
-
end
|
36
|
-
unless %i[in out].include? Config.clock
|
37
|
-
Kobot.logger.warn("Invalid clock operation: #{Config.clock}")
|
38
|
-
return
|
39
|
-
end
|
27
|
+
validate_today!
|
40
28
|
launch_browser
|
41
29
|
login
|
42
30
|
read_today_record
|
43
|
-
|
31
|
+
validate_today_record!
|
44
32
|
if Config.clock == :in
|
45
33
|
clock_in!
|
46
34
|
else
|
47
35
|
clock_out!
|
48
36
|
end
|
49
37
|
logout
|
38
|
+
rescue KotSkip => e
|
39
|
+
Kobot.logger.warn(e.message)
|
50
40
|
rescue KotRecordError => e
|
51
41
|
Kobot.logger.warn(e.message)
|
52
42
|
Mailer.send(clock_notify_message(status: e.message))
|
@@ -65,11 +55,20 @@ module Kobot
|
|
65
55
|
Mailer.send(clock_notify_message(status: e.message))
|
66
56
|
logout
|
67
57
|
ensure
|
68
|
-
|
58
|
+
close_browser
|
69
59
|
end
|
70
60
|
|
71
61
|
private
|
72
62
|
|
63
|
+
def validate_today!
|
64
|
+
raise KotSkip, "Today=#{@today} is skipped as per: --skip=#{Config.skip}" if skip?
|
65
|
+
|
66
|
+
return unless weekend?
|
67
|
+
raise KotSkip, "Today=#{@today} is weekend" unless Config.force
|
68
|
+
|
69
|
+
Kobot.logger.info("[Force] should have exited: today=#{@today} is weekend")
|
70
|
+
end
|
71
|
+
|
73
72
|
def launch_browser
|
74
73
|
prefs = {
|
75
74
|
profile: {
|
@@ -85,9 +84,18 @@ module Kobot
|
|
85
84
|
Kobot.logger.info('Launch browser successful')
|
86
85
|
end
|
87
86
|
|
87
|
+
def close_browser
|
88
|
+
return unless @browser
|
89
|
+
|
90
|
+
Kobot.logger.info('Close browser')
|
91
|
+
@browser.quit
|
92
|
+
end
|
93
|
+
|
88
94
|
def login
|
89
|
-
@browser.get @top_url
|
90
95
|
Kobot.logger.info("Navigate to: #{@top_url}")
|
96
|
+
@browser.get @top_url
|
97
|
+
@wait.until { @browser.find_element(id: 'modal_window') }
|
98
|
+
Kobot.logger.info "Page title: #{@browser.title}"
|
91
99
|
Kobot.logger.debug do
|
92
100
|
"Login with id=#{Credential.kot_id} and password=#{Credential.kot_password}"
|
93
101
|
end
|
@@ -104,13 +112,15 @@ module Kobot
|
|
104
112
|
Kobot.logger.warn "Get geolocation failed: #{e.message}"
|
105
113
|
end
|
106
114
|
end
|
107
|
-
Kobot.logger.info @browser.title
|
115
|
+
Kobot.logger.info "Page title: #{@browser.title}"
|
108
116
|
end
|
109
117
|
|
110
118
|
def logout
|
111
119
|
if @browser.current_url.include? 'admin'
|
120
|
+
Kobot.logger.info('Logout from タイムカード page')
|
112
121
|
@browser.find_element(css: 'div.htBlock-header_logoutButton').click
|
113
122
|
else
|
123
|
+
Kobot.logger.info('Logout from Myレコーダー page')
|
114
124
|
@wait.until { @browser.find_element(id: 'menu_icon') }.click
|
115
125
|
@wait.until { @browser.find_element(link: 'ログアウト') }.click
|
116
126
|
@browser.switch_to.alert.accept
|
@@ -119,6 +129,7 @@ module Kobot
|
|
119
129
|
end
|
120
130
|
|
121
131
|
def read_today_record
|
132
|
+
Kobot.logger.info('Navigate to タイムカード page')
|
122
133
|
@wait.until { @browser.find_element(id: 'menu_icon') }.click
|
123
134
|
@wait.until { @browser.find_element(link: 'タイムカード') }.click
|
124
135
|
|
@@ -131,8 +142,12 @@ module Kobot
|
|
131
142
|
@kot_today = date_cell.text
|
132
143
|
@kot_today_css_class = date_cell.attribute('class')
|
133
144
|
@kot_today_type = tr.find_element(css: 'td.work_day_type').text
|
134
|
-
@kot_today_clock_in = tr.find_element(
|
135
|
-
|
145
|
+
@kot_today_clock_in = tr.find_element(
|
146
|
+
css: 'td.start_end_timerecord[data-ht-sort-index="START_TIMERECORD"]'
|
147
|
+
).text
|
148
|
+
@kot_today_clock_out = tr.find_element(
|
149
|
+
css: 'td.start_end_timerecord[data-ht-sort-index="END_TIMERECORD"]'
|
150
|
+
).text
|
136
151
|
Kobot.logger.debug do
|
137
152
|
{
|
138
153
|
kot_toay: @kot_today,
|
@@ -146,10 +161,23 @@ module Kobot
|
|
146
161
|
end
|
147
162
|
end
|
148
163
|
|
149
|
-
def
|
150
|
-
raise KotRecordError, "Today=#{@today} is not found on kot
|
151
|
-
|
152
|
-
|
164
|
+
def validate_today_record!
|
165
|
+
raise KotRecordError, "Today=#{@today} is not found on kot" if @kot_today.strip.empty?
|
166
|
+
|
167
|
+
if kot_weekend?
|
168
|
+
raise KotRecordError, "Today=#{@today} is marked as weekend on kot: #{@kot_today}" unless Config.force
|
169
|
+
|
170
|
+
Kobot.logger.info(
|
171
|
+
"[Force] should have exited: today=#{@today} is marked as weekend on kot: #{@kot_today}"
|
172
|
+
)
|
173
|
+
end
|
174
|
+
|
175
|
+
return unless kot_public_holiday?
|
176
|
+
raise KotRecordError, "Today=#{@today} is marked as public holiday on kot: #{@kot_today}" unless Config.force
|
177
|
+
|
178
|
+
Kobot.logger.info(
|
179
|
+
"[Force] should have exited: today=#{@today} is marked as public holiday on kot: #{@kot_today}"
|
180
|
+
)
|
153
181
|
end
|
154
182
|
|
155
183
|
def clock_in!
|
@@ -192,21 +220,25 @@ module Kobot
|
|
192
220
|
end
|
193
221
|
|
194
222
|
def click_clock_in_button
|
223
|
+
Kobot.logger.info("Navigate to: #{@top_url}")
|
195
224
|
@browser.get @top_url
|
196
225
|
clock_in_button = @wait.until { @browser.find_element(css: 'div.record-clock-in') }
|
197
226
|
if Config.dryrun
|
198
227
|
Kobot.logger.info('[Dryrun] clock in button (出勤) would have been clicked')
|
199
228
|
else
|
229
|
+
Kobot.logger.info('Clicking the clock in button (出勤)')
|
200
230
|
clock_in_button.click
|
201
231
|
end
|
202
232
|
end
|
203
233
|
|
204
234
|
def click_clock_out_button
|
235
|
+
Kobot.logger.info("Navigate to: #{@top_url}")
|
205
236
|
@browser.get @top_url
|
206
237
|
clock_out_button = @wait.until { @browser.find_element(css: 'div.record-clock-out') }
|
207
238
|
if Config.dryrun
|
208
239
|
Kobot.logger.info('[Dryrun] clock out button (退勤) would have been clicked')
|
209
240
|
else
|
241
|
+
Kobot.logger.info('Clicking the clock in button (退勤)')
|
210
242
|
clock_out_button.click
|
211
243
|
end
|
212
244
|
end
|
@@ -215,7 +247,7 @@ module Kobot
|
|
215
247
|
@now.saturday? || @now.sunday?
|
216
248
|
end
|
217
249
|
|
218
|
-
def
|
250
|
+
def skip?
|
219
251
|
return false unless Config.skip
|
220
252
|
return false unless Config.skip.respond_to? :include?
|
221
253
|
|
data/lib/kobot/exception.rb
CHANGED
data/lib/kobot/mailer.rb
CHANGED
@@ -3,11 +3,9 @@
|
|
3
3
|
require 'net/smtp'
|
4
4
|
|
5
5
|
module Kobot
|
6
|
-
|
7
6
|
# Responsible for sending email notifications in SMTP with Gmail
|
8
7
|
class Mailer
|
9
8
|
class << self
|
10
|
-
|
11
9
|
# Sends email in preconfigured Gmail SMTP credential and to the recipient
|
12
10
|
# configured by #{Config.gmail_notify_to} or self if not configured, with
|
13
11
|
# email subject set by #{Config.gmail_notify_subject}.
|
data/lib/kobot/option.rb
CHANGED
@@ -3,33 +3,32 @@
|
|
3
3
|
require 'optparse'
|
4
4
|
|
5
5
|
module Kobot
|
6
|
-
|
7
6
|
# Responsible for parsing the command line options for custom execution.
|
8
7
|
class Option
|
9
8
|
class << self
|
10
|
-
|
11
9
|
# Parses command line options and returns a hash containing the options.
|
12
10
|
def parse!
|
13
11
|
options = {}
|
14
12
|
opt_parser = OptionParser.new do |opt|
|
15
13
|
opt.banner = "Usage: #{$PROGRAM_NAME} [options]"
|
16
14
|
|
17
|
-
opt.on('-c', '--clock CLOCK', '
|
15
|
+
opt.on('-c', '--clock CLOCK', 'Required; the clock action option: in, out') do |clock|
|
18
16
|
options[:clock] = clock
|
19
17
|
end
|
20
18
|
|
21
|
-
opt.on('-l', '--loglevel [LEVEL]', 'Specify log level: debug, info, warn, error
|
19
|
+
opt.on('-l', '--loglevel [LEVEL]', 'Specify log level: debug, info, warn, error; default is info') do |level|
|
22
20
|
options[:loglevel] = level
|
23
21
|
end
|
24
22
|
|
25
23
|
opt.on('-s', '--skip [D1,D2,D3]', Array,
|
26
24
|
'Specify dates to skip clock in/out with date format YYYY-MM-DD and',
|
27
|
-
'multiple values separated by comma, such as: 2020-05-01,2020-12-31'
|
25
|
+
'multiple values separated by comma, such as: 2020-05-01,2020-12-31;',
|
26
|
+
'weekends and public holidays in Japan will be skipped by default') do |skip|
|
28
27
|
options[:skip] = skip
|
29
28
|
end
|
30
29
|
|
31
30
|
opt.on('-t', '--to [TO]',
|
32
|
-
'Email address to send notification to
|
31
|
+
'Email address to send notification to; by default it is sent to',
|
33
32
|
'the same self email account used in SMTP config as the sender') do |to|
|
34
33
|
options[:to] = to
|
35
34
|
end
|
@@ -42,6 +41,12 @@ module Kobot
|
|
42
41
|
options[:dryrun] = dryrun
|
43
42
|
end
|
44
43
|
|
44
|
+
opt.on('-f', '--force',
|
45
|
+
'Run the process forcibly regardless of weekends or public holidays;',
|
46
|
+
'must be used together with --dryrun to prevent mistaken operations') do |force|
|
47
|
+
options[:force] = force
|
48
|
+
end
|
49
|
+
|
45
50
|
opt.on('-x', '--headless', 'Start browser in headless mode') do |headless|
|
46
51
|
options[:headless] = headless
|
47
52
|
end
|
@@ -62,7 +67,12 @@ module Kobot
|
|
62
67
|
end
|
63
68
|
opt_parser.parse! ARGV
|
64
69
|
raise OptionParser::MissingArgument, 'The clock option is required' if options[:clock].nil?
|
65
|
-
|
70
|
+
unless %w[in out].include? options[:clock]
|
71
|
+
raise OptionParser::InvalidArgument, 'The clock option must be either: in, out'
|
72
|
+
end
|
73
|
+
if options[:force] && !options[:dryrun]
|
74
|
+
raise OptionParser::InvalidArgument, 'Must specify --dryrun for forcibly running'
|
75
|
+
end
|
66
76
|
|
67
77
|
options
|
68
78
|
rescue OptionParser::MissingArgument, OptionParser::InvalidArgument => e
|
data/lib/kobot/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kobot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Jiang
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-09-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: webdrivers
|
@@ -100,7 +100,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
100
100
|
requirements:
|
101
101
|
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: 2.
|
103
|
+
version: 2.4.0
|
104
104
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
105
|
requirements:
|
106
106
|
- - ">="
|