Class: Icalendar::Component

Inherits:
Base show all
Defined in:
lib/icalendar/component.rb

Overview

The body of the iCalendar object consists of a sequence of calendar properties and one or more calendar components. The calendar properties are attributes that apply to the calendar as a whole. The calendar components are collections of properties that express a particular calendar semantic. For example, the calendar component can specify an Event, a Todo, a Journal entry, Timezone information, or Freebusy time information, or an Alarm.

Direct Known Subclasses

Alarm, Calendar, Event, Freebusy, Journal, Timezone, Todo

Constant Summary collapse

@@multi_properties =
{}
@@multiline_properties =
{}

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Base

debug, quiet

Constructor Details

#initialize(name) ⇒ Component

Returns a new instance of Component.



46
47
48
49
50
51
52
# File 'lib/icalendar/component.rb', line 46

def initialize(name)
  @name = name
  @components = Hash.new([])
  @properties = {}

  @@logger.info("New #{@name[1,@name.size].capitalize}...")
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args) ⇒ Object (private)



413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
# File 'lib/icalendar/component.rb', line 413

def method_missing(method, *args)
  @@logger.debug("Inside method_missing...")
  method_name = method.to_s.downcase

  super unless method_name =~ /x_.*/

  # x-properties are accessed with underscore but stored with a dash so
  # they output correctly and we don't have to special case the
  # output code, which would require checking every property.
  if args.size > 0 # Its a setter
    # Pull off the possible equals
    @properties[method_name[/x_[^=]*/].gsub('x_', 'x-')] = args.first
  else # Or its a getter
    return @properties[method_name.gsub('x_', 'x-')]
  end
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



40
41
42
# File 'lib/icalendar/component.rb', line 40

def name
  @name
end

#propertiesObject

Returns the value of attribute properties.



41
42
43
# File 'lib/icalendar/component.rb', line 41

def properties
  @properties
end

Instance Method Details

#add_component(component) ⇒ Object Also known as: add, add_event, add_todo, add_journal

Add a sub-component to the current component object.



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

def add_component(component)
  key = (component.class.to_s.downcase + 's').gsub('icalendar::', '').to_sym

  unless @components.has_key? key
    @components[key] = []
  end

  @components[key] << component
end

#add_sliced_text(add_to, escaped) ⇒ Object



165
166
167
168
169
# File 'lib/icalendar/component.rb', line 165

def add_sliced_text(add_to,escaped)
  escaped = escaped.split('') # split is unicdoe-aware when `$KCODE = 'u'`
  add_to << escaped.slice!(0,MAX_LINE_LENGTH).join << "\r\n " while escaped.length != 0 # shift(MAX_LINE_LENGTH) does not work with ruby 1.8.6
  add_to.gsub!(/ *$/, '')
end

#custom_property(name, value) ⇒ Object

TODO: Look into the x-property, x-param stuff… This would really only be needed for subclassing to add additional properties to an application using the API.



198
199
200
# File 'lib/icalendar/component.rb', line 198

def custom_property(name, value)
  @properties[name] = value
end

#escape_chars(value) ⇒ Object



159
160
161
162
163
# File 'lib/icalendar/component.rb', line 159

def escape_chars(value)
  v = value.gsub("\\", "\\\\").gsub("\r\n", "\n").gsub("\r", "\n").gsub("\n", "\\n").gsub(",", "\\,").gsub(";", "\\;")
  return v
   # return value
end

#multi_property?(name) ⇒ Boolean

Returns:

  • (Boolean)


202
203
204
# File 'lib/icalendar/component.rb', line 202

def multi_property?(name)
  @@multi_properties.has_key?(name.downcase)
end

#multiline_property?(name) ⇒ Boolean

Returns:

  • (Boolean)


206
207
208
# File 'lib/icalendar/component.rb', line 206

def multiline_property?(name)
  @@multiline_properties.has_key?(name.downcase)
end

#new_uidObject

Used to generate unique component ids



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

def new_uid
  "#{DateTime.now}_#{rand(999999999)}@#{Socket.gethostname}"
end

Print this icalendar component



114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/icalendar/component.rb', line 114

def print_component
  # Begin a new component
  "BEGIN:#{@name.upcase}\r\n" +

  # Then the properties
  print_properties +

  # sub components
  yield +

  # End of this component
  "END:#{@name.upcase}\r\n"
end

Print the parameters for a specific property.



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/icalendar/component.rb', line 172

def print_parameters(value)
  s = ""
  return s unless value.respond_to?(:ical_params) && !value.ical_params.nil?

  value.ical_params.each do |key, val|
    s << ";#{key}"
    val = [ val ] unless val.is_a?(Array)

    # Possible parameter values
    unless val.empty?
      s << "="
      sep = "" # First entry comes after = sign, but then we need commas
      val.each do |pval|
        if pval.respond_to? :to_ical
          s << sep << pval.to_ical
          sep = ","
        end
      end
    end
  end
  s
end


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
156
157
# File 'lib/icalendar/component.rb', line 128

def print_properties(properties = @properties)
  s = ""

  properties.sort.each do |key,val|
    # Take out underscore for property names that conflicted
    # with built-in words.
    if key =~ /ip_.*/
      key = key[3..-1]
    end

    # Property name
    if !multiline_property?(key)
      prelude = "#{key.gsub(/_/, '-').upcase}#{print_parameters val}"

      # Property value
      value = ":#{val.to_ical}"
      value = escape_chars(value) unless %w[geo rrule categories exdate].include?(key)
      add_sliced_text(s, prelude + value)
    else
      prelude = "#{key.gsub(/_/, '-').upcase}"
      val.each do |v|
        params = print_parameters(v)
        value = ":#{v.to_ical}"
        value = escape_chars(value)
        add_sliced_text(s, prelude + params + value)
      end
    end
  end
  s
end

#remove_component(component) ⇒ Object Also known as: remove, remove_event, remove_todo, remove_journal



77
78
79
80
81
82
83
# File 'lib/icalendar/component.rb', line 77

def remove_component(component)
  key = (component.class.to_s.downcase + 's').gsub('icalendar::', '').to_sym

  if @components.has_key? key
    @components[key].delete(component)
  end
end

#respond_to?(method_name) ⇒ Boolean

Returns:

  • (Boolean)


432
433
434
435
436
437
438
# File 'lib/icalendar/component.rb', line 432

def respond_to?(method_name)
  if method_name.to_s.downcase =~ /x_.*/
   true
  else
    super
  end
end

#to_icalObject

Output in the icalendar format



103
104
105
106
107
108
109
110
111
# File 'lib/icalendar/component.rb', line 103

def to_ical
  print_component do
    s = ""
    @components.each do |key, comps|
      comps.each { |component| s << component.to_ical }
    end
    s
  end
end