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)



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

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



168
169
170
171
172
# File 'lib/icalendar/component.rb', line 168

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.



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

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

#escape_chars(value) ⇒ Object



162
163
164
165
166
# File 'lib/icalendar/component.rb', line 162

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)


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

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

#multiline_property?(name) ⇒ Boolean

Returns:

  • (Boolean)


209
210
211
# File 'lib/icalendar/component.rb', line 209

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.



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

def print_parameters(value)
  s = ""
  return s unless value.respond_to?(:ical_params) and not 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
158
159
160
# File 'lib/icalendar/component.rb', line 128

def print_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
    unless multiline_property?(key)
      prelude = "#{key.gsub(/_/, '-').upcase}" +

      # Possible parameters
      print_parameters(val)

      # Property value
      value = ":#{val.to_ical}"
      value = escape_chars(value) unless %w[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) unless key == "rrule"
        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)


435
436
437
438
439
440
441
# File 'lib/icalendar/component.rb', line 435

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