Class: IceCube::Schedule

Inherits:
Object
  • Object
show all
Extended by:
Deprecated
Defined in:
lib/ice_cube/schedule.rb

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Methods included from Deprecated

deprecated, deprecated_alias

Constructor Details

- (Schedule) initialize(start_time = nil, options = {}) {|_self| ... }

Create a new schedule

Yields:

  • (_self)

Yield Parameters:



18
19
20
21
22
23
24
25
# File 'lib/ice_cube/schedule.rb', line 18

def initialize(start_time = nil, options = {})
  self.start_time = start_time || TimeUtil.now
  self.end_time = self.start_time + options[:duration] if options[:duration]
  self.end_time = options[:end_time] if options[:end_time]
  @all_recurrence_rules = []
  @all_exception_rules = []
  yield self if block_given?
end

Instance Attribute Details

- (Object) end_time

Get the end time



14
15
16
# File 'lib/ice_cube/schedule.rb', line 14

def end_time
  @end_time
end

- (Object) start_time

Get the start time



10
11
12
# File 'lib/ice_cube/schedule.rb', line 10

def start_time
  @start_time
end

Class Method Details

+ (Object) dump(schedule)



356
357
358
# File 'lib/ice_cube/schedule.rb', line 356

def self.dump(schedule)
  schedule.to_yaml
end

+ (Object) from_hash(original_hash, options = {})

Load the schedule from a hash



325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
# File 'lib/ice_cube/schedule.rb', line 325

def self.from_hash(original_hash, options = {})
  original_hash[:start_date] = options[:start_date_override] if options[:start_date_override]
  # And then deserialize
  data = IceCube::FlexibleHash.new(original_hash)
  schedule = IceCube::Schedule.new TimeUtil.deserialize_time(data[:start_date])
  schedule.end_time = schedule.start_time + data[:duration] if data[:duration]
  schedule.end_time = TimeUtil.deserialize_time(data[:end_time]) if data[:end_time]
  data[:rrules] && data[:rrules].each { |h| schedule.rrule(IceCube::Rule.from_hash(h)) }
  data[:exrules] && data[:exrules].each { |h| schedule.exrule(IceCube::Rule.from_hash(h)) }
  data[:rtimes] && data[:rtimes].each do |t|
    schedule.add_recurrence_time TimeUtil.deserialize_time(t)
  end
  data[:extimes] && data[:extimes].each do |t|
    schedule.add_exception_time TimeUtil.deserialize_time(t)
  end
  # Also serialize old format for backward compat
  data[:rdates] && data[:rdates].each do |t|
    schedule.add_recurrence_time TimeUtil.deserialize_time(t)
  end
  data[:exdates] && data[:exdates].each do |t|
    schedule.add_exception_time TimeUtil.deserialize_time(t)
  end
  schedule
end

+ (Object) from_yaml(yaml, options = {})

Load the schedule from yaml



300
301
302
303
304
305
306
# File 'lib/ice_cube/schedule.rb', line 300

def self.from_yaml(yaml, options = {})
  hash = IceCube::use_psych? ? Psych::load(yaml) : YAML::load(yaml)
  if match = yaml.match(/start_date: .+((?:-|\+)\d{2}:\d{2})$/)
    TimeUtil.restore_deserialized_offset(hash[:start_date], match[1])
  end
  from_hash hash, options
end

+ (Object) load(yaml)



360
361
362
# File 'lib/ice_cube/schedule.rb', line 360

def self.load(yaml)
  from_yaml(yaml) unless yaml.nil? || yaml.empty?
end

Instance Method Details

- (Object) add_exception_rule(rule) Also known as: exrule

Add an exception rule to the schedule



82
83
84
# File 'lib/ice_cube/schedule.rb', line 82

def add_exception_rule(rule)
  @all_exception_rules << rule unless @all_exception_rules.include?(rule)
end

- (Object) add_exception_time(time) Also known as: extime

Add an exception time to the schedule



59
60
61
62
63
64
# File 'lib/ice_cube/schedule.rb', line 59

