fugit 1.3.4 → 1.3.5

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: a10a8afb99cf16856e53766a86b1f0d13ddb0d2784c756cb525ceea8fbae7bd1
4
- data.tar.gz: dcd1d01a8f5f8fc819854f430e12fc6bf69850e64060cffbe93c595be78785a2
3
+ metadata.gz: d2a28ef486584f37659fbcf4e6e4fecfc76aa2a4a6e1fc61d25dd3c44cd3a5c3
4
+ data.tar.gz: db726ca071f0f98d0f59c3054fca04a537ec2a17fd302013b354d90e1d7dc3c8
5
5
  SHA512:
6
- metadata.gz: 4b29f59bffe4f786b90c0f0a42c26c682e78b523183863f7cfc8c486ecca9056bb96f5eae92b2ee9446ece5c84a10aeddd9a52077eece5357af8985853da99ee
7
- data.tar.gz: a32ac9539496ff7f4bc1949f97eeefcf836a8f1607569080acafd2d338befd7cb97e10179ffee06d2da3ebead95830147f5f418a883a4bd2a77f549455761788
6
+ metadata.gz: d1105627f83fd730a7826047679edfd38ad7deb19960715e93769d5c04e80e0079b02b9513f9e5d01614e2e70b75a016a2e16b7a72f568e2a5d3072c42e7e1dc
7
+ data.tar.gz: eb4b14f1f564bd89ae919c16d6c06ef180b725c81b8d78225661b0a0fb34dee067063de9f2b883e6361e51c0db323224b6ee0a80ab3ca80dd9091a0e872ceae4
@@ -2,6 +2,12 @@
2
2
  # CHANGELOG.md
3
3
 
4
4
 
5
+ ## fugit 1.3.5 released 2020-05-07
6
+
7
+ * Implement cron @noon, gh-37
8
+ * Normalize "every x", gh-37
9
+
10
+
5
11
  ## fugit 1.3.4 released 2020-04-06
6
12
 
7
13
  * Prevent #rough_frequency returning 0, gh-36
data/CREDITS.md CHANGED
@@ -4,7 +4,7 @@
4
4
  * Dominik Sander https://github.com/dsander #rough_frequency 0, gh-36
5
5
  * Milovan Zogovic https://github.com/assembler Cron#match? vs TZ, gh-31
6
6
  * Jessica Stokes https://github.com/ticky 0-24 issue with cron, gh-30
7
- * Shai Coleman https://github.com/shaicoleman parse_nat enhancements, gh-24, gh-25, and gh-28
7
+ * Shai Coleman https://github.com/shaicoleman parse_nat enhancements, gh-24, gh-25, gh-28, and gh-37
8
8
  * Jan Stevens https://github.com/JanStevens Fugit.parse('every 15 minutes') gh-22
9
9
  * Fabio Pitino https://github.com/hspazio nil on February 30 gh-21
10
10
  * Cristian Oneț https://github.com/conet #previous_time vs 1/-1 endless loop gh-15
@@ -1,7 +1,7 @@
1
1
 
2
2
  module Fugit
3
3
 
4
- VERSION = '1.3.4'
4
+ VERSION = '1.3.5'
5
5
  end
6
6
 
7
7
  require 'time'
@@ -11,6 +11,7 @@ module Fugit
11
11
  '@weekly' => '0 0 * * 0',
12
12
  '@daily' => '0 0 * * *',
13
13
  '@midnight' => '0 0 * * *',
14
+ '@noon' => '0 12 * * *',
14
15
  '@hourly' => '0 * * * *' }
15
16
  MAXDAYS = [
16
17
  nil, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]
@@ -15,6 +15,7 @@ module Fugit
15
15
  return nil unless s.is_a?(String)
16
16
 
17
17
  #p s; Raabro.pp(Parser.parse(s, debug: 3), colours: true)
18
+ #(p s; Raabro.pp(Parser.parse(s, debug: 1), colours: true)) rescue nil
18
19
  a = Parser.parse(s)
19
20
 
20
21
  return nil unless a
@@ -37,20 +38,16 @@ module Fugit
37
38
 
38
39
  def parse_crons(s, a, opts)
39
40
 
40
- dhs, aa = a
41
- .partition { |e| e[0] == :digital_hour }
42
- ms = dhs
43
- .inject({}) { |h, dh| (h[dh[1][0]] ||= []) << dh[1][1]; h }
41
+ hms, aa = a
42
+ .partition { |e| e[0] == :point && e[1][0] == :hour }
43
+ ms = hms
44
+ .inject({}) { |h, e| (h[e[1][1]] ||= []) << e[1][2]; h }
44
45
  .values
45
46
  .uniq
