ice_cube 0.10.1 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/ice_cube/enumerator.rb +65 -0
- data/lib/ice_cube/occurrence.rb +10 -5
- data/lib/ice_cube/schedule.rb +26 -5
- data/lib/ice_cube/version.rb +1 -1
- metadata +5 -4
@@ -0,0 +1,65 @@
|
|
1
|
+
module IceCube
|
2
|
+
class Enumerator < ::Enumerator
|
3
|
+
|
4
|
+
def initialize(schedule, from_time, to_time)
|
5
|
+
@schedule = schedule
|
6
|
+
@from_time = TimeUtil.ensure_time(from_time)
|
7
|
+
@to_time = TimeUtil.ensure_time(to_time)
|
8
|
+
align_start_time
|
9
|
+
@cursor = @from_time
|
10
|
+
end
|
11
|
+
|
12
|
+
def each
|
13
|
+
while res = self.find_next && @to_time.nil? || res <= @to_time
|
14
|
+
yield Occurrence.new(res, res + schedule.duration)
|
15
|
+
end
|
16
|
+
raise StopIteration
|
17
|
+
end
|
18
|
+
|
19
|
+
def find_next
|
20
|
+
loop do
|
21
|
+
min_time = recurrence_rules.reduce(nil) do |min_time, rule|
|
22
|
+
begin
|
23
|
+
new_time = rule.next_time(time, schedule, min_time || @to_time)
|
24
|
+
[min_time, new_time].compact.min
|
25
|
+
rescue CountExceeded, UntilExceeded
|
26
|
+
min_time
|
27
|
+
end
|
28
|
+
end
|
29
|
+
break nil unless min_time
|
30
|
+
@cursor = min_time + 1
|
31
|
+
next if exception_time?(min_time)
|
32
|
+
break min_time
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def align_start_time
|
39
|
+
if @from_time <= schedule.start_time || full_required?
|
40
|
+
@from_time = schedule.start_time
|
41
|
+
else
|
42
|
+
@from_time += @schedule.start_time.subsec - @from_time.subsec rescue 0
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Return a boolean indicating if any rule needs to be run from the start of time
|
47
|
+
def full_required?
|
48
|
+
recurrence_rules.any?(&:full_required?) ||
|
49
|
+
exception_rules.any?(&:full_required?)
|
50
|
+
end
|
51
|
+
|
52
|
+
def exception_rules
|
53
|
+
schedule.instance_variable_get(:@all_exception_rules)
|
54
|
+
end
|
55
|
+
|
56
|
+
def recurrence_rules
|
57
|
+
@recurrence_rules ||= if recurrence_rules.empty?
|
58
|
+
[SingleOccurrenceRule.new(schedule.start_time)].concat schedule.instance_variable_get(:@all_recurrence_rules)
|
59
|
+
else
|
60
|
+
schedule.instance_variable_get(:@all_recurrence_rules)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
data/lib/ice_cube/occurrence.rb
CHANGED
@@ -28,7 +28,7 @@ module IceCube
|
|
28
28
|
|
29
29
|
# Optimize for common methods to avoid method_missing
|
30
30
|
extend Forwardable
|
31
|
-
def_delegators :start_time, :
|
31
|
+
def_delegators :start_time, :to_i, :<=>, :==
|
32
32
|
def_delegators :to_range, :cover?, :include?, :each, :first, :last
|
33
33
|
|
34
34
|
attr_reader :start_time, :end_time
|
@@ -79,12 +79,17 @@ module IceCube
|
|
79
79
|
start_time
|
80
80
|
end
|
81
81
|
|
82
|
-
|
83
|
-
|
84
|
-
|
82
|
+
# Shows both the start and end time if there is a duration.
|
83
|
+
# Optional format argument (e.g. :long, :short) supports Rails
|
84
|
+
# time formats and is only used when ActiveSupport is available.
|
85
|
+
#
|
86
|
+
def to_s(format=nil)
|
87
|
+
if format && to_time.public_method(:to_s).arity > 0
|
88
|
+
t0, t1 = start_time.to_s(format), end_time.to_s(format)
|
85
89
|
else
|
86
|
-
|
90
|
+
t0, t1 = start_time.to_s, end_time.to_s
|
87
91
|
end
|
92
|
+
duration > 0 ? "#{t0} - #{t1}" : t0
|
88
93
|
end
|
89
94
|
|
90
95
|
def overnight?
|
data/lib/ice_cube/schedule.rb
CHANGED
@@ -172,6 +172,18 @@ module IceCube
|
|
172
172
|
find_occurrences(from + 1, nil, 1).first
|
173
173
|
end
|
174
174
|
|
175
|
+
# The previous occurrence from a given time
|
176
|
+
def previous_occurrence(from)
|
177
|
+
return nil if from <= start_time
|
178
|
+
find_occurrences(start_time, from - 1, nil, 1).last
|
179
|
+
end
|
180
|
+
|
181
|
+
# The previous n occurrences before a given time
|
182
|
+
def previous_occurrences(num, from)
|
183
|
+
return [] if from <= start_time
|
184
|
+
find_occurrences(start_time, from - 1, nil, num)
|
185
|
+
end
|
186
|
+
|
175
187
|
# The remaining occurrences (same requirements as all_occurrences)
|
176
188
|
def remaining_occurrences(from = nil)
|
177
189
|
require_terminating_rules
|
@@ -268,6 +280,14 @@ module IceCube
|
|
268
280
|
n.nil? ? occurrences.first : occurrences
|
269
281
|
end
|
270
282
|
|
283
|
+
# Get the final n occurrences of a terminating schedule
|
284
|
+
# or the final one if no n is given
|
285
|
+
def last(n = nil)
|
286
|
+
require_terminating_rules
|
287
|
+
occurrences = find_occurrences(start_time, nil, nil, n || 1)
|
288
|
+
n.nil? ? occurrences.last : occurrences[-n..-1]
|
289
|
+
end
|
290
|
+
|
271
291
|
# String serialization
|
272
292
|
def to_s
|
273
293
|
pieces = []
|
@@ -371,7 +391,7 @@ module IceCube
|
|
371
391
|
|
372
392
|
# Find all of the occurrences for the schedule between opening_time
|
373
393
|
# and closing_time
|
374
|
-
def find_occurrences(opening_time, closing_time = nil, limit = nil, &block)
|
394
|
+
def find_occurrences(opening_time, closing_time = nil, limit = nil, tail_limit = nil, &block)
|
375
395
|
opening_time = TimeUtil.ensure_time opening_time
|
376
396
|
closing_time = TimeUtil.ensure_time closing_time
|
377
397
|
opening_time += start_time.subsec - opening_time.subsec rescue 0
|
@@ -388,6 +408,7 @@ module IceCube
|
|
388
408
|
break if closing_time && res > closing_time
|
389
409
|
if res >= opening_time
|
390
410
|
block_given? ? block.call(res) : (answers << res)
|
411
|
+
answers.shift if tail_limit && answers.length > tail_limit
|
391
412
|
break if limit && answers.length == limit
|
392
413
|
end
|
393
414
|
time = res + 1
|
@@ -433,7 +454,7 @@ module IceCube
|
|
433
454
|
raise ArgumentError, "All recurrence rules must specify .until or .count to use #{method_name}"
|
434
455
|
end
|
435
456
|
|
436
|
-
def
|
457
|
+
def implicit_start_occurrence_rule
|
437
458
|
SingleOccurrenceRule.new(start_time)
|
438
459
|
end
|
439
460
|
|
@@ -442,8 +463,8 @@ module IceCube
|
|
442
463
|
end
|
443
464
|
|
444
465
|
def recurrence_times_with_start_time
|
445
|
-
if
|
446
|
-
[start_time]
|
466
|
+
if recurrence_rules.empty?
|
467
|
+
[start_time].concat recurrence_times_without_start_time
|
447
468
|
else
|
448
469
|
recurrence_times
|
449
470
|
end
|
@@ -451,7 +472,7 @@ module IceCube
|
|
451
472
|
|
452
473
|
def recurrence_rules_with_implicit_start_occurrence
|
453
474
|
if recurrence_rules.empty?
|
454
|
-
[
|
475
|
+
[implicit_start_occurrence_rule].concat @all_recurrence_rules
|
455
476
|
else
|
456
477
|
@all_recurrence_rules
|
457
478
|
end
|
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.11.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: 2013-
|
12
|
+
date: 2013-06-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -86,6 +86,7 @@ files:
|
|
86
86
|
- lib/ice_cube/builders/ical_builder.rb
|
87
87
|
- lib/ice_cube/builders/string_builder.rb
|
88
88
|
- lib/ice_cube/deprecated.rb
|
89
|
+
- lib/ice_cube/enumerator.rb
|
89
90
|
- lib/ice_cube/errors/count_exceeded.rb
|
90
91
|
- lib/ice_cube/errors/until_exceeded.rb
|
91
92
|
- lib/ice_cube/flexible_hash.rb
|
@@ -140,7 +141,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
140
141
|
version: '0'
|
141
142
|
segments:
|
142
143
|
- 0
|
143
|
-
hash:
|
144
|
+
hash: 3343770401458335569
|
144
145
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
145
146
|
none: false
|
146
147
|
requirements:
|
@@ -149,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
149
150
|
version: '0'
|
150
151
|
segments:
|
151
152
|
- 0
|
152
|
-
hash:
|
153
|
+
hash: 3343770401458335569
|
153
154
|
requirements: []
|
154
155
|
rubyforge_project: ice-cube
|
155
156
|
rubygems_version: 1.8.25
|