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/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, TZInfoTimezone, Timezone, Todo

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

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

:nodoc:



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

def initialize(parent=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



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

def method_missing(selector, *args, &b)
  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:



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

def imported
  @imported
end

Class Method Details

.entity_nameObject

:nodoc:



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

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

.from_parser(parser, parent) ⇒ Object

:nodoc:



61
62
63
64
65
66
67
68
69
70
# File 'lib/ri_cal/component.rb', line 61

def self.from_parser(parser, parent) #:nodoc:
  entity = self.new(parent)
  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:



72
73
74
# File 'lib/ri_cal/component.rb', line 72

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

.parse_string(string) ⇒ Object

:nodoc:



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

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

Instance Method Details

#add_property_date_times_to(required_timezones, property) ⇒ Object

:nodoc:



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

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:



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

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

#add_x_property(name, prop) ⇒ Object

Add a n extended property



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

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



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

def alarms
  subcomponents["VALARM"]
end

#daylightObject

:nodoc:



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

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

#entity_nameObject

:nodoc:



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

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



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

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:



172
173
174
175
176
177
# File 'lib/ri_cal/component.rb', line 172

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:



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

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



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

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

#export_x_properties_to(export_stream) ⇒ Object

:nodoc:



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

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

#find_timezone(identifier) ⇒ Object

:nodoc:



49
50
51
# File 'lib/ri_cal/component.rb', line 49

def find_timezone(identifier) #:nodoc:
  @parent.find_timezone(identifier)
end

#imported?Boolean

:nodoc:

Returns:

  • (Boolean)


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

def imported? #:nodoc:
  imported
end

#initialize_copy(original) ⇒ Object

:nodoc:



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

def initialize_copy(original) #:nodoc:
end

#last_before_local(period_array, time) ⇒ Object

:nodoc:



180
181
182
183
184
185
186
# File 'lib/ri_cal/component/timezone.rb', line 180

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:



172
173
174
175
176
177
178
# File 'lib/ri_cal/component/timezone.rb', line 172

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:



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

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:



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

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

#process_line(parser, line) ⇒ Object

:nodoc:



106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/ri_cal/component.rb', line 106

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:



151
152
153
154
155
156
157
158
# File 'lib/ri_cal/component.rb', line 151

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:



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

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

#subcomponent_classObject

:nodoc:



57
58
59
# File 'lib/ri_cal/component.rb', line 57

def subcomponent_class #:nodoc:
  {}
end

#subcomponentsObject

:nodoc:



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

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

#time_zone_for(ruby_object) ⇒ Object



53
54
55
# File 'lib/ri_cal/component.rb', line 53

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

#to_sObject

return a string containing the rfc2445 format of the component



192
193
194
195
196
# File 'lib/ri_cal/component.rb', line 192

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

#valid?Boolean

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

Returns:

  • (Boolean)


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

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)



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

def x_properties
  @x_properties ||= {}
end