say_when 0.3.0 → 1.0.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.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -4
  3. data/Gemfile +1 -1
  4. data/LICENSE +21 -0
  5. data/README.md +31 -0
  6. data/Rakefile +9 -1
  7. data/lib/generators/say_when/migration/migration_generator.rb +8 -5
  8. data/lib/generators/say_when/migration/templates/migration.rb +11 -8
  9. data/lib/say_when/base_job.rb +2 -0
  10. data/lib/say_when/cron_expression.rb +129 -191
  11. data/lib/say_when/processor/active_messaging.rb +7 -8
  12. data/lib/say_when/processor/base.rb +5 -3
  13. data/lib/say_when/processor/shoryuken.rb +14 -0
  14. data/lib/say_when/processor/simple.rb +2 -0
  15. data/lib/say_when/railtie.rb +9 -0
  16. data/lib/say_when/scheduler.rb +30 -56
  17. data/lib/say_when/storage/active_record/acts.rb +16 -16
  18. data/lib/say_when/storage/active_record/job.rb +17 -24
  19. data/lib/say_when/storage/active_record/job_execution.rb +5 -8
  20. data/lib/say_when/storage/memory/base.rb +3 -1
  21. data/lib/say_when/storage/memory/job.rb +14 -42
  22. data/lib/say_when/tasks.rb +4 -4
  23. data/lib/say_when/triggers/base.rb +4 -3
  24. data/lib/say_when/triggers/cron_strategy.rb +4 -3
  25. data/lib/say_when/triggers/instance_strategy.rb +4 -3
  26. data/lib/say_when/triggers/once_strategy.rb +3 -2
  27. data/lib/say_when/version.rb +3 -1
  28. data/lib/say_when.rb +8 -7
  29. data/lib/tasks/say_when.rake +3 -1
  30. data/say_when.gemspec +25 -19
  31. data/test/active_record_helper.rb +13 -0
  32. data/{spec → test}/db/schema.rb +4 -2
  33. data/{spec/spec_helper.rb → test/minitest_helper.rb} +9 -12
  34. data/test/say_when/cron_expression_spec.rb +74 -0
  35. data/{spec/say_when/processor/active_messaging_spec.rb → test/say_when/processor/active_messaging_test.rb} +16 -13
  36. data/test/say_when/scheduler_test.rb +75 -0
  37. data/test/say_when/storage/active_record/job_test.rb +90 -0
  38. data/test/say_when/storage/memory/job_test.rb +32 -0
  39. data/test/say_when/storage/memory/trigger_test.rb +54 -0
  40. data/test/say_when/triggers/once_strategy_test.rb +23 -0
  41. data/{spec → test}/support/models.rb +5 -3
  42. metadata +166 -153
  43. data/.travis.yml +0 -4
  44. data/generators/say_when_migration/say_when_migration_generator.rb +0 -11
  45. data/generators/say_when_migration/templates/migration.rb +0 -48
  46. data/spec/active_record_spec_helper.rb +0 -11
  47. data/spec/say_when/cron_expression_spec.rb +0 -72
  48. data/spec/say_when/scheduler_spec.rb +0 -76
  49. data/spec/say_when/storage/active_record/job_spec.rb +0 -98
  50. data/spec/say_when/storage/memory/job_spec.rb +0 -45
  51. data/spec/say_when/storage/memory/trigger_spec.rb +0 -54
  52. data/spec/say_when/triggers/once_strategy_spec.rb +0 -22
  53. data/spec/spec.opts +0 -4
@@ -1,8 +1,10 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'date'
2
4
 
3
5
  module SayWhen
4
6
 
5
- # Based on the extended cron capabilties
7
+ # Based on the extended cron capabilties
6
8
  # http://wiki.opensymphony.com/display/QRTZ1/CronTriggers+Tutorial
7
9
  class CronExpression
8
10
  attr_reader :expression
@@ -22,11 +24,11 @@ module SayWhen
22
24
  [:seconds, :minutes, :hours, :days_of_month, :months, :days_of_week, :years].each do |f|
23
25
  opts[f] ||= '*'
24
26
  end
