Class: Icalendar::RRule

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

Overview

This class is not yet fully functional..

Gem versions < 1.1.0.0 used to return a string for the recurrence_rule component, but now it returns this Icalendar::RRule class. ie It’s not backwards compatible!

To get the original RRULE value from a parsed feed, use the ‘orig_value’ property.

Example:

rules = event.recurrence_rules.map{ |rule| rule.orig_value }

Defined Under Namespace

Classes: Weekday

Instance Method Summary collapse

Methods inherited from Base

debug, quiet

Constructor Details

#initialize(name, params, value, parser) ⇒ RRule

Returns a new instance of RRule.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/icalendar/rrule.rb', line 37

def initialize(name, params, value, parser)
  @value = value
  frequency_match = value.match(/FREQ=(SECONDLY|MINUTELY|HOURLY|DAILY|WEEKLY|MONTHLY|YEARLY)/)
  raise Icalendar::InvalidPropertyValue.new("FREQ must be specified for RRULE values") unless frequency_match
  @frequency = frequency_match[1]
  @until = parse_date_val("UNTIL", value)
  @count = parse_int_val("COUNT", value)
  raise Icalendar::InvalidPropertyValue.new("UNTIL and COUNT must not both be specified for RRULE values") if [@until, @count].compact.length > 1
  @interval = parse_int_val("INTERVAL", value)
  @by_list = {:bysecond => parse_int_list("BYSECOND", value)}
  @by_list[:byminute] = parse_int_list("BYMINUTE",value)
  @by_list[:byhour] = parse_int_list("BYHOUR", value)
  @by_list[:byday] = parse_weekday_list("BYDAY", value)
  @by_list[:bymonthday] = parse_int_list("BYMONTHDAY", value)
  @by_list[:byyearday] = parse_int_list("BYYEARDAY", value)
  @by_list[:byweekno] = parse_int_list("BYWEEKNO", value)
  @by_list[:bymonth] = parse_int_list("BYMONTH", value)
  @by_list[:bysetpos] = parse_int_list("BYSETPOS", value)
  @wkst = parse_wkstart(value)
end

Instance Method Details

#occurrences_of_event_starting(event, datetime) ⇒ Object

TODO: Incomplete



123
124
125
126
127
128
129
130
# File 'lib/icalendar/rrule.rb', line 123

def occurrences_of_event_starting(event, datetime)
  initial_start = event.dtstart
  (0...@count).map {|day_offset| 
          occurrence = event.clone
          occurrence.dtstart = initial_start + day_offset
          occurrence.clone
          }
end

#orig_valueObject

Returns the original pre-parsed RRULE value.



59
60
61
# File 'lib/icalendar/rrule.rb', line 59

def orig_value
  @value
end

#parse_date_val(name, string) ⇒ Object



81
82
83
84
# File 'lib/icalendar/rrule.rb', line 81

def parse_date_val(name, string)
  match = string.match(/;#{name}=(.*?)(;|$)/)
  match ? DateTime.parse(match[1]) : nil
end

#parse_int_list(name, string) ⇒ Object



91
92
93
94
95
96
97
98
# File 'lib/icalendar/rrule.rb', line 91

def parse_int_list(name, string)
  match = string.match(/;#{name}=([+-]?.*?)(;|$)/)
  if match
    match[1].split(",").map {|int| int.to_i}
  else
    nil
  end
end

#parse_int_val(name, string) ⇒ Object



86
87
88
89
# File 'lib/icalendar/rrule.rb', line 86

def parse_int_val(name, string)
  match = string.match(/;#{name}=(\d+)(;|$)/)
  match ? match[1].to_i : nil
end

#parse_weekday_list(name, string) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/icalendar/rrule.rb', line 100

def parse_weekday_list(name, string)
  match = string.match(/;#{name}=(.*?)(;|$)/)
  if match
    return_array = match[1].split(",").map do |weekday|
      wd_match = weekday.match(/([+-]?\d*)(SU|MO|TU|WE|TH|FR|SA)/)
      Weekday.new(wd_match[2], wd_match[1])
    end
  else
    nil
  end
  return_array
end

#parse_wkstart(string) ⇒ Object



113
114
115
116
117
118
119
120
# File 'lib/icalendar/rrule.rb', line 113

def parse_wkstart(string)
  match = string.match(/;WKST=(SU|MO|TU|WE|TH|FR|SA)(;|$)/)
  if match
    match[1]
  else
    nil
  end
end

#to_icalObject



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/icalendar/rrule.rb', line 63

def to_ical
  result = ["FREQ=#{@frequency}"]
  result << ";UNTIL=#{@until.to_ical}" if @until
  result << ";COUNT=#{@count}" if @count
  result << ";INTERVAL=#{@interval}" if @interval
  @by_list.each do |key, value|
    if value
      if key == :byday
        result << ";BYDAY=#{value.join ','}"
      else
        result << ";#{key.to_s.upcase}=#{value}"
      end
    end
  end
  result << ";WKST=#{@wkst}" if @wkst
  result.join
end