taskloop 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.idea/.gitignore +8 -0
- data/.idea/misc.xml +4 -0
- data/.idea/modules.xml +8 -0
- data/.idea/taskloop.iml +51 -0
- data/.idea/vcs.xml +6 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +36 -0
- data/README.md +31 -0
- data/Rakefile +4 -0
- data/exe/taskloop +16 -0
- data/lib/taskloop/command/deploy.rb +136 -0
- data/lib/taskloop/command/env.rb +134 -0
- data/lib/taskloop/command/init.rb +42 -0
- data/lib/taskloop/command/launch.rb +67 -0
- data/lib/taskloop/command/list.rb +59 -0
- data/lib/taskloop/command/log.rb +104 -0
- data/lib/taskloop/command/run.rb +106 -0
- data/lib/taskloop/command/shutdown.rb +49 -0
- data/lib/taskloop/command/undeploy.rb +46 -0
- data/lib/taskloop/command.rb +168 -0
- data/lib/taskloop/dsl/dsl.rb +63 -0
- data/lib/taskloop/extension/integer_extension.rb +25 -0
- data/lib/taskloop/extension/string_extension.rb +18 -0
- data/lib/taskloop/rules/after_scope_rule.rb +91 -0
- data/lib/taskloop/rules/before_scope_rule.rb +90 -0
- data/lib/taskloop/rules/between_scope_rule.rb +130 -0
- data/lib/taskloop/rules/date_list_rule.rb +47 -0
- data/lib/taskloop/rules/default_rule.rb +19 -0
- data/lib/taskloop/rules/interval_rule.rb +26 -0
- data/lib/taskloop/rules/loop_rule.rb +25 -0
- data/lib/taskloop/rules/rule.rb +34 -0
- data/lib/taskloop/rules/scope_rule.rb +22 -0
- data/lib/taskloop/rules/specific_rule.rb +64 -0
- data/lib/taskloop/rules/time_list_rule.rb +49 -0
- data/lib/taskloop/task/task.rb +244 -0
- data/lib/taskloop/task/task_data_file.rb +46 -0
- data/lib/taskloop/task/task_error.rb +17 -0
- data/lib/taskloop/task/task_property.rb +294 -0
- data/lib/taskloop/utils/proj_tasklist.rb +145 -0
- data/lib/taskloop/version.rb +5 -0
- data/lib/taskloop.rb +9 -0
- data/sig/taskloop.rbs +4 -0
- data/taskloop.gemspec +37 -0
- metadata +103 -0
@@ -0,0 +1,244 @@
|
|
1
|
+
module TaskLoop
|
2
|
+
class Task
|
3
|
+
require 'digest'
|
4
|
+
require 'taskloop/extension/string_extension'
|
5
|
+
require 'taskloop/extension/integer_extension'
|
6
|
+
require_relative './task_error'
|
7
|
+
require_relative './task_property'
|
8
|
+
require_relative './task_data_file'
|
9
|
+
|
10
|
+
include TaskLoop::TaskProperty
|
11
|
+
include TaskLoop::TaskDataFile
|
12
|
+
|
13
|
+
@@tasklist = []
|
14
|
+
def self.tasklist
|
15
|
+
@@tasklist
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.tasklist=(value)
|
19
|
+
@@tasklist = value
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize()
|
23
|
+
yield self
|
24
|
+
check = true
|
25
|
+
unless @name
|
26
|
+
puts "Error: task name is required.".ansi.red
|
27
|
+
puts ""
|
28
|
+
check = false
|
29
|
+
end
|
30
|
+
unless @path
|
31
|
+
puts "Error: task path is required.".ansi.red
|
32
|
+
puts ""
|
33
|
+
check = false
|
34
|
+
end
|
35
|
+
unless check
|
36
|
+
raise TaskArgumentError, "Lack of <required> arguments."
|
37
|
+
end
|
38
|
+
@@tasklist.push(self)
|
39
|
+
end
|
40
|
+
|
41
|
+
#################################
|
42
|
+
# Check and Lint
|
43
|
+
#################################
|
44
|
+
def deploy_lint?
|
45
|
+
result = true
|
46
|
+
# check task name uniqueness
|
47
|
+
@@tasklist.each do |task|
|
48
|
+
if task != self && task.name == @name
|
49
|
+
puts "Error: #{task.desc} => there are multiple tasks with the same name in the Taskfile. Please check the task name again.".ansi.red
|
50
|
+
result = false
|
51
|
+
end
|
52
|
+
# only check with the task before self
|
53
|
+
if task == self
|
54
|
+
break
|
55
|
+
end
|
56
|
+
end
|
57
|
+
# check if task path exists
|
58
|
+
unless @path && File.exists?(@path)
|
59
|
+
puts "Error: #{desc} => the file in <#{@path}> is not exist. Please check the task path again.".ansi.red
|
60
|
+
result = false
|
61
|
+
end
|
62
|
+
# check task rules conflict
|
63
|
+
unless check_rule_conflict?
|
64
|
+
puts "Error: #{desc} rule conflicts have been detected above.".ansi.red
|
65
|
+
result = false
|
66
|
+
end
|
67
|
+
unless result
|
68
|
+
puts "=============================".ansi.red
|
69
|
+
end
|
70
|
+
return result
|
71
|
+
end
|
72
|
+
|
73
|
+
def check_rule_conflict?
|
74
|
+
result = true
|
75
|
+
# check year/month/day with date, they cannot be set at the same time
|
76
|
+
if hasYMD? && hasDate?
|
77
|
+
puts "Error: #{desc} => <year/month/day> and <date> cannot be set at the same time.".ansi.red
|
78
|
+
result = false
|
79
|
+
end
|
80
|
+
|
81
|
+
# check hour/minute with time, they cannot be set at the same time
|
82
|
+
if hasHM? && hasTime?
|
83
|
+
puts "Error: #{desc} => <hour/minute> and <time> cannot be set at the same time.".ansi.red
|
84
|
+
result = false
|
85
|
+
end
|
86
|
+
|
87
|
+
# check rule type
|
88
|
+
|
89
|
+
if hasYMD? && hasHM?
|
90
|
+
# check minute/hour/day/month/year. Get the last IntervalRule, than check if there is SpecificRule or ScopeRule before
|
91
|
+
rules = [minute, hour, day, month, year]
|
92
|
+
rIdx = rules.rindex { |rule| rule.is_a?(IntervalRule) }
|
93
|
+
if rIdx != nil
|
94
|
+
rules.each_with_index do |rule, index|
|
95
|
+
if index < rIdx && (rule.is_a?(ScopeRule) || rule.is_a?(SpecificRule))
|
96
|
+
puts "Error: #{desc} => a ScopeRule or a SpecificRule is assigned to a smaller unit while a IntervalRule is assigned to a larger unit.".ansi.red
|
97
|
+
result = false
|
98
|
+
break
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
if hasYMD? && hasTime?
|
108
|
+
# check year/month/day with time, YMD can not have IntervalRule
|
109
|
+
rules = [day, month, year]
|
110
|
+
hasInterval = rules.any? { |rule| rule.is_a?(IntervalRule) }
|
111
|
+
if hasInterval
|
112
|
+
puts "Error: #{desc} => a IntervalRule is assigned to <year/month/day> while <time> is assigned. It is a conflict!".ansi.red
|
113
|
+
result = false
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
if hasDate? && hasHM?
|
118
|
+
# it's ok
|
119
|
+
end
|
120
|
+
|
121
|
+
if hasDate? && hasTime?
|
122
|
+
# it's ok
|
123
|
+
end
|
124
|
+
|
125
|
+
return result
|
126
|
+
end
|
127
|
+
|
128
|
+
def check_all_rules?
|
129
|
+
last_exec_time = last_time
|
130
|
+
|
131
|
+
result = true
|
132
|
+
result &&= check_interval_rule?(last_exec_time)
|
133
|
+
result &&= check_scope_rule?(last_exec_time)
|
134
|
+
result &&= check_specific_fule?(last_exec_time)
|
135
|
+
result &&= check_loop_rule?(last_exec_time)
|
136
|
+
return result
|
137
|
+
end
|
138
|
+
|
139
|
+
private def check_interval_rule?(last_exec_time)
|
140
|
+
result = true
|
141
|
+
min = 0
|
142
|
+
if year.is_a?(IntervalRule)
|
143
|
+
min += year.interval * YEAR_MIN
|
144
|
+
end
|
145
|
+
if month.is_a?(IntervalRule)
|
146
|
+
min += month.interval * MONTH_MIN
|
147
|
+
end
|
148
|
+
if day.is_a?(IntervalRule)
|
149
|
+
min += day.interval * DAY_MIN
|
150
|
+
end
|
151
|
+
if hour.is_a?(IntervalRule)
|
152
|
+
min += hour.interval * HOUR_MIN
|
153
|
+
end
|
154
|
+
if minute.is_a?(IntervalRule)
|
155
|
+
min += minute.interval
|
156
|
+
end
|
157
|
+
correction = 20
|
158
|
+
result &&= (Time.now.to_i - last_exec_time.to_i + correction) / 60.0 >= min
|
159
|
+
return result
|
160
|
+
end
|
161
|
+
|
162
|
+
private def check_scope_rule?(last_exec_time)
|
163
|
+
result = true
|
164
|
+
if year.is_a?(ScopeRule)
|
165
|
+
result &&= year.is_conform_rule?(last_exec_time)
|
166
|
+
end
|
167
|
+
if month.is_a?(ScopeRule)
|
168
|
+
result &&= month.is_conform_rule?(last_exec_time)
|
169
|
+
end
|
170
|
+
if day.is_a?(ScopeRule)
|
171
|
+
result &&= day.is_conform_rule?(last_exec_time)
|
172
|
+
end
|
173
|
+
if hour.is_a?(ScopeRule)
|
174
|
+
result &&= hour.is_conform_rule?(last_exec_time)
|
175
|
+
end
|
176
|
+
if minute.is_a?(ScopeRule)
|
177
|
+
result &&= minute.is_conform_rule?(last_exec_time)
|
178
|
+
end
|
179
|
+
return result
|
180
|
+
end
|
181
|
+
|
182
|
+
private def check_specific_fule?(last_exec_time)
|
183
|
+
result = true
|
184
|
+
if year.is_a?(SpecificRule)
|
185
|
+
result &&= year.is_conform_rule?(last_exec_time)
|
186
|
+
end
|
187
|
+
if month.is_a?(SpecificRule)
|
188
|
+
result &&= month.is_conform_rule?(last_exec_time)
|
189
|
+
end
|
190
|
+
if day.is_a?(SpecificRule)
|
191
|
+
result &&= day.is_conform_rule?(last_exec_time)
|
192
|
+
end
|
193
|
+
if hour.is_a?(SpecificRule)
|
194
|
+
result &&= hour.is_conform_rule?(last_exec_time)
|
195
|
+
end
|
196
|
+
if minute.is_a?(SpecificRule)
|
197
|
+
result &&= minute.is_conform_rule?(last_exec_time)
|
198
|
+
end
|
199
|
+
if time.is_a?(TimeListRule)
|
200
|
+
result &&= time.is_conform_rule?(last_exec_time)
|
201
|
+
end
|
202
|
+
if date.is_a?(DateListRule)
|
203
|
+
result &&= time.is_conform_rule?(last_exec_time)
|
204
|
+
end
|
205
|
+
return result
|
206
|
+
end
|
207
|
+
|
208
|
+
private def check_loop_rule?(last_exec_time)
|
209
|
+
count = loop_count
|
210
|
+
|
211
|
+
result = true
|
212
|
+
if loop.is_a?(LoopRule)
|
213
|
+
result = count < loop.count
|
214
|
+
end
|
215
|
+
return result
|
216
|
+
end
|
217
|
+
|
218
|
+
|
219
|
+
#################################
|
220
|
+
# Sha1 and description
|
221
|
+
#################################
|
222
|
+
def sha1
|
223
|
+
sha1_digest = Digest::SHA1.new
|
224
|
+
sha1_digest.update(@name)
|
225
|
+
return sha1_digest.hexdigest
|
226
|
+
end
|
227
|
+
|
228
|
+
def desc
|
229
|
+
"<Task.name: #{@name}, sha1: #{sha1}>"
|
230
|
+
end
|
231
|
+
|
232
|
+
#################################
|
233
|
+
# Time Seconds
|
234
|
+
#################################
|
235
|
+
|
236
|
+
YEAR_MIN = 365 * 24 * 60
|
237
|
+
|
238
|
+
MONTH_MIN = 30 * 24 * 60
|
239
|
+
|
240
|
+
DAY_MIN = 24 * 60
|
241
|
+
|
242
|
+
HOUR_MIN = 60
|
243
|
+
end
|
244
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module TaskLoop
|
2
|
+
module TaskDataFile
|
3
|
+
# ~/.taskloop/cache/<project-sha>.
|
4
|
+
attr_accessor :data_proj_dir
|
5
|
+
|
6
|
+
def logfile_path
|
7
|
+
return File.join(@data_proj_dir, logfile_name)
|
8
|
+
end
|
9
|
+
|
10
|
+
def timefile_path
|
11
|
+
return File.join(@data_proj_dir, timefile_name)
|
12
|
+
end
|
13
|
+
|
14
|
+
def loopfile_path
|
15
|
+
return File.join(@data_proj_dir, loopfile_name)
|
16
|
+
end
|
17
|
+
|
18
|
+
def logfile_name
|
19
|
+
return sha1 + "_log"
|
20
|
+
end
|
21
|
+
def timefile_name
|
22
|
+
return sha1 + "_time"
|
23
|
+
end
|
24
|
+
def loopfile_name
|
25
|
+
return sha1 + "_loop"
|
26
|
+
end
|
27
|
+
|
28
|
+
def write_to_logfile(content)
|
29
|
+
file = File.open(logfile_path, "w")
|
30
|
+
file.puts content
|
31
|
+
file.close
|
32
|
+
end
|
33
|
+
|
34
|
+
def write_to_timefile(content)
|
35
|
+
file = File.open(timefile_path, "w")
|
36
|
+
file.puts content
|
37
|
+
file.close
|
38
|
+
end
|
39
|
+
|
40
|
+
def write_to_loopfile(content)
|
41
|
+
file = File.open(loopfile_path, "w")
|
42
|
+
file.puts content
|
43
|
+
file.close
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,294 @@
|
|
1
|
+
module TaskLoop
|
2
|
+
module TaskProperty
|
3
|
+
|
4
|
+
MONTH = {
|
5
|
+
:Jan => 1,
|
6
|
+
:Feb => 2,
|
7
|
+
:Mar => 3,
|
8
|
+
:Apr => 4,
|
9
|
+
:Jun => 6,
|
10
|
+
:Jul => 7,
|
11
|
+
:Aug => 8,
|
12
|
+
:Sep => 9,
|
13
|
+
:Oct => 10,
|
14
|
+
:Nov => 11,
|
15
|
+
:Dec => 12,
|
16
|
+
:mon1 => 1,
|
17
|
+
:mon2 => 2,
|
18
|
+
:mon3 => 3,
|
19
|
+
:mon4 => 4,
|
20
|
+
:mon5 => 5,
|
21
|
+
:mon6 => 6,
|
22
|
+
:mon7 => 7,
|
23
|
+
:mon8 => 8,
|
24
|
+
:mon9 => 9,
|
25
|
+
:mon10 => 10,
|
26
|
+
:mon11 => 11,
|
27
|
+
:mon12 => 12,
|
28
|
+
}
|
29
|
+
|
30
|
+
WEEK_BASE = 10000
|
31
|
+
WEEK = {
|
32
|
+
:Sun => 10000,
|
33
|
+
:Mon => 10001,
|
34
|
+
:Tue => 10002,
|
35
|
+
:Wed => 10003,
|
36
|
+
:Thu => 10004,
|
37
|
+
:Fri => 10005,
|
38
|
+
:Sat => 10006,
|
39
|
+
}
|
40
|
+
|
41
|
+
DAY = {
|
42
|
+
:day1 => 1,
|
43
|
+
:day2 => 2,
|
44
|
+
:day3 => 3,
|
45
|
+
:day4 => 4,
|
46
|
+
:day5 => 5,
|
47
|
+
:day6 => 6,
|
48
|
+
:day7 => 7,
|
49
|
+
:day8 => 8,
|
50
|
+
:day9 => 9,
|
51
|
+
:day10 => 10,
|
52
|
+
:day11 => 11,
|
53
|
+
:day12 => 12,
|
54
|
+
:day13 => 13,
|
55
|
+
:day14 => 14,
|
56
|
+
:day15 => 15,
|
57
|
+
:day16 => 16,
|
58
|
+
:day17 => 17,
|
59
|
+
:day18 => 18,
|
60
|
+
:day19 => 19,
|
61
|
+
:day20 => 20,
|
62
|
+
:day21 => 21,
|
63
|
+
:day22 => 22,
|
64
|
+
:day23 => 23,
|
65
|
+
:day24 => 24,
|
66
|
+
:day25 => 25,
|
67
|
+
:day26 => 26,
|
68
|
+
:day27 => 27,
|
69
|
+
:day28 => 28,
|
70
|
+
:day29 => 29,
|
71
|
+
:day30 => 30,
|
72
|
+
:day31 => 31,
|
73
|
+
}
|
74
|
+
|
75
|
+
# the name of task
|
76
|
+
attr_accessor :name
|
77
|
+
# the path of task
|
78
|
+
attr_accessor :path
|
79
|
+
|
80
|
+
#################################
|
81
|
+
# Setters & Getters
|
82
|
+
#################################
|
83
|
+
# specific syntax
|
84
|
+
# - of
|
85
|
+
# - example: in 2024
|
86
|
+
# interval syntax
|
87
|
+
# - interval
|
88
|
+
# - example: interval 1.year
|
89
|
+
# scope syntax
|
90
|
+
# - before
|
91
|
+
# - example: before 2025
|
92
|
+
# - between
|
93
|
+
# - example: between 2025, 2026
|
94
|
+
# - after
|
95
|
+
# - examle: after 2023
|
96
|
+
def year=(rule)
|
97
|
+
unless rule.is_a?(Rule)
|
98
|
+
raise TypeError, "the rule of year must be a class or subclass of Rule"
|
99
|
+
end
|
100
|
+
|
101
|
+
@year = rule
|
102
|
+
@year.unit = :year
|
103
|
+
end
|
104
|
+
|
105
|
+
def year
|
106
|
+
@year ||= DefaultRule.new(:year)
|
107
|
+
end
|
108
|
+
|
109
|
+
# specific syntax
|
110
|
+
# - of
|
111
|
+
# - example: of :Jan, :Feb, :Mar, :Apr, :Jun, :Jul, :Aug, :Sep, :Oct, :Nov, :Dec;
|
112
|
+
# - example: of :month1, :month2, :month3, ....
|
113
|
+
# interval syntax
|
114
|
+
# - every
|
115
|
+
# - example: interval 1.month
|
116
|
+
# scope syntax
|
117
|
+
# - before
|
118
|
+
# - example: before 2025
|
119
|
+
# - between
|
120
|
+
# - example: between 2025, 2026
|
121
|
+
# - after
|
122
|
+
# - examle: after 2023
|
123
|
+
def month=(rule)
|
124
|
+
unless rule.is_a?(Rule)
|
125
|
+
raise TypeError, "the rule of month must be a class or subclass of Rule"
|
126
|
+
end
|
127
|
+
@month = rule
|
128
|
+
@month.unit = :month
|
129
|
+
end
|
130
|
+
|
131
|
+
def month
|
132
|
+
@month||= DefaultRule.new(:month)
|
133
|
+
end
|
134
|
+
|
135
|
+
# specific syntax
|
136
|
+
# - on
|
137
|
+
# - example: on :Mon, :Tue, :Wed, :Thu, :Fri, :Sat, :Sun;
|
138
|
+
# - example: on :day1, :day2, :day3;
|
139
|
+
# interval syntax
|
140
|
+
# - interval
|
141
|
+
# - example: interval 10.day
|
142
|
+
# scope syntax
|
143
|
+
# - before
|
144
|
+
# - example: before :day10
|
145
|
+
# - between
|
146
|
+
# - example: between :day10, :day19
|
147
|
+
# - example: between :Mon, :Fri
|
148
|
+
# - after
|
149
|
+
# - example: after :day10
|
150
|
+
def day=(rule)
|
151
|
+
unless rule.is_a?(Rule)
|
152
|
+
raise TypeError, "the rule of day must be a class or subclass of Rule"
|
153
|
+
end
|
154
|
+
@day = rule
|
155
|
+
@day.unit = :day
|
156
|
+
end
|
157
|
+
|
158
|
+
def day
|
159
|
+
@day ||= DefaultRule.new(:day)
|
160
|
+
end
|
161
|
+
|
162
|
+
# specific syntax
|
163
|
+
# - at
|
164
|
+
# - example: at 10; at 23
|
165
|
+
# interval syntax
|
166
|
+
# - interval
|
167
|
+
# - example: interval 10.hour
|
168
|
+
# scope syntax
|
169
|
+
# - before
|
170
|
+
# - example: before 9
|
171
|
+
# - between
|
172
|
+
# - example: between 10, 12
|
173
|
+
# - after
|
174
|
+
# - example: after 11
|
175
|
+
def hour=(rule)
|
176
|
+
unless rule.is_a?(Rule)
|
177
|
+
raise TypeError, "the rule of hour must be a class or subclass of Rule"
|
178
|
+
end
|
179
|
+
@hour = rule
|
180
|
+
@hour.unit = :hour
|
181
|
+
end
|
182
|
+
|
183
|
+
def hour
|
184
|
+
@hour ||= DefaultRule.new(:hour)
|
185
|
+
end
|
186
|
+
|
187
|
+
# specific syntax
|
188
|
+
# - at
|
189
|
+
# - example: at 59; at 45
|
190
|
+
# interval syntax
|
191
|
+
# - interval
|
192
|
+
# - example: interval 5.minute
|
193
|
+
def minute=(rule)
|
194
|
+
unless rule.is_a?(Rule)
|
195
|
+
raise TypeError, "the rule of minute must be a class or subclass of Rule"
|
196
|
+
end
|
197
|
+
|
198
|
+
if rule.is_a?(ScopeRule)
|
199
|
+
raise TypeError, "the rule of minute cannot be a class or subclass of ScopeRule"
|
200
|
+
end
|
201
|
+
@minute = rule
|
202
|
+
@minute.unit = :minute
|
203
|
+
end
|
204
|
+
|
205
|
+
def minute
|
206
|
+
@minute ||= DefaultRule.new(:minute)
|
207
|
+
end
|
208
|
+
|
209
|
+
# loop syntax
|
210
|
+
# - loop
|
211
|
+
# - example: loop 5.times
|
212
|
+
def loop=(rule)
|
213
|
+
unless rule.is_a?(Rule)
|
214
|
+
raise TypeError, "the rule of loop must be a class or subclass of Rule"
|
215
|
+
end
|
216
|
+
|
217
|
+
@loop = rule
|
218
|
+
@loop.unit = :loop
|
219
|
+
end
|
220
|
+
def loop
|
221
|
+
@loop ||= DefaultRule.new(:loop)
|
222
|
+
end
|
223
|
+
|
224
|
+
# time list syntax
|
225
|
+
# - time
|
226
|
+
# - example: time "10:10:30", "9:10:20", "20:10:20"
|
227
|
+
def time=(rule)
|
228
|
+
unless rule.is_a?(TimeListRule)
|
229
|
+
raise TypeError, "the rule of time must be a TimeList Rule"
|
230
|
+
end
|
231
|
+
|
232
|
+
@time = rule
|
233
|
+
@time.unit = :time
|
234
|
+
end
|
235
|
+
def time
|
236
|
+
@time ||= DefaultRule.new(:time)
|
237
|
+
end
|
238
|
+
|
239
|
+
# date list syntax
|
240
|
+
# - date
|
241
|
+
# - example: date "2023-10-10", "2013-10-11", "2023-11-10"
|
242
|
+
def date=(rule)
|
243
|
+
unless rule.is_a?(DateListRule)
|
244
|
+
raise TypeError, "the rule of time must be a DateList Rule"
|
245
|
+
end
|
246
|
+
|
247
|
+
@date = rule
|
248
|
+
@date.unit = :date
|
249
|
+
end
|
250
|
+
def date
|
251
|
+
@date ||= DefaultRule.new(:date)
|
252
|
+
end
|
253
|
+
|
254
|
+
#################################
|
255
|
+
# Help Methods
|
256
|
+
#################################
|
257
|
+
def hasDate?
|
258
|
+
!date.is_a?(DefaultRule)
|
259
|
+
end
|
260
|
+
|
261
|
+
def hasTime?
|
262
|
+
!time.is_a?(DefaultRule)
|
263
|
+
end
|
264
|
+
|
265
|
+
def hasYMD?
|
266
|
+
[year, month, day].any? { |rule| !rule.is_a?(DefaultRule) }
|
267
|
+
end
|
268
|
+
|
269
|
+
def hasHM?
|
270
|
+
[hour, minute].any? { |rule| !rule.is_a?(DefaultRule) }
|
271
|
+
end
|
272
|
+
|
273
|
+
def has_interval_rule?
|
274
|
+
rules = [year, month, day, hour, minute]
|
275
|
+
return rules.any?{ |rule| rule.is_a?(IntervalRule) }
|
276
|
+
end
|
277
|
+
|
278
|
+
def loop_count
|
279
|
+
count = 0
|
280
|
+
File.open(loopfile_path, 'r') do |file|
|
281
|
+
count = file.gets.to_i
|
282
|
+
end
|
283
|
+
return count
|
284
|
+
end
|
285
|
+
|
286
|
+
def last_time
|
287
|
+
timestamp = 0
|
288
|
+
File.open(timefile_path, 'r') do |file|
|
289
|
+
timestamp = file.gets.to_i
|
290
|
+
end
|
291
|
+
return Time.at(timestamp)
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|