25
-
27
+
26
28
  "#{opts[:seconds]} #{opts[:minutes]} #{opts[:hours]} #{opts[:days_of_month]} #{opts[:months]} #{opts[:days_of_week]} #{opts[:years]}"
27
29
  end
28
-
29
- @time_zone = if opts.has_key?(:time_zone) && !opts[:time_zone].blank?
30
+
31
+ self.time_zone = if opts.has_key?(:time_zone) && !opts[:time_zone].blank?
30
32
  opts[:time_zone]
31
33
  else
32
34
  Time.zone.nil? ? "UTC" : Time.zone.name
@@ -34,7 +36,7 @@ module SayWhen
34
36
 
35
37
  else
36
38
  @expression = expression
37
- @time_zone = if time_zone.blank?
39
+ self.time_zone = if time_zone.blank?
38
40
  Time.zone.nil? ? "UTC" : Time.zone.name
39
41
  else
40
42
  time_zone
@@ -44,75 +46,62 @@ module SayWhen
44
46
  parse
45
47
  validate
46
48
  end
47
-
49
+
48
50
  def parse
49
- return if @expression.blank?
50
- vals = @expression.split.collect{|word| word.upcase.gsub(/\s/, '')}
51
- @seconds = SecondsCronValue.new(vals[0])
52
- @minutes = MinutesCronValue.new(vals[1])
53
- @hours = HoursCronValue.new(vals[2])
54
- @days_of_month = DaysOfMonthCronValue.new(vals[3])
55
- @months = MonthsCronValue.new(vals[4])
56
- @days_of_week = DaysOfWeekCronValue.new(vals[5])
57
- @years = YearsCronValue.new(vals[6] || "*")
58
- end
59
-
51
+ return if expression.blank?
52
+ vals = expression.split.map{ |word| word.upcase.gsub(/\s/, '') }
53
+ self.seconds = SecondsCronValue.new(vals[0])
54
+ self.minutes = MinutesCronValue.new(vals[1])
55
+ self.hours = HoursCronValue.new(vals[2])
56
+ self.days_of_month = DaysOfMonthCronValue.new(vals[3])
57
+ self.months = MonthsCronValue.new(vals[4])
58
+ self.days_of_week = DaysOfWeekCronValue.new(vals[5])
59
+ self.years = YearsCronValue.new(vals[6] || "*")
60
+ end
61
+
60
62
  def validate
61
- return if @expression.blank?
62
- raise "days_of_week or days_of_month needs to be ?" if (@days_of_month.is_specified && @days_of_week.is_specified)
63
+ return if expression.blank?
64
+ raise "days_of_week or days_of_month needs to be ?" if (days_of_month.is_specified && days_of_week.is_specified)
63
65
  end
64
-
66
+
65
67
  def to_s
66
68
  "s:#{seconds}m:#{minutes}h:#{hours}dom:#{days_of_month}m:#{months}dow:#{days_of_week}y:#{years}"
67
69
  end
68
-
70
+
69
71
  def will_fire_on?(date)
70
- # puts "will fire on? #{date} : #{self.to_s}"
71
- [@seconds, @minutes, @hours, @days_of_month, @months, @days_of_week, @years].detect{|part| !part.include?(date)}.nil?
72
+ [seconds, minutes, hours, days_of_month, months, days_of_week, years].detect { |part| !part.include?(date) }.nil?
72
73
  end
73
74
 
74
75
  def next_fire_at(time=nil)
75
- Time.zone = @time_zone
76
+ Time.zone = time_zone
76
77
  after = time.nil? ? Time.zone.now : time.in_time_zone(@time_zone)
77
- # after = 1.second.since(after)
78
- # puts "next fire at after: #{after.inspect}"
79
78
 
80
79
  while (true)
81
80
  [years, months, days_of_month, days_of_week, hours, minutes, seconds].each do |cron_value|
82
- # puts "next_fire_at cron val loop: #{cron_value.part}"
83
- # puts "before move_to_next: #{after.inspect}"
84
81
  after, changed = move_to_next(cron_value, after)
