ice_cube 0.11.0 → 0.11.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/ice_cube.rb +0 -11
- data/lib/ice_cube/builders/string_builder.rb +15 -23
- data/lib/ice_cube/deprecated.rb +26 -24
- data/lib/ice_cube/enumerator.rb +1 -3
- data/lib/ice_cube/hash_input.rb +71 -0
- data/lib/ice_cube/rule.rb +4 -6
- data/lib/ice_cube/rules/daily_rule.rb +1 -1
- data/lib/ice_cube/rules/hourly_rule.rb +1 -1
- data/lib/ice_cube/rules/minutely_rule.rb +1 -1
- data/lib/ice_cube/rules/monthly_rule.rb +1 -1
- data/lib/ice_cube/rules/secondly_rule.rb +1 -1
- data/lib/ice_cube/rules/yearly_rule.rb +1 -1
- data/lib/ice_cube/schedule.rb +4 -4
- data/lib/ice_cube/string_helpers.rb +10 -0
- data/lib/ice_cube/time_util.rb +14 -5
- data/lib/ice_cube/validations/count.rb +4 -6
- data/lib/ice_cube/validations/daily_interval.rb +13 -18
- data/lib/ice_cube/validations/day.rb +4 -4
- data/lib/ice_cube/validations/day_of_month.rb +8 -10
- data/lib/ice_cube/validations/day_of_week.rb +24 -26
- data/lib/ice_cube/validations/day_of_year.rb +11 -12
- data/lib/ice_cube/validations/hour_of_day.rb +9 -11
- data/lib/ice_cube/validations/hourly_interval.rb +18 -21
- data/lib/ice_cube/validations/lock.rb +35 -14
- data/lib/ice_cube/validations/minute_of_hour.rb +9 -11
- data/lib/ice_cube/validations/minutely_interval.rb +16 -19
- data/lib/ice_cube/validations/month_of_year.rb +4 -4
- data/lib/ice_cube/validations/monthly_interval.rb +15 -17
- data/lib/ice_cube/validations/schedule_lock.rb +12 -11
- data/lib/ice_cube/validations/second_of_minute.rb +5 -5
- data/lib/ice_cube/validations/secondly_interval.rb +13 -16
- data/lib/ice_cube/validations/until.rb +12 -12
- data/lib/ice_cube/validations/weekly_interval.rb +20 -23
- data/lib/ice_cube/validations/yearly_interval.rb +10 -11
- data/lib/ice_cube/version.rb +1 -1
- metadata +20 -33
@@ -10,8 +10,6 @@ module IceCube
|
|
10
10
|
self
|
11
11
|
end
|
12
12
|
|
13
|
-
# A validation for checking to make sure that a time
|
14
|
-
# is inside of a certain DailyInterval
|
15
13
|
class Validation
|
16
14
|
|
17
15
|
attr_reader :interval
|
@@ -20,6 +18,18 @@ module IceCube
|
|
20
18
|
@interval = interval
|
21
19
|
end
|
22
20
|
|
21
|
+
def type
|
22
|
+
:day
|
23
|
+
end
|
24
|
+
|
25
|
+
def validate(step_time, schedule)
|
26
|
+
t0, t1 = schedule.start_time, step_time
|
27
|
+
days = Date.new(t1.year, t1.month, t1.day) -
|
28
|
+
Date.new(t0.year, t0.month, t0.day)
|
29
|
+
offset = (days % interval).nonzero?
|
30
|
+
interval - offset if offset
|
31
|
+
end
|
32
|
+
|
23
33
|
def build_s(builder)
|
24
34
|
builder.base = interval == 1 ? 'Daily' : "Every #{interval} days"
|
25
35
|
end
|
@@ -30,22 +40,7 @@ module IceCube
|
|
30
40
|
|
31
41
|
def build_ical(builder)
|
32
42
|
builder['FREQ'] << 'DAILY'
|
33
|
-
unless interval == 1
|
34
|
-
builder['INTERVAL'] << interval
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def type
|
39
|
-
:day
|
40
|
-
end
|
41
|
-
|
42
|
-
def validate(time, schedule)
|
43
|
-
time_date = Date.new(time.year, time.month, time.day)
|
44
|
-
start_date = Date.new(schedule.start_time.year, schedule.start_time.month, schedule.start_time.day)
|
45
|
-
days = time_date - start_date
|
46
|
-
unless days % interval === 0
|
47
|
-
interval - (days % interval)
|
48
|
-
end
|
43
|
+
builder['INTERVAL'] << interval unless interval == 1
|
49
44
|
end
|
50
45
|
|
51
46
|
end
|
@@ -27,6 +27,10 @@ module IceCube
|
|
27
27
|
@day = day
|
28
28
|
end
|
29
29
|
|
30
|
+
def type
|
31
|
+
:wday
|
32
|
+
end
|
33
|
+
|
30
34
|
def build_s(builder)
|
31
35
|
builder.piece(:day) << day
|
32
36
|
end
|
@@ -43,10 +47,6 @@ module IceCube
|
|
43
47
|
end
|
44
48
|
end
|
45
49
|
|
46
|
-
def type
|
47
|
-
:wday
|
48
|
-
end
|
49
|
-
|
50
50
|
StringBuilder.register_formatter(:day) do |validation_days|
|
51
51
|
# sort the days
|
52
52
|
validation_days.sort!
|
@@ -2,8 +2,6 @@ module IceCube
|
|
2
2
|
|
3
3
|
module Validations::DayOfMonth
|
4
4
|
|
5
|
-
include Validations::Lock
|
6
|
-
|
7
5
|
def day_of_month(*days)
|
8
6
|
days.flatten.each do |day|
|
9
7
|
unless day.is_a?(Fixnum)
|
@@ -19,12 +17,6 @@ module IceCube
|
|
19
17
|
|
20
18
|
include Validations::Lock
|
21
19
|
|
22
|
-
StringBuilder.register_formatter(:day_of_month) do |entries|
|
23
|
-
str = "on the #{StringBuilder.sentence(entries)} "
|
24
|
-
str << (entries.size == 1 ? 'day of the month' : 'days of the month')
|
25
|
-
str
|
26
|
-
end
|
27
|
-
|
28
20
|
attr_reader :day
|
29
21
|
alias :value :day
|
30
22
|
|
@@ -32,6 +24,10 @@ module IceCube
|
|
32
24
|
@day = day
|
33
25
|
end
|
34
26
|
|
27
|
+
def type
|
28
|
+
:day
|
29
|
+
end
|
30
|
+
|
35
31
|
def build_s(builder)
|
36
32
|
builder.piece(:day_of_month) << StringBuilder.nice_number(day)
|
37
33
|
end
|
@@ -44,8 +40,10 @@ module IceCube
|
|
44
40
|
builder['BYMONTHDAY'] << day
|
45
41
|
end
|
46
42
|
|
47
|
-
|
48
|
-
|
43
|
+
StringBuilder.register_formatter(:day_of_month) do |entries|
|
44
|
+
str = "on the #{StringBuilder.sentence(entries)} "
|
45
|
+
str << (entries.size == 1 ? 'day of the month' : 'days of the month')
|
46
|
+
str
|
49
47
|
end
|
50
48
|
|
51
49
|
end
|
@@ -17,23 +17,31 @@ module IceCube
|
|
17
17
|
|
18
18
|
attr_reader :day, :occ
|
19
19
|
|
20
|
-
|
21
|
-
|
20
|
+
def initialize(day, occ)
|
21
|
+
@day = day
|
22
|
+
@occ = occ
|
22
23
|
end
|
23
24
|
|
24
25
|
def type
|
25
26
|
:day
|
26
27
|
end
|
27
28
|
|
28
|
-
def
|
29
|
-
|
29
|
+
def validate(step_time, schedule)
|
30
|
+
wday = step_time.wday
|
31
|
+
offset = (day < wday) ? (7 - wday + day) : (day - wday)
|
32
|
+
wrapper = TimeUtil::TimeWrapper.new(step_time)
|
33
|
+
wrapper.add :day, offset
|
34
|
+
loop do
|
35
|
+
which_occ, num_occ = TimeUtil.which_occurrence_in_month(wrapper.to_time, day)
|
36
|
+
this_occ = (occ < 0) ? (num_occ + occ + 1) : (occ)
|
37
|
+
break offset if which_occ == this_occ
|
38
|
+
wrapper.add :day, 7
|
39
|
+
offset += 7
|
40
|
+
end
|
30
41
|
end
|
31
42
|
|
32
|
-
def
|
33
|
-
|
34
|
-
# Delete any with this day and no occ first
|
35
|
-
builder['BYDAY'].delete_if { |d| d == ical_day }
|
36
|
-
builder['BYDAY'] << "#{occ}#{ical_day}"
|
43
|
+
def build_s(builder)
|
44
|
+
builder.piece(:day_of_week) << "#{StringBuilder.nice_number(occ)} #{Date::DAYNAMES[day]}"
|
37
45
|
end
|
38
46
|
|
39
47
|
def build_hash(builder)
|
@@ -42,25 +50,15 @@ module IceCube
|
|
42
50
|
arr << occ
|
43
51
|
end
|
44
52
|
|
45
|
-
def
|
46
|
-
|
47
|
-
|
53
|
+
def build_ical(builder)
|
54
|
+
ical_day = IcalBuilder.fixnum_to_ical_day(day)
|
55
|
+
# Delete any with this day and no occ first
|
56
|
+
builder['BYDAY'].delete_if { |d| d == ical_day }
|
57
|
+
builder['BYDAY'] << "#{occ}#{ical_day}"
|
48
58
|
end
|
49
59
|
|
50
|
-
|
51
|
-
|
52
|
-
sum = day >= time.wday ? day - time.wday : 7 - time.wday + day
|
53
|
-
wrapper = TimeUtil::TimeWrapper.new(time)
|
54
|
-
wrapper.add :day, sum
|
55
|
-
# and then count the week until a viable occ
|
56
|
-
loop do
|
57
|
-
which_occ, num_occ = TimeUtil.which_occurrence_in_month(wrapper.to_time, day)
|
58
|
-
this_occ = occ < 0 ? num_occ + occ + 1 : occ
|
59
|
-
break if which_occ == this_occ
|
60
|
-
sum += 7
|
61
|
-
wrapper.add :day, 7 # one week
|
62
|
-
end
|
63
|
-
sum
|
60
|
+
StringBuilder.register_formatter(:day_of_week) do |segments|
|
61
|
+
'on the ' + segments.join(' and ')
|
64
62
|
end
|
65
63
|
|
66
64
|
end
|
@@ -17,12 +17,6 @@ module IceCube
|
|
17
17
|
|
18
18
|
attr_reader :day
|
19
19
|
|
20
|
-
StringBuilder.register_formatter(:day_of_year) do |entries|
|
21
|
-
str = "on the #{StringBuilder.sentence(entries)} "
|
22
|
-
str << (entries.size == 1 ? 'day of the year' : 'days of the year')
|
23
|
-
str
|
24
|
-
end
|
25
|
-
|
26
20
|
def initialize(day)
|
27
21
|
@day = day
|
28
22
|
end
|
@@ -31,6 +25,13 @@ module IceCube
|
|
31
25
|
:day
|
32
26
|
end
|
33
27
|
|
28
|
+
def validate(step_time, schedule)
|
29
|
+
days_in_year = TimeUtil.days_in_year(step_time)
|
30
|
+
yday = day < 0 ? day + days_in_year : day
|
31
|
+
offset = yday - step_time.yday
|
32
|
+
offset >= 0 ? offset : offset + days_in_year
|
33
|
+
end
|
34
|
+
|
34
35
|
def build_s(builder)
|
35
36
|
builder.piece(:day_of_year) << StringBuilder.nice_number(day)
|
36
37
|
end
|
@@ -43,12 +44,10 @@ module IceCube
|
|
43
44
|
builder['BYYEARDAY'] << day
|
44
45
|
end
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
diff = the_day - time.yday
|
51
|
-
diff >= 0 ? diff : diff + days_in_year
|
47
|
+
StringBuilder.register_formatter(:day_of_year) do |entries|
|
48
|
+
str = "on the #{StringBuilder.sentence(entries)} "
|
49
|
+
str << (entries.size == 1 ? 'day of the year' : 'days of the year')
|
50
|
+
str
|
52
51
|
end
|
53
52
|
|
54
53
|
end
|
@@ -2,8 +2,6 @@ module IceCube
|
|
2
2
|
|
3
3
|
module Validations::HourOfDay
|
4
4
|
|
5
|
-
include Validations::Lock
|
6
|
-
|
7
5
|
# Add hour of day validations
|
8
6
|
def hour_of_day(*hours)
|
9
7
|
hours.flatten.each do |hour|
|
@@ -20,11 +18,6 @@ module IceCube
|
|
20
18
|
|
21
19
|
include Validations::Lock
|
22
20
|
|
23
|
-
StringBuilder.register_formatter(:hour_of_day) do |segments|
|
24
|
-
str = "on the #{StringBuilder.sentence(segments)} "
|
25
|
-
str << (segments.size == 1 ? 'hour of the day' : 'hours of the day')
|
26
|
-
end
|
27
|
-
|
28
21
|
attr_reader :hour
|
29
22
|
alias :value :hour
|
30
23
|
|
@@ -32,14 +25,14 @@ module IceCube
|
|
32
25
|
@hour = hour
|
33
26
|
end
|
34
27
|
|
35
|
-
def build_s(builder)
|
36
|
-
builder.piece(:hour_of_day) << StringBuilder.nice_number(hour)
|
37
|
-
end
|
38
|
-
|
39
28
|
def type
|
40
29
|
:hour
|
41
30
|
end
|
42
31
|
|
32
|
+
def build_s(builder)
|
33
|
+
builder.piece(:hour_of_day) << StringBuilder.nice_number(hour)
|
34
|
+
end
|
35
|
+
|
43
36
|
def build_hash(builder)
|
44
37
|
builder.validations_array(:hour_of_day) << hour
|
45
38
|
end
|
@@ -48,6 +41,11 @@ module IceCube
|
|
48
41
|
builder['BYHOUR'] << hour
|
49
42
|
end
|
50
43
|
|
44
|
+
StringBuilder.register_formatter(:hour_of_day) do |segments|
|
45
|
+
str = "on the #{StringBuilder.sentence(segments)} "
|
46
|
+
str << (segments.size == 1 ? 'hour of the day' : 'hours of the day')
|
47
|
+
end
|
48
|
+
|
51
49
|
end
|
52
50
|
|
53
51
|
end
|
@@ -13,10 +13,27 @@ module IceCube
|
|
13
13
|
|
14
14
|
attr_reader :interval
|
15
15
|
|
16
|
+
def initialize(interval)
|
17
|
+
@interval = interval
|
18
|
+
end
|
19
|
+
|
16
20
|
def type
|
17
21
|
:hour
|
18
22
|
end
|
19
23
|
|
24
|
+
def dst_adjust?
|
25
|
+
false
|
26
|
+
end
|
27
|
+
|
28
|
+
def validate(step_time, schedule)
|
29
|
+
t0, t1 = schedule.start_time.to_i, step_time.to_i
|
30
|
+
sec = (t1 - t1 % ONE_HOUR) -
|
31
|
+
(t0 - t0 % ONE_HOUR)
|
32
|
+
hours = sec / ONE_HOUR
|
33
|
+
offset = (hours % interval).nonzero?
|
34
|
+
interval - offset if offset
|
35
|
+
end
|
36
|
+
|
20
37
|
def build_s(builder)
|
21
38
|
builder.base = interval == 1 ? 'Hourly' : "Every #{interval} hours"
|
22
39
|
end
|
@@ -27,27 +44,7 @@ module IceCube
|
|
27
44
|
|
28
45
|
def build_ical(builder)
|
29
46
|
builder['FREQ'] << 'HOURLY'
|
30
|
-
unless interval == 1
|
31
|
-
builder['INTERVAL'] << interval
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def initialize(interval)
|
36
|
-
@interval = interval
|
37
|
-
end
|
38
|
-
|
39
|
-
def dst_adjust?
|
40
|
-
false
|
41
|
-
end
|
42
|
-
|
43
|
-
def validate(time, schedule)
|
44
|
-
start_time = schedule.start_time
|
45
|
-
sec = (time.to_i - time.to_i % ONE_HOUR) -
|
46
|
-
(start_time.to_i - start_time.to_i % ONE_HOUR)
|
47
|
-
hours = sec / ONE_HOUR
|
48
|
-
unless hours % interval == 0
|
49
|
-
interval - (hours % interval)
|
50
|
-
end
|
47
|
+
builder['INTERVAL'] << interval unless interval == 1
|
51
48
|
end
|
52
49
|
|
53
50
|
end
|
@@ -1,34 +1,49 @@
|
|
1
1
|
module IceCube
|
2
2
|
|
3
|
-
#
|
4
|
-
#
|
5
|
-
|
3
|
+
# This validation mixin is used by the various "fixed-time" (e.g. day,
|
4
|
+
# day_of_month, hour_of_day) Validation and ScheduleLock::Validation modules.
|
5
|
+
# It is not a standalone rule validation like the others.
|
6
|
+
#
|
7
|
+
# Given the including Validation's defined +type+ field, it will lock
|
8
|
+
# to the specified +value+ or else the corresponding time unit from the
|
9
|
+
# schedule's start_time
|
10
|
+
#
|
6
11
|
module Validations::Lock
|
7
12
|
|
8
|
-
INTERVALS = {:min => 60, :sec => 60, :month => 12, :wday => 7}
|
13
|
+
INTERVALS = {:min => 60, :sec => 60, :hour => 24, :month => 12, :wday => 7}
|
9
14
|
|
10
15
|
def validate(time, schedule)
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
16
|
+
case type
|
17
|
+
when :day then validate_day_lock(time, schedule)
|
18
|
+
when :hour then validate_hour_lock(time, schedule)
|
19
|
+
else validate_interval_lock(time, schedule)
|
20
|
+
end
|
15
21
|
end
|
16
22
|
|
17
23
|
private
|
18
24
|
|
25
|
+
# Validate if the current time unit matches the same unit from the schedule
|
26
|
+
# start time, returning the difference to the interval
|
27
|
+
#
|
28
|
+
def validate_interval_lock(time, schedule)
|
29
|
+
t0 = starting_unit(schedule.start_time)
|
30
|
+
t1 = time.send(type)
|
31
|
+
t0 >= t1 ? t0 - t1 : INTERVALS[type] - t1 + t0
|
32
|
+
end
|
33
|
+
|
19
34
|
# Lock the hour if explicitly set by hour_of_day, but allow for the nearest
|
20
35
|
# hour during DST start to keep the correct interval.
|
21
36
|
#
|
22
37
|
def validate_hour_lock(time, schedule)
|
23
|
-
|
24
|
-
|
25
|
-
if
|
26
|
-
|
38
|
+
h0 = starting_unit(schedule.start_time)
|
39
|
+
h1 = time.hour
|
40
|
+
if h0 >= h1
|
41
|
+
h0 - h1
|
27
42
|
else
|
28
43
|
if dst_offset = TimeUtil.dst_change(time)
|
29
|
-
|
44
|
+
h0 - h1 + dst_offset
|
30
45
|
else
|
31
|
-
24 -
|
46
|
+
24 - h1 + h0
|
32
47
|
end
|
33
48
|
end
|
34
49
|
end
|
@@ -69,6 +84,12 @@ module IceCube
|
|
69
84
|
sleeps >= 0 ? sleeps : until_next_month
|
70
85
|
end
|
71
86
|
|
87
|
+
def starting_unit(start_time)
|
88
|
+
start = value || start_time.send(type)
|
89
|
+
start += INTERVALS[type] while start < 0
|
90
|
+
start
|
91
|
+
end
|
92
|
+
|
72
93
|
end
|
73
94
|
|
74
95
|
end
|
@@ -2,8 +2,6 @@ module IceCube
|
|
2
2
|
|
3
3
|
module Validations::MinuteOfHour
|
4
4
|
|
5
|
-
include Validations::Lock
|
6
|
-
|
7
5
|
def minute_of_hour(*minutes)
|
8
6
|
minutes.flatten.each do |minute|
|
9
7
|
unless minute.is_a?(Fixnum)
|
@@ -19,11 +17,6 @@ module IceCube
|
|
19
17
|
|
20
18
|
include Validations::Lock
|
21
19
|
|
22
|
-
StringBuilder.register_formatter(:minute_of_hour) do |segments|
|
23
|
-
str = "on the #{StringBuilder.sentence(segments)} "
|
24
|
-
str << (segments.size == 1 ? 'minute of the hour' : 'minutes of the hour')
|
25
|
-
end
|
26
|
-
|
27
20
|
attr_reader :minute
|
28
21
|
alias :value :minute
|
29
22
|
|
@@ -31,14 +24,14 @@ module IceCube
|
|
31
24
|
@minute = minute
|
32
25
|
end
|
33
26
|
|
34
|
-
def build_s(builder)
|
35
|
-
builder.piece(:minute_of_hour) << StringBuilder.nice_number(minute)
|
36
|
-
end
|
37
|
-
|
38
27
|
def type
|
39
28
|
:min
|
40
29
|
end
|
41
30
|
|
31
|
+
def build_s(builder)
|
32
|
+
builder.piece(:minute_of_hour) << StringBuilder.nice_number(minute)
|
33
|
+
end
|
34
|
+
|
42
35
|
def build_hash(builder)
|
43
36
|
builder.validations_array(:minute_of_hour) << minute
|
44
37
|
end
|
@@ -47,6 +40,11 @@ module IceCube
|
|
47
40
|
builder['BYMINUTE'] << minute
|
48
41
|
end
|
49
42
|
|
43
|
+
StringBuilder.register_formatter(:minute_of_hour) do |segments|
|
44
|
+
str = "on the #{StringBuilder.sentence(segments)} "
|
45
|
+
str << (segments.size == 1 ? 'minute of the hour' : 'minutes of the hour')
|
46
|
+
end
|
47
|
+
|
50
48
|
end
|
51
49
|
|
52
50
|
end
|