Class: RiCal::Component

Inherits:
Object show all
Defined in:
lib/ri_cal/component.rb,
lib/ri_cal/component/todo.rb,
lib/ri_cal/component/alarm.rb,
lib/ri_cal/component/event.rb,
lib/ri_cal/component/journal.rb,
lib/ri_cal/component/calendar.rb,
lib/ri_cal/component/freebusy.rb,
lib/ri_cal/component/timezone.rb,
lib/ri_cal/component/non_standard.rb,
lib/ri_cal/component/timezone/daylight_period.rb,
lib/ri_cal/component/timezone/standard_period.rb,
lib/ri_cal/component/timezone/timezone_period.rb

Overview

  • ©2009 Rick DeNatale, All rights reserved. Refer to the file README.txt for the license

Defined Under Namespace

Classes: Alarm, Calendar, ComponentBuilder, Event, Freebusy, Journal, NonStandard, TZInfoTimezone, Timezone, Todo

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent = nil, entity_name = nil, &init_block) ⇒ Component

:nodoc:



37
38
39
40
41
42
43
44
45
46
# File 'lib/ri_cal/component.rb', line 37

def initialize(parent=nil, entity_name = nil, &init_block) #:nodoc:
  @parent = parent
  if block_given?
    if init_block.arity == 1
      init_block.call(ComponentBuilder.new(self))
    else
      ComponentBuilder.new(self).instance_eval(&init_block)
    end
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(selector, *args, &b) ⇒ Object

:nodoc:



153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/ri_cal/component.rb', line 153

def method_missing(selector, *args, &b) #:nodoc:
  xprop_candidate = selector.to_s
  if (match = /^x_(.+)(=?)$/.match(xprop_candidate))
    if match[2] == "="
      add_x_property("x_#{match[1]}", *args)
    else
      x_properties[xprop_candidate]
    end
  else
    super
  end
end

Instance Attribute Details

#importedObject

:nodoc:



35
36
37
# File 'lib/ri_cal/component.rb', line 35

def imported
  @imported
end

Class Method Details

.entity_nameObject

:nodoc:



152
153
154
# File 'lib/ri_cal/component/timezone.rb', line 152

def self.entity_name #:nodoc:
  "VTIMEZONE"
end

.from_parser(parser, parent, entity_name) ⇒ Object

:nodoc:



84
85
86
87
88
89
90
91
92
93
# File 'lib/ri_cal/component.rb', line 84

def self.from_parser(parser, parent, entity_name) #:nodoc:
  entity = self.new(parent, entity_name)
  entity.imported = true
  line = parser.next_separated_line
  while parser.still_in(entity_name, line)
    entity.process_line(parser, line)
    line = parser.next_separated_line
  end
  entity
end

.parse(io) ⇒ Object

:nodoc:



95
96
97
# File 'lib/ri_cal/component.rb', line 95

def self.parse(io) #:nodoc:
  Parser.new(io).parse
end

.parse_string(string) ⇒ Object

:nodoc:



103
104
105
# File 'lib/ri_cal/component.rb', line 103

def self.parse_string(string) #:nodoc:
  parse(StringIO.new(string))
end

Instance Method Details

#add_property_date_times_to(required_timezones, property) ⇒ Object

:nodoc:



183
184
185
186
187
188
189
190
191
192
193
# File 'lib/ri_cal/component.rb', line 183

def add_property_date_times_to(required_timezones, property) #:nodoc:
  if property
    if Array === property
      property.each do |prop|
        prop.add_date_times_to(required_timezones)
      end
    else
      property.add_date_times_to(required_timezones)
    end
  end
end

#add_subcomponent(component) ⇒ Object

:nodoc:



121
122
123
# File 'lib/ri_cal/component.rb', line 121

def add_subcomponent(component) #:nodoc:
  subcomponents[component.entity_name] << component
end

#add_x_property(name, prop) ⇒ Object

Add a n extended property



149
150
151
# File 'lib/ri_cal/component.rb', line 149

def add_x_property(name, prop)
  x_properties[name] << prop