85
- # puts "after move_to_next: #{after.inspect}"
86
82
  return if after.nil?
87
83
  break if changed
88
84
  end
89
-
85
+
90
86
  break if will_fire_on?(after)
91
87
  end
92
- # puts "NEXT FIRE AT: #{after}, NOW: #{Time.zone.now}"
93
- return after
88
+ after
94
89
  end
95
90
 
96
91
  def last_fire_at(time=nil)
97
- Time.zone = @time_zone
92
+ Time.zone = time_zone
98
93
  before = time.nil? ? Time.zone.now : time.in_time_zone(@time_zone)
99
- # before = 1.second.ago(before)
100
- # puts "last fire at before: #{before.inspect}"
101
94
 
102
95
  while (true)
103
96
  [years, months, days_of_month, days_of_week, hours, minutes, seconds].each do |cron_value|
104
- # puts "last_fire_at cron val loop: #{cron_value.part} for #{before.inspect}"
105
- # puts "before move_to_last: #{before.to_s}"
106
97
  before, changed = move_to_last(cron_value, before)
107
- # puts "after move_to_last: #{before.to_s}"
108
98
  return if before.nil?
109
99
  break if changed
110
100
  end
111
-
101
+
112
102
  break if will_fire_on?(before)
113
103
  end
114
- # puts "NEXT FIRE AT: #{before}, NOW: #{Time.zone.now}"
115
- return before
104
+ before
116
105
  end
117
106
 
118
107
  protected
@@ -133,12 +122,12 @@ module SayWhen
133
122
  [before, false]
134
123
  end
135
124
 
136
-
125
+
137
126
  end
138
127
 
139
128
  class CronValue
140
- attr_accessor :part, :min, :max, :expression, :values
141
-
129
+ attr_accessor :part, :min, :max, :expression, :values
130
+
142
131
  def initialize(p, min, max, exp)
143
132
  self.part = p
144
133
  self.min = min
@@ -147,29 +136,29 @@ module SayWhen
147
136
  self.expression = exp
148
137
  parse(exp)
149
138
  end
150
-
139
+
151
140
  def parse(exp)
152
- self.values = self.class.parse_number(self.min, self.max, exp.upcase)
141
+ self.values = CronValue.parse_number(min, max, exp.upcase)
153
142
  end
154
143
 
155
144
  def to_s
156
- "[e:#{self.expression}, v:#{self.values.inspect}]\n"
145
+ "[e:#{expression}, v:#{values.inspect}]\n"
157
146
  end
158
-
147
+
159
148
  def include?(date)
160
- self.values.include?(date.send(part))
149
+ values.include?(date.send(part))
161
150
  end
162
-
151
+
163
152
  #works for secs, mins, hours
164
153
  def self.parse_number(min, max, val)
165
154
  values = []
166
155
  case val
167
156
  #check for a '/' for increments
168
- when /(\w+)\/(\d+)/ then (( $1 == "*") ? min : $1.to_i).step(max, $2.to_i) {|x| values << x}
169
-
157
+ when /(\w+)\/(\d+)/ then (( $1 == "*") ? min : $1.to_i).step(max, $2.to_i) { |x| values << x }
158
+
170
159
  #check for ',' for list of values
171
- when /(\d+)(,\d+)+/ then values = val.split(',').collect{|v| v.to_i}.sort
172
-
160
+ when /(\d+)(,\d+)+/ then values = val.split(',').map{ |v| v.to_i }.sort
161
+
173
162
  #check for '-' for range of values
174
163
  when /(\d+)-(\d+)/ then values = (($1.to_i)..($2.to_i)).to_a
175
164
 
@@ -192,26 +181,22 @@ module SayWhen
192
181
  end
193
182
 
194
183
  def next(date)
195
- # date = date.to_time
196
- n = self.values.detect{|v| v > date.sec}
184
+ n = values.detect { |v| v > date.sec }
197
185
  if n.blank?
198
- 1.minute.since(date).change(:sec=>self.values.first)
186
+ 1.minute.since(date).change(sec: values.first)
199
187
  else
200
- date.change(:sec=>n)
188
+ date.change(sec: n)
201
189
  end