def add_exception_time(time)
  return nil if time.nil?
  rule = SingleOccurrenceRule.new(time)
  add_exception_rule rule
  time
end

- (Object) add_recurrence_rule(rule) Also known as: rrule

Add a recurrence rule to the schedule



70
71
72
# File 'lib/ice_cube/schedule.rb', line 70

def add_recurrence_rule(rule)
  @all_recurrence_rules << rule unless @all_recurrence_rules.include?(rule)
end

- (Object) add_recurrence_time(time) Also known as: rtime

Add a recurrence time to the schedule



48
49
50
51
52
53
# File 'lib/ice_cube/schedule.rb', line 48

def add_recurrence_time(time)
  return nil if time.nil?
  rule = SingleOccurrenceRule.new(time)
  add_recurrence_rule rule
  time
end

- (Object) all_occurrences

All of the occurrences



152
153
154
155
# File 'lib/ice_cube/schedule.rb', line 152

def all_occurrences
  require_terminating_rules
  find_occurrences(start_time)
end

- (Boolean) conflicts_with?(other_schedule, closing_time = nil)

Determine if this schedule conflicts with another schedule

Parameters:

  • other_schedule (IceCube::Schedule)
    • The schedule to compare to

  • closing_time (Time) (defaults to: nil)
    • the last time to consider

Returns:

  • (Boolean)

    whether or not the schedules conflict at all



225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# File 'lib/ice_cube/schedule.rb', line 225

def conflicts_with?(other_schedule, closing_time = nil)
  closing_time = TimeUtil.ensure_time closing_time
  unless terminating? || other_schedule.terminating? || closing_time
    raise ArgumentError.new 'At least one schedule must be terminating to use #conflicts_with?'
  end
  # Pick the terminating schedule, and other schedule
  # No need to reverse if terminating? or there is a closing time
  terminating_schedule = self
  unless terminating? || closing_time
    terminating_schedule, other_schedule = other_schedule, terminating_schedule
  end
  # Go through each occurrence of the terminating schedule and determine
  # if the other occurs at that time
  last_time = nil
  terminating_schedule.each_occurrence do |time|
    if closing_time && time > closing_time
      last_time = closing_time
      break
    end
    last_time = time
    return true if other_schedule.occurring_at?(time)
  end
  # Due to durations, we need to walk up to the end time, and verify in the
  # other direction
  if last_time
    last_time += terminating_schedule.duration
    other_schedule.each_occurrence do |time|
      break if time > last_time
      return true if terminating_schedule.occurring_at?(time)
    end
  end
  # No conflict, return false
  false
end

- (Object) duration



39
40
41
# File 'lib/ice_cube/schedule.rb', line 39

def duration
  end_time ? end_time - start_time : 0
end

- (Object) duration=(seconds)



43
44
45
# File 'lib/ice_cube/schedule.rb', line 43

def duration=(seconds)
  @end_time = start_time + seconds
end

- (Object) each_occurrence(&block)

Iterate forever



158
159
160
161
# File 'lib/ice_cube/schedule.rb', line 158

def each_occurrence(&block)
  find_occurrences(start_time, &block)
  self
end

- (Object) exception_rules Also known as: exrules

Get the exception rules



100
101
102
# File 'lib/ice_cube/schedule.rb', line 100

def exception_rules
  @all_exception_rules.reject { |r| r.is_a?(SingleOccurrenceRule) }
end

- (Object) exception_times Also known as: extimes

Get the exception times that are on the schedule



126
127
128
# File 'lib/ice_cube/schedule.rb', line 126

def exception_times
  @all_exception_rules.select { |r| r.is_a?(SingleOccurrenceRule) }.map(&:time)
end

- (Object) first(n = nil)

Get the first n occurrences, or the first occurrence if n is skipped



266
267
268
269
# File 'lib/ice_cube/schedule.rb', line 266

def first(n = nil)
  occurrences = find_occurrences start_time, nil, n || 1
  n.nil? ? occurrences.first : occurrences
end

- (Object) next_occurrence(from = nil)

The next occurrence after now (overridable)



170
171
172
173
# File 'lib/ice_cube/schedule.rb', line 170

