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

:nodoc:

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:



44
45
46
47
48
49
50
51
52
53
# File 'lib/ri_cal/component.rb', line 44

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:



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

def method_missing(selector, *args, &b) #:nodoc:
  xprop_candidate = selector.to_s
  if (match = /^(x_.+)(=?)$/.match(xprop_candidate))
    x_property_key = match[1].gsub('_','-').upcase
    if match[2] == "="
      args.each do |val|
        add_x_property(x_property_key, val)
      end
    else
      x_properties[x_property_key].map {|property| property.value}
    end
  else
    super
  end
end

Instance Attribute Details

#importedObject

:nodoc:



42
43
44
# File 'lib/ri_cal/component.rb', line 42

def imported
  @imported
end

Class Method Details

.entity_nameObject

:nodoc:



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

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

.from_parser(parser, parent, entity_name) ⇒ Object

:nodoc:



91
92
93
94
95
96
97
98
99
100
# File 'lib/ri_cal/component.rb', line 91

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:



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

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

.parse_string(string) ⇒ Object

:nodoc:



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

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

Instance Method Details

#add_property_date_times_to(required_timezones, property) ⇒ Object

:nodoc:



193
194
195
196
197
198
199
200
201
202
203
# File 'lib/ri_cal/component.rb', line 193

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:



128
129
130
# File 'lib/ri_cal/component.rb', line 128

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

#add_x_property(name, prop, debug = false) ⇒ Object

Add a n extended property



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

def add_x_property(name, prop, debug=false)
  x_properties[name.gsub("_","-").upcase] << prop.to_ri_cal_text_property
end

#alarmsObject

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



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

def alarms
  subcomponents["VALARM"]
end

#daylightObject

:nodoc:



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

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

#default_tzidObject

:nodoc:



55
56
57
58
59
60
61
# File 'lib/ri_cal/component.rb', line 55

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

#entity_nameObject

:nodoc:



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

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



248
249
250
251
252
# File 'lib/ri_cal/component.rb', line 248

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:



205
206
207
208
209
210
# File 'lib/ri_cal/component.rb', line 205

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:



220
221
222
223
224
# File 'lib/ri_cal/component.rb', line 220

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



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

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:



212
213
214
215
216
217
218
# File 'lib/ri_cal/component.rb', line 212

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:



63
64
65
66
67
68
69
70
71
72
73
# File 'lib/ri_cal/component.rb', line 63

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)


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

def imported? #:nodoc:
  imported
end

#initialize_copy(original) ⇒ Object

:nodoc:



181
182
# File 'lib/ri_cal/component.rb', line 181

def initialize_copy(original) #:nodoc:
end

#last_before_local(period_array, time) ⇒ Object

:nodoc:



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

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

#last_before_utc(period_array, time) ⇒ Object

:nodoc:



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

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

#last_period(standard, daylight) ⇒ Object

:nodoc:



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

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:



132
133
134
# File 'lib/ri_cal/component.rb', line 132

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

#process_line(parser, line) ⇒ Object

:nodoc:



136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/ri_cal/component.rb', line 136

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:



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

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:



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

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

#subcomponent_classObject

:nodoc:



87
88
89
# File 'lib/ri_cal/component.rb', line 87

def subcomponent_class #:nodoc:
  {}
end

#subcomponentsObject

:nodoc:



114
115
116
# File 'lib/ri_cal/component.rb', line 114

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

#time_zone_for(ruby_object) ⇒ Object

:nodoc:



83
84
85
# File 'lib/ri_cal/component.rb', line 83

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



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

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

#tz_info_source?Boolean

Returns:

  • (Boolean)


75
76
77
78
79
80
81
# File 'lib/ri_cal/component.rb', line 75

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)


177
178
179
# File 'lib/ri_cal/component.rb', line 177

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)



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

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