202
190
  end
203
-
191
+
204
192
  def last(date)
205
- # date = date.to_time
206
- n = self.values.reverse.detect{|v| v < date.sec}
193
+ n = values.reverse.detect { |v| v < date.sec }
207
194
  if n.blank?
208
- 1.minute.ago(date).change(:sec=>self.values.last)
195
+ 1.minute.ago(date).change(sec: values.last)
209
196
  else
210
- date.change(:sec=>n)
197
+ date.change(sec: n)
211
198
  end
212
199
  end
213
-
214
-
215
200
  end
216
201
 
217
202
  class MinutesCronValue < CronValue
@@ -220,22 +205,20 @@ module SayWhen
220
205
  end
221
206
 
222
207
  def next(date)
223
- # date = date.to_time
224
- n = self.values.detect{|v| v > date.min}
208
+ n = values.detect { |v| v > date.min }
225
209
  if n.blank?
226
- 1.hour.since(date).change(:min=>self.values.first, :sec=>0)
210
+ 1.hour.since(date).change(min: values.first, sec: 0)
227
211
  else
228
- date.change(:min=>n, :sec=>0)
212
+ date.change(min: n, sec: 0)
229
213
  end
230
214
  end
231
215
 
232
216
  def last(date)
233
- # date = date.to_time
234
- n = self.values.reverse.detect{|v| v < date.min}
217
+ n = values.reverse.detect { |v| v < date.min }
235
218
  if n.blank?
236
- 1.hour.ago(date).change(:min=>self.values.last, :sec=>59)
219
+ 1.hour.ago(date).change(min: values.last, sec: 59)
237
220
  else
238
- date.change(:min=>n, :sec=>59)
221
+ date.change(min: n, sec: 59)
239
222
  end
240
223
  end
241
224
  end
@@ -244,28 +227,24 @@ module SayWhen
244
227
  def initialize(exp)
245
228
  super(:hour, 0, 24, exp)
246
229
  end
247
-
230
+
248
231
  def next(date)
249
- # date = date.to_time
250
- # puts "HoursCronValue next: date: #{date.inspect}, hour: #{date.hour}"
251
- n = self.values.detect{|v| v > date.hour}
232
+ n = values.detect { |v| v > date.hour }
252
233
  if n.blank?
253
- 1.day.since(date).change(:hour=>self.values.first, :min=>0, :sec=>0)
234
+ 1.day.since(date).change(hour: values.first, min: 0, sec: 0)
254
235
  else
255
- date.change(:hour=>n, :min=>0, :sec=>0)
236
+ date.change(hour: n, min: 0, sec: 0)
256
237
  end
257
238
  end
258
239
 
259
240
  def last(date)
260
- # date = date.to_time
261
- n = self.values.reverse.detect{|v| v < date.hour}
241
+ n = values.reverse.detect { |v| v < date.hour }
262
242
  if n.blank?
263
- 1.day.ago(date).change(:hour=>self.values.last, :min=>59, :sec=>59)
243
+ 1.day.ago(date).change(hour: values.last, min: 59, sec: 59)
264
244
  else
265
- date.change(:hour=>n, :min=>59, :sec=>59)
245
+ date.change(hour: n, min: 59, sec: 59)
266
246
  end
267
247
  end
268
-
269
248
  end
270
249
 
271
250
  class DaysOfMonthCronValue < CronValue
@@ -275,14 +254,14 @@ module SayWhen
275
254
  self.is_weekday = false
276
255
  super(:mday, 1, 31, exp)
277
256
  end
278
-
257
+
279
258
  def parse(exp)
280
- if self.is_specified = !(self.expression =~ /\?/)
259
+ if self.is_specified = !(expression =~ /\?/)
281
260
  case exp
282
261
  when /^(L)$/ then self.is_last = true
283
262
  when /^(W)$/ then self.is_weekday = true
284
263
  when /^(WL|LW)$/ then self.is_last = (self.is_weekday = true)
285
- when /^(\d+)W$/ then self.is_weekday = true; self.values << $1.to_i
264
+ when /^(\d+)W$/ then self.is_weekday = true; self.values << $1.to_i
286
265
  else super(exp)