46
-
47
47
  crons =
48
- #if ms.size <= 1 || hs.size <= 1
49
- if ms.size <= 1
50
- [ parse_cron(a, opts) ]
51
- else
52
- dhs.collect { |dh| parse_cron([ dh ] + aa, opts) }
53
- end
48
+ ms.size > 1 ?
49
+ hms.collect { |e| parse_cron([ e ] + aa, opts) } :
50
+ [ parse_cron(a, opts) ]
54
51
 
55
52
  fail ArgumentError.new(
56
53
  "multiple crons in #{s.inspect} " +
@@ -66,34 +63,36 @@ module Fugit
66
63
 
67
64
  def parse_cron(a, opts)
68
65
 
69
- h = { min: nil, hou: [], dom: nil, mon: nil, dow: nil }
66
+ h = { min: nil, hou: nil, dom: nil, mon: nil, dow: nil }
70
67
  hkeys = h.keys
71
68
 
69
+ i0s, es = a.partition { |e| e[0] == :interval0 }
70
+ a = es + i0s
71
+ # interval0s are fallback
72
+
72
73
  a.each do |key, val|
73
- if key == :biz_day
74
+ case key
75
+ when :biz_day
74
76
  (h[:dow] ||= []) << '1-5'
75
- elsif key == :simple_hour || key == :numeral_hour
76
- h[:hou] << val
77
- elsif key == :digital_hour
78
- (h[:hou] ||= []) << val[0].to_i
79
- (h[:min] ||= []) << val[1].to_i
80
- elsif key == :name_day
77
+ when :name_day
81
78
  (h[:dow] ||= []) << val
82
- elsif key == :day_range
79
+ when :day_range
83
80
  (h[:dow] ||= []) << val.collect { |v| v.to_s[0, 3] }.join('-')
84
- elsif key == :tz
81
+ when :tz
85
82
  h[:tz] = val
86
- elsif key == :duration
87
- process_duration(h, *val[0].to_h.first)
83
+ when :point
84
+ process_point(h, *val)
85
+ when :interval1
86
+ process_interval1(h, *val[0].to_h.first)
87
+ when :interval0
88
+ process_interval0(h, val)
88
89
  end
89
90
  end
90
91
 
91
- h[:min] ||= [ 0 ]
92
- h[:min].uniq!
93
-
94
- h[:hou].uniq!;
95
- h[:hou].sort!
92
+ return nil if h[:fail]
96
93
 
94
+ h[:min] = (h[:min] || [ 0 ]).uniq
95
+ h[:hou] = (h[:hou] || []).uniq.sort
97
96
  h[:dow].sort! if h[:dow]
98
97
 
99
98
  a = hkeys
@@ -108,40 +107,92 @@ module Fugit
108
107
  Fugit::Cron.parse(s)
109
108
  end
110
109
 
111
- def process_duration(h, interval, value)
112
-
113
- send("process_duration_#{interval}", h, value)
114
- end
115
-
116
- def process_duration_mon(h, value)
110
+ def process_point(h, key, *value)
117
111
 
118
- h[:hou] = [ 0 ]
119
- h[:dom] = [ 1 ]
120
- h[:mon] = [ value == 1 ? '*' : "*/#{value}" ]
121
- end
122
-
123
- def process_duration_day(h, value)
124
-
125
- h[:hou] = [ 0 ]
126
- h[:dom] = [ value == 1 ? '*' : "*/#{value}" ]
112
+ case key
113
+ when :hour
114
+ v0, v1 = value
115
+ v0 = v0.to_i if v0.is_a?(String) && v0.match(/^\d+$/)
116
+ (h[:hou] ||= []) << v0
117
+ (h[:min] ||= []) << v1.to_i if v1
118
+ when :sec, :min
119
+ (h[key] ||= []) << value[0]
120
+ end
127
121
  end
128
122
 
129
- def process_duration_hou(h, value)
130
-
131
- h[:hou] = [ value == 1 ? '*' : "*/#{value}" ]
123
+ def process_interval0(h, value)
124
+
125
+ case value
126
+ when 'sec', 'second'
127
+ h[:min] = [ '*' ]
128
+ h[:sec] = [ '*' ]
129
+ when 'min', 'minute'
130
+ h[:min] = [ '*' ]
131
+ when 'hour'
132
+ unless h[:min] || h[:hou]
133
+ h[:min] = [ 0 ]
134
+ h[:hou] = [ '*' ]
135
+ end
136
+ when 'day'
137
+ unless h[:min] || h[:hou]
138
+ h[:min] = [ 0 ]
139
+ h[:hou] = [ 0 ]
140
+ end
141
+ when 'week'
142
+ unless h[:min] || h[:hou] || h[:dow]
143
+ h[:min] = [ 0 ]
144
+ h[:hou] = [ 0 ]
145
+ h[:dow] = [ 0 ]
146
+ end
147
+ when 'month'
148
+ unless h[:min] || h[:hou]
149
+ h[:min] = [ 0 ]
150
+ h[:hou] = [ 0 ]
151
+ end
152
+ (h[:dom] ||= []) << 1
153
+ when 'year'
154
+ unless h[:min] || h[:hou]
155
+ h[:min] = [ 0 ]
156
+ h[:hou] = [ 0 ]
157
+ end
158
+ (h[:dom] ||= []) << 1
159
+ (h[:mon] ||= []) << 1
160
+ end
132
161
  end
133
162
 
134
- def process_duration_min(h, value)
135
-
136
- h[:hou] = [ '*' ]
137
- h[:min] = [ value == 1 ? '*' : "*/#{value}" ]
138
- end
163
+ def process_interval1(h, interval, value)
139
164
 
140
- def process_duration_sec(h, value)
165
+ if value != 1 && [ :yea, :wee ].include?(interval)
166
+ int = interval == :year ? 'years' : 'weeks'
167
+ h[:fail] = "cannot cron for \"every #{value} #{int}\""
168
+ return
169
+ end
141
170
 
142
- h[:hou] = [ '*' ]
143
- h[:min] = [ '*' ]
144
- h[:sec] = [ value == 1 ? '*' : "*/#{value}" ]
171
+ case interval
172
+ when :yea
173
+ h[:hou] = [ 0 ]
174
+ h[:mon] = [ 1 ]
175
+ h[:dom] = [ 1 ]
176
+ when :mon
177
+ h[:hou] = [ 0 ]
178
+ h[:dom] = [ 1 ]
179
+ h[:mon] = [ value == 1 ? '*' : "*/#{value}" ]
180
+ when :wee
181
+ h[:hou] = [ 0 ]
182
+ h[:dow] = [ 0 ] # Sunday
183
+ when :day
184
+ h[:hou] = [ 0 ]
185
+ h[:dom] = [ value == 1 ? '*' : "*/#{value}" ]
186
+ when :hou
187
+ h[:hou] = [ value == 1 ? '*' : "*/#{value}" ]
188
+ when :min
189
+ h[:hou] = [ '*' ]
190
+ h[:min] = [ value == 1 ? '*' : "*/#{value}" ]
191
+ when :sec
192
+ h[:hou] = [ '*' ]
193
+ h[:min] = [ '*' ]
194
+ h[:sec] = [ value == 1 ? '*' : "*/#{value}" ]
195
+ end
145
196
  end
146
197
  end
147
198
 
@@ -160,6 +211,11 @@ module Fugit
160
211
 
161
212
  # piece parsers bottom to top
162
213
 
214
+ def interval0(i)
215
+ rex(:interval0, i,
216
+ /(year|month|week|day|hour|min(ute)?|sec(ond)?)(?![a-z])/i)
217
+ end
218
+
163
219
  def am_pm(i)
164
220
  rex(:am_pm, i, / *(am|pm)/i)
165
221
  end
@@ -186,7 +242,6 @@ module Fugit
186
242
  rex(:name_hour, i, /(#{NHOURS.keys.join('|')})/i)
187
243
  end
188
244
 
189
- def plain_day(i); rex(:plain_day, i, /day/i); end
190
245
  def biz_day(i); rex(:biz_day, i, /(biz|business|week) *day/i); end
191
246
  def name_day(i); rex(:name_day, i, /#{WEEKDAYS.reverse.join('|')}/i); end
192
247
 
@@ -204,26 +259,36 @@ module Fugit
204
259
  end
205
260
  def _tz(i); alt(:tz, i, :_tz_delta, :_tz_name); end
206
261
 
207
- def duration(i)
208
- rex(
209
- :duration, i,
262
+ def interval1(i)
263
+ rex(:interval1, i,
210
264
  /
211
265
  \d+
212
266
  \s?
213
- (mon(ths?)?|d(ays?)?|h(ours?)?|m(in(ute)?s?)?|s(ec(ond)?s?)?)
267
+ (y(ears?)?|months?|w(eeks?)?|d(ays?)?|
268
+ h(ours?)?|m(in(ute)?s?)?|s(ec(ond)?s?)?)
214
269
  /ix)
215
270
  end
216
271
 
272
+ def min_or_sec(i)
273
+ rex(:min_or_sec, i, /(min(ute)?|sec(ond)?)\s+\d+/i)
274
+ end
275
+
276
+ def point(i)
277
+ alt(:point, i,
278
+ :min_or_sec,
279
+ :name_hour, :numeral_hour, :digital_hour, :simple_hour)
280
+ end
281
+
217
282
  def flag(i); rex(:flag, i, /(every|from|at|after|on|in)/i); end
218
283
 
219
284
  def datum(i)
220
285
  alt(nil, i,
221
- :day_range,
222
- :plain_day, :biz_day, :name_day,
223
- :_tz,
224
286
  :flag,
225
- :duration,
226
- :name_hour, :numeral_hour, :digital_hour, :simple_hour)
287
+ :interval1,
288
+ :point,
289
+ :interval0,
290
+ :day_range, :biz_day, :name_day,
291
+ :_tz)
227
292
  end
228
293
 
229
294
  def sugar(i); rex(nil, i, /(and|or|[, \t]+)/i); end
@@ -233,38 +298,62 @@ module Fugit
233
298
 
234
299
  # rewrite parsed tree
235
300
 
301
+ def _rewrite(t)
302
+ [ t.name, t.string.downcase ]
303
+ end
304
+ alias rewrite_flag _rewrite
305
+ alias rewrite_interval0 _rewrite
306
+ alias rewrite_biz_day _rewrite
307
+
308
+ def rewrite_name_day(t)
309
+ [ :name_day, WEEKDAYS.index(t.string.downcase[0, 3]) ]
310
+ end
311
+
312
+ def rewrite_day_range(t)
313
+ [ :day_range, t.subgather(nil).collect { |st| st.string.downcase } ]
314
+ end
315
+
316
+ def rewrite_name_hour(t)
317
+ [ :hour, *NHOURS[t.string.strip.downcase] ]
318
+ end
319
+ def rewrite_numeral_hour(t)
320
+ vs = t.subgather(nil).collect { |st| st.string.downcase.strip }
321
+ v = NUMS.index(vs[0])
322
+ v += 12 if vs[1] == 'pm'
323
+ [ :hour, v, 0 ]
324
+ end
325
+ def rewrite_simple_hour(t)
326
+ vs = t.subgather(nil).collect { |st| st.string.downcase.strip }
327
+ v = vs[0].to_i
328
+ v += 12 if vs[1] == 'pm'
329
+ [ :hour, v, 0 ]
330
+ end
331
+ def rewrite_digital_hour(t)
332
+ v = t.string.gsub(/:/, '')
333
+ [ :hour, v[0, 2], v[2, 2] ]
334
+ end
335
+
336
+ def rewrite_min_or_sec(t)
337
+ unit, num = t.string.split(/\s+/)
338
+ [ unit[0, 3].to_sym, num.to_i ]
339
+ end
340
+
341
+ def rewrite_point(t)
342
+ [ :point, rewrite(t.sublookup) ]
343
+ end
344
+
345
+ def rewrite_tz(t)
346
+ [ :tz, [ t.string.strip, EtOrbi.get_tzone(t.string.strip) ] ]
347
+ end
348
+
349
+ def rewrite_interval1(t)
350
+ [ t.name, [ Fugit::Duration.parse(t.string.strip) ] ]
351
+ end
352
+
236
353
  def rewrite_nat(t)
237
354
 
238
355
  #Raabro.pp(t, colours: true)
239
- t
240
- .subgather(nil)
241
- .collect { |tt|
242
-
243
- k = tt.name
244
- v = tt.string.downcase
245
-
246
- case k
247
- when :tz
248
- [ k, [ tt.string.strip, EtOrbi.get_tzone(tt.string.strip) ] ]
249
- when :duration
250
- [ k, [ Fugit::Duration.parse(tt.string.strip) ] ]
251
- when :digital_hour
252
- v = v.gsub(/:/, '')
253
- [ k, [ v[0, 2], v[2, 2] ] ]
254
- when :name_hour
255
- [ :digital_hour, NHOURS[v] ]
256
- when :name_day
257
- [ k, WEEKDAYS.index(v[0, 3]) ]
258
- when :day_range
259
- [ k, tt.subgather(nil).collect { |st| st.string.downcase } ]
260
- when :numeral_hour, :simple_hour
261
- vs = tt.subgather(nil).collect { |ttt| ttt.string.downcase.strip }
262
- v = k == :simple_hour ? vs[0].to_i : NUMS.index(vs[0])
263
- v += 12 if vs[1] == 'pm'
264
- [ k, v ]
265
- else
266
- [ k, v ]
267
- end }
356
+ t.subgather(nil).collect { |tt| rewrite(tt) }
268
357
  end
269
358
  end
270
359
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fugit
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.4
4
+ version: 1.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Mettraux
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-05 00:00:00.000000000 Z
11
+ date: 2020-05-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: raabro