icalendar 0.96.4 → 0.97
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/README +66 -53
- data/Rakefile +33 -24
- data/docs/api/classes/Array.html +9 -11
- data/docs/api/classes/Array.src/M000002.html +18 -0
- data/docs/api/classes/Date.html +2 -22
- data/docs/api/classes/Date.src/M000004.html +29 -0
- data/docs/api/classes/DateTime.html +2 -43
- data/docs/api/classes/DateTime.src/M000005.html +50 -0
- data/docs/api/classes/Fixnum.html +2 -11
- data/docs/api/classes/Fixnum.src/M000011.html +18 -0
- data/docs/api/classes/Float.html +2 -11
- data/docs/api/classes/Float.src/M000003.html +18 -0
- data/docs/api/classes/HashAttrs.html +15 -60
- data/docs/api/classes/HashAttrs.src/M000068.html +26 -0
- data/docs/api/classes/HashAttrs.src/M000069.html +27 -0
- data/docs/api/classes/HashAttrs.src/M000070.html +19 -0
- data/docs/api/classes/Icalendar/Alarm.html +5 -15
- data/docs/api/classes/Icalendar/Alarm.src/M000020.html +22 -0
- data/docs/api/classes/Icalendar/Base.html +41 -0
- data/docs/api/classes/Icalendar/Base.src/M000022.html +18 -0
- data/docs/api/classes/Icalendar/Base.src/M000023.html +18 -0
- data/docs/api/classes/Icalendar/Calendar.html +116 -116
- data/docs/api/classes/Icalendar/Calendar.src/M000054.html +23 -0
- data/docs/api/classes/Icalendar/Calendar.src/M000055.html +23 -0
- data/docs/api/classes/Icalendar/Calendar.src/M000056.html +18 -0
- data/docs/api/classes/Icalendar/Calendar.src/M000057.html +23 -0
- data/docs/api/classes/Icalendar/Calendar.src/M000058.html +18 -0
- data/docs/api/classes/Icalendar/Calendar.src/M000059.html +23 -0
- data/docs/api/classes/Icalendar/Calendar.src/M000060.html +18 -0
- data/docs/api/classes/Icalendar/Calendar.src/M000061.html +23 -0
- data/docs/api/classes/Icalendar/Calendar.src/M000062.html +18 -0
- data/docs/api/classes/Icalendar/Calendar.src/M000063.html +23 -0
- data/docs/api/classes/Icalendar/Calendar.src/M000064.html +19 -0
- data/docs/api/classes/Icalendar/Component.html +200 -367
- data/docs/api/classes/Icalendar/Component.src/M000029.html +22 -0
- data/docs/api/classes/Icalendar/Component.src/M000030.html +24 -0
- data/docs/api/classes/Icalendar/Component.src/M000035.html +22 -0
- data/docs/api/classes/Icalendar/Component.src/M000040.html +18 -0
- data/docs/api/classes/Icalendar/Component.src/M000041.html +24 -0
- data/docs/api/classes/Icalendar/Component.src/M000042.html +28 -0
- data/docs/api/classes/Icalendar/Component.src/M000043.html +37 -0
- data/docs/api/classes/Icalendar/Component.src/M000044.html +37 -0
- data/docs/api/classes/Icalendar/Component.src/M000045.html +18 -0
- data/docs/api/classes/Icalendar/Component.src/M000046.html +18 -0
- data/docs/api/classes/Icalendar/Component.src/M000047.html +18 -0
- data/docs/api/classes/Icalendar/Component.src/M000048.html +26 -0
- data/docs/api/classes/Icalendar/Component.src/M000049.html +29 -0
- data/docs/api/classes/Icalendar/Component.src/M000050.html +22 -0
- data/docs/api/classes/Icalendar/DateProp.html +2 -12
- data/docs/api/classes/Icalendar/DateProp.src/M000013.html +19 -0
- data/docs/api/classes/Icalendar/DateProp/ClassMethods.html +2 -59
- data/docs/api/classes/Icalendar/DateProp/ClassMethods.src/M000014.html +66 -0
- data/docs/api/classes/Icalendar/Daylight.html +5 -14
- data/docs/api/classes/Icalendar/Daylight.src/M000051.html +18 -0
- data/docs/api/classes/Icalendar/Event.html +30 -37
- data/docs/api/classes/Icalendar/Event.src/M000052.html +23 -0
- data/docs/api/classes/Icalendar/Event.src/M000053.html +23 -0
- data/docs/api/classes/Icalendar/Freebusy.html +5 -14
- data/docs/api/classes/Icalendar/Freebusy.src/M000065.html +21 -0
- data/docs/api/classes/Icalendar/Geo.html +192 -0
- data/docs/api/classes/Icalendar/Geo.src/M000024.html +19 -0
- data/docs/api/classes/Icalendar/Geo.src/M000025.html +18 -0
- data/docs/api/classes/Icalendar/Journal.html +2 -11
- data/docs/api/classes/Icalendar/Journal.src/M000016.html +22 -0
- data/docs/api/classes/Icalendar/Parameter.html +5 -23
- data/docs/api/classes/Icalendar/Parameter.src/M000066.html +27 -0
- data/docs/api/classes/Icalendar/Parser.html +36 -212
- data/docs/api/classes/Icalendar/Parser.src/M000017.html +32 -0
- data/docs/api/classes/Icalendar/Parser.src/M000018.html +43 -0
- data/docs/api/classes/Icalendar/Parser.src/M000019.html +33 -0
- data/docs/api/classes/Icalendar/Standard.html +2 -11
- data/docs/api/classes/Icalendar/Standard.src/M000015.html +18 -0
- data/docs/api/classes/Icalendar/Timezone.html +16 -48
- data/docs/api/classes/Icalendar/Timezone.src/M000026.html +19 -0
- data/docs/api/classes/Icalendar/Timezone.src/M000027.html +22 -0
- data/docs/api/classes/Icalendar/Timezone.src/M000028.html +18 -0
- data/docs/api/classes/Icalendar/Todo.html +5 -14
- data/docs/api/classes/Icalendar/Todo.src/M000021.html +22 -0
- data/docs/api/classes/Object.html +10 -59
- data/docs/api/classes/Object.src/M000006.html +20 -0
- data/docs/api/classes/Object.src/M000007.html +18 -0
- data/docs/api/classes/Object.src/M000008.html +20 -0
- data/docs/api/classes/Object.src/M000009.html +18 -0
- data/docs/api/classes/Object.src/M000010.html +18 -0
- data/docs/api/classes/String.html +2 -11
- data/docs/api/classes/String.src/M000012.html +18 -0
- data/docs/api/classes/Time.html +2 -26
- data/docs/api/classes/Time.src/M000001.html +37 -0
- data/docs/api/classes/URI/Generic.html +5 -14
- data/docs/api/classes/URI/Generic.src/M000067.html +18 -0
- data/docs/api/created.rid +1 -1
- data/docs/api/files/COPYING.html +1 -1
- data/docs/api/files/GPL.html +1 -1
- data/docs/api/files/README.html +76 -64
- data/docs/api/files/lib/hash_attrs_rb.html +1 -1
- data/docs/api/files/lib/icalendar/base_rb.html +1 -1
- data/docs/api/files/lib/icalendar/calendar_rb.html +1 -1
- data/docs/api/files/lib/icalendar/component/alarm_rb.html +1 -1
- data/docs/api/files/lib/icalendar/component/event_rb.html +1 -1
- data/docs/api/files/lib/icalendar/component/freebusy_rb.html +1 -1
- data/docs/api/files/lib/icalendar/component/journal_rb.html +1 -1
- data/docs/api/files/lib/icalendar/component/timezone_rb.html +1 -1
- data/docs/api/files/lib/icalendar/component/todo_rb.html +1 -1
- data/docs/api/files/lib/icalendar/component_rb.html +8 -1
- data/docs/api/files/lib/icalendar/conversions_rb.html +1 -1
- data/docs/api/files/lib/icalendar/helpers_rb.html +1 -1
- data/docs/api/files/lib/icalendar/parameter_rb.html +1 -1
- data/docs/api/files/lib/icalendar/parser_rb.html +2 -1
- data/docs/api/files/lib/icalendar_rb.html +1 -1
- data/docs/api/files/lib/meta_rb.html +1 -1
- data/docs/api/fr_class_index.html +1 -0
- data/docs/api/fr_method_index.html +57 -41
- data/docs/rfcs/itip_notes.txt +69 -0
- data/examples/create_cal.rb +33 -32
- data/examples/parse_cal.rb +2 -2
- data/lib/icalendar/base.rb +8 -0
- data/lib/icalendar/calendar.rb +32 -3
- data/lib/icalendar/component.rb +187 -113
- data/lib/icalendar/component/alarm.rb +3 -0
- data/lib/icalendar/component/event.rb +9 -3
- data/lib/icalendar/component/freebusy.rb +3 -0
- data/lib/icalendar/component/journal.rb +4 -0
- data/lib/icalendar/component/todo.rb +4 -0
- data/lib/icalendar/conversions.rb +7 -1
- data/lib/icalendar/parser.rb +68 -90
- data/test/calendar_test.rb +32 -8
- data/test/component/event_test.rb +4 -7
- data/test/component/todo_test.rb +13 -0
- data/test/component_test.rb +21 -34
- data/test/conversions_test.rb +66 -0
- data/test/coverage/-home-rosejn-projects-icalendar-lib-hash_attrs_rb.html +574 -0
- data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar-base_rb.html +575 -0
- data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar-calendar_rb.html +629 -0
- data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar-component-alarm_rb.html +581 -0
- data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar-component-event_rb.html +658 -0
- data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar-component-freebusy_rb.html +574 -0
- data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar-component-journal_rb.html +597 -0
- data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar-component-timezone_rb.html +625 -0
- data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar-component-todo_rb.html +600 -0
- data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar-component_rb.html +924 -0
- data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar-conversions_rb.html +667 -0
- data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar-parser_rb.html +938 -0
- data/test/coverage/-home-rosejn-projects-icalendar-lib-icalendar_rb.html +576 -0
- data/test/coverage/-home-rosejn-projects-icalendar-lib-meta_rb.html +572 -0
- data/test/coverage/calendar_test_rb.html +590 -0
- data/test/coverage/component_test_rb.html +602 -0
- data/test/coverage/index.html +1009 -0
- data/test/coverage/lib-hash_attrs_rb.html +574 -0
- data/test/coverage/lib-icalendar-base_rb.html +583 -0
- data/test/coverage/lib-icalendar-calendar_rb.html +631 -0
- data/test/coverage/lib-icalendar-component-alarm_rb.html +581 -0
- data/test/coverage/lib-icalendar-component-event_rb.html +661 -0
- data/test/coverage/lib-icalendar-component-freebusy_rb.html +576 -0
- data/test/coverage/lib-icalendar-component-journal_rb.html +599 -0
- data/test/coverage/lib-icalendar-component-timezone_rb.html +625 -0
- data/test/coverage/lib-icalendar-component-todo_rb.html +602 -0
- data/test/coverage/lib-icalendar-component_rb.html +941 -0
- data/test/coverage/lib-icalendar-conversions_rb.html +673 -0
- data/test/coverage/lib-icalendar-parser_rb.html +916 -0
- data/test/coverage/lib-icalendar_rb.html +576 -0
- data/test/coverage/lib-meta_rb.html +572 -0
- data/test/coverage/parameter_test_rb.html +569 -0
- data/test/coverage/parser_test_rb.html +623 -0
- data/test/coverage/test-calendar_test_rb.html +590 -0
- data/test/coverage/test-component-event_test_rb.html +584 -0
- data/test/coverage/test-component_test_rb.html +606 -0
- data/test/coverage/test-conversions_test_rb.html +603 -0
- data/test/coverage/test-parameter_test_rb.html +569 -0
- data/test/coverage/test-parser_test_rb.html +624 -0
- data/test/interactive.rb +3 -1
- data/test/life.ics +46 -1092
- data/test/parameter_test.rb +11 -2
- data/test/parser_test.rb +12 -11
- metadata +259 -126
- data/test/old_life.ics +0 -46
- data/test/rw.ics +0 -947
|
@@ -19,7 +19,7 @@ module Icalendar
|
|
|
19
19
|
## Single instance properties
|
|
20
20
|
|
|
21
21
|
# Access classification (PUBLIC, PRIVATE, CONFIDENTIAL...)
|
|
22
|
-
ical_property :ip_class
|
|
22
|
+
ical_property :ip_class, :klass
|
|
23
23
|
|
|
24
24
|
# Date & time of creation
|
|
25
25
|
ical_property :created
|
|
@@ -31,7 +31,7 @@ module Icalendar
|
|
|
31
31
|
ical_property :dtstart, :start
|
|
32
32
|
|
|
33
33
|
# Latitude & longitude for specified activity
|
|
34
|
-
ical_property :geo
|
|
34
|
+
ical_property :geo, :geo_location
|
|
35
35
|
|
|
36
36
|
# Date & time this item was last modified
|
|
37
37
|
ical_property :last_modified
|
|
@@ -57,7 +57,7 @@ module Icalendar
|
|
|
57
57
|
ical_property :transp, :transparency
|
|
58
58
|
|
|
59
59
|
# Defines a persistent, globally unique id for this item
|
|
60
|
-
ical_property :uid, :
|
|
60
|
+
ical_property :uid, :unique_id
|
|
61
61
|
|
|
62
62
|
# Defines a URL associated with this item
|
|
63
63
|
ical_property :url
|
|
@@ -102,6 +102,11 @@ module Icalendar
|
|
|
102
102
|
|
|
103
103
|
def initialize()
|
|
104
104
|
super("VEVENT")
|
|
105
|
+
|
|
106
|
+
# Now doing some basic initialization
|
|
107
|
+
sequence 0
|
|
108
|
+
timestamp DateTime.now
|
|
109
|
+
uid new_uid
|
|
105
110
|
end
|
|
106
111
|
|
|
107
112
|
def alarm(&block)
|
|
@@ -113,5 +118,6 @@ module Icalendar
|
|
|
113
118
|
a
|
|
114
119
|
end
|
|
115
120
|
|
|
121
|
+
|
|
116
122
|
end
|
|
117
123
|
end
|
|
@@ -20,7 +20,7 @@ require 'uri/generic'
|
|
|
20
20
|
|
|
21
21
|
class String
|
|
22
22
|
def to_ical
|
|
23
|
-
"#{self
|
|
23
|
+
"#{self}"
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
|
|
@@ -36,6 +36,8 @@ class Float
|
|
|
36
36
|
end
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
+
# From the spec: "Values in a list of values MUST be separated by a COMMA
|
|
40
|
+
# character (US-ASCII decimal 44)."
|
|
39
41
|
class Array
|
|
40
42
|
def to_ical
|
|
41
43
|
map{|elem| elem.to_ical}.join ','
|
|
@@ -107,6 +109,8 @@ end
|
|
|
107
109
|
|
|
108
110
|
class Time
|
|
109
111
|
def to_ical(utc = false)
|
|
112
|
+
s = ""
|
|
113
|
+
|
|
110
114
|
# Double digit hour
|
|
111
115
|
s << "0" unless self.hour > 9
|
|
112
116
|
s << self.hour.to_s
|
|
@@ -123,5 +127,7 @@ class Time
|
|
|
123
127
|
if utc
|
|
124
128
|
s << "Z"
|
|
125
129
|
end
|
|
130
|
+
|
|
131
|
+
s
|
|
126
132
|
end
|
|
127
133
|
end
|
data/lib/icalendar/parser.rb
CHANGED
|
@@ -9,27 +9,20 @@
|
|
|
9
9
|
|
|
10
10
|
require 'date'
|
|
11
11
|
require 'uri'
|
|
12
|
+
require 'stringio'
|
|
12
13
|
|
|
13
14
|
module Icalendar
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
NAME = '[-a-z0-9]+'
|
|
17
|
-
|
|
18
|
-
# <"> <Any character except CTLs, DQUOTE> <">
|
|
19
|
-
QSTR = '"[^"]*"'
|
|
15
|
+
def Icalendar.parse(src, single = false)
|
|
16
|
+
cals = Icalendar::Parser.new(src).parse
|
|
20
17
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
# Contentline
|
|
28
|
-
LINE = "(#{NAME})([^:]*)\:(.*)"
|
|
29
|
-
|
|
30
|
-
# param = name "=" param-value *("," param-value)
|
|
31
|
-
PARAM = ";(#{NAME})(=?)((?:#{PVALUE})(?:,#{PVALUE})*)"
|
|
18
|
+
if single
|
|
19
|
+
cals.first
|
|
20
|
+
else
|
|
21
|
+
cals
|
|
22
|
+
end
|
|
23
|
+
end
|
|
32
24
|
|
|
25
|
+
class Parser < Icalendar::Base
|
|
33
26
|
# date = date-fullyear ["-"] date-month ["-"] date-mday
|
|
34
27
|
# date-fullyear = 4 DIGIT
|
|
35
28
|
# date-month = 2 DIGIT
|
|
@@ -46,92 +39,59 @@ module Icalendar
|
|
|
46
39
|
TIME = '(\d\d):?(\d\d):?(\d\d)(\.\d+)?(Z|[-+]\d\d:?\d\d)?'
|
|
47
40
|
|
|
48
41
|
def initialize(src)
|
|
49
|
-
@@logger.debug("New Calendar Parser")
|
|
50
|
-
|
|
51
42
|
# Setup the parser method hash table
|
|
52
43
|
setup_parsers()
|
|
53
44
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
45
|
+
if src.respond_to?(:gets)
|
|
46
|
+
@file = src
|
|
47
|
+
elsif (not src.nil?) and src.respond_to?(:to_s)
|
|
48
|
+
@file = StringIO.new(src.to_s, 'r')
|
|
49
|
+
else
|
|
50
|
+
raise ArgumentError, "CalendarParser.new cannot be called with a #{src.class} type!"
|
|
51
|
+
end
|
|
57
52
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
unfolded = []
|
|
53
|
+
@prev_line = @file.gets
|
|
54
|
+
@prev_line.chomp! unless @prev_line.nil?
|
|
61
55
|
|
|
62
|
-
|
|
63
|
-
|
|
56
|
+
@@logger.debug("New Calendar Parser: #{@file.inspect}")
|
|
57
|
+
end
|
|
64
58
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
elsif( line =~ /^$/ )
|
|
70
|
-
else
|
|
71
|
-
unfolded << line
|
|
72
|
-
end
|
|
73
|
-
end
|
|
59
|
+
# Define next line for an IO object.
|
|
60
|
+
# Works for strings now with StringIO
|
|
61
|
+
def next_line
|
|
62
|
+
line = @prev_line
|
|
74
63
|
|
|
75
|
-
|
|
76
|
-
|
|
64
|
+
if line.nil?
|
|
65
|
+
return nil
|
|
66
|
+
end
|
|
77
67
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
return nil
|
|
83
|
-
else
|
|
84
|
-
line = @lines[@index]
|
|
85
|
-
@index += 1
|
|
86
|
-
return line
|
|
87
|
-
end
|
|
88
|
-
end
|
|
68
|
+
# Loop through until we get to a non-continuation line...
|
|
69
|
+
loop do
|
|
70
|
+
nextLine = @file.gets
|
|
71
|
+
@@logger.debug "new_line: #{nextLine}"
|
|
89
72
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
elsif src.respond_to?(:gets)
|
|
93
|
-
@file = src
|
|
94
|
-
@prev_line = src.gets
|
|
95
|
-
if !@prev_line.nil?
|
|
96
|
-
@prev_line.chomp!
|
|
73
|
+
if !nextLine.nil?
|
|
74
|
+
nextLine.chomp!
|
|
97
75
|
end
|
|
98
76
|
|
|
99
|
-
#
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
# Loop through until we get to a non-continuation line...
|
|
108
|
-
loop do
|
|
109
|
-
nextLine = @file.gets
|
|
110
|
-
if !nextLine.nil?
|
|
111
|
-
nextLine.chomp!
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
# If it's a continuation line, add it to the last.
|
|
115
|
-
# If it's an empty line, drop it from the input.
|
|
116
|
-
if( nextLine =~ /^[ \t]/ )
|
|
117
|
-
line << nextLine[1, nextLine.size]
|
|
118
|
-
elsif( nextLine =~ /^$/ )
|
|
119
|
-
else
|
|
120
|
-
@prev_line = nextLine
|
|
121
|
-
break
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
line
|
|
77
|
+
# If it's a continuation line, add it to the last.
|
|
78
|
+
# If it's an empty line, drop it from the input.
|
|
79
|
+
if( nextLine =~ /^[ \t]/ )
|
|
80
|
+
line << nextLine[1, nextLine.size]
|
|
81
|
+
elsif( nextLine =~ /^$/ )
|
|
82
|
+
else
|
|
83
|
+
@prev_line = nextLine
|
|
84
|
+
break
|
|
125
85
|
end
|
|
126
|
-
else
|
|
127
|
-
raise ArgumentError, "CalendarParser.new cannot be called with a #{src.class} type!"
|
|
128
86
|
end
|
|
87
|
+
line
|
|
129
88
|
end
|
|
130
89
|
|
|
131
90
|
# Parse the calendar into an object representation
|
|
132
91
|
def parse
|
|
133
92
|
calendars = []
|
|
134
93
|
|
|
94
|
+
@@logger.debug "parsing..."
|
|
135
95
|
# Outer loop for Calendar objects
|
|
136
96
|
while (line = next_line)
|
|
137
97
|
fields = parse_line(line)
|
|
@@ -139,6 +99,7 @@ module Icalendar
|
|
|
139
99
|
# Just iterate through until we find the beginning of a calendar object
|
|
140
100
|
if fields[:name] == "BEGIN" and fields[:value] == "VCALENDAR"
|
|
141
101
|
cal = parse_component
|
|
102
|
+
@@logger.debug "Added parsed calendar..."
|
|
142
103
|
calendars << cal
|
|
143
104
|
end
|
|
144
105
|
end
|
|
@@ -153,6 +114,8 @@ module Icalendar
|
|
|
153
114
|
# and then one or more calendar components: VEVENT, VTODO, VJOURNAL,
|
|
154
115
|
# VFREEBUSY, VTIMEZONE
|
|
155
116
|
def parse_component(component = Calendar.new)
|
|
117
|
+
@@logger.debug "parsing new component..."
|
|
118
|
+
|
|
156
119
|
while (line = next_line)
|
|
157
120
|
fields = parse_line(line)
|
|
158
121
|
|
|
@@ -208,7 +171,7 @@ module Icalendar
|
|
|
208
171
|
if component.multi_property?(name)
|
|
209
172
|
adder = "add_" + name
|
|
210
173
|
if component.respond_to?(adder)
|
|
211
|
-
component.send(adder
|
|
174
|
+
component.send(adder, value, params)
|
|
212
175
|
else
|
|
213
176
|
raise(UnknownPropertyMethod, "Unknown property type: #{adder}")
|
|
214
177
|
end
|
|
@@ -225,6 +188,24 @@ module Icalendar
|
|
|
225
188
|
component
|
|
226
189
|
end
|
|
227
190
|
|
|
191
|
+
# 1*(ALPHA / DIGIT / "=")
|
|
192
|
+
NAME = '[-a-z0-9]+'
|
|
193
|
+
|
|
194
|
+
# <"> <Any character except CTLs, DQUOTE> <">
|
|
195
|
+
QSTR = '"[^"]*"'
|
|
196
|
+
|
|
197
|
+
# Contentline
|
|
198
|
+
LINE = "(#{NAME})(.*(?:#{QSTR})|(?:[^:]*))\:(.*)"
|
|
199
|
+
|
|
200
|
+
# *<Any character except CTLs, DQUOTE, ";", ":", ",">
|
|
201
|
+
PTEXT = '[^";:,]*'
|
|
202
|
+
|
|
203
|
+
# param-value = ptext / quoted-string
|
|
204
|
+
PVALUE = "#{QSTR}|#{PTEXT}"
|
|
205
|
+
|
|
206
|
+
# param = name "=" param-value *("," param-value)
|
|
207
|
+
PARAM = ";(#{NAME})(=?)((?:#{PVALUE})(?:,#{PVALUE})*)"
|
|
208
|
+
|
|
228
209
|
def parse_line(line)
|
|
229
210
|
unless line =~ %r{#{LINE}}i # Case insensitive match for a valid line
|
|
230
211
|
raise "Invalid line in calendar string!"
|
|
@@ -274,7 +255,7 @@ module Icalendar
|
|
|
274
255
|
end
|
|
275
256
|
end
|
|
276
257
|
|
|
277
|
-
{:name => name, :
|
|
258
|
+
{:name => name, :value => value, :params => params}
|
|
278
259
|
end
|
|
279
260
|
|
|
280
261
|
## Following is a collection of parsing functions for various
|
|
@@ -388,10 +369,7 @@ module Icalendar
|
|
|
388
369
|
return value
|
|
389
370
|
end
|
|
390
371
|
|
|
391
|
-
|
|
392
|
-
val[0] = strloc[0].to_f
|
|
393
|
-
val[1] = strloc[1].to_f
|
|
394
|
-
val
|
|
372
|
+
Geo.new(strloc[0].to_f, strloc[1].to_f)
|
|
395
373
|
end
|
|
396
374
|
|
|
397
375
|
end
|
data/test/calendar_test.rb
CHANGED
|
@@ -6,11 +6,12 @@ require 'icalendar'
|
|
|
6
6
|
require 'date'
|
|
7
7
|
|
|
8
8
|
class TestCalendar < Test::Unit::TestCase
|
|
9
|
+
include Icalendar
|
|
9
10
|
# Generate a calendar using the raw api, and then spit it out
|
|
10
11
|
# as a string. Parse the string and make sure everything matches up.
|
|
11
12
|
def test_raw_generation
|
|
12
13
|
# Create a fresh calendar
|
|
13
|
-
cal =
|
|
14
|
+
cal = Calendar.new
|
|
14
15
|
|
|
15
16
|
cal.calscale = "GREGORIAN"
|
|
16
17
|
cal.version = "3.2"
|
|
@@ -20,7 +21,7 @@ class TestCalendar < Test::Unit::TestCase
|
|
|
20
21
|
# that everything was set, generated and parsed correctly.
|
|
21
22
|
calString = cal.to_ical
|
|
22
23
|
|
|
23
|
-
cals =
|
|
24
|
+
cals = Parser.new(calString).parse
|
|
24
25
|
|
|
25
26
|
cal2 = cals.first
|
|
26
27
|
assert_equal("GREGORIAN", cal2.calscale)
|
|
@@ -29,19 +30,42 @@ class TestCalendar < Test::Unit::TestCase
|
|
|
29
30
|
end
|
|
30
31
|
|
|
31
32
|
def test_block_creation
|
|
32
|
-
cal =
|
|
33
|
+
cal = Calendar.new
|
|
33
34
|
cal.event do
|
|
34
|
-
dtend "19970903T190000Z"
|
|
35
|
-
summary "This is my summary"
|
|
35
|
+
self.dtend = "19970903T190000Z"
|
|
36
|
+
self.summary = "This is my summary"
|
|
36
37
|
end
|
|
37
38
|
|
|
38
39
|
event = cal.event
|
|
39
|
-
event.dtend
|
|
40
|
-
event.summary
|
|
40
|
+
event.dtend "19970903T190000Z", {:TZID => "Europe/Copenhagen"}
|
|
41
|
+
event.summary "This is my summary"
|
|
41
42
|
|
|
42
|
-
# breakpoint
|
|
43
43
|
ev = cal.events.each do |ev|
|
|
44
44
|
assert_equal("19970903T190000Z", ev.dtend)
|
|
45
|
+
assert_equal("This is my summary", ev.summary)
|
|
45
46
|
end
|
|
46
47
|
end
|
|
48
|
+
|
|
49
|
+
def test_find
|
|
50
|
+
cal = Calendar.new
|
|
51
|
+
|
|
52
|
+
# add some events so we actually have to search
|
|
53
|
+
10.times do
|
|
54
|
+
cal.event
|
|
55
|
+
cal.todo
|
|
56
|
+
cal.journal
|
|
57
|
+
cal.freebusy
|
|
58
|
+
end
|
|
59
|
+
event = cal.events[5]
|
|
60
|
+
assert_equal(event, cal.find_event(event.uid))
|
|
61
|
+
|
|
62
|
+
todo = cal.todos[5]
|
|
63
|
+
assert_equal(todo, cal.find_todo(todo.uid))
|
|
64
|
+
|
|
65
|
+
journal = cal.journals[5]
|
|
66
|
+
assert_equal(journal, cal.find_journal(journal.uid))
|
|
67
|
+
|
|
68
|
+
freebusy = cal.freebusys[5]
|
|
69
|
+
assert_equal(freebusy, cal.find_freebusy(freebusy.uid))
|
|
70
|
+
end
|
|
47
71
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
|
|
2
2
|
|
|
3
3
|
require 'test/unit'
|
|
4
4
|
require 'icalendar'
|
|
@@ -16,7 +16,7 @@ CATEGORIES:BUSINESS,HUMAN RESOURCES
|
|
|
16
16
|
END:VEVENT
|
|
17
17
|
EOS
|
|
18
18
|
|
|
19
|
-
class
|
|
19
|
+
class TestEvent < Test::Unit::TestCase
|
|
20
20
|
|
|
21
21
|
# Create a calendar with an event for each test.
|
|
22
22
|
def setup
|
|
@@ -32,16 +32,13 @@ class TestVevent < Test::Unit::TestCase
|
|
|
32
32
|
def test_single_properties
|
|
33
33
|
@event.ip_class = "PRIVATE"
|
|
34
34
|
|
|
35
|
-
@cal.
|
|
35
|
+
@cal.add_event(@event)
|
|
36
36
|
|
|
37
37
|
cals = Icalendar::Parser.new(@cal.to_ical).parse
|
|
38
38
|
cal2 = cals.first
|
|
39
39
|
event2 = cal2.events.first
|
|
40
40
|
|
|
41
|
-
assert_equal(event2.ip_class
|
|
41
|
+
assert_equal("PRIVATE", event2.ip_class)
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
# def test_restricted_properties
|
|
45
|
-
# end
|
|
46
|
-
|
|
47
44
|
end
|