287
266
  end
288
267
  end
@@ -296,7 +275,7 @@ module SayWhen
296
275
  eom = nearest_week_day(eom) if is_weekday
297
276
  if eom > date
298
277
  eom = 1.month.ago(date)
299
- eom = nearest_week_day(eom.change(:day=>eom.end_of_month))
278
+ eom = nearest_week_day(eom.change(day: eom.end_of_month))
300
279
  end
301
280
  eom
302
281
  elsif is_weekday
@@ -304,72 +283,58 @@ module SayWhen
304
283
  nearest = nearest_week_day(date)
305
284
  if nearest > date
306
285
  nearest = 1.month.ago(date)
307
- nearest = nearest_week_day(date.change(:day=>date.end_of_month))
286
+ nearest = nearest_week_day(date.change(day: date.end_of_month))
308
287
  end
309
288
  else
310
- nearest = nearest_week_day(date.change(:day=>values.first))
311
- nearest = nearest_week_day(1.month.ago(date).change(:day=>values.first)) if nearest > date
289
+ nearest = nearest_week_day(date.change(day: values.first))
290
+ nearest = nearest_week_day(1.month.ago(date).change(day: values.first)) if nearest > date
312
291
  end
313
292
  nearest
314
293
  else
315
- # puts "change to the next specified day of the month...#{self.values.inspect} "
316
- l = self.values.reverse.detect{|v| v < date.mday}
317
- # puts "last should be #{n}"
294
+ l = values.reverse.detect { |v| v < date.mday }
318
295
  if l.blank?
319
- 1.month.ago(date).change(:day=>self.values.last)
296
+ 1.month.ago(date).change(day: values.last)
320
297
  else
321
- # puts "change date to have day of month of #{n}"
322
- date.change(:day=>l.to_i)
298
+ date.change(day: l.to_i)
323
299
  end
324
300
  end
325
- result = result.change(:hour=>23, :min=>59, :sec=>59)
326
- # puts "result after change #{result}"
327
- result
301
+ result.change(hour: 23, min: 59, sec: 59)
328
302
  end
329
-
303
+
330
304
  def next(date)
331
305
  result = if !is_specified
332
306
  date
333
307
  elsif is_last
334
308
  last = date.end_of_month
335
309
  last = nearest_week_day(last) if is_weekday
336
- # last = nearest_week_day(1.month.since(date).change(:day=>1)) if last < date
337
310
  if last < date
338
311
  last = 1.month.since(date)
339
- last = nearest_week_day(last.change(:day=>last.end_of_month))
312
+ last = nearest_week_day(last.change(day: last.end_of_month))
340
313
  end
341
314
  last
342
315
  elsif is_weekday
343
316
  if values.empty?
344
317
  nearest = nearest_week_day(date)
345
- nearest = nearest_week_day(1.month.since(date).change(:day=>1)) if nearest < date
318
+ nearest = nearest_week_day(1.month.since(date).change(day: 1)) if nearest < date
346
319
  else
347
- nearest = nearest_week_day(date.change(:day=>values.first))
348
- nearest = nearest_week_day(1.month.since(date).change(:day=>values.first)) if nearest < date
320
+ nearest = nearest_week_day(date.change(day: values.first))
321
+ nearest = nearest_week_day(1.month.since(date).change(day: values.first)) if nearest < date
349
322
  end
350
323
  nearest
351
324
  else
352
- # puts "change to the next specified day of the month...#{self.values.inspect} "
353
- n = self.values.detect{|v| v > date.mday}
354
- # puts "next should be #{n}"
325
+ n = values.detect { |v| v > date.mday }
355
326
  if n.blank?
356
- date.months_since(1).change(:day=>self.values.first)
327
+ date.months_since(1).change(day: values.first)
357
328
  else
358
- # puts "change date to have day of month of #{n}"
359
- ndate = date.change(:day=>n.to_i)
360
- # puts "after change date #{ndate}, #{ndate.class.name}"
361
- ndate
329
+ date.change(day: n.to_i)
362
330
  end
