rubyredrick-ri_cal 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. data/History.txt +3 -0
  2. data/Manifest.txt +122 -0
  3. data/README.txt +271 -0
  4. data/Rakefile +31 -0
  5. data/bin/ri_cal +8 -0
  6. data/component_attributes/alarm.yml +10 -0
  7. data/component_attributes/calendar.yml +4 -0
  8. data/component_attributes/component_property_defs.yml +180 -0
  9. data/component_attributes/event.yml +45 -0
  10. data/component_attributes/freebusy.yml +16 -0
  11. data/component_attributes/journal.yml +35 -0
  12. data/component_attributes/timezone.yml +3 -0
  13. data/component_attributes/timezone_period.yml +11 -0
  14. data/component_attributes/todo.yml +46 -0
  15. data/copyrights.txt +2 -0
  16. data/docs/draft-ietf-calsify-2446bis-08.txt +7280 -0
  17. data/docs/draft-ietf-calsify-rfc2445bis-09.txt +10416 -0
  18. data/docs/incrementers.txt +7 -0
  19. data/docs/rfc2445.pdf +0 -0
  20. data/lib/ri_cal/component/alarm.rb +22 -0
  21. data/lib/ri_cal/component/calendar.rb +199 -0
  22. data/lib/ri_cal/component/event.rb +30 -0
  23. data/lib/ri_cal/component/freebusy.rb +19 -0
  24. data/lib/ri_cal/component/journal.rb +22 -0
  25. data/lib/ri_cal/component/t_z_info_timezone.rb +124 -0
  26. data/lib/ri_cal/component/timezone/daylight_period.rb +26 -0
  27. data/lib/ri_cal/component/timezone/standard_period.rb +24 -0
  28. data/lib/ri_cal/component/timezone/timezone_period.rb +54 -0
  29. data/lib/ri_cal/component/timezone.rb +193 -0
  30. data/lib/ri_cal/component/todo.rb +26 -0
  31. data/lib/ri_cal/component.rb +224 -0
  32. data/lib/ri_cal/core_extensions/array/conversions.rb +15 -0
  33. data/lib/ri_cal/core_extensions/array.rb +7 -0
  34. data/lib/ri_cal/core_extensions/date/conversions.rb +27 -0
  35. data/lib/ri_cal/core_extensions/date.rb +13 -0
  36. data/lib/ri_cal/core_extensions/date_time/conversions.rb +27 -0
  37. data/lib/ri_cal/core_extensions/date_time.rb +13 -0
  38. data/lib/ri_cal/core_extensions/object/conversions.rb +20 -0
  39. data/lib/ri_cal/core_extensions/object.rb +8 -0
  40. data/lib/ri_cal/core_extensions/string/conversions.rb +32 -0
  41. data/lib/ri_cal/core_extensions/string.rb +8 -0
  42. data/lib/ri_cal/core_extensions/time/calculations.rb +153 -0
  43. data/lib/ri_cal/core_extensions/time/conversions.rb +27 -0
  44. data/lib/ri_cal/core_extensions/time/week_day_predicates.rb +88 -0
  45. data/lib/ri_cal/core_extensions/time.rb +11 -0
  46. data/lib/ri_cal/core_extensions.rb +6 -0
  47. data/lib/ri_cal/invalid_timezone_identifer.rb +20 -0
  48. data/lib/ri_cal/occurrence_enumerator.rb +172 -0
  49. data/lib/ri_cal/parser.rb +138 -0
  50. data/lib/ri_cal/properties/alarm.rb +390 -0
  51. data/lib/ri_cal/properties/calendar.rb +164 -0
  52. data/lib/ri_cal/properties/event.rb +1526 -0
  53. data/lib/ri_cal/properties/freebusy.rb +594 -0
  54. data/lib/ri_cal/properties/journal.rb +1240 -0
  55. data/lib/ri_cal/properties/timezone.rb +151 -0
  56. data/lib/ri_cal/properties/timezone_period.rb +416 -0
  57. data/lib/ri_cal/properties/todo.rb +1562 -0
  58. data/lib/ri_cal/property_value/array.rb +19 -0
  59. data/lib/ri_cal/property_value/cal_address.rb +12 -0
  60. data/lib/ri_cal/property_value/date.rb +119 -0
  61. data/lib/ri_cal/property_value/date_time/additive_methods.rb +43 -0
  62. data/lib/ri_cal/property_value/date_time/time_machine.rb +180 -0
  63. data/lib/ri_cal/property_value/date_time/timezone_support.rb +65 -0
  64. data/lib/ri_cal/property_value/date_time.rb +324 -0
  65. data/lib/ri_cal/property_value/duration.rb +106 -0
  66. data/lib/ri_cal/property_value/geo.rb +12 -0
  67. data/lib/ri_cal/property_value/integer.rb +13 -0
  68. data/lib/ri_cal/property_value/occurrence_list.rb +82 -0
  69. data/lib/ri_cal/property_value/period.rb +63 -0
  70. data/lib/ri_cal/property_value/recurrence_rule/enumeration_support_methods.rb +98 -0
  71. data/lib/ri_cal/property_value/recurrence_rule/enumerator.rb +77 -0
  72. data/lib/ri_cal/property_value/recurrence_rule/initialization_methods.rb +149 -0
  73. data/lib/ri_cal/property_value/recurrence_rule/negative_setpos_enumerator.rb +54 -0
  74. data/lib/ri_cal/property_value/recurrence_rule/numbered_span.rb +32 -0
  75. data/lib/ri_cal/property_value/recurrence_rule/occurence_incrementer.rb +794 -0
  76. data/lib/ri_cal/property_value/recurrence_rule/recurring_day.rb +132 -0
  77. data/lib/ri_cal/property_value/recurrence_rule/recurring_month_day.rb +61 -0
  78. data/lib/ri_cal/property_value/recurrence_rule/recurring_numbered_week.rb +34 -0
  79. data/lib/ri_cal/property_value/recurrence_rule/recurring_year_day.rb +50 -0
  80. data/lib/ri_cal/property_value/recurrence_rule/validations.rb +126 -0
  81. data/lib/ri_cal/property_value/recurrence_rule.rb +146 -0
  82. data/lib/ri_cal/property_value/text.rb +41 -0
  83. data/lib/ri_cal/property_value/uri.rb +12 -0
  84. data/lib/ri_cal/property_value/utc_offset.rb +34 -0
  85. data/lib/ri_cal/property_value.rb +110 -0
  86. data/lib/ri_cal/required_timezones.rb +56 -0
  87. data/lib/ri_cal/time_with_floating_timezone.rb +59 -0
  88. data/lib/ri_cal.rb +134 -0
  89. data/ri_cal.gemspec +47 -0
  90. data/sample_ical_files/from_ical_dot_app/test1.ics +38 -0
  91. data/script/console +10 -0
  92. data/script/destroy +14 -0
  93. data/script/generate +14 -0
  94. data/script/txt2html +71 -0
  95. data/spec/ri_cal/component/alarm_spec.rb +13 -0
  96. data/spec/ri_cal/component/calendar_spec.rb +55 -0
  97. data/spec/ri_cal/component/event_spec.rb +157 -0
  98. data/spec/ri_cal/component/freebusy_spec.rb +13 -0
  99. data/spec/ri_cal/component/journal_spec.rb +13 -0
  100. data/spec/ri_cal/component/t_z_info_timezone_spec.rb +37 -0
  101. data/spec/ri_cal/component/timezone_spec.rb +155 -0
  102. data/spec/ri_cal/component/todo_spec.rb +61 -0
  103. data/spec/ri_cal/component_spec.rb +212 -0
  104. data/spec/ri_cal/core_extensions/time/calculations_spec.rb +189 -0
  105. data/spec/ri_cal/core_extensions/time/week_day_predicates_spec.rb +46 -0
  106. data/spec/ri_cal/occurrence_enumerator_spec.rb +218 -0
  107. data/spec/ri_cal/parser_spec.rb +304 -0
  108. data/spec/ri_cal/property_value/date_spec.rb +22 -0
  109. data/spec/ri_cal/property_value/date_time_spec.rb +448 -0
  110. data/spec/ri_cal/property_value/duration_spec.rb +80 -0
  111. data/spec/ri_cal/property_value/period_spec.rb +50 -0
  112. data/spec/ri_cal/property_value/recurrence_rule/recurring_year_day_spec.rb +22 -0
  113. data/spec/ri_cal/property_value/recurrence_rule_spec.rb +1815 -0
  114. data/spec/ri_cal/property_value/text_spec.rb +14 -0
  115. data/spec/ri_cal/property_value/utc_offset_spec.rb +49 -0
  116. data/spec/ri_cal/property_value_spec.rb +111 -0
  117. data/spec/ri_cal/required_timezones_spec.rb +68 -0
  118. data/spec/ri_cal_spec.rb +54 -0
  119. data/spec/spec.opts +4 -0
  120. data/spec/spec_helper.rb +24 -0
  121. data/tasks/ri_cal.rake +403 -0
  122. data/tasks/spec.rake +35 -0
  123. metadata +201 -0
