paulsm-icalendar 1.1.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/COPYING +56 -0
  2. data/GPL +340 -0
  3. data/README +266 -0
  4. data/Rakefile +109 -0
  5. data/docs/rfcs/itip_notes.txt +69 -0
  6. data/docs/rfcs/rfc2425.pdf +0 -0
  7. data/docs/rfcs/rfc2426.pdf +0 -0
  8. data/docs/rfcs/rfc2445.pdf +0 -0
  9. data/docs/rfcs/rfc2446.pdf +0 -0
  10. data/docs/rfcs/rfc2447.pdf +0 -0
  11. data/docs/rfcs/rfc3283.txt +738 -0
  12. data/examples/create_cal.rb +45 -0
  13. data/examples/parse_cal.rb +20 -0
  14. data/examples/single_event.ics +18 -0
  15. data/lib/hash_attrs.rb +34 -0
  16. data/lib/icalendar.rb +39 -0
  17. data/lib/icalendar/base.rb +43 -0
  18. data/lib/icalendar/calendar.rb +113 -0
  19. data/lib/icalendar/component.rb +442 -0
  20. data/lib/icalendar/component/alarm.rb +44 -0
  21. data/lib/icalendar/component/event.rb +129 -0
  22. data/lib/icalendar/component/freebusy.rb +38 -0
  23. data/lib/icalendar/component/journal.rb +61 -0
  24. data/lib/icalendar/component/timezone.rb +105 -0
  25. data/lib/icalendar/component/todo.rb +64 -0
  26. data/lib/icalendar/conversions.rb +150 -0
  27. data/lib/icalendar/helpers.rb +109 -0
  28. data/lib/icalendar/parameter.rb +33 -0
  29. data/lib/icalendar/parser.rb +396 -0
  30. data/lib/icalendar/rrule.rb +126 -0
  31. data/lib/icalendar/tzinfo.rb +121 -0
  32. data/lib/meta.rb +32 -0
  33. data/test/calendar_test.rb +71 -0
  34. data/test/component/event_test.rb +256 -0
  35. data/test/component/timezone_test.rb +67 -0
  36. data/test/component/todo_test.rb +13 -0
  37. data/test/component_test.rb +76 -0
  38. data/test/conversions_test.rb +97 -0
  39. data/test/coverage/STUB +0 -0
  40. data/test/fixtures/folding.ics +23 -0
  41. data/test/fixtures/life.ics +46 -0
  42. data/test/fixtures/simplecal.ics +119 -0
  43. data/test/fixtures/single_event.ics +23 -0
  44. data/test/interactive.rb +17 -0
  45. data/test/parameter_test.rb +29 -0
  46. data/test/parser_test.rb +84 -0
  47. data/test/read_write.rb +23 -0
  48. metadata +108 -0