363
331
  end
364
- result = result.change(:hour=>0)
365
- # puts "result after change #{result}"
366
- result
332
+ result.change(hour: 0)
367
333
  end
368
-
334
+
369
335
  def include?(date)
370
336
  return true unless is_specified
371
337
  last = date.clone
372
- #must be last weekday of the month
373
338
  if is_last
374
339
  last = last.end_of_month.to_date
375
340
  last = nearest_week_day(last) if is_weekday
@@ -378,13 +343,13 @@ module SayWhen
378
343
  if values.empty?
379
344
  (1..5).include?(date.wday)
380
345
  else
381
- nearest_week_day(date.change(:day=>values.first)) == date
346
+ nearest_week_day(date.change(day: values.first)) == date
382
347
  end
383
348
  else
384
349
  super(date)
385
350
  end
386
351
  end
387
-
352
+
388
353
  def nearest_week_day(date)
389
354
  if (1..5).include?(date.wday)
390
355
  date
@@ -394,52 +359,48 @@ module SayWhen
394
359
  (date.end_of_month.to_date == date.to_date) ? date = 2.days.ago(date) : 1.day.since(date)
395
360
  end
396
361
  end
397
-
362
+
398
363
  def to_s
399
- "[e:#{self.expression}, v:#{self.values.inspect}, is:#{is_specified}, il:#{is_last}, iw:#{is_weekday}]\n"
400
- end
364
+ "[e:#{expression}, v:#{values.inspect}, is:#{is_specified}, il:#{is_last}, iw:#{is_weekday}]\n"
365
+ end
401
366
  end
402
367
 
403
368
  class MonthsCronValue < CronValue
404
- MONTHS = Date::ABBR_MONTHNAMES[1..-1].collect{|a| a.upcase }
405
-
369
+ MONTHS = Date::ABBR_MONTHNAMES[1..-1].map { |a| a.upcase }
370
+
406
371
  def initialize(exp)
407
372
  super(:month, 1, 12, exp)
408
373
  end
409
-
410
- def parse(exp)
374
+
375
+ def parse(exp)
411
376
  if exp =~ /[A-Z]+/
412
- MONTHS.each_with_index{|mon, index|
413
- exp = exp.gsub(mon, (index+1).to_s)
414
- }
377
+ MONTHS.each_with_index { |mon, index| exp = exp.gsub(mon, (index + 1).to_s) }
415
378
  end
416
379
  super(exp)
417
380
  end
418
381
 
419
382
  def last(date)
420
- last_month = self.values.reverse.detect{|v| v < date.month}
383
+ last_month = values.reverse.detect { |v| v < date.month }
421
384
  result = if last_month.nil?
422
- date.change(:year=>date.year - 1, :month=>self.values.last)
385
+ date.change(year: date.year - 1, month: values.last)
423
386
  else
424
- date.change(:month=>last_month)
387
+ date.change(month: last_month)
425
388
  end
426
- result.change(:day=>result.end_of_month, :hour=>23, :min=>59, :sec=>59)
389
+ result.change(day: result.end_of_month, hour: 23, min: 59, sec: 59)
427
390
  end
428
391
 
429
392
  def next(date)
430
- next_month = self.values.detect{|v| v > date.month}
431
- result = if next_month.nil?
432
- date.change(:year=>date.year + 1, :month=>self.values.first, :day=>1, :hour=>0)
393
+ next_month = values.detect { |v| v > date.month }
394
+ if next_month.nil?
395
+ date.change(year: date.year + 1, month: values.first, day: 1, hour: 0)
433
396
  else
434
- date.change(:month=>next_month, :day=>1, :hour=>0)
397
+ date.change(month: next_month, day: 1, hour: 0)
435
398
  end
436
- result
437
399
  end
438
-
439
400
  end
440
401
 
441
402
  class DaysOfWeekCronValue < CronValue
442
- DAYS = Date::ABBR_DAYNAMES.collect{|a| a.upcase }
403
+ DAYS = Date::ABBR_DAYNAMES.map { |a| a.upcase }
443
404
  attr_accessor :is_specified, :is_last, :nth_day
