ice_cube 0.8.1 → 0.9.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.
- data/lib/ice_cube.rb +1 -0
- data/lib/ice_cube/flexible_hash.rb +24 -0
- data/lib/ice_cube/rule.rb +3 -2
- data/lib/ice_cube/schedule.rb +17 -13
- data/lib/ice_cube/time_util.rb +5 -0
- data/lib/ice_cube/validated_rule.rb +8 -1
- data/lib/ice_cube/validations/daily_interval.rb +1 -0
- data/lib/ice_cube/validations/hourly_interval.rb +1 -0
- data/lib/ice_cube/validations/minutely_interval.rb +1 -0
- data/lib/ice_cube/validations/monthly_interval.rb +1 -0
- data/lib/ice_cube/validations/secondly_interval.rb +1 -0
- data/lib/ice_cube/validations/until.rb +2 -2
- data/lib/ice_cube/validations/weekly_interval.rb +1 -0
- data/lib/ice_cube/validations/yearly_interval.rb +1 -0
- data/lib/ice_cube/version.rb +1 -1
- metadata +3 -2
data/lib/ice_cube.rb
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
|
3
|
+
module IceCube
|
4
|
+
|
5
|
+
# A way to symbolize what's necessary on the fly
|
6
|
+
# Due to the serialization format of ice_cube, this limited implementation
|
7
|
+
# is entirely sufficient
|
8
|
+
|
9
|
+
class FlexibleHash < SimpleDelegator
|
10
|
+
|
11
|
+
def initialize(hash)
|
12
|
+
@underlying = hash
|
13
|
+
end
|
14
|
+
|
15
|
+
def [](key)
|
16
|
+
case key
|
17
|
+
when String then @underlying[key] || @underlying[key.to_sym]
|
18
|
+
else @underlying[key] || @underlying[key.to_s]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
data/lib/ice_cube/rule.rb
CHANGED
@@ -44,7 +44,8 @@ module IceCube
|
|
44
44
|
end
|
45
45
|
|
46
46
|
# Convert from a hash and create a rule
|
47
|
-
def self.from_hash(
|
47
|
+
def self.from_hash(original_hash)
|
48
|
+
hash = IceCube::FlexibleHash.new original_hash
|
48
49
|
return nil unless match = hash[:rule_type].match(/\:\:(.+?)Rule/)
|
49
50
|
rule = IceCube::Rule.send(match[1].downcase.to_sym, hash[:interval] || 1)
|
50
51
|
rule.until(TimeUtil.deserialize_time(hash[:until])) if hash[:until]
|
@@ -70,7 +71,7 @@ module IceCube
|
|
70
71
|
|
71
72
|
# Whether this rule requires a full run
|
72
73
|
def full_required?
|
73
|
-
!@count.nil?
|
74
|
+
!@count.nil? || (!@interval.nil? && @interval > 1)
|
74
75
|
end
|
75
76
|
|
76
77
|
# Convenience methods for creating Rules
|
data/lib/ice_cube/schedule.rb
CHANGED
@@ -21,7 +21,7 @@ module IceCube
|
|
21
21
|
|
22
22
|
# Create a new schedule
|
23
23
|
def initialize(start_time = nil, options = {})
|
24
|
-
@start_time = start_time ||
|
24
|
+
@start_time = start_time || TimeUtil.now
|
25
25
|
@end_time = options[:end_time]
|
26
26
|
@duration = options[:duration]
|
27
27
|
@all_recurrence_rules = []
|
@@ -145,17 +145,17 @@ module IceCube
|
|
145
145
|
end
|
146
146
|
|
147
147
|
# The next n occurrences after now
|
148
|
-
def next_occurrences(num, from =
|
148
|
+
def next_occurrences(num, from = TimeUtil.now)
|
149
149
|
find_occurrences(from + 1, nil, num)
|
150
150
|
end
|
151
151
|
|
152
152
|
# The next occurrence after now (overridable)
|
153
|
-
def next_occurrence(from =
|
153
|
+
def next_occurrence(from = TimeUtil.now)
|
154
154
|
find_occurrences(from + 1, nil, 1).first
|
155
155
|
end
|
156
156
|
|
157
157
|
# The remaining occurrences (same requirements as all_occurrences)
|
158
|
-
def remaining_occurrences(from =
|
158
|
+
def remaining_occurrences(from = TimeUtil.now)
|
159
159
|
find_occurrences(from)
|
160
160
|
end
|
161
161
|
|
@@ -170,6 +170,13 @@ module IceCube
|
|
170
170
|
!find_occurrences(begin_time, closing_time, 1).empty?
|
171
171
|
end
|
172
172
|
|
173
|
+
# Return a boolean indicating if an occurrence is occurring between
|
174
|
+
# two times, inclusive
|
175
|
+
def occurring_between?(begin_time, closing_time)
|
176
|
+
dur = duration || 0
|
177
|
+
occurs_between?(begin_time - dur + 1, closing_time + dur - 1)
|
178
|
+
end
|
179
|
+
|
173
180
|
# Return a boolean indicating if an occurrence falls on a certain date
|
174
181
|
def occurs_on?(date)
|
175
182
|
begin_time = TimeUtil.beginning_of_date(date)
|
@@ -215,6 +222,7 @@ module IceCube
|
|
215
222
|
# Due to durations, we need to walk up to the end time, and verify in the
|
216
223
|
# other direction
|
217
224
|
if last_time
|
225
|
+
last_time = terminating_schedule.duration ? last_time + terminating_schedule.duration : last_time
|
218
226
|
other_schedule.each_occurrence do |time|
|
219
227
|
break if time > last_time
|
220
228
|
return true if terminating_schedule.occurring_at?(time)
|
@@ -243,7 +251,6 @@ module IceCube
|
|
243
251
|
pieces.concat rrules.map { |t| t.to_s }
|
244
252
|
pieces.concat exrules.map { |t| "not #{t.to_s}" }
|
245
253
|
pieces.concat ed.sort.map { |t| "not on #{t.strftime(IceCube.to_s_time_format)}" }
|
246
|
-
pieces << "until #{end_time.strftime(IceCube.to_s_time_format)}" if end_time
|
247
254
|
pieces.join(' / ')
|
248
255
|
end
|
249
256
|
|
@@ -274,7 +281,7 @@ module IceCube
|
|
274
281
|
def to_hash
|
275
282
|
data = {}
|
276
283
|
data[:start_date] = TimeUtil.serialize_time(start_time)
|
277
|
-
data[:end_time] = end_time if end_time
|
284
|
+
data[:end_time] = TimeUtil.serialize_time(end_time) if end_time
|
278
285
|
data[:duration] = duration if duration
|
279
286
|
data[:rrules] = recurrence_rules.map(&:to_hash)
|
280
287
|
data[:exrules] = exception_rules.map(&:to_hash)
|
@@ -288,9 +295,10 @@ module IceCube
|
|
288
295
|
end
|
289
296
|
|
290
297
|
# Load the schedule from a hash
|
291
|
-
def self.from_hash(
|
292
|
-
|
298
|
+
def self.from_hash(original_hash, options = {})
|
299
|
+
original_hash[:start_date] = options[:start_date_override] if options[:start_date_override]
|
293
300
|
# And then deserialize
|
301
|
+
data = IceCube::FlexibleHash.new(original_hash)
|
294
302
|
schedule = IceCube::Schedule.new TimeUtil.deserialize_time(data[:start_date])
|
295
303
|
schedule.duration = data[:duration] if data[:duration]
|
296
304
|
schedule.end_time = TimeUtil.deserialize_time(data[:end_time]) if data[:end_time]
|
@@ -315,7 +323,7 @@ module IceCube
|
|
315
323
|
# Determine if the schedule will end
|
316
324
|
# @return [Boolean] true if ending, false if repeating forever
|
317
325
|
def terminating?
|
318
|
-
|
326
|
+
recurrence_rules.empty? || recurrence_rules.all?(&:terminating?)
|
319
327
|
end
|
320
328
|
|
321
329
|
def self.dump(schedule)
|
@@ -339,10 +347,6 @@ module IceCube
|
|
339
347
|
def find_occurrences(opening_time, closing_time = nil, limit = nil, &block)
|
340
348
|
reset
|
341
349
|
answers = []
|
342
|
-
# ensure the bounds are proper
|
343
|
-
if end_time
|
344
|
-
closing_time = end_time unless closing_time && closing_time < end_time
|
345
|
-
end
|
346
350
|
opening_time = start_time if opening_time < start_time
|
347
351
|
# walk up to the opening time - and off we go
|
348
352
|
# If we have rules with counts, we need to walk from the beginning of time,
|
data/lib/ice_cube/time_util.rb
CHANGED
@@ -18,6 +18,11 @@ module IceCube
|
|
18
18
|
:november => 11, :december => 12
|
19
19
|
}
|
20
20
|
|
21
|
+
# Provides a Time.now without the usec
|
22
|
+
def self.now
|
23
|
+
Time.at Time.now.to_i
|
24
|
+
end
|
25
|
+
|
21
26
|
# Serialize a time appropriate for storing
|
22
27
|
def self.serialize_time(time)
|
23
28
|
if defined?(:ActiveSupport) && const_defined?(:ActiveSupport) && time.is_a?(ActiveSupport::TimeWithZone)
|
@@ -39,6 +39,9 @@ module IceCube
|
|
39
39
|
wrapper = TimeUtil::TimeWrapper.new(time, dst_adjust)
|
40
40
|
wrapper.add(type, fwd)
|
41
41
|
wrapper.clear_below(type)
|
42
|
+
if wrapper.to_time == time
|
43
|
+
wrapper.add(:sec, wrapper.to_time.utc_offset * 2)
|
44
|
+
end
|
42
45
|
time = wrapper.to_time
|
43
46
|
end
|
44
47
|
false
|
@@ -93,7 +96,11 @@ module IceCube
|
|
93
96
|
|
94
97
|
# Fully replace validations
|
95
98
|
def replace_validations_for(key, arr)
|
96
|
-
|
99
|
+
if arr.nil?
|
100
|
+
@validations.delete(key)
|
101
|
+
else
|
102
|
+
@validations[key] = arr
|
103
|
+
end
|
97
104
|
end
|
98
105
|
|
99
106
|
# Remove the specified base validations
|
data/lib/ice_cube/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ice_cube
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-10-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -72,6 +72,7 @@ files:
|
|
72
72
|
- lib/ice_cube/deprecated.rb
|
73
73
|
- lib/ice_cube/errors/count_exceeded.rb
|
74
74
|
- lib/ice_cube/errors/until_exceeded.rb
|
75
|
+
- lib/ice_cube/flexible_hash.rb
|
75
76
|
- lib/ice_cube/rule.rb
|
76
77
|
- lib/ice_cube/rules/daily_rule.rb
|
77
78
|
- lib/ice_cube/rules/hourly_rule.rb
|