@@ -0,0 +1,44 @@
1
+ =begin
2
+ Copyright (C) 2005 Jeff Rose
3
+
4
+ This library is free software; you can redistribute it and/or modify it
5
+ under the same terms as the ruby language itself, see the file COPYING for
6
+ details.
7
+ =end
8
+ module Icalendar
9
+ # An Alarm calendar component is a grouping of component
10
+ # properties that is a reminder or alarm for an event or a
11
+ # to-do. For example, it may be used to define a reminder for a
12
+ # pending Event or an overdue Todo.
13
+ class Alarm < Component
14
+
15
+ # Single properties
16
+ ical_property :action
17
+ ical_property :description
18
+ ical_property :trigger
19
+ ical_property :summary
20
+
21
+ # Single but must appear together
22
+ ical_property :duration
23
+ ical_property :repeat
24
+
25
+ # Single and only occurring once
26
+
27
+ ical_property :created
28
+ ical_property :last_modified
29
+ ical_property :timestamp
30
+ ical_property :sequence
31
+
32
+ # Multi properties
33
+ ical_multiline_property :attendee, :attendee, :attendees
34
+ ical_multiline_property :attach, :attachment, :attachments
35
+
36
+ def initialize()
37
+ super("VALARM")
38
+
39
+ # Almost everyone just wants to display so I make it the
40
+ # default so it works for most people right away...
41
+ action "DISPLAY"
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,129 @@
1
+ =begin
2
+ Copyright (C) 2005 Jeff Rose
3
+
4
+ This library is free software; you can redistribute it and/or modify it
5
+ under the same terms as the ruby language itself, see the file COPYING for
6
+ details.
7
+ =end
8
+
9
+ module Icalendar
10
+ # A Event calendar component is a grouping of component
11
+ # properties, and possibly including Alarm calendar components, that
12
+ # represents a scheduled amount of time on a calendar. For example, it
13
+ # can be an activity; such as a one-hour long, department meeting from
14
+ # 8:00 AM to 9:00 AM, tomorrow. Generally, an event will take up time
15
+ # on an individual calendar.
16
+ class Event < Component
17
+ ical_component :alarms
18
+
19
+ ## Single instance properties
20
+
21
+ # Access classification (PUBLIC, PRIVATE, CONFIDENTIAL...)
22
+ ical_property :ip_class, :klass
23
+
24
+ # Date & time of creation
25
+ ical_property :created
26
+
27
+ # Complete description of the calendar component
28
+ ical_property :description
29
+
30
+ # Specifies the timezone for the event
31
+ attr_accessor :tzid
32
+
33
+ # Specifies date-time when calendar component begins
34
+ ical_property :dtstart, :start
35
+
36
+ # Latitude & longitude for specified activity
37
+ ical_property :geo, :geo_location
38
+
39
+ # Date & time this item was last modified
40
+ ical_property :last_modified
41
+
42
+ # Specifies the intended venue for this activity
43
+ ical_property :location
44
+
45
+ # Defines organizer of this item
46
+ ical_property :organizer
47
+
48
+ # Defines relative priority for this item (1-9... 1 = best)
49
+ ical_property :priority
50
+
51
+ # Indicate date & time when this item was created
52
+ ical_property :dtstamp, :timestamp
53
+
54
+ # Revision sequence number for this item
55
+ ical_property :sequence, :seq
56
+
57
+ # Defines overall status or confirmation of this item
58
+ ical_property :status
59
+ ical_property :summary
60
+ ical_property :transp, :transparency
61
+
62
+ # Defines a persistent, globally unique id for this item
63
+ ical_property :uid, :unique_id
64
+
65
+ # Defines a URL associated with this item
66
+ ical_property :url
67
+ ical_property :recurid, :recurrence_id
68
+
69
+ ## Single but mutually exclusive properties (Not testing though)
70
+
71
+ # Specifies a date and time that this item ends
72
+ ical_property :dtend, :end
73
+
74
+ # Specifies a positive duration time
75
+ ical_property :duration
76
+
77
+ ## Multi-instance properties
78
+
79
+ # Associates a URI or binary blob with this item
80
+ ical_multi_property :attach, :attachment, :attachments
81
+
82
+ # Defines an attendee for this calendar item
83
+ ical_multiline_property :attendee, :attendee, :attendees
84
+
85
+ # Defines the categories for a calendar component (school, work...)
86
+ ical_multi_property :categories, :category, :categories
87
+
88
+ # Simple comment for the calendar user.
89
+ ical_multi_property :comment, :comment, :comments
90
+
91
+ # Contact information associated with this item.
92
+ ical_multi_property :contact, :contact, :contacts
93
+ ical_multi_property :exdate, :exception_date, :exception_dates
94
+ ical_multi_property :exrule, :exception_rule, :exception_rules
95
+ ical_multi_property :rstatus, :request_status, :request_statuses
96
+
97
+ # Used to represent a relationship between two calendar items
98
+ ical_multi_property :related_to, :related_to, :related_tos
99
+ ical_multi_property :resources, :resource, :resources
100
+
101
+ # Used with the UID & SEQUENCE to identify a specific instance of a
102
+ # recurring calendar item.
103
+ ical_multi_property :rdate, :recurrence_date, :recurrence_dates
104
+ ical_multi_property :rrule, :recurrence_rule, :recurrence_rules
105
+
106
+ def initialize()
107
+ super("VEVENT")
108
+
109
+ # Now doing some basic initialization
110
+ sequence 0
111
+ timestamp DateTime.now
112
+ uid new_uid
113
+ end
114
+
115
+ def alarm(&block)
116
+ a = Alarm.new
117
+ self.add a
118
+
119
+ a.instance_eval &block if block
120
+
121
+ a
122
+ end
123
+
124
+ def occurrences_starting(time)
125
+ recurrence_rules.first.occurrences_of_event_starting(self, time)
126
+ end
127
+
128
+ end
129
+ end
@@ -0,0 +1,38 @@
1
+ =begin
2
+ Copyright (C) 2005 Jeff Rose
3
+
4
+ This library is free software; you can redistribute it and/or modify it
5
+ under the same terms as the ruby language itself, see the file COPYING for
6
+ details.
7
+ =end
8
+ module Icalendar
9
+ # A Freebusy calendar component is a grouping of
10
+ # component properties that represents either a request for, a reply to
11
+ # a request for free or busy time information or a published set of
12
+ # busy time information.
13
+ class Freebusy < Component
14
+ # Single properties
15
+ ical_property :contact
16
+ ical_property :dtstart, :start
17
+ ical_property :dtend, :end
18
+ ical_property :dtstamp, :timestamp
19
+ ical_property :duration
20
+ ical_property :organizer
21
+ ical_property :uid, :user_id
22
+ ical_property :url
23
+ ical_property :summary
24
+
25
+ # Multi-properties
26
+ ical_multiline_property :attendee, :attendee, :attendees
27
+ ical_multi_property :comment, :comment, :comments
28
+ ical_multiline_property :freebusy, :freebusy, :freebusys
29
+ ical_multi_property :rstatus, :request_status, :request_statuses
30
+
31
+ def initialize()
32
+ super("VFREEBUSY")
33
+
34
+ timestamp DateTime.now
35
+ uid new_uid
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,61 @@
1
+ =begin
2
+ Copyright (C) 2005 Jeff Rose
3
+
4
+ This library is free software; you can redistribute it and/or modify it
5
+ under the same terms as the ruby language itself, see the file COPYING for
6
+ details.
7
+ =end
8
+ module Icalendar
9
+ # A Journal calendar component is a grouping of
10
+ # component properties that represent one or more descriptive text
11
+ # notes associated with a particular calendar date. The "DTSTART"
12
+ # property is used to specify the calendar date that the journal entry
13
+ # is associated with. Generally, it will have a DATE value data type,
14
+ # but it can also be used to specify a DATE-TIME value data type.
15
+ # Examples of a journal entry include a daily record of a legislative
16
+ # body or a journal entry of individual telephone contacts for the day
17
+ # or an ordered list of accomplishments for the day. The Journal
18
+ # calendar component can also be used to associate a document with a
19
+ # calendar date.
20
+ class Journal < Component
21
+
22
+ # Single properties
23
+ ical_property :ip_class
24
+ ical_property :created
25
+ ical_property :description
26
+ ical_property :dtstart, :start
27
+ ical_property :last_modified
28
+ ical_property :organizer
29
+ ical_property :dtstamp, :timestamp
30
+ ical_property :sequence, :seq
31
+ ical_property :status
32
+ ical_property :summary
33
+ ical_property :uid, :user_id
34
+ ical_property :url
35
+ ical_property :recurid, :recurrence_id
36
+
37
+ # Multi-properties
38
+ ical_multi_property :attach, :attachment, :attachments
39
+ ical_multiline_property :attendee, :attendee, :attendees
40
+ ical_multi_property :categories, :category, :categories
41
+ ical_multi_property :comment, :comment, :comments
42
+ ical_multi_property :contact, :contact, :contacts
43
+ ical_multi_property :exdate, :exception_date, :exception_dates
44
+ ical_multi_property :exrule, :exception_rule, :exception_rules
45
+ ical_multi_property :rstatus, :request_status, :request_statuses
46
+ ical_multi_property :related_to, :related_to, :related_tos
47
+ ical_multi_property :resources, :resource, :resources
48
+ ical_multi_property :rdate, :recurrence_date, :recurrence_dates
49
+ ical_multi_property :rrule, :recurrence_rule, :recurrence_rules
50
+
51
+ def initialize()
52
+ super("VJOURNAL")
53
+
54
+ sequence 0
55
+ timestamp DateTime.now
56
+ uid new_uid
57
+ end
58
+
59
+ end
60
+ end
61
+
@@ -0,0 +1,105 @@
1
+ =begin
2
+ Copyright (C) 2005 Jeff Rose
3
+
4
+ This library is free software; you can redistribute it and/or modify it
5
+ under the same terms as the ruby language itself, see the file COPYING for
6
+ details.
7
+ =end
8
+ module Icalendar
9
+ # A Timezone is unambiguously defined by the set of time
10
+ # measurement rules determined by the governing body for a given
11
+ # geographic area. These rules describe at a minimum the base offset
12
+ # from UTC for the time zone, often referred to as the Standard Time
13
+ # offset. Many locations adjust their Standard Time forward or backward
14
+ # by one hour, in order to accommodate seasonal changes in number of
15
+ # daylight hours, often referred to as Daylight Saving Time. Some
16
+ # locations adjust their time by a fraction of an hour. Standard Time
17
+ # is also known as Winter Time. Daylight Saving Time is also known as
18
+ # Advanced Time, Summer Time, or Legal Time in certain countries. The
19
+ # following table shows the changes in time zone rules in effect for
20
+ # New York City starting from 1967. Each line represents a description
21
+ # or rule for a particular observance.
22
+ class Timezone < Component
23
+ ical_component :standard, :daylight
24
+
25
+ # Single properties
26
+ ical_property :dtstart, :start
27
+ ical_property :tzoffsetto, :timezone_offset_to
28
+ ical_property :tzoffsetfrom, :timezone_offset_from
29
+ ical_property :tzid, :timezone_id
30
+ ical_property :tzname, :timezone_name
31
+
32
+ ical_property :created
33
+ ical_property :last_modified
34
+ ical_property :timestamp
35
+ ical_property :sequence
36
+
37
+ # Multi-properties
38
+ ical_multi_property :comment, :comment, :comments
39
+ ical_multi_property :rdate, :recurrence_date, :recurrence_dates
40
+ ical_multi_property :rrule, :recurrence_rule, :recurrence_rules
41
+
42
+ # Define a custom add component method because standard and daylight
43
+ # are the only components that can occur just once with their parent.
44
+ def add_component(component)
45
+ key = component.class.to_s.downcase.gsub('icalendar::','').to_sym
46
+ @components[key] = component
47
+ end
48
+
49
+ # Also need a custom to_ical because typically it iterates over an array
50
+ # of components.
51
+ def to_ical
52
+ print_component do
53
+ s = ""
54
+ @components.each_value do |comp|
55
+ s << comp.to_ical
56
+ end
57
+ s
58
+ end
59
+ end
60
+
61
+
62
+ def initialize(name = "VTIMEZONE")
63
+ super(name)
64
+ end
65
+
66
+ # Allow block syntax for declaration of standard and daylight components of timezone
67
+ def standard(&block)
68
+ e = Standard.new
69
+ self.add_component e
70
+
71
+ e.instance_eval &block if block
72
+
73
+ e
74
+ end
75
+
76
+ def daylight(&block)
77
+ e = Daylight.new
78
+ self.add_component e
79
+
80
+ e.instance_eval &block if block
81
+
82
+ e
83
+ end
84
+ end
85
+
86
+ # A Standard component is a sub-component of the Timezone component which
87
+ # is used to describe the standard time offset.
88
+ class Standard < Timezone
89
+
90
+ def initialize()
91
+ super("STANDARD")
92
+ end
93
+ end
94
+
95
+ # A Daylight component is a sub-component of the Timezone component which
96
+ # is used to describe the time offset for what is commonly known as
97
+ # daylight savings time.
98
+ class Daylight < Timezone
99
+
100
+ def initialize()
101
+ super("DAYLIGHT")
102
+ end
103
+ end
104
+
105
+ end
@@ -0,0 +1,64 @@
1
+ =begin
2
+ Copyright (C) 2005 Jeff Rose
3
+
4
+ This library is free software; you can redistribute it and/or modify it
5
+ under the same terms as the ruby language itself, see the file COPYING for
6
+ details.
7
+ =end
8
+ module Icalendar
9
+ # A Todo calendar component is a grouping of component
10
+ # properties and possibly Alarm calendar components that represent
11
+ # an action-item or assignment. For example, it can be used to
12
+ # represent an item of work assigned to an individual; such as "turn in
13
+ # travel expense today".
14
+ class Todo < Component
15
+ ical_component :alarms
16
+
17
+ # Single properties
18
+ ical_property :ip_class
19
+ ical_property :completed
20
+ ical_property :created
21
+ ical_property :description
22
+ ical_property :dtstamp, :timestamp
23
+ ical_property :dtstart, :start
24
+ ical_property :geo
25
+ ical_property :last_modified
26
+ ical_property :location
27
+ ical_property :organizer
28
+ ical_property :percent
29
+ ical_property :priority
30
+ ical_property :recurid, :recurrence_id
31
+ ical_property :seq, :sequence
32
+ ical_property :status
33
+ ical_property :summary
34
+ ical_property :uid, :user_id
35
+ ical_property :url
36
+
37
+ # Single but mutually exclusive TODO: not testing anything yet
38
+ ical_property :due
39
+ ical_property :duration
40
+
41
+ # Multi-properties
42
+ ical_multi_property :attach, :attachment, :attachments
43
+ ical_multiline_property :attendee, :attendee, :attendees
44
+ ical_multi_property :categories, :category, :categories
45
+ ical_multi_property :comment, :comment, :comments
46
+ ical_multi_property :contact, :contact, :contacts
47
+ ical_multi_property :exdate, :exception_date, :exception_dates
48
+ ical_multi_property :exrule, :exception_rule, :exception_rules
49
+ ical_multi_property :rstatus, :request_status, :request_statuses
50
+ ical_multi_property :related_to, :related_to, :related_tos
51
+ ical_multi_property :resources, :resource, :resources
52
+ ical_multi_property :rdate, :recurrence_date, :recurrence_dates
53
+ ical_multi_property :rrule, :recurrence_rule, :recurrence_rules
54
+
55
+ def initialize()
56
+ super("VTODO")
57
+
58
+ sequence 0
59
+ timestamp DateTime.now
60
+ uid new_uid
61
+ end
62
+
63
+ end
64
+ end
@@ -0,0 +1,150 @@
1
+ =begin
2
+ Copyright (C) 2005 Jeff Rose
3
+
4
+ This library is free software; you can redistribute it and/or modify it
5
+ under the same terms as the ruby language itself, see the file COPYING for
6
+ details.
7
+ =end
8
+
9
+ require 'date'
10
+
11
+ ### Add some to_ical methods to classes
12
+
13
+ # class Object
14
+ # def to_ical
15
+ # raise(NotImplementedError, "This object does not implement the to_ical method!")
16
+ # end
17
+ # end
18
+
19
+ module Icalendar
20
+ module TzidSupport
21
+ attr_accessor :icalendar_tzid
22
+ end
23
+ end
24
+
25
+ require 'uri/generic'
26
+
27
+ class String
28
+ def to_ical
29
+ self
30
+ end
31
+ end
32
+
33
+ class Fixnum
34
+ def to_ical
35
+ "#{self}"
36
+ end
37
+ end
38
+
39
+ class Bignum
40
+ def to_ical
41
+ "#{self}"
42
+ end
43
+ end
44
+
45
+ class Float
46
+ def to_ical
47
+ "#{self}"
48
+ end
49
+ end
50
+
51
+ # From the spec: "Values in a list of values MUST be separated by a COMMA
52
+ # character (US-ASCII decimal 44)."
53
+ class Array
54
+ def to_ical
55
+ map{|elem| elem.to_ical}.join ','
56
+ end
57
+ end
58
+
59
+ module URI
60
+ class Generic
61
+ def to_ical
62
+ "#{self}"
63
+ end
64
+ end
65
+ end
66
+
67
+ class DateTime < Date
68
+ attr_accessor :ical_params
69
+ include Icalendar::TzidSupport
70
+
71
+ def to_ical
72
+ s = ""
73
+
74
+ # 4 digit year
75
+ s << self.year.to_s
76
+
77
+ # Double digit month
78
+ s << "0" unless self.month > 9
79
+ s << self.month.to_s
80
+
81
+ # Double digit day
82
+ s << "0" unless self.day > 9
83
+ s << self.day.to_s
84
+
85
+ s << "T"
86
+
87
+ # Double digit hour
88
+ s << "0" unless self.hour > 9
89
+ s << self.hour.to_s
90
+
91
+ # Double digit minute
92
+ s << "0" unless self.min > 9
93
+ s << self.min.to_s
94
+
95
+ # Double digit second
96
+ s << "0" unless self.sec > 9
97
+ s << self.sec.to_s
98
+
99
+ # UTC time gets a Z suffix
100
+ if icalendar_tzid == "UTC"
101
+ s << "Z"
102
+ end
103
+
104
+ s
105
+ end
106
+ end
107
+
108
+ class Date
109
+ attr_accessor :ical_params
110
+ def to_ical(utc = false)
111
+ s = ""
112
+
113
+ # 4 digit year
114
+ s << self.year.to_s
115
+
116
+ # Double digit month
117
+ s << "0" unless self.month > 9
118
+ s << self.month.to_s
119
+
120
+ # Double digit day
121
+ s << "0" unless self.day > 9
122
+ s << self.day.to_s
123
+ end
124
+ end
125
+
126
+ class Time
127
+ attr_accessor :ical_params
128
+ def to_ical(utc = false)
129
+ s = ""
130
+
131
+ # Double digit hour
132
+ s << "0" unless self.hour > 9
133
+ s << self.hour.to_s
134
+
135
+ # Double digit minute
136
+ s << "0" unless self.min > 9
137
+ s << self.min.to_s
138
+
139
+ # Double digit second
140
+ s << "0" unless self.sec > 9
141
+ s << self.sec.to_s
142
+
143
+ # UTC time gets a Z suffix
144
+ if utc
145
+ s << "Z"
146
+ end
147
+
148
+ s
149
+ end
150
+ end