444
405
 
445
406
  def initialize(exp)
@@ -448,14 +409,12 @@ module SayWhen
448
409
  end
449
410
 
450
411
  def parse(exp)
451
- if self.is_specified = !(self.expression =~ /\?/)
412
+ if self.is_specified = !(expression =~ /\?/)
452
413
  if exp =~ /[A-Z]+/
453
- DAYS.each_with_index{|day, index|
454
- exp = exp.gsub(day, (index+1).to_s)
455
- }
414
+ DAYS.each_with_index { |day, index| exp = exp.gsub(day, (index + 1).to_s) }
456
415
  end
457
416
  case exp
458
- when /^L$/ then values << self.max
417
+ when /^L$/ then values << max
459
418
  when /^(\d+)L$/ then self.is_last = true; values << $1.to_i
460
419
  when /^(\d+)#(\d+)/ then self.values << $1.to_i; self.nth_day = $2.to_i
461
420
  else super(exp)
@@ -464,48 +423,41 @@ module SayWhen
464
423
  end
465
424
 
466
425
  def include?(date)
467
- # puts "DaysOfWeekCronValue::include? is_specified:#{is_specified}, date:#{date}"
468
426
  return true unless is_specified
469
427
  if is_last
470
428
  last = last_wday(date, values.first).to_date
471
- # puts "checking is_last: date=#{date} == last #{last}"
472
429
  date.to_date == last
473
430
  elsif nth_day
474
- date.to_date == nth_wday(self.nth_day, self.values.first, date.month, date.year).to_date
431
+ date.to_date == nth_wday(nth_day, values.first, date.month, date.year).to_date
475
432
  else
476
- self.values.include?(date.wday+1)
433
+ values.include?(date.wday + 1)
477
434
  end
478
435
  end
479
-
436
+
480
437
  def last(date)
481
- # puts "DaysOfWeekCronValue::last date:#{date}, is_last:#{is_last}"
482
438
  last_dow = if !is_specified
483
439
  date
484
440
  elsif is_last
485
441
  last = last_wday(date, values.first)
486
- # puts "DaysOfWeekCronValue::last after first last_wday: #{date}"
487
442
  if last.to_date > date.to_date
488
- last = last_wday(1.month.ago(date).change(:day=>1), values.first)
443
+ last = last_wday(1.month.ago(date).change(day: 1), values.first)
489
444
  end
490
445
  last
491
446
  elsif nth_day
492
- nth = nth_wday(self.nth_day, self.values.first, date.month, date.year)
493
- # puts "DaysOfWeekCronValue::last after first nth_wday: #{nth}"
447
+ nth = nth_wday(nth_day, values.first, date.month, date.year)
494
448
  if nth.to_date > date.to_date
495
- nth = 1.month.ago(date).change(:day=>1)
496
- nth = nth_wday(self.nth_day, self.values.first, nth.month, nth.year)
449
+ nth = 1.month.ago(date).change(day: 1)
450
+ nth = nth_wday(nth_day, values.first, nth.month, nth.year)
497
451
  end
498
452
  nth
499
453
  else
500
- n = self.values.detect{|v| v > date.wday}
501
- n = self.values[0] if n.blank?
454
+ n = values.detect { |v| v > date.wday }
455
+ n = values[0] if n.blank?
502
456
  base = (n < (date.wday + 1)) ? 7 : 0
503
457
  days_forward = n + (base - (date.wday + 1))
504
458
  days_forward.days.since(date)
505
459
  end
506
- last_dow = last_dow.change(:hour=>23, :min=>59, :sec=>59)
507
- # puts "DaysOfWeekCronValue: #{last_dow.class.name}: #{last_dow.to_s}"
508
- last_dow
460
+ last_dow.change(hour: 23, min: 59, sec: 59)
509
461
  end
510
462
 
511
463
  def next(date)
@@ -513,36 +465,28 @@ module SayWhen
513
465
  date
514
466
  elsif is_last
515
467
  last = last_wday(date, values.first)
516
- # puts "1 last_wday = #{last}"
517
468
  if last.to_date <= date.to_date