data/History.txt ADDED
@@ -0,0 +1,3 @@
1
+ == 0.0.1 / 2009-4/26
2
+
3
+ * Initial public release
data/Manifest.txt ADDED
@@ -0,0 +1,122 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/ri_cal
6
+ component_attributes/alarm.yml
7
+ component_attributes/calendar.yml
8
+ component_attributes/component_property_defs.yml
9
+ component_attributes/event.yml
10
+ component_attributes/freebusy.yml
11
+ component_attributes/journal.yml
12
+ component_attributes/timezone.yml
13
+ component_attributes/timezone_period.yml
14
+ component_attributes/todo.yml
15
+ copyrights.txt
16
+ docs/draft-ietf-calsify-2446bis-08.txt
17
+ docs/draft-ietf-calsify-rfc2445bis-09.txt
18
+ docs/incrementers.txt
19
+ docs/rfc2445.pdf
20
+ lib/ri_cal.rb
21
+ lib/ri_cal/component.rb
22
+ lib/ri_cal/component/alarm.rb
23
+ lib/ri_cal/component/calendar.rb
24
+ lib/ri_cal/component/event.rb
25
+ lib/ri_cal/component/freebusy.rb
26
+ lib/ri_cal/component/journal.rb
27
+ lib/ri_cal/component/t_z_info_timezone.rb
28
+ lib/ri_cal/component/timezone.rb
29
+ lib/ri_cal/component/timezone/daylight_period.rb
30
+ lib/ri_cal/component/timezone/standard_period.rb
31
+ lib/ri_cal/component/timezone/timezone_period.rb
32
+ lib/ri_cal/component/todo.rb
33
+ lib/ri_cal/core_extensions.rb
34
+ lib/ri_cal/core_extensions/array.rb
35
+ lib/ri_cal/core_extensions/array/conversions.rb
36
+ lib/ri_cal/core_extensions/date.rb
37
+ lib/ri_cal/core_extensions/date/conversions.rb
38
+ lib/ri_cal/core_extensions/date_time.rb
39
+ lib/ri_cal/core_extensions/date_time/conversions.rb
40
+ lib/ri_cal/core_extensions/object.rb
41
+ lib/ri_cal/core_extensions/object/conversions.rb
42
+ lib/ri_cal/core_extensions/string.rb
43
+ lib/ri_cal/core_extensions/string/conversions.rb
44
+ lib/ri_cal/core_extensions/time.rb
45
+ lib/ri_cal/core_extensions/time/calculations.rb
46
+ lib/ri_cal/core_extensions/time/conversions.rb
47
+ lib/ri_cal/core_extensions/time/week_day_predicates.rb
48
+ lib/ri_cal/invalid_timezone_identifer.rb
49
+ lib/ri_cal/occurrence_enumerator.rb
50
+ lib/ri_cal/parser.rb
51
+ lib/ri_cal/properties/alarm.rb
52
+ lib/ri_cal/properties/calendar.rb
53
+ lib/ri_cal/properties/event.rb
54
+ lib/ri_cal/properties/freebusy.rb
55
+ lib/ri_cal/properties/journal.rb
56
+ lib/ri_cal/properties/timezone.rb
57
+ lib/ri_cal/properties/timezone_period.rb
58
+ lib/ri_cal/properties/todo.rb
59
+ lib/ri_cal/property_value.rb
60
+ lib/ri_cal/property_value/array.rb
61
+ lib/ri_cal/property_value/cal_address.rb
62
+ lib/ri_cal/property_value/date.rb
63
+ lib/ri_cal/property_value/date_time.rb
64
+ lib/ri_cal/property_value/date_time/additive_methods.rb
65
+ lib/ri_cal/property_value/date_time/time_machine.rb
66
+ lib/ri_cal/property_value/date_time/timezone_support.rb
67
+ lib/ri_cal/property_value/duration.rb
68
+ lib/ri_cal/property_value/geo.rb
69
+ lib/ri_cal/property_value/integer.rb
70
+ lib/ri_cal/property_value/occurrence_list.rb
71
+ lib/ri_cal/property_value/period.rb
72
+ lib/ri_cal/property_value/recurrence_rule.rb
73
+ lib/ri_cal/property_value/recurrence_rule/enumeration_support_methods.rb
74
+ lib/ri_cal/property_value/recurrence_rule/enumerator.rb
75
+ lib/ri_cal/property_value/recurrence_rule/initialization_methods.rb
76
+ lib/ri_cal/property_value/recurrence_rule/negative_setpos_enumerator.rb
77
+ lib/ri_cal/property_value/recurrence_rule/numbered_span.rb
78
+ lib/ri_cal/property_value/recurrence_rule/occurence_incrementer.rb
79
+ lib/ri_cal/property_value/recurrence_rule/recurring_day.rb
80
+ lib/ri_cal/property_value/recurrence_rule/recurring_month_day.rb
81
+ lib/ri_cal/property_value/recurrence_rule/recurring_numbered_week.rb
82
+ lib/ri_cal/property_value/recurrence_rule/recurring_year_day.rb
83
+ lib/ri_cal/property_value/recurrence_rule/validations.rb
84
+ lib/ri_cal/property_value/text.rb
85
+ lib/ri_cal/property_value/uri.rb
86
+ lib/ri_cal/property_value/utc_offset.rb
87
+ lib/ri_cal/required_timezones.rb
88
+ lib/ri_cal/time_with_floating_timezone.rb
89
+ ri_cal.gemspec
90
+ sample_ical_files/from_ical_dot_app/test1.ics
91
+ script/console
92
+ script/destroy
93
+ script/generate
94
+ script/txt2html
95
+ spec/ri_cal/component/alarm_spec.rb
96
+ spec/ri_cal/component/calendar_spec.rb
97
+ spec/ri_cal/component/event_spec.rb
98
+ spec/ri_cal/component/freebusy_spec.rb
99
+ spec/ri_cal/component/journal_spec.rb
100
+ spec/ri_cal/component/t_z_info_timezone_spec.rb
101
+ spec/ri_cal/component/timezone_spec.rb
102
+ spec/ri_cal/component/todo_spec.rb
103
+ spec/ri_cal/component_spec.rb
104
+ spec/ri_cal/core_extensions/time/calculations_spec.rb
105
+ spec/ri_cal/core_extensions/time/week_day_predicates_spec.rb
106
+ spec/ri_cal/occurrence_enumerator_spec.rb
107
+ spec/ri_cal/parser_spec.rb
108
+ spec/ri_cal/property_value/date_spec.rb
109
+ spec/ri_cal/property_value/date_time_spec.rb
110
+ spec/ri_cal/property_value/duration_spec.rb
111
+ spec/ri_cal/property_value/period_spec.rb
112
+ spec/ri_cal/property_value/recurrence_rule/recurring_year_day_spec.rb
113
+ spec/ri_cal/property_value/recurrence_rule_spec.rb
114
+ spec/ri_cal/property_value/text_spec.rb
115
+ spec/ri_cal/property_value/utc_offset_spec.rb
116
+ spec/ri_cal/property_value_spec.rb
117
+ spec/ri_cal/required_timezones_spec.rb
118
+ spec/ri_cal_spec.rb
119
+ spec/spec.opts
120
+ spec/spec_helper.rb
121
+ tasks/ri_cal.rake
122
+ tasks/spec.rake
data/README.txt ADDED
@@ -0,0 +1,271 @@
1
+ == RI_CAL -- a new implementation of RFC2445 in Ruby
2
+ http://rical.rubyforge.org/
3
+
4
+ by Rick DeNatale
5
+ == DESCRIPTION:
6
+
7
+ This is an UNOFFICIAL version. The public official version will be released on RubyForge. Github will be used
8
+ for interim versions. USE THIS VERSION AT YOUR OWN RISK.
9
+
10
+ A new Ruby implementation of RFC2445 iCalendar.
11
+
12
+ The existing Ruby iCalendar libraries (e.g. icalendar, vpim) provide for parsing and generating icalendar files,
13
+ but do not support important things like enumerating occurrences of repeating events.
14
+
15
+ This is a clean-slate implementation of RFC2445.
16
+
17
+ == FEATURES/PROBLEMS:
18
+
19
+ * All examples of recurring events in RFC 2445 are handled. RSpec examples are provided for them.
20
+
21
+ == SYNOPSIS:
22
+
23
+ === Components and properties
24
+
25
+ An iCalendar calendar comprises subcomponents like Events, Timezones and Todos. Each component may have
26
+ properties, for example an event has a dtstart property which defines the time (and date) on which the event
27
+ starts.
28
+
29
+ RiCal components will provide reasonable ruby objects as the values of these properties, and allow the properties
30
+ to be set to ruby objects which are reasonable for the particular property. For example time properties like dtstart
31
+ can be set to a ruby Time, DateTime or Date object, and will return a DateTime or Date object when queried.
32
+
33
+ The methods for accessing the properties of each type of component are defined in a module with the same name
34
+ as the component class in the RiCal::properties module. For example the property accessing methods for
35
+ RiCal::Component::Event are defined in RiCal::Properties::Event
36
+
37
+ === Creating Calendars and Calendar Components
38
+
39
+ RiCal provides a builder DSL for creating calendars and calendar components. An example
40
+
41
+ RiCal.Calendar do
42
+ event do
43
+ description "MA-6 First US Manned Spaceflight"
44
+ dtstart DateTime.parse("2/20/1962 14:47:39")
45
+ dtend DateTime.parse("2/20/1962 19:43:02")
46
+ location "Cape Canaveral"
47
+ add_attendee "john.glenn@nasa.gov"
48
+ alarm do
49
+ description "Segment 51"
50
+ end
51
+ end
52
+ end
53
+
54
+ This style is for compatibility with the iCalendar and vpim to ease migration. The downside is that the block is evaluated
55
+ in the context of a different object which cause surprising if the block contains direct instance variable references or
56
+ implicit references to self. Note that, in this style, one must use 'declarative' method calls like dtstart to set values
57
+ rather than more natural attribute writer methods, like dtstart=
58
+
59
+ Alternatively you can pass a block with a single argument, in this case the component being built will be passed as that argument
60
+
61
+ RiCal.Calendar do |cal|
62
+ cal.event do |event|
63
+ event.description = "MA-6 First US Manned Spaceflight"
64
+ event.dtstart = DateTime.parse("2/20/1962 14:47:39")
65
+ event.dtend = DateTime.parse("2/20/1962 19:43:02")
66
+ event.location = "Cape Canaveral"
67
+ event.add_attendee "john.glenn@nasa.gov"
68
+ event.alarm do
69
+ description "Segment 51"
70
+ end
71
+ end
72
+ end
73
+
74
+ As the example shows, the two styles can be mixed, the inner block which builds the alarm uses the first style.
75
+
76
+ The blocks are evaluated in the context of an object which builds the calendar or calendar component. method names
77
+ starting with add_ or remove_ are sent to the component, method names which correspond to a property value setter of
78
+ the object being built will cause that setter to be sent to the component with the provided value.
79
+
80
+ A method corresponding to the name of one of the components sub component will create the sub component and
81
+ evaluate the block in the context of the new subcomponent.
82
+
83
+ === Times, Time zones, and Floating Times
84
+
85
+ RFC2445 describes three different kinds of DATE-TIME values with respect to time zones:
86
+
87
+ 1. date-times with a local time. These have no actual time zone, instead they are to be interpreted in the local time zone of the viewer. These floating times are used for things like the New Years celebration which is observed at local midnight whether you happen to be in Paris, London, or New York.
88
+
89
+ 2. date-times with UTC time. An application would either display these with an indication of the time zone, or convert them to the viewer's time zone, perhaps depending on user settings.
90
+
91
+ 3. date-times with a specified time zone.
92
+
93
+ RiCal can be given ruby Time, DateTime, or Date objects for the value of properties requiring an
94
+ iCalendar DATE-TIME value. It can also be given a two element array where the first element is a Time or DateTime,
95
+ and the second is a string representation of the time zone identifier.
96
+
97
+ Note that a date only DATE-TIME value has no time zone by definition, effectively such values float and describe
98
+ a date as viewed by the user in his/her local time zone.
99
+
100
+ When a Ruby Time or DateTime instance is used to set properties with with a DATE-TIME value, it needs to determine
101
+ which of the three types it represents. RiCal is designed to make use of the TimeWithZone support which has been
102
+ part of the ActiveSupport component of Ruby on Rails since Rails 2.2. However it's been carefully designed not
103
+ to require Rails or ActiveSupport, but to dynamically detect the presence of the TimeWithZone support.
104
+
105
+ When the value of a DATE-TIME property is set to a value, the following processing occurs:
106
+
107
+ * If the object responds to both the :acts_as_time, and :timezone methods then the result of the timezone method (assumed to be an instance of TZInfoTimezone) is used as a specific local time zone.
108
+
109
+ * If not then the default time zone id is used. The normal default timezone id is "UTC". You can set the default by calling ::RiCal::PropertyValue::DateTime.default_tzid = timezone_identifier, where timezone_identifier isa string, or nil. If you set the default tzid to 'none' or :none, then Times or DateTimes without timezones will be treated as floating times.
110
+
111
+ Note it is likely that in a future version of RiCal that the default timezone will be set on a Calendar by Calendar
112
+ basis rather than on the DateTime property class.
113
+
114
+ Also note that time zone identifiers are not standardized by RFC 2445. For an RiCal originated calendar
115
+ time zone identifiers recognized by the TZInfo gem, or the TZInfo implementation provided by ActiveSupport as the case
116
+ may be may be used. The valid time zone identifiers for a non-RiCal generated calendar imported into RiCalendar
117
+ are determined by the VTIMEZONE compoents within the imported calendar.
118
+
119
+ If you use a timezone identifer within a calendar which is not defined within the calendar it will detected at the time
120
+ you try to convert a timezone. In this case an InvalidTimezoneIdentifier error will be raised by the conversion method.
121
+
122
+ To explicitly set a floating time you can use the method #with_floating_timezone on Time or DateTime instances as in
123
+
124
+ event.dtstart = Time.parse("1/1/2010 00:00:00").with_floating_timezone
125
+
126
+ === Parsing
127
+
128
+ RiCal can parse icalendar data from either a string or a Ruby io object.
129
+
130
+ The data may consist of one or more icalendar calendars, or one or more icalendar components (e.g. one or more
131
+ VEVENT, or VTODO objects.)
132
+
133
+ In either case the result will be an array of components.
134
+ ==== From a string
135
+ RiCal.parse_string <<ENDCAL
136
+ BEGIN:VCALENDAR
137
+ X-WR-TIMEZONE:America/New_York
138
+ PRODID:-//Apple Inc.//iCal 3.0//EN
139
+ CALSCALE:GREGORIAN
140
+ X-WR-CALNAME:test
141
+ VERSION:2.0
142
+ X-WR-RELCALID:1884C7F8-BC8E-457F-94AC-297871967D5E
143
+ X-APPLE-CALENDAR-COLOR:#2CA10B
144
+ BEGIN:VTIMEZONE
145
+ TZID:US/Eastern
146
+ BEGIN:DAYLIGHT
147
+ TZOFFSETFROM:-0500
148
+ TZOFFSETTO:-0400
149
+ DTSTART:20070311T020000
150
+ RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
151
+ TZNAME:EDT
152
+ END:DAYLIGHT
153
+ BEGIN:STANDARD
154
+ TZOFFSETFROM:-0400
155
+ TZOFFSETTO:-0500
156
+ DTSTART:20071104T020000
157
+ RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
158
+ TZNAME:EST
159
+ END:STANDARD
160
+ END:VTIMEZONE
161
+ BEGIN:VEVENT
162
+ SEQUENCE:5
163
+ TRANSP:OPAQUE
164
+ UID:00481E53-9258-4EA7-9F8D-947D3041A3F2
165
+ DTSTART;TZID=US/Eastern:20090224T090000
166
+ DTSTAMP:20090225T000908Z
167
+ SUMMARY:Test Event
168
+ CREATED:20090225T000839Z
169
+ DTEND;TZID=US/Eastern:20090224T100000
170
+ RRULE:FREQ=DAILY;INTERVAL=1;UNTIL=20090228T045959Z
171
+ END:VEVENT
172
+ END:VCALENDAR
173
+ ENDCAL
174
+
175
+ <b>Beware of the initial whitespace in the above example which is for rdoc formatting.</b> The parser does not strip initial whitespace from lines in the file and will fail.
176
+
177
+ As already stated the string argument may be a full icalendar format calendar, or just one or more subcomponents, e.g.
178
+
179
+ RiCal.parse_string("BEGIN:VEVENT\nDTSTART;TZID=US/Eastern:20090224T090000\nSUMMARY:Test Event\nDTEND;TZID=US/Eastern:20090224T100000\nRRULE:FREQ=DAILY;INTERVAL=1;UNTIL=20090228T045959Z\nEND:VEVENT")
180
+
181
+ ==== From an Io
182
+ File.open("path/to/file", "r") do |file|
183
+ components = RiCal.parse(file)
184
+ end
185
+
186
+ === Occurrence Enumeration
187
+
188
+ Event, Journal, and Todo components can have recurrences which are defined following the RFC 2445 specification.
189
+ A component with recurrences can enumerate those occurrences.
190
+
191
+ These components have common methods for enumeration which are defined in the RiCal::OccurrenceEnumerator module.
192
+
193
+ ==== Obtaining an array of occurrences
194
+
195
+ To get an array of occurrences, Use the RiCal::OccurrenceEnumerator#occurrences method:
196
+
197
+ event.occurrences
198
+
199
+ This method may fail with an argument error, if the component has an unbounded recurrence definition. This happens
200
+ when one or more of its RRULES don't have a COUNT, or UNTIL part. This may be tested by using the RiCal::OccurrenceEnumerator#bounded? method.
201
+
202
+ In the case of unbounded components, you must either use the :count, or :before options of the RiCal::OccurrenceEnumerator#occurrences method:
203
+
204
+ event.occurrences(:count => 10)
205
+
206
+ or
207
+
208
+ event.occurrences(:before => Date.today >> 1)
209
+
210
+ Alternately, you can use the RiCal::OccurrenceEnumerator#each method,
211
+ or another Enumerable method (RiCal::OccurrenceEnumerator includes Enumerable), and terminate when you wish by breaking out of the block.
212
+
213
+ event.each do |event|
214
+ break if some_termination_condition
215
+ #....
216
+ end
217
+
218
+ == REQUIREMENTS:
219
+
220
+ * RiCal requires that an implementation of TZInfo::Timezone. This requirement may be satisfied by either the TzInfo gem,
221
+ or by a recent(>= 2.2) version of the ActiveSupport gem which is part of Ruby on Rails.
222
+
223
+ == INSTALL:
224
+
225
+ === From RubyForge
226
+
227
+ sudo gem install ri_cal
228
+
229
+ === From github
230
+
231
+ #TODO: publish to github
232
+
233
+ ==== As a Gem
234
+
235
+ #TODO: add the gem source info for github
236
+ sudo gem install ????? --source http://github.com/????
237
+
238
+ ==== From source
239
+
240
+ 1. cd to a directory in which you want to install ri_cal as a subdirectory
241
+ 2. git clone http://github.com/rubyredrick/ri_cal your_install_subdirectory
242
+ 3. cd your_install_directory
243
+ 4. rake spec
244
+ 5. rake install_gem
245
+
246
+
247
+
248
+ == LICENSE:
249
+
250
+ (The MIT License)
251
+
252
+ Copyright (c) 2009 Richard J. DeNatale
253
+
254
+ Permission is hereby granted, free of charge, to any person obtaining
255
+ a copy of this software and associated documentation files (the
256
+ 'Software'), to deal in the Software without restriction, including
257
+ without limitation the rights to use, copy, modify, merge, publish,
258
+ distribute, sublicense, and/or sell copies of the Software, and to
259
+ permit persons to whom the Software is furnished to do so, subject to
260
+ the following conditions:
261
+
262
+ The above copyright notice and this permission notice shall be
263
+ included in all copies or substantial portions of the Software.
264
+
265
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
266
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
267
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
268
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
269
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
270
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
271
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,31 @@
1
+ #- ©2009 Rick DeNatale
2
+ #- All rights reserved. Refer to the file README.txt for the license
3
+ #
4
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
5
+ require File.dirname(__FILE__) + '/lib/ri_cal'
6
+
7
+ # Generate all the Rake tasks
8
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
9
+ $hoe = Hoe.new('ri_cal', RiCal::VERSION) do |p|
10
+ p.developer('author=Rick DeNatale', 'rick.denatale@gmail.com')
11
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
12
+ # p.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
13
+ p.rubyforge_name = 'rical'
14
+ # p.extra_deps = [
15
+ # ['tzinfo','>= 2.0.2'],
16
+ # ]
17
+ p.extra_dev_deps = [
18
+ ['newgem', ">= #{::Newgem::VERSION}"]
19
+ ]
20
+
21
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
22
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
23
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
24
+ p.rsync_args = '-av --delete --ignore-errors'
25
+ end
26
+
27
+ require 'newgem/tasks' # load /tasks/*.rake
28
+ Dir['tasks/**/*.rake'].each { |t| load t }
29
+
30
+ # TODO - want other tests/tasks run by default? Add them to the list
31
+ task :default => [:spec]
data/bin/ri_cal ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(
4
+ File.join(File.dirname(__FILE__), %w[.. lib rfc2445]))
5
+
6
+ # Put your code here
7
+
8
+ # EOF
@@ -0,0 +1,10 @@
1
+ - action
2
+ - description
3
+ - trigger
4
+ - duration
5
+ - repeat
6
+ - summary
7
+ - attendee:
8
+ multi: *
9
+ - attach:
10
+ multi: *
@@ -0,0 +1,4 @@
1
+ - calscale
2
+ - method
3
+ - prodid
4
+ - version
@@ -0,0 +1,180 @@
1
+ calscale:
2
+ purpose: This property defines the calendar scale used for the calendar information specified in the calendar object.
3
+ constant_value: GREGORIAN
4
+ rfc_ref: "4.7.1 p 73"
5
+ method:
6
+ purpose: This property defines the iCalendar object method associated with the calendar object
7
+ ruby_name: icalendar_method
8
+ rfc_ref: "4.7.2 p 74-75"
9
+ prodid:
10
+ purpose: This property specifies the identifier for the product that created the iCalendar object.
11
+ required: true
12
+ default_value: '-//com.denhaven2/NONSGML ri_cal gem//EN'
13
+ rfc_ref: '4.7.3 pp 75-76'
14
+ version:
15
+ purpose: This property specifies the identifier corresponding to thehighest version number or the minimum and maximum range of the iCalendar specification that is required in order to interpret the iCalendar object.
16
+ constant_value: '2.0'
17
+ rfc_ref: '4.7.4 pp 76-77'
18
+ attach:
19
+ purpose: The property provides the capability to associate a document object with a calendar component.
20
+ type: Uri
21
+ rfc_ref: '4.8.1.1 pp 77-78'
22
+ categories:
23
+ purpose: This property defines the categories for a calendar component.
24
+ type: Array
25
+ array_type: Text
26
+ rfc_ref: '4.8.1.2 pp 78-79'
27
+ class:
28
+ ruby_name: security_class
29
+ purpose: This property defines the access classification for a calendar component.
30
+ rfc_ref: '4.8.1.3 pp 79-80'
31
+ comment:
32
+ purpose: This property specifies non-processing information intended to provide a comment to the calendar user.
33
+ rfc_ref: '4.8.1.4 pp 80-81'
34
+ description:
35
+ purpose: This property provides a more complete description of the calendar component, than that provided by the "SUMMARY" property.
36
+ rfc_ref: '4.8.1.5 pp 81-82'
37
+ geo:
38
+ purpose: This property specifies information related to the global position for the activity specified by a calendar component.
39
+ type: Geo
40
+ rfc_ref: '4.8.1.6 pp 82-83'
41
+ location:
42
+ purpose: This property defines the intended venue for the activity defined by a calendar component.
43
+ rfc_ref: '4.8.1.7 pp 84'
44
+ percent-complete:
45
+ purpose: This property is used by an assignee or delegatee of a to-do to convey the percent completion of a to-do to the Organizer.
46
+ type: Integer
47
+ rfc_ref: '4.8.1.8 pp 85'
48
+ priority:
49
+ type: Integer
50
+ purpose: This property defines the relative priority for a calendar component.
51
+ rfc_ref: '4.8.1.9 pp 85-87'
52
+ resources:
53
+ purpose: This property defines the equipment or resources anticipated for an activity specified by a calendar entity.
54
+ type: 'Array'
55
+ rfc_ref: '4.8.1.10 pp 87-88'
56
+ status:
57
+ purpose: This property defines a short summary or subject for the calendar component.
58
+ rfc_ref: '4.8.1.11 pp 80-89'
59
+ summary:
60
+ purpose: This property defines a short summary or subject for the calendar component.
61
+ rfc_ref: '4.8.1.12 pp 89-90'
62
+ completed:
63
+ purpose: This property specifies the date and time that a to-do was actually completed.
64
+ type: DateTime
65
+ type_constraint: must_be_utc
66
+ rfc_ref: '4.8.2.1 pp 90-91'
67
+ dtend:
68
+ purpose: This property specifies the date and time that a calendar component ends.
69
+ type: date_time_or_date
70
+ rfc_ref: '4.8.2.2 pp 91-92'
71
+ due:
72
+ purpose: This property defines the date and time that a to-do is expected to be completed.
73
+ type: date_time_or_date
74
+ rfc_ref: '4.8.2.3 pp 92-93'
75
+ dtstart:
76
+ purpose: This property specifies when the calendar component begins.
77
+ type: date_time_or_date
78
+ rfc_ref: '4.8.2.4 pp 93-94'
79
+ duration:
80
+ purpose: This property specifies a positive duration of time.
81
+ type: Duration
82
+ rfc_ref: '4.8.2.5 pp 94-95'
83
+ freebusy:
84
+ purpose: This property defines one or more free or busy time intervals.
85
+ type: Period
86
+ type_constraint: must_be_utc
87
+ rfc_ref: '4.8.2.6 pp 95-96'
88
+ transp:
89
+ purpose: This property defines whether an event is transparent or not to busy time searches.
90
+ rfc_ref: '4.8.2.7 pp 96-97'
91
+ tzid:
92
+ purpose: This property specifies the text value that uniquely indentifies the "VTIMEZONE" calendar component.
93
+ rfc_ref: '4.8.3.1 pp 97-98'
94
+ tzname:
95
+ purpose: This property specifies the customary designation for a time zone description.
96
+ rfc_ref: '4.8.3.2 p 99'
97
+ tzoffsetfrom:
98
+ purpose: This property specifies the offset which is in use prior to this time zone observance
99
+ type: UtcOffset
100
+ rfc_ref: '4.8.3.3 pp 99-100'
101
+ tzoffsetto:
102
+ purpose: This property specifies the offset which is in use in this time zone observance
103
+ type: UtcOffset
104
+ rfc_ref: '4.8.3.4 pp 100-101'
105
+ tzurl:
106
+ purpose: The TZURL provies a means for a VTIMEZONE component to point to a network location that can be used to retrieve an up-to_date version of itself.
107
+ type: Uri
108
+ rfc_ref: '4.8.3.4 p 101'
109
+ attendee:
110
+ purpose: The property defines an 'Attendee' within a calendar component.
111
+ type: CalAddress
112
+ rfc_ref: '4.8.4.1 pp 102-104'
113
+ contact:
114
+ purpose: The property is used to represent contact information oralternately a reference to contact information associated with the calendar component.
115
+ rfc_ref: '4.8.4.2 pp 104-106'
116
+ organizer:
117
+ purpose: The property defines the organizer for a calendar component.
118
+ type: CalAddress
119
+ rfc_ref: '4.8.4.3 pp 106-107'
120
+ recurrence-id:
121
+ purpose: This property is used in conjunction with the "UID" and "SEQUENCE" property to identify a specific instance of a recurring "VEVENT", "VTODO" or "VJOURNAL" calendar component. The property value is the effective value of the "DTSTART" property of the recurrence instance.
122
+ type: date_time_or_date
123
+ rfc_ref: '4.8.4.4 pp 107-109'
124
+ related-to:
125
+ purpose: The property is used to represent a relationship or reference between one calendar component and another.
126
+ rfc_ref: '4.8.4.5 pp 109-110'
127
+ url:
128
+ purpose: This property defines a Uniform Resource Locator (URL) associated with the iCalendar object.
129
+ type: Uri
130
+ rfc_ref: '4.8.4.6 pp 110-111'
131
+ uid:
132
+ purpose: This property defines the persistent, globally unique identifier for the calendar component.
133
+ rfc_ref: '4.8.4.7 pp 111-112'
134
+ exdate:
135
+ purpose: This property defines the list of date/time exceptions for a recurring calendar component.
136
+ type: 'OccurrenceList'
137
+ rfc_ref: '4.8.5.1 pp 112-114'
138
+ exrule:
139
+ purpose: This property defines a rule or repeating pattern for an exception to a recurrence set.
140
+ type: 'RecurrenceRule'
141
+ rfc_ref: '4.8.5.2 pp 114-125'
142
+ rdate:
143
+ purpose: This property defines the list of date/times for a recurring calendar component.
144
+ type: 'OccurrenceList'
145
+ rfc_ref: '4.8.5.3 pp 115-117'
146
+ rrule:
147
+ purpose: This property defines a rule or repeating pattern for recurring events, to-dos, or time zone definitions.
148
+ type: 'RecurrenceRule'
149
+ rfc_ref: '4.8.5.4 pp 117-125'
150
+ action:
151
+ purpose: This property defines the action to be invoked when an alarm is triggered
152
+ rfc_ref: '4.8.6.1 p 126'
153
+ repeat:
154
+ purpose: This property defines the number of times the alarm should be repeated, after the initial trigger.
155
+ type: Integer
156
+ rfc_ref: '4.8.6.2 p 126-127'
157
+ trigger:
158
+ purpose: This property specifies when an alarm will trigger.
159
+ type: duration_or_utc_date_time
160
+ rfc_ref: '4.8.6.3 p 127-129'
161
+ created:
162
+ purpose: This property specifies the date and time that the calendar information was created by teh calendar user agent in the calendar store.
163
+ type: DateTime
164
+ rfc_ref: '4.8.7.1 pp 129-130'
165
+ dtstamp:
166
+ purpose: This property indicates the date/time that the instance of the iCalendar object was created.
167
+ type: DateTime
168
+ auto_set: to_ical
169
+ rfc_ref: '4.8.7.2 pp 130-131'
170
+ last-modified:
171
+ purpose: This property specifies the date and time that the information associated with the calendar component was last revised in teh calendar store.
172
+ type: DateTime
173
+ rfc_ref: '4.8.7.3 p 131'
174
+ sequence:
175
+ purpose: This property defines the revision sequence number of the calendar component within a sequence of revisions.
176
+ type: Integer
177
+ auto_set: sequence_modifiers
178
+ rfc_ref: '4.8.7.4 pp 131-133'
179
+ request-status:
180
+ rfc_ref: '4.8.8.2 pp 134-136'
@@ -0,0 +1,45 @@
1
+ - class
2
+ - created
3
+ - description
4
+ - dtstart
5
+ - geo
6
+ - last-modified
7
+ - location
8
+ - organizer
9
+ - priority
10
+ - dtstamp
11
+ - sequence
12
+ - status
13
+ - summary
14
+ - transp
15
+ - uid
16
+ - url
17
+ - recurrence-id
18
+ - dtend:
19
+ conflicts_with: duration
20
+ - duration:
21
+ conflicts_with: dtend
22
+ - attach:
23
+ multi: *
24
+ - attendee:
25
+ multi: *
26
+ - categories:
27
+ multi: *
28
+ - comment:
29
+ multi: *
30
+ - contact:
31
+ multi: *
32
+ - exdate:
33
+ multi: *
34
+ - rdate:
35
+ multi: *
36
+ - exrule:
37
+ multi: *
38
+ - request-status:
39
+ multi: *
40
+ - related-to:
41
+ multi: *
42
+ - resources:
43
+ multi: *
44
+ - rrule:
45
+ multi: *