ice_cube 0.13.3 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/ice_cube/parsers/ical_parser.rb +2 -1
- data/lib/ice_cube/schedule.rb +22 -19
- data/lib/ice_cube/version.rb +1 -1
- metadata +3 -9
- data/lib/ice_cube/enumerator.rb +0 -69
- data/lib/ice_cube/hash_input.rb +0 -71
- data/lib/ice_cube/time_step.rb +0 -30
- data/lib/ice_cube/validations/interval.rb +0 -19
- data/spec/manual_regression.rb +0 -50
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5882c908ac2e56578482bda2b172c91edf4a55df
|
4
|
+
data.tar.gz: f4ec09ff6db92240f0d3ed669ca6b8be495d2784
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e94d7e1c2a4a4745957bbe13bda1d05211af20bb04618852aad3d114c7ff24632a0588012d7ef5b6aeda3e268d93f060e98c5ad8cddb55f330d157758328e6a
|
7
|
+
data.tar.gz: 5384b4f0700a8c185b3bc88d628ed82825f3115a71331cff0e0689f1446422277e1443f96a90c3c1d18e469ae1784e89c095d5f84041a5004eca66da39bf240b
|
data/lib/ice_cube/schedule.rb
CHANGED
@@ -166,15 +166,15 @@ module IceCube
|
|
166
166
|
end
|
167
167
|
|
168
168
|
# The next n occurrences after now
|
169
|
-
def next_occurrences(num, from = nil)
|
169
|
+
def next_occurrences(num, from = nil, options = {})
|
170
170
|
from = TimeUtil.match_zone(from, start_time) || TimeUtil.now(start_time)
|
171
|
-
enumerate_occurrences(from + 1, nil).take(num)
|
171
|
+
enumerate_occurrences(from + 1, nil, options).take(num)
|
172
172
|
end
|
173
173
|
|
174
174
|
# The next occurrence after now (overridable)
|
175
|
-
def next_occurrence(from = nil)
|
175
|
+
def next_occurrence(from = nil, options = {})
|
176
176
|
from = TimeUtil.match_zone(from, start_time) || TimeUtil.now(start_time)
|
177
|
-
enumerate_occurrences(from + 1, nil).next
|
177
|
+
enumerate_occurrences(from + 1, nil, options).next
|
178
178
|
rescue StopIteration
|
179
179
|
nil
|
180
180
|
end
|
@@ -195,26 +195,26 @@ module IceCube
|
|
195
195
|
end
|
196
196
|
|
197
197
|
# The remaining occurrences (same requirements as all_occurrences)
|
198
|
-
def remaining_occurrences(from = nil)
|
198
|
+
def remaining_occurrences(from = nil, options = {})
|
199
199
|
require_terminating_rules
|
200
200
|
from ||= TimeUtil.now(@start_time)
|
201
|
-
enumerate_occurrences(from).to_a
|
201
|
+
enumerate_occurrences(from, nil, options).to_a
|
202
202
|
end
|
203
203
|
|
204
204
|
# Returns an enumerator for all remaining occurrences
|
205
|
-
def remaining_occurrences_enumerator(from = nil)
|
205
|
+
def remaining_occurrences_enumerator(from = nil, options = {})
|
206
206
|
from ||= TimeUtil.now(@start_time)
|
207
|
-
enumerate_occurrences(from)
|
207
|
+
enumerate_occurrences(from, nil, options)
|
208
208
|
end
|
209
209
|
|
210
210
|
# Occurrences between two times
|
211
|
-
def occurrences_between(begin_time, closing_time)
|
212
|
-
enumerate_occurrences(begin_time, closing_time).to_a
|
211
|
+
def occurrences_between(begin_time, closing_time, options = {})
|
212
|
+
enumerate_occurrences(begin_time, closing_time, options).to_a
|
213
213
|
end
|
214
214
|
|
215
215
|
# Return a boolean indicating if an occurrence falls between two times
|
216
|
-
def occurs_between?(begin_time, closing_time)
|
217
|
-
enumerate_occurrences(begin_time, closing_time).next
|
216
|
+
def occurs_between?(begin_time, closing_time, options = {})
|
217
|
+
enumerate_occurrences(begin_time, closing_time, options).next
|
218
218
|
true
|
219
219
|
rescue StopIteration
|
220
220
|
false
|
@@ -226,9 +226,7 @@ module IceCube
|
|
226
226
|
# occurrences at the end of the range since none of their duration
|
227
227
|
# intersects the range.
|
228
228
|
def occurring_between?(opening_time, closing_time)
|
229
|
-
opening_time
|
230
|
-
closing_time = closing_time - 1 if duration > 0
|
231
|
-
occurs_between?(opening_time, closing_time)
|
229
|
+
occurs_between?(opening_time, closing_time, :spans => true)
|
232
230
|
end
|
233
231
|
|
234
232
|
# Return a boolean indicating if an occurrence falls on a certain date
|
@@ -407,25 +405,30 @@ module IceCube
|
|
407
405
|
# Find all of the occurrences for the schedule between opening_time
|
408
406
|
# and closing_time
|
409
407
|
# Iteration is unrolled in pairs to skip duplicate times in end of DST
|
410
|
-
def enumerate_occurrences(opening_time, closing_time = nil, &block)
|
408
|
+
def enumerate_occurrences(opening_time, closing_time = nil, options = {}, &block)
|
411
409
|
opening_time = TimeUtil.match_zone(opening_time, start_time)
|
412
410
|
closing_time = TimeUtil.match_zone(closing_time, start_time)
|
413
411
|
opening_time += start_time.subsec - opening_time.subsec rescue 0
|
414
412
|
opening_time = start_time if opening_time < start_time
|
413
|
+
spans = options[:spans] == true && duration != 0
|
415
414
|
Enumerator.new do |yielder|
|
416
415
|
reset
|
417
|
-
t1 = full_required? ? start_time : realign(opening_time)
|
416
|
+
t1 = full_required? ? start_time : realign((spans ? opening_time - duration : opening_time))
|
418
417
|
loop do
|
419
418
|
break unless (t0 = next_time(t1, closing_time))
|
420
419
|
break if closing_time && t0 > closing_time
|
421
|
-
|
420
|
+
if (spans ? (t0.end_time > opening_time) : (t0 >= opening_time))
|
421
|
+
yielder << (block_given? ? block.call(t0) : t0)
|
422
|
+
end
|
422
423
|
break unless (t1 = next_time(t0 + 1, closing_time))
|
423
424
|
break if closing_time && t1 > closing_time
|
424
425
|
if TimeUtil.same_clock?(t0, t1) && recurrence_rules.any?(&:dst_adjust?)
|
425
426
|
wind_back_dst
|
426
427
|
next (t1 += 1)
|
427
428
|
end
|
428
|
-
|
429
|
+
if (spans ? (t1.end_time > opening_time) : (t1 >= opening_time))
|
430
|
+
yielder << (block_given? ? block.call(t1) : t1)
|
431
|
+
end
|
429
432
|
next (t1 += 1)
|
430
433
|
end
|
431
434
|
end
|
data/lib/ice_cube/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ice_cube
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Crepezzi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-02-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -95,11 +95,9 @@ files:
|
|
95
95
|
- lib/ice_cube/builders/ical_builder.rb
|
96
96
|
- lib/ice_cube/builders/string_builder.rb
|
97
97
|
- lib/ice_cube/deprecated.rb
|
98
|
-
- lib/ice_cube/enumerator.rb
|
99
98
|
- lib/ice_cube/errors/count_exceeded.rb
|
100
99
|
- lib/ice_cube/errors/until_exceeded.rb
|
101
100
|
- lib/ice_cube/flexible_hash.rb
|
102
|
-
- lib/ice_cube/hash_input.rb
|
103
101
|
- lib/ice_cube/i18n.rb
|
104
102
|
- lib/ice_cube/null_i18n.rb
|
105
103
|
- lib/ice_cube/occurrence.rb
|
@@ -116,7 +114,6 @@ files:
|
|
116
114
|
- lib/ice_cube/rules/yearly_rule.rb
|
117
115
|
- lib/ice_cube/schedule.rb
|
118
116
|
- lib/ice_cube/single_occurrence_rule.rb
|
119
|
-
- lib/ice_cube/time_step.rb
|
120
117
|
- lib/ice_cube/time_util.rb
|
121
118
|
- lib/ice_cube/validated_rule.rb
|
122
119
|
- lib/ice_cube/validations/count.rb
|
@@ -128,7 +125,6 @@ files:
|
|
128
125
|
- lib/ice_cube/validations/fixed_value.rb
|
129
126
|
- lib/ice_cube/validations/hour_of_day.rb
|
130
127
|
- lib/ice_cube/validations/hourly_interval.rb
|
131
|
-
- lib/ice_cube/validations/interval.rb
|
132
128
|
- lib/ice_cube/validations/lock.rb
|
133
129
|
- lib/ice_cube/validations/minute_of_hour.rb
|
134
130
|
- lib/ice_cube/validations/minutely_interval.rb
|
@@ -141,7 +137,6 @@ files:
|
|
141
137
|
- lib/ice_cube/validations/weekly_interval.rb
|
142
138
|
- lib/ice_cube/validations/yearly_interval.rb
|
143
139
|
- lib/ice_cube/version.rb
|
144
|
-
- spec/manual_regression.rb
|
145
140
|
- spec/spec_helper.rb
|
146
141
|
homepage: http://seejohnrun.github.com/ice_cube/
|
147
142
|
licenses:
|
@@ -163,10 +158,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
163
158
|
version: '0'
|
164
159
|
requirements: []
|
165
160
|
rubyforge_project: ice-cube
|
166
|
-
rubygems_version: 2.
|
161
|
+
rubygems_version: 2.4.5
|
167
162
|
signing_key:
|
168
163
|
specification_version: 4
|
169
164
|
summary: Ruby Date Recurrence Library
|
170
165
|
test_files:
|
171
|
-
- spec/manual_regression.rb
|
172
166
|
- spec/spec_helper.rb
|
data/lib/ice_cube/enumerator.rb
DELETED
@@ -1,69 +0,0 @@
|
|
1
|
-
module IceCube
|
2
|
-
class Enumerator < ::Enumerator
|
3
|
-
|
4
|
-
def initialize(schedule, opening_time, closing_time)
|
5
|
-
@schedule = schedule
|
6
|
-
@opening_time = TimeUtil.ensure_time(opening_time)
|
7
|
-
@closing_time = TimeUtil.ensure_time(closing_time)
|
8
|
-
align_opening_time
|
9
|
-
@cursor = @opening_time
|
10
|
-
end
|
11
|
-
|
12
|
-
def each
|
13
|
-
return to_enum unless block_given?
|
14
|
-
while res = self.next && @closing_time.nil? || res <= @closing_time
|
15
|
-
yield Occurrence.new(res, res + schedule.duration)
|
16
|
-
end
|
17
|
-
raise StopIteration
|
18
|
-
end
|
19
|
-
|
20
|
-
def next
|
21
|
-
t1 = full_required? ? schedule.start_time : opening_time
|
22
|
-
Enumerator.new do |yielder|
|
23
|
-
loop do
|
24
|
-
t1.tap { |t| puts "LDA #{t}" + " #{File.basename(__FILE__)}:#{__LINE__}" }
|
25
|
-
break unless (t0 = next_time(t1, closing_time).tap { |t| puts "LDB #{t}" + " #{File.basename(__FILE__)}:#{__LINE__}" })
|
26
|
-
break if closing_time && t0 > closing_time
|
27
|
-
yielder << (block_given? ? block.call(t0) : t0) if t0 >= opening_time
|
28
|
-
break unless (t1 = next_time(t0 + 1, closing_time))
|
29
|
-
break if closing_time && t1 > closing_time
|
30
|
-
if TimeUtil.same_clock?(t0, t1) && recurrence_rules.any?(&:dst_adjust?)
|
31
|
-
wind_back_dst
|
32
|
-
next (t1 += 1)
|
33
|
-
end
|
34
|
-
yielder << (block_given? ? block.call(t1) : t1) if t1 >= opening_time
|
35
|
-
next (t1 += 1)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
def align_start_time
|
43
|
-
if @opening_time <= schedule.start_time || full_required?
|
44
|
-
@opening_time = schedule.start_time
|
45
|
-
else
|
46
|
-
@opening_time += @schedule.start_time.subsec - @opening_time.subsec rescue 0
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
# Return a boolean indicating if any rule needs to be run from the start of time
|
51
|
-
def full_required?
|
52
|
-
recurrence_rules.any?(&:full_required?) ||
|
53
|
-
exception_rules.any?(&:full_required?)
|
54
|
-
end
|
55
|
-
|
56
|
-
def exception_rules
|
57
|
-
schedule.instance_variable_get(:@all_exception_rules)
|
58
|
-
end
|
59
|
-
|
60
|
-
def recurrence_rules
|
61
|
-
@recurrence_rules ||= if recurrence_rules.empty?
|
62
|
-
[SingleOccurrenceRule.new(schedule.start_time)].concat schedule.instance_variable_get(:@all_recurrence_rules)
|
63
|
-
else
|
64
|
-
schedule.instance_variable_get(:@all_recurrence_rules)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
end
|
69
|
-
end
|
data/lib/ice_cube/hash_input.rb
DELETED
@@ -1,71 +0,0 @@
|
|
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/time_step.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
module IceCube
|
2
|
-
class TimeStep
|
3
|
-
SECS = 1
|
4
|
-
MINS = 60
|
5
|
-
HOURS = MINS * 60
|
6
|
-
DAYS = HOURS * 24
|
7
|
-
WEEKS = DAYS * 7
|
8
|
-
MONTHS = {
|
9
|
-
1 => [ 28, 29, 30, 31].map { |m| m * DAYS },
|
10
|
-
2 => [ 59, 60, 61, 62].map { |m| m * DAYS },
|
11
|
-
3 => [ 89, 90, 91, 92].map { |m| m * DAYS },
|
12
|
-
4 => [120, 121, 122, 123].map { |m| m * DAYS },
|
13
|
-
5 => [150, 151, 152, 153].map { |m| m * DAYS },
|
14
|
-
6 => [181, 182, 183, 184].map { |m| m * DAYS },
|
15
|
-
7 => [212, 213, 214, 215].map { |m| m * DAYS },
|
16
|
-
8 => [242, 243, 244, 245].map { |m| m * DAYS },
|
17
|
-
9 => [273, 274, 275, 276].map { |m| m * DAYS },
|
18
|
-
10 => [303, 304, 305, 306].map { |m| m * DAYS },
|
19
|
-
11 => [334, 335, 336, 337].map { |m| m * DAYS },
|
20
|
-
12 => [365, 366] .map { |m| m * DAYS }
|
21
|
-
}
|
22
|
-
YEARS = [365, 366]
|
23
|
-
|
24
|
-
def next(base, validations)
|
25
|
-
end
|
26
|
-
|
27
|
-
def prev(base, validations)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
module IceCube
|
2
|
-
class Validations::Interval
|
3
|
-
|
4
|
-
def initialize(interval)
|
5
|
-
self.interval = interval
|
6
|
-
end
|
7
|
-
|
8
|
-
def interval=(number)
|
9
|
-
i = number.to_i
|
10
|
-
raise unless i > 0
|
11
|
-
@interval = i
|
12
|
-
rescue
|
13
|
-
raise ArgumentError.new "#{number.inspect} is not a valid input for interval, expecting positive integer"
|
14
|
-
end
|
15
|
-
|
16
|
-
attr_reader :interval
|
17
|
-
|
18
|
-
end
|
19
|
-
end
|
data/spec/manual_regression.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
require 'rbkit'
|
2
|
-
Rbkit.start_profiling
|
3
|
-
require 'ice_cube'
|
4
|
-
|
5
|
-
module Kwip
|
6
|
-
def self.womp
|
7
|
-
threads = []
|
8
|
-
start = Time.new(2104,1,1)
|
9
|
-
daily = IceCube::Rule.daily.hour_of_day(6, 12, 18, 23)
|
10
|
-
|
11
|
-
# ObjectSpace.dump_all(output: File.open('heap1.json','w'))
|
12
|
-
3.times do
|
13
|
-
threads << Thread.new do
|
14
|
-
schedule = IceCube::Schedule.new(start)
|
15
|
-
schedule.add_recurrence_rule(daily)
|
16
|
-
schedule.next_occurrence
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
threads.each &:join
|
21
|
-
threads.clear
|
22
|
-
nil
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
# GC::Tracer.start_logging('gc.log') do
|
27
|
-
# GC.disable
|
28
|
-
10000.times do
|
29
|
-
Kwip.womp
|
30
|
-
Kwip.womp
|
31
|
-
Kwip.womp
|
32
|
-
end
|
33
|
-
# GC.enable
|
34
|
-
# GC.start
|
35
|
-
|
36
|
-
# str = 'asdf'
|
37
|
-
# str = nil
|
38
|
-
# GC.start
|
39
|
-
# end
|
40
|
-
|
41
|
-
# ObjectSpace.each_object do |o|
|
42
|
-
# if o.is_a?(IceCube::Occurrence) || o.is_a?(IceCube::Schedule) || o.is_a?(IceCube::Rule)
|
43
|
-
# puts "#{o.object_id} => #{o.class} (#{ObjectSpace.memsize_of(o)})"
|
44
|
-
# # puts ObjectSpace.allocation_sourcefile(o), #=> "example.rb"
|
45
|
-
# # ObjectSpace.allocation_sourceline(o), #=> 6
|
46
|
-
# # ObjectSpace.allocation_generation(o), #=> 1
|
47
|
-
# # ObjectSpace.allocation_class_path(o), #=> "MyApp"
|
48
|
-
# # ObjectSpace.allocation_method_id(o) #=> :perform
|
49
|
-
# end
|
50
|
-
# end
|