518
- last = last_wday(1.month.since(date).change(:day=>1), values.first)
519
- # puts "2 last_wday = #{last}"
469
+ last = last_wday(1.month.since(date).change(day: 1), values.first)
520
470
  end
521
471
  last
522
472
  elsif nth_day
523
- nth = nth_wday(self.nth_day, self.values.first, date.month, date.year)
473
+ nth = nth_wday(nth_day, values.first, date.month, date.year)
524
474
  if nth.to_date <= date.to_date
525
475
  date = 1.month.since(date)
526
- nth = nth_wday(self.nth_day, self.values.first, date.month, date.year)
476
+ nth = nth_wday(nth_day, values.first, date.month, date.year)
527
477
  end
528
478
  nth
529
479
  else
530
- n = self.values.detect{|v| v > date.wday}
531
- n = self.values[0] if n.blank?
480
+ n = values.detect { |v| v > date.wday }
481
+ n = values[0] if n.blank?
532
482
  base = (n < (date.wday + 1)) ? 7 : 0
533
483
  days_forward = n + (base - (date.wday + 1))
534
484
  days_forward.days.since(date)
535
485
  end
536
- next_dow.change(:hour=>0)
486
+ next_dow.change(hour: 0)
537
487
  end
538
488
 
539
- # 1 last_wday = 2008-05-30
540
- # latest_wday date=Sun Jun 01 10:00:00 -0400 2008, wday=5
541
- # 2 last_wday = 2008-06-28 '
542
- # **** should be 06-27
543
489
  def last_wday(date, aWday)
544
- # puts "last_wday date=#{date.to_time}, wday=#{wday}"
545
- # sleep(1)
546
490
  wday = aWday - 1
547
491
  eom = date.end_of_month
548
492
  if eom.wday == wday
@@ -563,7 +507,6 @@ module SayWhen
563
507
  raise ArgumentError
564
508
  end
565
509
  t = Time.zone.local year, month, 1
566
- # puts "t = #{t}"
567
510
  first = t.wday
568
511
  if first == wday
569
512
  fwd = 1
@@ -575,7 +518,6 @@ module SayWhen
575
518
  target = fwd + (n-1)*7
576
519
  begin
577
520
  t2 = Time.zone.local year, month, target
578
- # puts "t2 = #{t2}"
579
521
  rescue ArgumentError
580
522
  return nil
581
523
  end
@@ -586,11 +528,9 @@ module SayWhen
586
528
  end
587
529
  end
588
530
 
589
-
590
531
  def to_s
591
- "[e:#{self.expression}, v:#{self.values.inspect}, is:#{is_specified}, il:#{is_last}, nd:#{nth_day}]\n"
532
+ "[e:#{expression}, v:#{values.inspect}, is:#{is_specified}, il:#{is_last}, nd:#{nth_day}]\n"
592
533
  end
593
-
594
534
  end
595
535
 
596
536
  class YearsCronValue < CronValue
@@ -599,23 +539,21 @@ module SayWhen
599
539
  end
600
540
 
601
541
  def next(date)
602
- next_year = self.values.detect{|v| v > date.year}
603
- if next_year.nil?
542
+ next_year = values.detect { |v| v > date.year }
543
+ if next_year.nil?
604
544
  return nil
605
545
  else
606
- date.change(:year=>next_year, :month=>1, :day=>1, :hour=>0)
546
+ date.change(year: next_year, month: 1, day: 1, hour: 0)
607
547
  end
608
548
  end
609
549
 
610
550
  def last(date)
611
- last_year = self.values.reverse.detect{|v| v < date.year}
612
- if last_year.nil?
551
+ last_year = values.reverse.detect { |v| v < date.year }
552
+ if last_year.nil?
613
553
  return nil
614
554
  else
615
- date.change(:year=>last_year, :month=>12, :day=>31, :hour=>23, :min=>59, :sec=>59)
555
+ date.change(year: last_year, month: 12, day: 31, hour: 23, min: 59, sec: 59)
616
556
  end
617
557
  end
618
-
619
558
  end
620
-
621
559
  end