kobot 1.2.5 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +3 -0
- data/lib/kobot/config.rb +9 -12
- data/lib/kobot/engine.rb +53 -35
- data/lib/kobot/option.rb +7 -0
- data/lib/kobot/version.rb +1 -1
- data/lib/kobot.rb +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '08261437cd35a8b09dfad79740f2f6ec52e87fea47713aba5e00133aa570ac08'
|
4
|
+
data.tar.gz: a7941208f88d46d40fb8d5366851f5b466bb85e975b3d5ff95e7753bf9f8032c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f14ebacda3eaec90ae6f6e9f995821d3116599e2fdff2e19afcd546c43404f6453055d256828f4f549e07d5f3e08ac0ba4cbc1c6ee0e4b3739a02277b0285258
|
7
|
+
data.tar.gz: d42d8f45187cc512eb08b13d5c891cd7b0bf567a76bf55b49ffc089c240946f0345208b7586fecbd2a32c8e3f3855f22086913bed5c79152e3248e5db0692d75
|
data/CHANGELOG.md
CHANGED
@@ -28,3 +28,8 @@
|
|
28
28
|
|
29
29
|
### v1.2.5
|
30
30
|
- Added I18n support for both English and Japanese KOT UI
|
31
|
+
|
32
|
+
### v1.3.0
|
33
|
+
- Added config option (-a, --auto-skip-without) to enable automatic skipping based on schedule
|
34
|
+
- Replaced deprecated options with capabilities option in Selenium driver initialization
|
35
|
+
- Refactored scattered attr_accessors and reduced instance variables count reported by Rubocop
|
data/README.md
CHANGED
@@ -62,6 +62,9 @@ Usage: kobot [options]
|
|
62
62
|
-s, --skip [D1,D2,D3] Specify dates to skip clock in/out with date format YYYY-MM-DD and
|
63
63
|
multiple values separated by comma, such as: 2020-05-01,2020-12-31;
|
64
64
|
weekends and public holidays in Japan will be skipped by default
|
65
|
+
-a [SCHEDULE], Enable automatic skipping by reading schedule from the Time Card page;
|
66
|
+
--auto-skip-without skip today if the provided text is not contained in the schedule column
|
67
|
+
on the Time Card page; by default 裁量労働 is used
|
65
68
|
-t, --to [TO] Email address to send notification to; by default it is sent to
|
66
69
|
the same self email account used in SMTP config as the sender
|
67
70
|
-n, --notify Enable email notification
|
data/lib/kobot/config.rb
CHANGED
@@ -8,24 +8,21 @@ module Kobot
|
|
8
8
|
attr_accessor :clock,
|
9
9
|
:loglevel,
|
10
10
|
:skip,
|
11
|
+
:auto_skip_without,
|
11
12
|
:dryrun,
|
12
|
-
:force
|
13
|
-
|
14
|
-
attr_accessor :kot_url,
|
13
|
+
:force,
|
14
|
+
:kot_url,
|
15
15
|
:kot_timezone_offset,
|
16
|
-
:kot_date_format
|
17
|
-
|
18
|
-
attr_accessor :gmail_notify_enabled,
|
16
|
+
:kot_date_format,
|
17
|
+
:gmail_notify_enabled,
|
19
18
|
:gmail_notify_subject,
|
20
19
|
:gmail_notify_to,
|
21
20
|
:gmail_smtp_address,
|
22
|
-
:gmail_smtp_port
|
23
|
-
|
24
|
-
attr_accessor :browser_headless,
|
21
|
+
:gmail_smtp_port,
|
22
|
+
:browser_headless,
|
25
23
|
:browser_geolocation,
|
26
|
-
:browser_wait_timeout
|
27
|
-
|
28
|
-
attr_accessor :credentials_file
|
24
|
+
:browser_wait_timeout,
|
25
|
+
:credentials_file
|
29
26
|
|
30
27
|
def configure
|
31
28
|
yield self
|
data/lib/kobot/engine.rb
CHANGED
@@ -81,7 +81,10 @@ module Kobot
|
|
81
81
|
}
|
82
82
|
options = Selenium::WebDriver::Chrome::Options.new(prefs: prefs)
|
83
83
|
options.headless! if Config.browser_headless
|
84
|
-
|
84
|
+
caps = [
|
85
|
+
options
|
86
|
+
]
|
87
|
+
@browser = Selenium::WebDriver.for(:chrome, capabilities: caps)
|
85
88
|
@wait = Selenium::WebDriver::Wait.new(timeout: Config.browser_wait_timeout)
|
86
89
|
Kobot.logger.info('Launch browser successful')
|
87
90
|
end
|
@@ -151,22 +154,24 @@ module Kobot
|
|
151
154
|
next unless date_cell.text.include? @today
|
152
155
|
|
153
156
|
Kobot.logger.info('Reading today record')
|
154
|
-
@
|
155
|
-
@
|
156
|
-
@
|
157
|
-
@
|
157
|
+
@kot_data = {}
|
158
|
+
@kot_data[:today] = date_cell.text
|
159
|
+
@kot_data[:today_css_class] = date_cell.attribute('class')
|
160
|
+
@kot_data[:today_type] = tr.find_element(css: 'td.work_day_type').text
|
161
|
+
@kot_data[:today_schedule] = tr.find_element(css: 'td.schedule').text
|
162
|
+
@kot_data[:today_clock_in] = tr.find_element(
|
158
163
|
css: 'td.start_end_timerecord[data-ht-sort-index="START_TIMERECORD"]'
|
159
164
|
).text
|
160
|
-
@
|
165
|
+
@kot_data[:today_clock_out] = tr.find_element(
|
161
166
|
css: 'td.start_end_timerecord[data-ht-sort-index="END_TIMERECORD"]'
|
162
167
|
).text
|
163
168
|
Kobot.logger.debug do
|
164
169
|
{
|
165
|
-
kot_toay: @
|
166
|
-
kot_today_css_class: @
|
167
|
-
kot_today_type: @
|
168
|
-
kot_today_clock_in: @
|
169
|
-
kot_today_clock_out: @
|
170
|
+
kot_toay: @kot_data[:today],
|
171
|
+
kot_today_css_class: @kot_data[:today_css_class],
|
172
|
+
kot_today_type: @kot_data[:today_type],
|
173
|
+
kot_today_clock_in: @kot_data[:today_clock_in],
|
174
|
+
kot_today_clock_out: @kot_data[:today_clock_out]
|
170
175
|
}
|
171
176
|
end
|
172
177
|
break
|
@@ -174,60 +179,69 @@ module Kobot
|
|
174
179
|
end
|
175
180
|
|
176
181
|
def validate_today_record!
|
177
|
-
raise KotRecordError, "Today=#{@today} is not found on kot" if @
|
182
|
+
raise KotRecordError, "Today=#{@today} is not found on kot" if @kot_data[:today].strip.empty?
|
178
183
|
|
179
184
|
if kot_weekend?
|
180
|
-
raise KotRecordError, "Today=#{@today} is marked as weekend
|
185
|
+
raise KotRecordError, "Today=#{@today} is marked as weekend: #{@kot_data[:today]}" unless Config.force
|
186
|
+
|
187
|
+
Kobot.logger.info(
|
188
|
+
"[Force] should have exited: today=#{@today} is marked as weekend: #{@kot_data[:today]}"
|
189
|
+
)
|
190
|
+
end
|
191
|
+
|
192
|
+
if kot_public_holiday?
|
193
|
+
raise KotRecordError, "Today=#{@today} is marked as public holiday: #{@kot_data[:today]}" unless Config.force
|
181
194
|
|
182
195
|
Kobot.logger.info(
|
183
|
-
"[Force] should have exited: today=#{@today} is marked as
|
196
|
+
"[Force] should have exited: today=#{@today} is marked as public holiday: #{@kot_data[:today]}"
|
184
197
|
)
|
185
198
|
end
|
186
199
|
|
187
|
-
|
188
|
-
|
200
|
+
if kot_non_work_schedule?
|
201
|
+
raise KotRecordError, "Today=#{@today} is non-work schedule: #{@kot_data[:today_schedule]}" unless Config.force
|
189
202
|
|
190
|
-
|
191
|
-
|
192
|
-
|
203
|
+
Kobot.logger.info(
|
204
|
+
"[Force] should have exited: today=#{@today} is non-work schedule: #{@kot_data[:today_schedule]}"
|
205
|
+
)
|
206
|
+
end
|
193
207
|
end
|
194
208
|
|
195
209
|
def clock_in!
|
196
210
|
Kobot.logger.warn("Clock in during the afternoon: #{@now}") if @now.hour > 12
|
197
|
-
if @
|
211
|
+
if @kot_data[:today_clock_in].strip.empty?
|
198
212
|
click_clock_in_button
|
199
213
|
return if Config.dryrun
|
200
214
|
|
201
215
|
read_today_record
|
202
|
-
raise KotClockInError, 'Clock in operation seems to have failed' if @
|
216
|
+
raise KotClockInError, 'Clock in operation seems to have failed' if @kot_data[:today_clock_in].strip.empty?
|
203
217
|
|
204
|
-
Kobot.logger.info("Clock in successful: #{@
|
218
|
+
Kobot.logger.info("Clock in successful: #{@kot_data[:today_clock_in]}")
|
205
219
|
Mailer.send(clock_notify_message(clock: :in))
|
206
220
|
else
|
207
|
-
Kobot.logger.warn("Clock in done already: #{@
|
221
|
+
Kobot.logger.warn("Clock in done already: #{@kot_data[:today_clock_in]}")
|
208
222
|
end
|
209
223
|
end
|
210
224
|
|
211
225
|
def clock_out!
|
212
226
|
Kobot.logger.warn("Clock out during the morning: #{@now}") if @now.hour <= 12
|
213
227
|
unless Config.dryrun
|
214
|
-
if @
|
228
|
+
if @kot_data[:today_clock_in].strip.empty?
|
215
229
|
raise KotClockOutError,
|
216
|
-
"!!!No clock in record for today=#{@
|
230
|
+
"!!!No clock in record for today=#{@kot_data[:today]}!!!"
|
217
231
|
end
|
218
232
|
end
|
219
233
|
|
220
|
-
if @
|
234
|
+
if @kot_data[:today_clock_out].strip.empty?
|
221
235
|
click_clock_out_button
|
222
236
|
return if Config.dryrun
|
223
237
|
|
224
238
|
read_today_record
|
225
|
-
raise KotClockOutError, 'Clock out operation seems to have failed' if @
|
239
|
+
raise KotClockOutError, 'Clock out operation seems to have failed' if @kot_data[:today_clock_out].strip.empty?
|
226
240
|
|
227
|
-
Kobot.logger.info("Clock out successful: #{@
|
241
|
+
Kobot.logger.info("Clock out successful: #{@kot_data[:today_clock_out]}")
|
228
242
|
Mailer.send(clock_notify_message(clock: :out))
|
229
243
|
else
|
230
|
-
Kobot.logger.warn("Clock out done already: #{@
|
244
|
+
Kobot.logger.warn("Clock out done already: #{@kot_data[:today_clock_out]}")
|
231
245
|
end
|
232
246
|
end
|
233
247
|
|
@@ -270,18 +284,22 @@ module Kobot
|
|
270
284
|
[
|
271
285
|
@selector.kot_date_saturday,
|
272
286
|
@selector.kot_date_sunday
|
273
|
-
].any? { |weekend| @
|
287
|
+
].any? { |weekend| @kot_data[:today]&.include? weekend }
|
288
|
+
end
|
289
|
+
|
290
|
+
def kot_non_work_schedule?
|
291
|
+
!@kot_data[:today_schedule]&.include?(Config.auto_skip_without)
|
274
292
|
end
|
275
293
|
|
276
294
|
def kot_public_holiday?
|
277
|
-
return true if @
|
295
|
+
return true if @kot_data[:today_type]&.include? @selector.kot_workday_time_off_text
|
278
296
|
|
279
297
|
kot_today_highlighted = %w[sunday saturday].any? do |css|
|
280
|
-
@
|
298
|
+
@kot_data[:today_css_class]&.include? css
|
281
299
|
end
|
282
300
|
if kot_today_highlighted
|
283
301
|
Kobot.logger.warn(
|
284
|
-
"Today=#{@
|
302
|
+
"Today=#{@kot_data[:today]} is highlighted (holiday) but not marked as #{@selector.kot_workday_time_off_text}"
|
285
303
|
)
|
286
304
|
end
|
287
305
|
kot_today_highlighted
|
@@ -293,8 +311,8 @@ module Kobot
|
|
293
311
|
"<b>Date:</b> #{@today}",
|
294
312
|
"<b>Status:</b> <span style='color:#{color}'>#{status}</span>"
|
295
313
|
]
|
296
|
-
message << "<b>Clock_in:</b> #{@
|
297
|
-
message << "<b>Clock_out:</b> #{@
|
314
|
+
message << "<b>Clock_in:</b> #{@kot_data[:today_clock_in]}" if clock
|
315
|
+
message << "<b>Clock_out:</b> #{@kot_data[:today_clock_out]}" if clock == :out
|
298
316
|
message.join('<br>')
|
299
317
|
end
|
300
318
|
end
|
data/lib/kobot/option.rb
CHANGED
@@ -27,6 +27,13 @@ module Kobot
|
|
27
27
|
options[:skip] = skip
|
28
28
|
end
|
29
29
|
|
30
|
+
opt.on('-a', '--auto-skip-without [SCHEDULE]',
|
31
|
+
'Enable automatic skipping by reading schedule from the Time Card page;',
|
32
|
+
'skip today if the provided text is not contained in the schedule column',
|
33
|
+
'on the Time Card page; by default 裁量労働 is used') do |schedule|
|
34
|
+
options[:auto_skip_without] = schedule
|
35
|
+
end
|
36
|
+
|
30
37
|
opt.on('-t', '--to [TO]',
|
31
38
|
'Email address to send notification to; by default it is sent to',
|
32
39
|
'the same self email account used in SMTP config as the sender') do |to|
|
data/lib/kobot/version.rb
CHANGED
data/lib/kobot.rb
CHANGED
@@ -34,6 +34,7 @@ module Kobot
|
|
34
34
|
config.dryrun = options[:dryrun]
|
35
35
|
config.force = options[:force]
|
36
36
|
config.skip = options[:skip] || []
|
37
|
+
config.auto_skip_without = options[:auto_skip_without] || '裁量労働'
|
37
38
|
|
38
39
|
config.kot_url = 'https://s2.kingtime.jp/independent/recorder/personal/'
|
39
40
|
config.kot_timezone_offset = '+09:00'
|
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.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Jiang
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-12-
|
11
|
+
date: 2021-12-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: webdrivers
|