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
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0cf51eea4a5e3f9a8c15eedc224978494d2a79df
|
4
|
+
data.tar.gz: 8daed67d6ab9f6e610ea40c08e7e032a96552e47
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7acfe2a1546d074b0b43a9250ce4e937f339f084fd3abf9a04b840cc529849140d224b4d2bdd134254ecf1088c19e6845fce195b9440eea2fddbb31baa25ca2b
|
7
|
+
data.tar.gz: d722e7ef0d0ee4fb2bfaaf5e28b330df6898ad49f183f2cb0ab43e6115bcf91be64cd07755df568318dd83deffe94439b83ec8ba0c60f2b06711d39a3c174534
|
data/lib/ice_cube.rb
CHANGED
@@ -1,13 +1,6 @@
|
|
1
1
|
require 'date'
|
2
2
|
require 'ice_cube/deprecated'
|
3
3
|
|
4
|
-
# Use psych if we can
|
5
|
-
begin
|
6
|
-
require 'psych'
|
7
|
-
rescue LoadError
|
8
|
-
require 'yaml'
|
9
|
-
end
|
10
|
-
|
11
4
|
module IceCube
|
12
5
|
|
13
6
|
autoload :VERSION, 'ice_cube/version'
|
@@ -71,10 +64,6 @@ module IceCube
|
|
71
64
|
ONE_DAY = ONE_HOUR * 24
|
72
65
|
ONE_WEEK = ONE_DAY * 7
|
73
66
|
|
74
|
-
def self.use_psych?
|
75
|
-
@use_psych ||= defined?(Psych) && defined?(Psych::VERSION)
|
76
|
-
end
|
77
|
-
|
78
67
|
# Defines the format used by IceCube when printing out Schedule#to_s.
|
79
68
|
# Defaults to '%B %e, %Y'
|
80
69
|
def self.to_s_time_format
|
@@ -13,32 +13,26 @@ module IceCube
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def to_s
|
16
|
-
|
17
|
-
res = @types.map do |type, segments|
|
16
|
+
@types.each_with_object(@base || '') do |(type, segments), str|
|
18
17
|
if f = self.class.formatter(type)
|
19
|
-
str << ' '
|
18
|
+
str << ' ' << f.call(segments)
|
20
19
|
else
|
21
20
|
next if segments.empty?
|
22
|
-
str << ' '
|
21
|
+
str << ' ' << self.class.sentence(segments)
|
23
22
|
end
|
24
23
|
end
|
25
|
-
str
|
26
24
|
end
|
27
25
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
@formatters[type]
|
32
|
-
end
|
33
|
-
|
34
|
-
def register_formatter(type, &formatter)
|
35
|
-
@formatters ||= {}
|
36
|
-
@formatters[type] = formatter
|
37
|
-
end
|
26
|
+
def self.formatter(type)
|
27
|
+
@formatters[type]
|
28
|
+
end
|
38
29
|
|
30
|
+
def self.register_formatter(type, &formatter)
|
31
|
+
@formatters ||= {}
|
32
|
+
@formatters[type] = formatter
|
39
33
|
end
|
40
34
|
|
41
|
-
|
35
|
+
module Helpers
|
42
36
|
|
43
37
|
NUMBER_SUFFIX = ['th', 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th']
|
44
38
|
SPECIAL_SUFFIX = { 11 => 'th', 12 => 'th', 13 => 'th', 14 => 'th' }
|
@@ -54,21 +48,19 @@ module IceCube
|
|
54
48
|
end
|
55
49
|
|
56
50
|
def nice_number(number)
|
57
|
-
if number == -1
|
58
|
-
|
59
|
-
|
60
|
-
suffix = SPECIAL_SUFFIX.include?(number) ?
|
61
|
-
SPECIAL_SUFFIX[number] : NUMBER_SUFFIX[number.abs % 10]
|
51
|
+
return 'last' if number == -1
|
52
|
+
suffix = SPECIAL_SUFFIX[number] || NUMBER_SUFFIX[number.abs % 10]
|
53
|
+
if number < -1
|
62
54
|
number.abs.to_s << suffix << ' to last'
|
63
55
|
else
|
64
|
-
suffix = SPECIAL_SUFFIX.include?(number) ?
|
65
|
-
SPECIAL_SUFFIX[number] : NUMBER_SUFFIX[number.abs % 10]
|
66
56
|
number.to_s << suffix
|
67
57
|
end
|
68
58
|
end
|
69
59
|
|
70
60
|
end
|
71
61
|
|
62
|
+
extend Helpers
|
63
|
+
|
72
64
|
end
|
73
65
|
|
74
66
|
end
|
data/lib/ice_cube/deprecated.rb
CHANGED
@@ -1,28 +1,30 @@
|
|
1
|
-
module
|
1
|
+
module IceCube
|
2
|
+
module Deprecated
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
4
|
+
# Define a deprecated alias for a method
|
5
|
+
# @param [Symbol] name - name of method to define
|
6
|
+
# @param [Symbol] replacement - name of method to replace (alias)
|
7
|
+
def deprecated_alias(name, replacement)
|
8
|
+
# Create a wrapped version
|
9
|
+
define_method(name) do |*args, &block|
|
10
|
+
warn "IceCube: ##{name} deprecated (please use ##{replacement})"
|
11
|
+
send replacement, *args, &block
|
12
|
+
end
|
13
|
+
end
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
15
|
+
# Deprecate a defined method
|
16
|
+
# @param [Symbol] name - name of deprecated method
|
17
|
+
# @param [Symbol] replacement - name of the desired replacement
|
18
|
+
def deprecated(name, replacement)
|
19
|
+
# Replace old method
|
20
|
+
old_name = :"#{name}_without_deprecation"
|
21
|
+
alias_method old_name, name
|
22
|
+
# And replace it with a wrapped version
|
23
|
+
define_method(name) do |*args, &block|
|
24
|
+
warn "IceCube: ##{name} deprecated (please use ##{replacement})"
|
25
|
+
send old_name, *args, &block
|
26
|
+
end
|
27
|
+
end
|
27
28
|
|
29
|
+
end
|
28
30
|
end
|
data/lib/ice_cube/enumerator.rb
CHANGED
@@ -19,11 +19,9 @@ module IceCube
|
|
19
19
|
def find_next
|
20
20
|
loop do
|
21
21
|
min_time = recurrence_rules.reduce(nil) do |min_time, rule|
|
22
|
-
|
22
|
+
catch :limit do
|
23
23
|
new_time = rule.next_time(time, schedule, min_time || @to_time)
|
24
24
|
[min_time, new_time].compact.min
|
25
|
-
rescue CountExceeded, UntilExceeded
|
26
|
-
min_time
|
27
25
|
end
|
28
26
|
end
|
29
27
|
break nil unless min_time
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module IceCube
|
2
|
+
class HashInput
|
3
|
+
|
4
|
+
class Mash
|
5
|
+
def initialize(hash)
|
6
|
+
@hash = hash
|
7
|
+
end
|
8
|
+
|
9
|
+
# Fetch values indifferently by symbol or string key without symbolizing
|
10
|
+
# arbitrary string input
|
11
|
+
#
|
12
|
+
def [](key)
|
13
|
+
@hash.fetch(key) do |key|
|
14
|
+
str_key = key.to_s
|
15
|
+
@hash.each_pair.detect do |sym_key, value|
|
16
|
+
return value if sym_key.to_s == str_key
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(hash)
|
23
|
+
@input = Mash.new(hash)
|
24
|
+
end
|
25
|
+
|
26
|
+
def [](key)
|
27
|
+
@input[key]
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_rule
|
31
|
+
return nil unless rule_class
|
32
|
+
rule = rule_class.new(interval, week_start)
|
33
|
+
rule.until(limit_time) if limit_time
|
34
|
+
rule.count(limit_count) if limit_count
|
35
|
+
validations.each do |validation, args|
|
36
|
+
rule.send(validation, *args)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def rule_class
|
41
|
+
return @rule_class if @rule_class
|
42
|
+
match = @input[:rule_type].match(/::(\w+Rule)$/)
|
43
|
+
@rule_class = IceCube.const_get(match[1]) if match
|
44
|
+
end
|
45
|
+
|
46
|
+
def interval
|
47
|
+
@input[:interval] || 1
|
48
|
+
end
|
49
|
+
|
50
|
+
def week_start
|
51
|
+
@input[:week_start] || :sunday
|
52
|
+
end
|
53
|
+
|
54
|
+
def limit_time
|
55
|
+
@limit_time ||= TimeUtil.deserialize_time(@input[:until])
|
56
|
+
end
|
57
|
+
|
58
|
+
def limit_count
|
59
|
+
@input[:count]
|
60
|
+
end
|
61
|
+
|
62
|
+
def validations
|
63
|
+
input_validations = Mash.new(@input[:validations] || {})
|
64
|
+
ValidatedRule::VALIDATION_ORDER.each_with_object({}) do |key, output_validations|
|
65
|
+
args = input_validations[key]
|
66
|
+
output_validations[key] = Array(args) if args
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
data/lib/ice_cube/rule.rb
CHANGED
@@ -23,24 +23,22 @@ module IceCube
|
|
23
23
|
h.nil? ? super : h.hash
|
24
24
|
end
|
25
25
|
|
26
|
-
# Expected to be overridden by subclasses
|
27
26
|
def to_ical
|
28
|
-
|
27
|
+
raise MethodNotImplemented, "Expected to be overrridden by subclasses"
|
29
28
|
end
|
30
29
|
|
31
30
|
# Yaml implementation
|
32
31
|
def to_yaml(*args)
|
33
|
-
|
32
|
+
YAML::dump(to_hash, *args)
|
34
33
|
end
|
35
34
|
|
36
35
|
# From yaml
|
37
36
|
def self.from_yaml(yaml)
|
38
|
-
from_hash
|
37
|
+
from_hash YAML::load(yaml)
|
39
38
|
end
|
40
39
|
|
41
|
-
# Expected to be overridden by subclasses
|
42
40
|
def to_hash
|
43
|
-
|
41
|
+
raise MethodNotImplemented, "Expected to be overridden by subclasses"
|
44
42
|
end
|
45
43
|
|
46
44
|
# Convert from a hash and create a rule
|
data/lib/ice_cube/schedule.rb
CHANGED
@@ -4,7 +4,7 @@ module IceCube
|
|
4
4
|
|
5
5
|
class Schedule
|
6
6
|
|
7
|
-
extend
|
7
|
+
extend Deprecated
|
8
8
|
|
9
9
|
# Get the start time
|
10
10
|
attr_reader :start_time
|
@@ -237,7 +237,7 @@ module IceCube
|
|
237
237
|
def conflicts_with?(other_schedule, closing_time = nil)
|
238
238
|
closing_time = TimeUtil.ensure_time closing_time
|
239
239
|
unless terminating? || other_schedule.terminating? || closing_time
|
240
|
-
raise ArgumentError
|
240
|
+
raise ArgumentError, "One or both schedules must be terminating to use #conflicts_with?"
|
241
241
|
end
|
242
242
|
# Pick the terminating schedule, and other schedule
|
243
243
|
# No need to reverse if terminating? or there is a closing time
|
@@ -313,12 +313,12 @@ module IceCube
|
|
313
313
|
|
314
314
|
# Convert the schedule to yaml
|
315
315
|
def to_yaml(*args)
|
316
|
-
|
316
|
+
YAML::dump(to_hash, *args)
|
317
317
|
end
|
318
318
|
|
319
319
|
# Load the schedule from yaml
|
320
320
|
def self.from_yaml(yaml, options = {})
|
321
|
-
hash =
|
321
|
+
hash = YAML::load(yaml)
|
322
322
|
if match = yaml.match(/start_date: .+((?:-|\+)\d{2}:\d{2})$/)
|
323
323
|
TimeUtil.restore_deserialized_offset(hash[:start_date], match[1])
|
324
324
|
end
|
data/lib/ice_cube/time_util.rb
CHANGED
@@ -3,7 +3,7 @@ require 'date'
|
|
3
3
|
module IceCube
|
4
4
|
module TimeUtil
|
5
5
|
|
6
|
-
extend
|
6
|
+
extend Deprecated
|
7
7
|
|
8
8
|
DAYS = {
|
9
9
|
:sunday => 0, :monday => 1, :tuesday => 2, :wednesday => 3,
|
@@ -82,7 +82,7 @@ module IceCube
|
|
82
82
|
# keep it. If it was serialized with a different offset than local TZ it
|
83
83
|
# will lose the zone and not support DST.
|
84
84
|
def self.restore_deserialized_offset(time, orig_offset_str)
|
85
|
-
return time if time.respond_to?(:time_zone)
|
85
|
+
return time if time.respond_to?(:time_zone) ||
|
86
86
|
time.getlocal(orig_offset_str).utc_offset == time.utc_offset
|
87
87
|
warn 'IceCube: parsed Time from nonlocal TZ. Use ActiveSupport to fix DST'
|
88
88
|
time.localtime(orig_offset_str)
|
@@ -113,21 +113,30 @@ module IceCube
|
|
113
113
|
# Convert a symbol to a numeric month
|
114
114
|
def self.sym_to_month(sym)
|
115
115
|
return wday = sym if (1..12).include? sym
|
116
|
-
MONTHS.fetch(sym)
|
116
|
+
MONTHS.fetch(sym) do |k|
|
117
|
+
raise ArgumentError, "Expecting Fixnum or Symbol value for month. " \
|
118
|
+
"No such month: #{k.inspect}"
|
119
|
+
end
|
117
120
|
end
|
118
121
|
deprecated_alias :symbol_to_month, :sym_to_month
|
119
122
|
|
120
123
|
# Convert a symbol to a wday number
|
121
124
|
def self.sym_to_wday(sym)
|
122
125
|
return sym if (0..6).include? sym
|
123
|
-
DAYS.fetch(sym)
|
126
|
+
DAYS.fetch(sym) do |k|
|
127
|
+
raise ArgumentError, "Expecting Fixnum or Symbol value for weekday. " \
|
128
|
+
"No such weekday: #{k.inspect}"
|
129
|
+
end
|
124
130
|
end
|
125
131
|
deprecated_alias :symbol_to_day, :sym_to_wday
|
126
132
|
|
127
133
|
# Convert wday number to day symbol
|
128
134
|
def self.wday_to_sym(wday)
|
129
135
|
return sym = wday if DAYS.keys.include? wday
|
130
|
-
DAYS.invert.fetch(wday)
|
136
|
+
DAYS.invert.fetch(wday) do |i|
|
137
|
+
raise ArgumentError, "Expecting Fixnum value for weekday. " \
|
138
|
+
"No such wday number: #{i.inspect}"
|
139
|
+
end
|
131
140
|
end
|
132
141
|
|
133
142
|
# Convert weekday from base sunday to the schedule's week start.
|
@@ -2,7 +2,7 @@ module IceCube
|
|
2
2
|
|
3
3
|
module Validations::Count
|
4
4
|
|
5
|
-
#
|
5
|
+
# Value reader for limit
|
6
6
|
def occurrence_count
|
7
7
|
@count
|
8
8
|
end
|
@@ -12,7 +12,7 @@ module IceCube
|
|
12
12
|
raise ArgumentError, "Expecting Fixnum or nil value for count, got #{max.inspect}"
|
13
13
|
end
|
14
14
|
@count = max
|
15
|
-
replace_validations_for(:count, [Validation.new(max, self)])
|
15
|
+
replace_validations_for(:count, max && [Validation.new(max, self)])
|
16
16
|
self
|
17
17
|
end
|
18
18
|
|
@@ -26,13 +26,11 @@ module IceCube
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def type
|
29
|
-
:
|
29
|
+
:limit
|
30
30
|
end
|
31
31
|
|
32
32
|
def validate(time, schedule)
|
33
|
-
if rule.uses && rule.uses >= count
|
34
|
-
raise CountExceeded
|
35
|
-
end
|
33
|
+
raise CountExceeded if rule.uses && rule.uses >= count
|
36
34
|
end
|
37
35
|
|
38
36
|
def build_s(builder)
|