end

#alarmsObject

return an array of Alarm components within this component :nodoc: Alarms may be contained within Events, and Todos



117
118
119
# File 'lib/ri_cal/component.rb', line 117

def alarms
  subcomponents["VALARM"]
end

#daylightObject

:nodoc:



160
161
162
# File 'lib/ri_cal/component/timezone.rb', line 160

def daylight #:nodoc:
  @subcomponents["DAYLIGHT"]
end

#default_tzidObject

:nodoc:



48
49
50
51
52
53
54
# File 'lib/ri_cal/component.rb', line 48

def default_tzid #:nodoc:
  if @parent
    @parent.default_tzid
  else
    PropertyValue::DateTime.default_tzid
  end
end

#entity_nameObject

:nodoc:



111
112
113
# File 'lib/ri_cal/component.rb', line 111

def entity_name #:nodoc:
  self.class.entity_name
end

#export(stream = nil) ⇒ Object

Export this single component as an iCalendar component containing only this component and any required additional components (i.e. VTIMEZONES referenced from this component) if stream is nil (the default) then this method will return a string, otherwise stream should be an IO to which the iCalendar file contents will be written



238
239
240
241
242
# File 'lib/ri_cal/component.rb', line 238

def export(stream=nil)
  wrapper_calendar = Calendar.new
  wrapper_calendar.add_subcomponent(self)
  wrapper_calendar.export(stream)
end

#export_prop_to(export_stream, name, prop) ⇒ Object

:nodoc:



195
196
197
198
199
200
# File 'lib/ri_cal/component.rb', line 195

def export_prop_to(export_stream, name, prop) #:nodoc:
  if prop
    string = prop_string(name, prop)
    export_stream.puts(string) if string
  end
end

#export_subcomponent_to(export_stream, subcomponent) ⇒ Object

:nodoc:



210
211
212
213
214
# File 'lib/ri_cal/component.rb', line 210

def export_subcomponent_to(export_stream, subcomponent) #:nodoc:
  subcomponent.each do |component|
    component.export_to(export_stream)
  end
end

#export_to(export_stream) ⇒ Object

Export this component to an export stream



224
225
226
227
228
229
230
231
232
# File 'lib/ri_cal/component.rb', line 224

def export_to(export_stream)
  export_stream.puts("BEGIN:#{entity_name}")
  export_properties_to(export_stream)
  export_x_properties_to(export_stream)
  subcomponents.values.each do |sub|
    export_subcomponent_to(export_stream, sub)
  end
  export_stream.puts("END:#{entity_name}")
end

#export_x_properties_to(export_stream) ⇒ Object

:nodoc:



202
203
204
205
206
207
208
# File 'lib/ri_cal/component.rb', line 202

def export_x_properties_to(export_stream) #:nodoc:
  x_properties.each do |name, props|
    props.each do | prop |
      export_stream.puts("#{name}:#{prop}")
    end
  end
end

#find_timezone(identifier) ⇒ Object

:nodoc:



56
57
58
59
60
61
62
63
64
65
66
# File 'lib/ri_cal/component.rb', line 56

def find_timezone(identifier) #:nodoc:
  if @parent
    @parent.find_timezone(identifier)
  else
    begin
      Calendar::TZInfoWrapper.new(TZInfo::Timezone.get(identifier), self)
    rescue ::TZInfo::InvalidTimezoneIdentifier => ex
      raise RiCal::InvalidTimezoneIdentifier.invalid_tzinfo_identifier(identifier)
    end
  end
end

#imported?Boolean

:nodoc:

Returns:

  • (Boolean)


99
100
101
# File 'lib/ri_cal/component.rb', line 99

def imported? #:nodoc:
  imported
end

#initialize_copy(original) ⇒ Object

:nodoc:



171
172
# File 'lib/ri_cal/component.rb', line 171

def initialize_copy(original) #:nodoc:
end

#last_before_local(period_array, time) ⇒ Object

:nodoc:



184
185
186
187
188
189
190
# File 'lib/ri_cal/component/timezone.rb', line 184

