ice_cube 0.10.1 → 0.11.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.
@@ -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
@@ -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, :to_s, :to_i, :<=>, :==
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
- def to_s
83
- if duration > 0
84
- "#{start_time} - #{end_time}"
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
- "#{start_time}"
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?
@@ -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 implicit_start_occurrence
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 (recurrence_rules).empty?
446
- [start_time] + recurrence_times_without_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
- [implicit_start_occurrence] + @all_recurrence_rules
475
+ [implicit_start_occurrence_rule].concat @all_recurrence_rules
455
476
  else
456
477
  @all_recurrence_rules
457
478
  end
@@ -1,5 +1,5 @@
1
1
  module IceCube
2
2
 
3
- VERSION = '0.10.1'
3
+ VERSION = '0.11.0'
4
4
 
5
5
  end
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.10.1
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-05-17 00:00:00.000000000 Z
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: 2800901123420442900
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: 2800901123420442900
153
+ hash: 3343770401458335569
153
154
  requirements: []
154
155
  rubyforge_project: ice-cube
155
156
  rubygems_version: 1.8.25