curzonj-icalendar 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +56 -0
- data/GPL +340 -0
- data/README +266 -0
- data/Rakefile +110 -0
- data/docs/rfcs/itip_notes.txt +69 -0
- data/docs/rfcs/rfc2425.pdf +0 -0
- data/docs/rfcs/rfc2426.pdf +0 -0
- data/docs/rfcs/rfc2445.pdf +0 -0
- data/docs/rfcs/rfc2446.pdf +0 -0
- data/docs/rfcs/rfc2447.pdf +0 -0
- data/docs/rfcs/rfc3283.txt +738 -0
- data/examples/create_cal.rb +45 -0
- data/examples/parse_cal.rb +20 -0
- data/examples/single_event.ics +18 -0
- data/lib/hash_attrs.rb +34 -0
- data/lib/icalendar.rb +39 -0
- data/lib/icalendar/base.rb +43 -0
- data/lib/icalendar/calendar.rb +113 -0
- data/lib/icalendar/component.rb +442 -0
- data/lib/icalendar/component/alarm.rb +44 -0
- data/lib/icalendar/component/event.rb +129 -0
- data/lib/icalendar/component/freebusy.rb +38 -0
- data/lib/icalendar/component/journal.rb +61 -0
- data/lib/icalendar/component/timezone.rb +105 -0
- data/lib/icalendar/component/todo.rb +64 -0
- data/lib/icalendar/conversions.rb +150 -0
- data/lib/icalendar/helpers.rb +109 -0
- data/lib/icalendar/parameter.rb +33 -0
- data/lib/icalendar/parser.rb +396 -0
- data/lib/meta.rb +32 -0
- data/test/calendar_test.rb +71 -0
- data/test/component/event_test.rb +256 -0
- data/test/component/todo_test.rb +13 -0
- data/test/component_test.rb +76 -0
- data/test/conversions_test.rb +97 -0
- data/test/fixtures/folding.ics +23 -0
- data/test/fixtures/life.ics +46 -0
- data/test/fixtures/simplecal.ics +119 -0
- data/test/fixtures/single_event.ics +23 -0
- data/test/interactive.rb +17 -0
- data/test/parameter_test.rb +29 -0
- data/test/parser_test.rb +84 -0
- data/test/read_write.rb +23 -0
- metadata +105 -0
@@ -0,0 +1,97 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'icalendar'
|
5
|
+
|
6
|
+
require 'date'
|
7
|
+
|
8
|
+
class TestConversions < Test::Unit::TestCase
|
9
|
+
include Icalendar
|
10
|
+
|
11
|
+
RESULT = <<EOS
|
12
|
+
BEGIN:VCALENDAR
|
13
|
+
VERSION:2.0
|
14
|
+
CALSCALE:GREGORIAN
|
15
|
+
PRODID:iCalendar-Ruby
|
16
|
+
BEGIN:VEVENT
|
17
|
+
LAST-MODIFIED:19960817T133000
|
18
|
+
SEQUENCE:2
|
19
|
+
ORGANIZER:mailto:joe@example.com?subject=Ruby
|
20
|
+
UID:foobar
|
21
|
+
X-TIME-OF-DAY:101736
|
22
|
+
CATEGORIES:foo\\,bar\\,baz
|
23
|
+
GEO:46.01\\;8.57
|
24
|
+
DESCRIPTION:desc
|
25
|
+
DTSTART:20060720
|
26
|
+
DTSTAMP:20060720T174052
|
27
|
+
END:VEVENT
|
28
|
+
END:VCALENDAR
|
29
|
+
EOS
|
30
|
+
|
31
|
+
def setup
|
32
|
+
@cal = Calendar.new
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_to_ical_conversions
|
36
|
+
@cal.event do
|
37
|
+
# String
|
38
|
+
description "desc"
|
39
|
+
|
40
|
+
# Fixnum
|
41
|
+
sequence 2
|
42
|
+
|
43
|
+
# Float by way of Geo class
|
44
|
+
geo(Geo.new(46.01, 8.57))
|
45
|
+
|
46
|
+
# Array
|
47
|
+
categories ["foo", "bar"]
|
48
|
+
add_category "baz"
|
49
|
+
|
50
|
+
# Last Modified
|
51
|
+
last_modified DateTime.parse("1996-08-17T13:30:00")
|
52
|
+
|
53
|
+
# URI
|
54
|
+
organizer(URI::MailTo.build(['joe@example.com', 'subject=Ruby']))
|
55
|
+
|
56
|
+
# Date
|
57
|
+
start Date.parse("2006-07-20")
|
58
|
+
|
59
|
+
# DateTime
|
60
|
+
timestamp DateTime.parse("2006-07-20T17:40:52+0200")
|
61
|
+
|
62
|
+
# Time
|
63
|
+
x_time_of_day Time.at(123456).utc
|
64
|
+
|
65
|
+
uid "foobar"
|
66
|
+
end
|
67
|
+
|
68
|
+
assert_equal(RESULT.gsub("\n", "\r\n"), @cal.to_ical)
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_to_ical_folding
|
72
|
+
@cal.x_wr_calname = 'Test Long Description'
|
73
|
+
|
74
|
+
@cal.event do
|
75
|
+
url 'http://test.com/events/644'
|
76
|
+
dtend DateTime.parse('20061215T180000')
|
77
|
+
dtstart DateTime.parse('20061215T160000')
|
78
|
+
timestamp DateTime.parse('20061215T114034')
|
79
|
+
seq 1001
|
80
|
+
uid 'foobar'
|
81
|
+
summary 'DigiWorld 2006'
|
82
|
+
|
83
|
+
description "FULL DETAILS:\nhttp://test.com/events/570\n\n" +
|
84
|
+
"Cary Brothers walks the same musical ground as Pete Yorn, Nick Drake, " +
|
85
|
+
"Jeff Buckley and others; crafting emotional melodies, with strong vocals " +
|
86
|
+
"and thoughtful lyrics. Brett Dennen has "that thing." " +
|
87
|
+
"Inspired fans describe it: "lush shimmering vocals, an intricately " +
|
88
|
+
"groovin' guitar style, a lyrical beauty rare in a young songwriter," +
|
89
|
+
"" and "this soulful blend of everything that feels good." " +
|
90
|
+
"Rising up around him is music; transcending genres, genders and generations."
|
91
|
+
end
|
92
|
+
|
93
|
+
folded = File.read(File.join(File.dirname(__FILE__), 'fixtures/folding.ics')).gsub("\n", "\r\n")
|
94
|
+
assert_equal(folded, @cal.to_ical)
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
BEGIN:VCALENDAR
|
2
|
+
VERSION:2.0
|
3
|
+
CALSCALE:GREGORIAN
|
4
|
+
PRODID:iCalendar-Ruby
|
5
|
+
X-WR-CALNAME:Test Long Description
|
6
|
+
BEGIN:VEVENT
|
7
|
+
SEQUENCE:1001
|
8
|
+
DTEND:20061215T180000
|
9
|
+
URL:http://test.com/events/644
|
10
|
+
UID:foobar
|
11
|
+
DESCRIPTION:FULL DETAILS:\nhttp://test.com/events/570\n\nCary Brothers walk
|
12
|
+
s the same musical ground as Pete Yorn\, Nick Drake\, Jeff Buckley and othe
|
13
|
+
rs\; crafting emotional melodies\, with strong vocals and thoughtful lyrics
|
14
|
+
. Brett Dennen has "\;that thing."\; Inspired fans describe it: &qu
|
15
|
+
ot\;lush shimmering vocals\, an intricately groovin'\; guitar style\, a
|
16
|
+
lyrical beauty rare in a young songwriter\,"\; and "\;this soulful
|
17
|
+
blend of everything that feels good."\; Rising up around him is music\;
|
18
|
+
transcending genres\, genders and generations.
|
19
|
+
SUMMARY:DigiWorld 2006
|
20
|
+
DTSTART:20061215T160000
|
21
|
+
DTSTAMP:20061215T114034
|
22
|
+
END:VEVENT
|
23
|
+
END:VCALENDAR
|
@@ -0,0 +1,46 @@
|
|
1
|
+
BEGIN:VCALENDAR
|
2
|
+
VERSION:2.0
|
3
|
+
X-WR-CALNAME:Life
|
4
|
+
PRODID:-//Apple Computer\, Inc//iCal 2.0//EN
|
5
|
+
X-WR-RELCALID:69FB0467-7E07-4DE7-901D-B70242B3DB25
|
6
|
+
X-WR-TIMEZONE:America/Chicago
|
7
|
+
CALSCALE:GREGORIAN
|
8
|
+
METHOD:PUBLISH
|
9
|
+
BEGIN:VTIMEZONE
|
10
|
+
TZID:America/Chicago
|
11
|
+
LAST-MODIFIED:20050825T194346Z
|
12
|
+
BEGIN:DAYLIGHT
|
13
|
+
DTSTART:20050403T080000
|
14
|
+
TZOFFSETTO:-0500
|
15
|
+
TZOFFSETFROM:+0000
|
16
|
+
TZNAME:CDT
|
17
|
+
END:DAYLIGHT
|
18
|
+
BEGIN:STANDARD
|
19
|
+
DTSTART:20051030T020000
|
20
|
+
TZOFFSETTO:-0600
|
21
|
+
TZOFFSETFROM:-0500
|
22
|
+
TZNAME:CST
|
23
|
+
END:STANDARD
|
24
|
+
END:VTIMEZONE
|
25
|
+
BEGIN:VEVENT
|
26
|
+
UID:bsuidfortestabc123
|
27
|
+
ORGANIZER:mailto:joebob@random.net
|
28
|
+
ATTACH:http://bush.sucks.org/impeach/him.rhtml
|
29
|
+
ATTACH:http://corporations-dominate.existence.net/why.rhtml
|
30
|
+
LAST-MODIFIED:20050825T194346Z
|
31
|
+
SUMMARY:This is a really long summary
|
32
|
+
to test the method of unfolding lines
|
33
|
+
so I'm just going to ma
|
34
|
+
ke it
|
35
|
+
a whol
|
36
|
+
e
|
37
|
+
bunch of lines.
|
38
|
+
CLASS:PRIVATE
|
39
|
+
PRIORITY:2
|
40
|
+
GEO:37.386013;-122.0829322
|
41
|
+
DTSTART;TZID=US-Mountain:20050120T170000
|
42
|
+
DTEND:20050120T184500
|
43
|
+
DTSTAMP:20050118T211523Z
|
44
|
+
END:VEVENT
|
45
|
+
END:VCALENDAR
|
46
|
+
|
@@ -0,0 +1,119 @@
|
|
1
|
+
BEGIN:VCALENDAR
|
2
|
+
VERSION
|
3
|
+
:2.0
|
4
|
+
PRODID
|
5
|
+
:-//Mozilla.org/NONSGML Mozilla Calendar V1.0//EN
|
6
|
+
BEGIN:VEVENT
|
7
|
+
UID
|
8
|
+
:a08863de-1dd1-11b2-9445-d6248402dd19
|
9
|
+
SUMMARY
|
10
|
+
:Hybrid Embedded Systems. This is a really long summary
|
11
|
+
to test the method of unfolding lines
|
12
|
+
so I'm just going to ma
|
13
|
+
ke it
|
14
|
+
a whole
|
15
|
+
bunch of lines.
|
16
|
+
CATEGORIES
|
17
|
+
:Personal
|
18
|
+
STATUS
|
19
|
+
:CONFIRMED
|
20
|
+
CLASS
|
21
|
+
:PRIVATE
|
22
|
+
RRULE
|
23
|
+
:FREQ=WEEKLY;INTERVAL=1;BYDAY=TH
|
24
|
+
DTSTART
|
25
|
+
:20050120T170000
|
26
|
+
DTEND
|
27
|
+
:20050120T184500
|
28
|
+
DTSTAMP
|
29
|
+
:20050118T211523Z
|
30
|
+
END:VEVENT
|
31
|
+
BEGIN:VEVENT
|
32
|
+
UID
|
33
|
+
:6226e2f6-1dd2-11b2-9ad7-9b8d2d642229
|
34
|
+
SUMMARY
|
35
|
+
:Databases
|
36
|
+
LOCATION
|
37
|
+
:ECCS 1b12
|
38
|
+
CATEGORIES
|
39
|
+
:Personal
|
40
|
+
STATUS
|
41
|
+
:CONFIRMED
|
42
|
+
CLASS
|
43
|
+
:PRIVATE
|
44
|
+
X-MOZILLA-ALARM-DEFAULT-LENGTH
|
45
|
+
:30
|
46
|
+
X-MOZILLA-LASTALARMACK
|
47
|
+
:20050118T141054
|
48
|
+
RRULE
|
49
|
+
:FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,WE
|
50
|
+
DTSTART
|
51
|
+
:20050117T173000
|
52
|
+
DTEND
|
53
|
+
:20050117T184500
|
54
|
+
DTSTAMP
|
55
|
+
:20050118T210648Z
|
56
|
+
LAST-MODIFIED
|
57
|
+
:20050118T211954Z
|
58
|
+
BEGIN:VALARM
|
59
|
+
TRIGGER
|
60
|
+
;VALUE=DURATION
|
61
|
+
:-PT30M
|
62
|
+
END:VALARM
|
63
|
+
END:VEVENT
|
64
|
+
BEGIN:VEVENT
|
65
|
+
UID
|
66
|
+
:d8f4468a-1dd1-11b2-9e0a-bbe95143dbed
|
67
|
+
SUMMARY
|
68
|
+
:Software Radios
|
69
|
+
LOCATION
|
70
|
+
:ECCR 1b06
|
71
|
+
CATEGORIES
|
72
|
+
:Personal
|
73
|
+
STATUS
|
74
|
+
:CONFIRMED
|
75
|
+
CLASS
|
76
|
+
:PRIVATE
|
77
|
+
X-MOZILLA-ALARM-DEFAULT-LENGTH
|
78
|
+
:30
|
79
|
+
X-MOZILLA-LASTALARMACK
|
80
|
+
:20050118T141351
|
81
|
+
RRULE
|
82
|
+
:FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,WE
|
83
|
+
DTSTART
|
84
|
+
:20050117T100000
|
85
|
+
DTEND
|
86
|
+
:20050117T111500
|
87
|
+
DTSTAMP
|
88
|
+
:20050118T211304Z
|
89
|
+
LAST-MODIFIED
|
90
|
+
:20050118T212016Z
|
91
|
+
BEGIN:VALARM
|
92
|
+
TRIGGER
|
93
|
+
;VALUE=DURATION
|
94
|
+
:-PT30M
|
95
|
+
END:VALARM
|
96
|
+
END:VEVENT
|
97
|
+
BEGIN:VEVENT
|
98
|
+
UID
|
99
|
+
:9acd4cc8-1dd1-11b2-a65e-b276ad1df3b9
|
100
|
+
SUMMARY
|
101
|
+
:Israel & Palestine peace accord talk...
|
102
|
+
LOCATION
|
103
|
+
:Chem. 140
|
104
|
+
CATEGORIES
|
105
|
+
:Personal
|
106
|
+
STATUS
|
107
|
+
:CONFIRMED
|
108
|
+
CLASS
|
109
|
+
:PRIVATE
|
110
|
+
DTSTART
|
111
|
+
:20050118T193000
|
112
|
+
DTEND
|
113
|
+
:20050118T203000
|
114
|
+
DTSTAMP
|
115
|
+
:20050118T212943Z
|
116
|
+
LAST-MODIFIED
|
117
|
+
:20050118T213355Z
|
118
|
+
END:VEVENT
|
119
|
+
END:VCALENDAR
|
@@ -0,0 +1,23 @@
|
|
1
|
+
BEGIN:VCALENDAR
|
2
|
+
VERSION:2.0
|
3
|
+
PRODID:bsprodidfortestabc123
|
4
|
+
BEGIN:VEVENT
|
5
|
+
UID:bsuidfortestabc123
|
6
|
+
ORGANIZER:mailto:joebob@random.net
|
7
|
+
ATTACH:http://bush.sucks.org/impeach/him.rhtml
|
8
|
+
ATTACH:http://corporations-dominate.existence.net/why.rhtml
|
9
|
+
SUMMARY:This is a really long summary
|
10
|
+
to test the method of unfolding lines\,
|
11
|
+
so I'm just going to ma
|
12
|
+
ke it
|
13
|
+
a whol
|
14
|
+
e
|
15
|
+
bunch of lines.
|
16
|
+
CLASS:PRIVATE
|
17
|
+
PRIORITY:2
|
18
|
+
GEO:37.386013;-122.0829322
|
19
|
+
DTSTART;TZID=US-Mountain:20050120T170000
|
20
|
+
DTEND:20050120T184500
|
21
|
+
DTSTAMP:20050118T211523Z
|
22
|
+
END:VEVENT
|
23
|
+
END:VCALENDAR
|
data/test/interactive.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# NOTE: you must have installed ruby-breakpoint in order to use this script.
|
4
|
+
# Grab it using gem with "gem install ruby-breakpoint --remote" or download
|
5
|
+
# from the website (http://ruby-breakpoint.rubyforge.org/) then run setup.rb
|
6
|
+
|
7
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
8
|
+
|
9
|
+
require 'rubygems'
|
10
|
+
require 'breakpoint'
|
11
|
+
|
12
|
+
require 'icalendar'
|
13
|
+
|
14
|
+
cal = Icalendar::Parser.new(File.new("life.ics")).parse
|
15
|
+
#cal = Icalendar::Calendar.new
|
16
|
+
|
17
|
+
breakpoint
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Test out property parameter functionality
|
2
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
3
|
+
|
4
|
+
require 'date'
|
5
|
+
require 'test/unit'
|
6
|
+
require 'icalendar'
|
7
|
+
|
8
|
+
class TestComponent < Test::Unit::TestCase
|
9
|
+
|
10
|
+
# Create a calendar with an event for each test.
|
11
|
+
def setup
|
12
|
+
@cal = Icalendar::Calendar.new
|
13
|
+
@event = Icalendar::Event.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_property_parameters
|
17
|
+
params = {"ALTREP" =>['"http://my.language.net"'], "LANGUAGE" => ["SPANISH"]}
|
18
|
+
@event.summary("This is a test summary.", params)
|
19
|
+
|
20
|
+
assert_equal params, @event.summary.ical_params
|
21
|
+
|
22
|
+
@cal.add_event @event
|
23
|
+
cal_str = @cal.to_ical
|
24
|
+
|
25
|
+
cals = Icalendar::Parser.new(cal_str).parse
|
26
|
+
event = cals.first.events.first
|
27
|
+
assert_equal params, event.summary.ical_params
|
28
|
+
end
|
29
|
+
end
|
data/test/parser_test.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'icalendar'
|
5
|
+
|
6
|
+
# This is a test class for the calendar parser.
|
7
|
+
class TestIcalendarParser < Test::Unit::TestCase
|
8
|
+
|
9
|
+
TEST_CAL = File.join(File.dirname(__FILE__), 'fixtures', 'single_event.ics')
|
10
|
+
|
11
|
+
# First make sure that we can run the parser and get back objects.
|
12
|
+
def test_new
|
13
|
+
# Make sure we don't take invalid object types.
|
14
|
+
assert_raise(ArgumentError) { Icalendar::Parser.new(nil) }
|
15
|
+
|
16
|
+
# Make sure we get an object back from parsing a file
|
17
|
+
calFile = File.open(TEST_CAL)
|
18
|
+
cals = Icalendar::Parser.new(calFile).parse
|
19
|
+
assert(cals)
|
20
|
+
calFile.close
|
21
|
+
|
22
|
+
# Make sure we get an object back from parsing a string
|
23
|
+
calString = File.open(TEST_CAL).read
|
24
|
+
cals = Icalendar::Parser.new(calString).parse
|
25
|
+
assert(cals)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Now go through and make sure the object is correct using the
|
29
|
+
# dynamically generated raw interfaces.
|
30
|
+
def test_zzfile_parse
|
31
|
+
calFile = File.open(TEST_CAL)
|
32
|
+
cals = Icalendar.parse(calFile)
|
33
|
+
calFile.close
|
34
|
+
do_asserts(cals)
|
35
|
+
|
36
|
+
Icalendar::Base.quiet
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_string_parse
|
40
|
+
# Make sure we get an object back from parsing a string
|
41
|
+
calString = File.open(TEST_CAL).read
|
42
|
+
cals = Icalendar::Parser.new(calString).parse
|
43
|
+
do_asserts(cals)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Just a helper method so we don't have to repeat the same tests.
|
47
|
+
def do_asserts(cals)
|
48
|
+
# Should just get one calendar back.
|
49
|
+
assert_equal(1, cals.size)
|
50
|
+
|
51
|
+
cal = cals.first
|
52
|
+
|
53
|
+
# Calendar properties
|
54
|
+
assert_equal("2.0", cal.version)
|
55
|
+
assert_equal("bsprodidfortestabc123", cal.prodid)
|
56
|
+
|
57
|
+
# Now the event
|
58
|
+
assert_equal(1, cal.events.size)
|
59
|
+
|
60
|
+
event = cal.events.first
|
61
|
+
assert_equal("bsuidfortestabc123", event.uid)
|
62
|
+
|
63
|
+
summary = "This is a really long summary to test the method of unfolding lines, so I'm just going to make it a whole bunch of lines."
|
64
|
+
|
65
|
+
assert_equal(summary, event.summary)
|
66
|
+
|
67
|
+
start = DateTime.parse("20050120T170000")
|
68
|
+
daend = DateTime.parse("20050120T184500")
|
69
|
+
stamp = DateTime.parse("20050118T211523Z")
|
70
|
+
assert_equal(start, event.dtstart)
|
71
|
+
assert_equal(daend, event.dtend)
|
72
|
+
assert_equal(stamp, event.dtstamp)
|
73
|
+
|
74
|
+
organizer = URI.parse("mailto:joebob@random.net")
|
75
|
+
assert_equal(organizer, event.organizer)
|
76
|
+
|
77
|
+
ats = event.attachments
|
78
|
+
assert_equal(2, ats.size)
|
79
|
+
attachment = URI.parse("http://bush.sucks.org/impeach/him.rhtml")
|
80
|
+
assert_equal(attachment, ats[0])
|
81
|
+
attachment = URI.parse("http://corporations-dominate.existence.net/why.rhtml")
|
82
|
+
assert_equal(attachment, ats[1])
|
83
|
+
end
|
84
|
+
end
|