def next_occurrence(from = nil)
  from ||= TimeUtil.now(@start_time)
  find_occurrences(from + 1, nil, 1).first
end

- (Object) next_occurrences(num, from = nil)

The next n occurrences after now



164
165
166
167
# File 'lib/ice_cube/schedule.rb', line 164

def next_occurrences(num, from = nil)
  from ||= TimeUtil.now(@start_time)
  find_occurrences(from + 1, nil, num)
end

- (Object) occurrences(closing_time)

Get all of the occurrences from the start_time up until a given Time



147
148
149
# File 'lib/ice_cube/schedule.rb', line 147

def occurrences(closing_time)
  find_occurrences(start_time, closing_time)
end

- (Object) occurrences_between(begin_time, closing_time)

Occurrences between two times



183
184
185
# File 'lib/ice_cube/schedule.rb', line 183

def occurrences_between(begin_time, closing_time)
  find_occurrences(begin_time, closing_time)
end

- (Boolean) occurring_at?(time)

Determine if the schedule is occurring at a given time

Returns:

  • (Boolean)


212
213
214
215
216
217
218
219
# File 'lib/ice_cube/schedule.rb', line 212

def occurring_at?(time)
  if duration > 0
    return false if exception_time?(time)
    occurs_between?(time - duration + 1, time)
  else
    occurs_at?(time)
  end
end

- (Boolean) occurring_between?(opening_time, closing_time)

Return a boolean indicating if an occurrence is occurring between two times, inclusive of its duration. This counts zero-length occurrences that intersect the start of the range and within the range, but not occurrences at the end of the range since none of their duration intersects the range.

Returns:

  • (Boolean)


197
198
199
200
201
# File 'lib/ice_cube/schedule.rb', line 197

def occurring_between?(opening_time, closing_time)
  opening_time = opening_time - duration
  closing_time = closing_time - 1 if duration > 0
  occurs_between?(opening_time, closing_time)
end

- (Boolean) occurs_at?(time)

Determine if the schedule occurs at a specific time

Returns:

  • (Boolean)


261
262
263
# File 'lib/ice_cube/schedule.rb', line 261

def occurs_at?(time)
  occurs_between?(time, time)
end

- (Boolean) occurs_between?(begin_time, closing_time)

Return a boolean indicating if an occurrence falls between two times

Returns:

  • (Boolean)


188
189
190
# File 'lib/ice_cube/schedule.rb', line 188

def occurs_between?(begin_time, closing_time)
  !find_occurrences(begin_time, closing_time, 1).empty?
end

- (Boolean) occurs_on?(date)

Return a boolean indicating if an occurrence falls on a certain date

Returns:

  • (Boolean)


204
205
206
207
208
209
# File 'lib/ice_cube/schedule.rb', line 204

def occurs_on?(date)
  date = TimeUtil.ensure_date date
  begin_time = TimeUtil.beginning_of_date(date, start_time)
  closing_time = TimeUtil.end_of_date(date, start_time)
  occurs_between?(begin_time, closing_time)
end

- (Object) recurrence_rules Also known as: rrules

Get the recurrence rules



94
95
96
# File 'lib/ice_cube/schedule.rb', line 94

def recurrence_rules
  @all_recurrence_rules.reject { |r| r.is_a?(SingleOccurrenceRule) }
end

- (Object) recurrence_times Also known as: rtimes

Get the recurrence times that are on the schedule



106
107
108
# File 'lib/ice_cube/schedule.rb', line 106

def recurrence_times
  @all_recurrence_rules.select { |r| r.is_a?(SingleOccurrenceRule) }.map(&:time)
end

- (Object) remaining_occurrences(from = nil)

The remaining occurrences (same requirements as all_occurrences)



176
177
178
179
180
# File 'lib/ice_cube/schedule.rb', line 176

def remaining_occurrences(from = nil)
  require_terminating_rules
  from ||= TimeUtil.now(@start_time)
  find_occurrences(from)
end

- (Object) remove_exception_rule(rule)

Remove an exception rule



88
89
90
91
# File 'lib/ice_cube/schedule.rb', line 88

