1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
# -*- coding: utf-8 -*-
module RiCal
class PropertyValue
# OccurrenceList is used to represent the value of an RDATE or EXDATE property.
#- ©2009 Rick DeNatale, All rights reserved. Refer to the file README.txt for the license
#
class OccurrenceList < Array
attr_accessor :tzid #:nodoc:
class Enumerator # :nodoc:
attr_accessor :default_duration, :occurrence_list
# TODO: the component parameter should always be the parent
def initialize(occurrences, component) # :nodoc:
self.occurrence_list = occurrences
self.default_duration = component.default_duration
@index = 0
end
def bounded?
true
end
def empty?
occurrence_list.empty?
end
def next_occurrence
if @index < occurrence_list.length
result = occurrence_list[@index].occurrence_period(default_duration)
@index += 1
result
else
nil
end
end
end
def initialize(timezone_finder, options={}) # :nodoc:
super
validate_elements
end
def self.convert(timezone_finder, *ruby_objects) # :nodoc:
# ruby_objects = [ruby_objects] unless Array === ruby_objects
source_elements = ruby_objects.inject([]) { |se, element|
if String === element
element.split(",").each {|str| se << str}
else
se << element
end
se
}
new(timezone_finder, :source_elements => source_elements )
end
def values_to_elements(values) # :nodoc:
values.map {|val| val.to_ri_cal_occurrence_list_value(self)}
end
def tzid_from_source_elements # :nodoc:
if @source_elements && String === (first_source = @source_elements.first)
probe = first_source.to_ri_cal_occurrence_list_value rescue nil
unless probe
return @source_elements.shift
end
end
nil
end
def tzid_conflict(element_tzid) # :nodoc:
element_tzid && tzid != element_tzid
end
def validate_elements # :nodoc:
if @source_elements
self.tzid = tzid_from_source_elements
@elements = values_to_elements(@source_elements)
@value = @elements.map {|prop| prop.value}
else
@elements = values_to_elements(@value)
self.tzid = params['TZID']
end
# if the tzid wasn't set by the parameters
self.tzid ||= @elements.map {|element| element.tzid}.find {|id| id}
@elements.each do |element|
raise InvalidPropertyValue.new("Mixed timezones are not allowed in an occurrence list") if tzid_conflict(element.tzid)
element.tzid = tzid
end
end
def has_local_timezone? # :nodoc:
tzid && tzid != 'UTC'
end
def visible_params # :nodoc:
result = params.dup
case @elements.first
when Date
result = {"VALUE" => "DATE"}.merge(params)
when DateTime
result = {"VALUE" => "DATE-TIME"}.merge(params)
when Period
result = {"VALUE" => "PERIOD"}.merge(params)
end
if has_local_timezone?
result['TZID'] = tzid
else
result.delete('TZID')
end
result
end
def value # :nodoc:
@elements.map {|element| element.value}.join(",")
end
# Return an array of the occurrences within the list
def ruby_value
@elements.map {|prop| prop.ruby_value}
end
end
attr_accessor :elements, :source_elements #:nodoc:
private :elements, :elements=, :source_elements=, :source_elements
def for_parent(parent) #:nodoc:
if timezone_finder.nil?
@timezone_finder = parent
self
elsif timezone_finder == parent
self
else
OccurrenceList.new(parent, :value => value)
end
end
# Return an enumerator which can produce the elements of the occurrence list
def enumerator(component) # :nodoc:
OccurrenceList::Enumerator.new(@elements, component)
end
def add_date_times_to(required_timezones) #:nodoc:
if @elements
@elements.each do | occurrence |
occurrence.add_date_times_to(required_timezones)
end
end
end
end
end
|