def last_before_local(period_array, time) #:nodoc:
  candidates = period_array.map {|period|
    period.last_before_local(time)
  }
  result = candidates.max {|a, b| a.dtstart_property <=> b.dtstart_property}
  result
end

#last_before_utc(period_array, time) ⇒ Object

:nodoc:



176
177
178
179
180
181
182
# File 'lib/ri_cal/component/timezone.rb', line 176

def last_before_utc(period_array, time) #:nodoc:
  candidates = period_array.map {|period|
    period.last_before_utc(time)
  }
  result = candidates.max {|a, b| a.dtstart_property <=> b.dtstart_property}
  result
end

#last_period(standard, daylight) ⇒ Object

:nodoc:



164
165
166
167
168
169
170
171
172
173
174
# File 'lib/ri_cal/component/timezone.rb', line 164

def last_period(standard, daylight) #:nodoc:
  if standard
    if daylight
      standard.dtstart > daylight.dtstart ? standard : daylight
    else
      standard
    end
  else
    daylight
  end
end

#parse_subcomponent(parser, line) ⇒ Object

:nodoc:



125
126
127
# File 'lib/ri_cal/component.rb', line 125

def parse_subcomponent(parser, line) #:nodoc:
  subcomponents[line[:value]] << parser.parse_one(line, self)
end

#process_line(parser, line) ⇒ Object

:nodoc:



129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/ri_cal/component.rb', line 129

def process_line(parser, line) #:nodoc:
  if line[:name] == "BEGIN"
    parse_subcomponent(parser, line)
  else
    setter = self.class.property_parser[line[:name]]
    if setter
      send(setter, line)
    else
      self.add_x_property(line[:name], PropertyValue::Text.new(self, line))
    end
  end
end

#prop_string(prop_name, *properties) ⇒ Object

:nodoc:



174
175
176
177
178
179
180
181
# File 'lib/ri_cal/component.rb', line 174

def prop_string(prop_name, *properties) #:nodoc:
  properties = properties.flatten.compact
  if properties && !properties.empty?
    properties.map {|prop| "#{prop_name}#{prop.to_s}"}.join("\n")
  else
    nil
  end
end

#standardObject

:nodoc:



156
157
158
# File 'lib/ri_cal/component/timezone.rb', line 156

def standard #:nodoc:
  @subcomponents["STANDARD"]
end

#subcomponent_classObject

:nodoc:



80
81
82
# File 'lib/ri_cal/component.rb', line 80

def subcomponent_class #:nodoc:
  {}
end

#subcomponentsObject

:nodoc:



107
108
109
# File 'lib/ri_cal/component.rb', line 107

def subcomponents #:nodoc:
  @subcomponents ||= Hash.new {|h, k| h[k] = []}
end

#time_zone_for(ruby_object) ⇒ Object

:nodoc:



76
77
78
# File 'lib/ri_cal/component.rb', line 76

def time_zone_for(ruby_object) #:nodoc:
  @parent.time_zone_for(ruby_object) #:nodoc:
end

#to_sObject

return a string containing the rfc2445 format of the component



217
218
219
220
221
# File 'lib/ri_cal/component.rb', line 217

def to_s
  io = StringIO.new
  export_to(io)
  io.string
end

#tz_info_source?Boolean

Returns:

  • (Boolean)


68
69
70
71
72
73
74
# File 'lib/ri_cal/component.rb', line 68

def tz_info_source?
  if @parent
    @parent.tz_info_source?
  else
    true
  end
end

#valid?Boolean

Predicate to determine if the component is valid according to RFC 2445

Returns:

  • (Boolean)


167
168
169
# File 'lib/ri_cal/component.rb', line 167

def valid?
  !mutual_exclusion_violation
end

#x_propertiesObject

return a hash of any extended properties, (i.e. those with a property name starting with “X-” representing an extension to the RFC 2445 specification)



144
145
146
# File 'lib/ri_cal/component.rb', line 144

def x_properties
  @x_properties ||= Hash.new {|h,k| h[k] = []}
end