ice_cube 0.13.2 → 0.13.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f1996d1af50e76edf7126fd606e821318c90f664
4
- data.tar.gz: 8648cc31b2e0e14ee2fb220156bdc8070ca9f428
3
+ metadata.gz: 1cd6fca3c4607f135ad7b4628cc08c627cb437c9
4
+ data.tar.gz: 5018a7cf1feb4910571ac5695dcb3b051cad71d7
5
5
  SHA512:
6
- metadata.gz: 7801823fe9d150835ff03e10a9418d83c29bf1f9ee1e01955fa30d33467a06d3b0a0e378b8018a68d1142e79b06bfbd0bfcf90aefe6a80e5e886fadf3f3d49a4
7
- data.tar.gz: 90ab20b3029f1d0083c132c4fc3cd6ae421b2f9e2465cb6f32a5c18710f7098d6df7d8e85f6cb4c026fc5fd9f4d457ed3c5afcd48723a0f41229d16574df74cd
6
+ metadata.gz: 9c5446069c5e5c45819e7247114661aec92cdb0dff6a5dd2a8259aa12f7423df9bdc9dae671d9fad21180d478528ce08a846762742154f334f8b2791af34d85b
7
+ data.tar.gz: 7bbb442e21950216fb329699446ab0466848c97e50d4765623a5888d6c66f5e601d6166932df62d55e4cfe14c27cef759fafa835f7761ba31f82bb6b16011327
@@ -83,7 +83,7 @@ module IceCube
83
83
  # Retain backwards compatibility for schedules exported from older versions
84
84
  # This represents the version number, 11 = 0.11, 1.0 will be 100
85
85
  def self.compatibility
86
- @compatibility ||= 11
86
+ @compatibility ||= IceCube::VERSION.scan(/\d+/)[0..1].join.to_i
87
87
  end
88
88
 
89
89
  def self.compatibility=(version)
@@ -0,0 +1,69 @@
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
@@ -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
@@ -0,0 +1,30 @@
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
@@ -126,7 +126,7 @@ module IceCube
126
126
  # Convert a symbol to a numeric month
127
127
  def self.sym_to_month(sym)
128
128
  MONTHS.fetch(sym) do |k|
129
- return wday = sym.to_i if MONTHS.values.any? { |i| i.to_s == sym.to_s }
129
+ MONTHS.values.detect { |i| i.to_s == k.to_s } or
130
130
  raise ArgumentError, "Expecting Fixnum or Symbol value for month. " \
131
131
  "No such month: #{k.inspect}"
132
132
  end
@@ -136,7 +136,7 @@ module IceCube
136
136
  # Convert a symbol to a wday number
137
137
  def self.sym_to_wday(sym)
138
138
  DAYS.fetch(sym) do |k|
139
- return sym.to_i if DAYS.values.any? { |i| i.to_s == sym.to_s }
139
+ DAYS.values.detect { |i| i.to_s == k.to_s } or
140
140
  raise ArgumentError, "Expecting Fixnum or Symbol value for weekday. " \
141
141
  "No such weekday: #{k.inspect}"
142
142
  end
@@ -140,21 +140,19 @@ module IceCube
140
140
  true
141
141
  end
142
142
 
143
+ # Returns true if all validations for the current rule match
144
+ # otherwise false and shifts to the first (largest) unmatched offset
145
+ #
143
146
  def validation_accepts_or_updates_time?(validations_for_type)
144
- res = validated_results(validations_for_type)
145
- return true if res.any? { |r| r.nil? || r == 0 }
146
- return nil if res.all? { |r| r == true }
147
- res.reject! { |r| r == true }
147
+ res = validations_for_type.each_with_object([]) do |validation, offsets|
148
+ r = validation.validate(@time, @schedule)
149
+ return true if r.nil? || r == 0
150
+ offsets << r
151
+ end
148
152
  shift_time_by_validation(res, validations_for_type.first)
149
153
  false
150
154
  end
151
155
 
152
- def validated_results(validations_for_type)
153
- validations_for_type.map do |validation|
154
- validation.validate(@time, @schedule)
155
- end
156
- end
157
-
158
156
  def shift_time_by_validation(res, validation)
159
157
  return unless (interval = res.min)
160
158
  wrapper = TimeUtil::TimeWrapper.new(@time, validation.dst_adjust?)
@@ -0,0 +1,19 @@
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
@@ -1,5 +1,5 @@
1
1
  module IceCube
2
2
 
3
- VERSION = '0.13.2'
3
+ VERSION = '0.13.3'
4
4
 
5
5
  end
@@ -0,0 +1,50 @@
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
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.13.2
4
+ version: 0.13.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Crepezzi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-09 00:00:00.000000000 Z
11
+ date: 2016-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -95,9 +95,11 @@ 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
98
99
  - lib/ice_cube/errors/count_exceeded.rb
99
100
  - lib/ice_cube/errors/until_exceeded.rb
100
101
  - lib/ice_cube/flexible_hash.rb
102
+ - lib/ice_cube/hash_input.rb
101
103
  - lib/ice_cube/i18n.rb
102
104
  - lib/ice_cube/null_i18n.rb
103
105
  - lib/ice_cube/occurrence.rb
@@ -114,6 +116,7 @@ files:
114
116
  - lib/ice_cube/rules/yearly_rule.rb
115
117
  - lib/ice_cube/schedule.rb
116
118
  - lib/ice_cube/single_occurrence_rule.rb
119
+ - lib/ice_cube/time_step.rb
117
120
  - lib/ice_cube/time_util.rb
118
121
  - lib/ice_cube/validated_rule.rb
119
122
  - lib/ice_cube/validations/count.rb
@@ -125,6 +128,7 @@ files:
125
128
  - lib/ice_cube/validations/fixed_value.rb
126
129
  - lib/ice_cube/validations/hour_of_day.rb
127
130
  - lib/ice_cube/validations/hourly_interval.rb
131
+ - lib/ice_cube/validations/interval.rb
128
132
  - lib/ice_cube/validations/lock.rb
129
133
  - lib/ice_cube/validations/minute_of_hour.rb
130
134
  - lib/ice_cube/validations/minutely_interval.rb
@@ -137,6 +141,7 @@ files:
137
141
  - lib/ice_cube/validations/weekly_interval.rb
138
142
  - lib/ice_cube/validations/yearly_interval.rb
139
143
  - lib/ice_cube/version.rb
144
+ - spec/manual_regression.rb
140
145
  - spec/spec_helper.rb
141
146
  homepage: http://seejohnrun.github.com/ice_cube/
142
147
  licenses:
@@ -158,9 +163,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
158
163
  version: '0'
159
164
  requirements: []
160
165
  rubyforge_project: ice-cube
161
- rubygems_version: 2.4.8
166
+ rubygems_version: 2.2.2
162
167
  signing_key:
163
168
  specification_version: 4
164
169
  summary: Ruby Date Recurrence Library
165
170
  test_files:
171
+ - spec/manual_regression.rb
166
172
  - spec/spec_helper.rb