def remove_exception_rule(rule)
  res = @all_exception_rules.delete(rule)
  res.nil? ? [] : [res]
end

- (Object) remove_exception_time(time) Also known as: remove_extime

Remove an exception time



134
135
136
137
138
139
140
# File 'lib/ice_cube/schedule.rb', line 134

def remove_exception_time(time)
  found = false
  @all_exception_rules.delete_if do |rule|
    found = true if rule.is_a?(SingleOccurrenceRule) && rule.time == time
  end
  time if found
end

- (Object) remove_recurrence_rule(rule)

Remove a recurrence rule



76
77
78
79
# File 'lib/ice_cube/schedule.rb', line 76

def remove_recurrence_rule(rule)
  res = @all_recurrence_rules.delete(rule)
  res.nil? ? [] : [res]
end

- (Object) remove_recurrence_time(time) Also known as: remove_rtime

Remove a recurrence time



114
115
116
117
118
119
120
# File 'lib/ice_cube/schedule.rb', line 114

def remove_recurrence_time(time)
  found = false
  @all_recurrence_rules.delete_if do |rule|
    found = true if rule.is_a?(SingleOccurrenceRule) && rule.time == time
  end
  time if found
end

- (Boolean) terminating?

Determine if the schedule will end

Returns:

  • (Boolean)

    true if ending, false if repeating forever



352
353
354
# File 'lib/ice_cube/schedule.rb', line 352

def terminating?
  recurrence_rules.empty? || recurrence_rules.all?(&:terminating?)
end

- (Object) to_hash

Convert the schedule to a hash



309
310
311
312
313
314
315
316
317
318
319
320
321
322
# File 'lib/ice_cube/schedule.rb', line 309

def to_hash
  data = {}
  data[:start_date] = TimeUtil.serialize_time(start_time)
  data[:end_time] = TimeUtil.serialize_time(end_time) if end_time
  data[:rrules] = recurrence_rules.map(&:to_hash)
  data[:exrules] = exception_rules.map(&:to_hash)
  data[:rtimes] = recurrence_times.map do |rt|
    TimeUtil.serialize_time(rt)
  end
  data[:extimes] = exception_times.map do |et|
    TimeUtil.serialize_time(et)
  end
  data
end

- (Object) to_ical(force_utc = false)

Serialize this schedule to_ical



283
284
285
286
287
288
289
290
291
292
# File 'lib/ice_cube/schedule.rb', line 283

def to_ical(force_utc = false)
  pieces = []
  pieces << "DTSTART#{IcalBuilder.ical_format(start_time, force_utc)}"
  pieces.concat recurrence_rules.map { |r| "RRULE:#{r.to_ical}" }
  pieces.concat exception_rules.map  { |r| "EXRULE:#{r.to_ical}" }
  pieces.concat recurrence_times_without_start_time.map { |t| "RDATE#{IcalBuilder.ical_format(t, force_utc)}" }
  pieces.concat exception_times.map  { |t| "EXDATE#{IcalBuilder.ical_format(t, force_utc)}" }
  pieces << "DTEND#{IcalBuilder.ical_format(end_time, force_utc)}" if end_time
  pieces.join("\n")
end

- (Object) to_s

String serialization



272
273
274
275
276
277
278
279
280
# File 'lib/ice_cube/schedule.rb', line 272

def to_s
  pieces = []
  rd = recurrence_times_with_start_time - extimes
  pieces.concat rd.sort.map { |t| t.strftime(IceCube.to_s_time_format) }
  pieces.concat rrules.map  { |t| t.to_s }
  pieces.concat exrules.map { |t| "not #{t.to_s}" }
  pieces.concat extimes.sort.map { |t| "not on #{t.strftime(IceCube.to_s_time_format)}" }
  pieces.join(' / ')
end

- (Object) to_yaml(*args)

Convert the schedule to yaml



295
296
297
# File 'lib/ice_cube/schedule.rb', line 295

def to_yaml(*args)
  IceCube::use_psych? ? Psych::dump(to_hash, *args) : YAML::dump(to_hash, *args)
end