icalendar 0.96.4 → 0.97
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/examples/parse_cal.rb
CHANGED
@@ -10,11 +10,11 @@ cal_file = File.open("../test/life.ics")
|
|
10
10
|
|
11
11
|
# Parser returns an array of calendars because a single file
|
12
12
|
# can have multiple calendar objects.
|
13
|
-
cals = Icalendar::
|
13
|
+
cals = Icalendar::parse(cal_file)
|
14
14
|
cal = cals.first
|
15
15
|
|
16
16
|
# Now you can access the cal object in just the same way I created it
|
17
17
|
event = cal.events.first
|
18
18
|
|
19
|
-
puts "
|
19
|
+
puts "start date-time: " + event.dtstart.to_s
|
20
20
|
puts "summary: " + event.summary
|
data/lib/icalendar/base.rb
CHANGED
data/lib/icalendar/calendar.rb
CHANGED
@@ -18,12 +18,10 @@ module Icalendar
|
|
18
18
|
|
19
19
|
def initialize()
|
20
20
|
super("VCALENDAR")
|
21
|
-
@properties = {}
|
22
|
-
@property_params = {}
|
23
21
|
|
24
22
|
# Set some defaults
|
25
23
|
self.calscale = "GREGORIAN" # Who knows, but this is the only one in the spec.
|
26
|
-
self.prodid = "iCalendar-Ruby" # Current product... Should be overwritten
|
24
|
+
self.prodid = "iCalendar-Ruby" # Current product... Should be overwritten by apps that use the library
|
27
25
|
self.version = "2.0" # Version of the specification
|
28
26
|
end
|
29
27
|
|
@@ -35,6 +33,10 @@ module Icalendar
|
|
35
33
|
|
36
34
|
e
|
37
35
|
end
|
36
|
+
|
37
|
+
def find_event(uid)
|
38
|
+
self.events.find {|e| e.uid == uid}
|
39
|
+
end
|
38
40
|
|
39
41
|
def todo(&block)
|
40
42
|
e = Todo.new
|
@@ -45,6 +47,10 @@ module Icalendar
|
|
45
47
|
e
|
46
48
|
end
|
47
49
|
|
50
|
+
def find_todo(uid)
|
51
|
+
self.todos.find {|t| t.uid == uid}
|
52
|
+
end
|
53
|
+
|
48
54
|
def journal(&block)
|
49
55
|
e = Journal.new
|
50
56
|
self.add_component e
|
@@ -54,6 +60,10 @@ module Icalendar
|
|
54
60
|
e
|
55
61
|
end
|
56
62
|
|
63
|
+
def find_journal(uid)
|
64
|
+
self.journals.find {|j| j.uid == uid}
|
65
|
+
end
|
66
|
+
|
57
67
|
def freebusy(&block)
|
58
68
|
e = Freebusy.new
|
59
69
|
self.add_component e
|
@@ -63,6 +73,10 @@ module Icalendar
|
|
63
73
|
e
|
64
74
|
end
|
65
75
|
|
76
|
+
def find_freebusy(uid)
|
77
|
+
self.freebusys.find {|f| f.uid == uid}
|
78
|
+
end
|
79
|
+
|
66
80
|
def timezone(&block)
|
67
81
|
e = Timezone.new
|
68
82
|
self.add_component e
|
@@ -71,6 +85,21 @@ module Icalendar
|
|
71
85
|
|
72
86
|
e
|
73
87
|
end
|
88
|
+
|
89
|
+
# The "PUBLISH" method in a "VEVENT" calendar component is an
|
90
|
+
# unsolicited posting of an iCalendar object. Any CU may add published
|
91
|
+
# components to their calendar. The "Organizer" MUST be present in a
|
92
|
+
# published iCalendar component. "Attendees" MUST NOT be present. Its
|
93
|
+
# expected usage is for encapsulating an arbitrary event as an
|
94
|
+
# iCalendar object. The "Organizer" may subsequently update (with
|
95
|
+
# another "PUBLISH" method), add instances to (with an "ADD" method),
|
96
|
+
# or cancel (with a "CANCEL" method) a previously published "VEVENT"
|
97
|
+
# calendar component.
|
98
|
+
def publish
|
99
|
+
ip_method = "PUBLISH"
|
100
|
+
|
101
|
+
end
|
102
|
+
|
74
103
|
end # class Calendar
|
75
104
|
|
76
105
|
end # module Icalendar
|
data/lib/icalendar/component.rb
CHANGED
@@ -7,6 +7,23 @@
|
|
7
7
|
=end
|
8
8
|
|
9
9
|
module Icalendar
|
10
|
+
require 'socket'
|
11
|
+
|
12
|
+
class Geo < Icalendar::Base
|
13
|
+
attr_accessor :latitude, :longitude
|
14
|
+
alias :lat :latitude
|
15
|
+
alias :long :longitude
|
16
|
+
|
17
|
+
def initialize(lat, long)
|
18
|
+
@lat = lat
|
19
|
+
@long = long
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_ical
|
23
|
+
"#{@lat.to_ical};#{@long.to_ical}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
10
27
|
# The body of the iCalendar object consists of a sequence of calendar
|
11
28
|
# properties and one or more calendar components. The calendar
|
12
29
|
# properties are attributes that apply to the calendar as a whole. The
|
@@ -19,7 +36,7 @@ module Icalendar
|
|
19
36
|
meta_include HashAttrs
|
20
37
|
|
21
38
|
attr_reader :name
|
22
|
-
attr_accessor :properties
|
39
|
+
attr_accessor :properties
|
23
40
|
|
24
41
|
@@multi_properties = {}
|
25
42
|
|
@@ -27,7 +44,6 @@ module Icalendar
|
|
27
44
|
@name = name
|
28
45
|
@components = Hash.new([])
|
29
46
|
@properties = {}
|
30
|
-
@property_params = {}
|
31
47
|
|
32
48
|
@@logger.info("New #{@name[1,@name.size].capitalize}...")
|
33
49
|
end
|
@@ -43,37 +59,74 @@ module Icalendar
|
|
43
59
|
@components[key] << component
|
44
60
|
end
|
45
61
|
|
62
|
+
# Add a component to the calendar.
|
46
63
|
alias add add_component
|
47
64
|
|
65
|
+
# Add an event to the calendar.
|
66
|
+
alias add_event add_component
|
67
|
+
|
68
|
+
# Add a todo item to the calendar.
|
69
|
+
alias add_todo add_component
|
70
|
+
|
71
|
+
# Add a journal item to the calendar.
|
72
|
+
alias add_journal add_component
|
73
|
+
|
74
|
+
def remove_component(component)
|
75
|
+
key = (component.class.to_s.downcase + 's').gsub('icalendar::', '').to_sym
|
76
|
+
|
77
|
+
if @components.has_key? key
|
78
|
+
@components[key].delete(component)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Remove a component from the calendar.
|
83
|
+
alias remove remove_component
|
84
|
+
|
85
|
+
# Remove an event from the calendar.
|
86
|
+
alias remove_event remove_component
|
87
|
+
|
88
|
+
# Remove a todo item from the calendar.
|
89
|
+
alias remove_todo remove_component
|
90
|
+
|
91
|
+
# Remove a journal item from the calendar.
|
92
|
+
alias remove_journal remove_component
|
93
|
+
|
94
|
+
# Used to generate unique component ids
|
95
|
+
def new_uid
|
96
|
+
"#{DateTime.now}_#{rand(999999999)}@#{Socket.gethostname}"
|
97
|
+
end
|
98
|
+
|
99
|
+
# Output in the icalendar format
|
48
100
|
def to_ical
|
49
|
-
print_component do
|
101
|
+
print_component do
|
102
|
+
s = ""
|
50
103
|
@components.each_value do |comps|
|
51
104
|
comps.each { |component| s << component.to_ical }
|
52
105
|
end
|
106
|
+
s
|
53
107
|
end
|
54
108
|
end
|
55
109
|
|
56
110
|
# Print this icalendar component
|
57
111
|
def print_component
|
58
|
-
s = ""
|
59
|
-
|
60
112
|
# Begin a new component
|
61
|
-
|
113
|
+
"BEGIN:#{@name.upcase}\r\n" +
|
62
114
|
|
63
115
|
# Then the properties
|
64
|
-
print_properties
|
116
|
+
print_properties +
|
65
117
|
|
66
|
-
#
|
67
|
-
yield
|
118
|
+
# sub components
|
119
|
+
yield +
|
68
120
|
|
69
121
|
# End of this component
|
70
|
-
|
122
|
+
"END:#{@name.upcase}\r\n"
|
71
123
|
end
|
72
124
|
|
73
125
|
# Print this components properties
|
74
|
-
def print_properties
|
75
|
-
|
126
|
+
def print_properties
|
127
|
+
s = ""
|
76
128
|
|
129
|
+
@properties.each do |key,val|
|
77
130
|
# Take out underscore for property names that conflicted
|
78
131
|
# with built-in words.
|
79
132
|
if key =~ /ip_.*/
|
@@ -81,47 +134,51 @@ module Icalendar
|
|
81
134
|
end
|
82
135
|
|
83
136
|
# Property name
|
84
|
-
s << "#{key.upcase}"
|
137
|
+
s << "#{key.upcase}" +
|
85
138
|
|
86
139
|
# Possible parameters
|
87
|
-
|
140
|
+
print_parameters(val) +
|
88
141
|
|
89
142
|
# Property value
|
90
|
-
|
143
|
+
":#{val.to_ical}\r\n"
|
91
144
|
end
|
145
|
+
|
146
|
+
s
|
92
147
|
end
|
93
148
|
|
94
149
|
# Print the parameters for a specific property
|
95
|
-
def
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
150
|
+
def print_parameters(val)
|
151
|
+
s = ""
|
152
|
+
return s unless val.respond_to?(:ical_params) and not val.ical_params.nil?
|
153
|
+
|
154
|
+
val.ical_params.each do |key,val|
|
155
|
+
s << ";#{key}"
|
156
|
+
val = [ val ] unless val.is_a?(Array)
|
157
|
+
|
158
|
+
# Possible parameter values
|
159
|
+
unless val.empty?
|
160
|
+
s << "="
|
161
|
+
sep = "" # First entry comes after = sign, but then we need commas
|
162
|
+
val.each do |pval|
|
163
|
+
if pval.respond_to? :to_ical
|
164
|
+
s << sep << pval.to_ical
|
165
|
+
sep = ","
|
111
166
|
end
|
112
167
|
end
|
113
|
-
|
114
168
|
end
|
115
169
|
end
|
170
|
+
s
|
116
171
|
end
|
117
172
|
|
118
173
|
# TODO: Look into the x-property, x-param stuff...
|
174
|
+
# This would really only be needed for subclassing to add additional
|
175
|
+
# properties to an application using the API.
|
119
176
|
def custom_property(name, value)
|
120
177
|
@properties[name] = value
|
121
178
|
end
|
122
179
|
|
123
180
|
def multi_property?(name)
|
124
|
-
@@multi_properties.has_key?(name.
|
181
|
+
@@multi_properties.has_key?(name.downcase)
|
125
182
|
end
|
126
183
|
|
127
184
|
# Make it protected so we can monitor usage...
|
@@ -133,107 +190,114 @@ module Icalendar
|
|
133
190
|
|
134
191
|
# Define a set of methods supporting a new property
|
135
192
|
def Component.ical_property(property, alias_name = nil, prop_name = nil)
|
136
|
-
|
137
193
|
property = "#{property}".strip.downcase
|
138
|
-
getter = "#{property}"
|
139
|
-
setter = "#{property}="
|
140
|
-
query = "#{property}?"
|
141
194
|
alias_name = "#{alias_name}".strip.downcase unless alias_name.nil?
|
142
195
|
|
143
196
|
# If a prop_name was given then we use that for the actual storage
|
144
|
-
property = "#{prop_name}".strip.
|
197
|
+
property = "#{prop_name}".strip.downcase unless prop_name.nil?
|
145
198
|
|
146
|
-
|
147
|
-
property
|
199
|
+
generate_getter(property, alias_name)
|
200
|
+
generate_setter(property, alias_name)
|
201
|
+
generate_query(property, alias_name)
|
202
|
+
end
|
203
|
+
|
204
|
+
# Define a set of methods defining a new property, which
|
205
|
+
# supports multiple values for the same property name.
|
206
|
+
def Component.ical_multi_property(property, singular, plural)
|
207
|
+
property = "#{property}".strip.downcase.gsub(/-/, '_')
|
208
|
+
plural = "#{plural}".strip.downcase
|
148
209
|
|
149
|
-
#
|
150
|
-
|
210
|
+
# Set this key so the parser knows to use an array for
|
211
|
+
# storing this property type.
|
212
|
+
@@multi_properties["#{property}"] = true
|
151
213
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
# Set the value just like normal
|
159
|
-
self.#{setter}(val)
|
160
|
-
end
|
161
|
-
end
|
162
|
-
code
|
214
|
+
generate_multi_getter(property, plural)
|
215
|
+
generate_multi_setter(property, plural)
|
216
|
+
generate_multi_query(property, plural)
|
217
|
+
generate_multi_adder(property, singular)
|
218
|
+
generate_multi_remover(property, singular)
|
219
|
+
end
|
163
220
|
|
164
|
-
|
165
|
-
alias_method("#{alias_name}", "#{getter}") unless alias_name.nil?
|
166
|
-
end
|
221
|
+
private
|
167
222
|
|
168
|
-
|
223
|
+
def Component.generate_getter(property, alias_name)
|
224
|
+
unless instance_methods.include? property
|
169
225
|
code = <<-code
|
170
|
-
def #{
|
226
|
+
def #{property}(val = nil, params = nil)
|
227
|
+
return @properties["#{property}"] if val.nil?
|
228
|
+
|
171
229
|
unless val.respond_to?(:to_ical)
|
172
230
|
raise(NotImplementedError, "Value of type (" + val.class.to_s + ") does not support to_ical method!")
|
173
231
|
end
|
174
232
|
|
233
|
+
unless params.nil?
|
234
|
+
# Extend with the parameter methods only if we have to...
|
235
|
+
unless val.respond_to?(:ical_params)
|
236
|
+
val.class.class_eval { attr_accessor :ical_params }
|
237
|
+
end
|
238
|
+
val.ical_params = params
|
239
|
+
end
|
240
|
+
|
175
241
|
@properties["#{property}"] = val
|
176
242
|
end
|
177
243
|
code
|
178
244
|
|
179
|
-
class_eval code, "component.rb",
|
245
|
+
class_eval code, "component.rb", 219
|
246
|
+
alias_method("#{alias_name}", "#{property}") unless alias_name.nil?
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
def Component.generate_setter(property, alias_name)
|
251
|
+
setter = property + '='
|
252
|
+
unless instance_methods.include? setter
|
253
|
+
code = <<-code
|
254
|
+
def #{setter}(val)
|
255
|
+
#{property}(val)
|
256
|
+
end
|
257
|
+
code
|
180
258
|
|
181
|
-
|
259
|
+
class_eval code, "component.rb", 233
|
260
|
+
alias_method("#{alias_name}=", "#{property+'='}") unless alias_name.nil?
|
182
261
|
end
|
262
|
+
end
|
183
263
|
|
264
|
+
def Component.generate_query(property, alias_name)
|
265
|
+
query = "#{property}?"
|
184
266
|
unless instance_methods.include? query
|
185
267
|
code = <<-code
|
186
268
|
def #{query}
|
187
|
-
@properties.has_key?("#{property}")
|
269
|
+
@properties.has_key?("#{property.downcase}")
|
188
270
|
end
|
189
271
|
code
|
190
272
|
|
191
|
-
class_eval code, "component.rb",
|
273
|
+
class_eval code, "component.rb", 226
|
192
274
|
|
193
275
|
alias_method("#{alias_name}\?", "#{query}") unless alias_name.nil?
|
194
276
|
end
|
195
277
|
end
|
196
278
|
|
197
|
-
|
198
|
-
# supports multiple values for the same property name.
|
199
|
-
def Component.ical_multi_property(property, singular, plural)
|
200
|
-
property = "#{property}".strip.upcase
|
201
|
-
singular = "#{singular}".strip.downcase
|
202
|
-
plural = "#{plural}".strip.downcase
|
203
|
-
|
204
|
-
getter = "#{plural}"
|
205
|
-
setter = "#{plural}="
|
206
|
-
adder = "add_#{singular}"
|
207
|
-
remover = "remove_#{singular}"
|
208
|
-
query = "#{plural}?"
|
209
|
-
|
210
|
-
# Set this key so the parser knows to use an array for
|
211
|
-
# storing this property type.
|
212
|
-
@@multi_properties["#{property}"] = true
|
213
|
-
|
279
|
+
def Component.generate_multi_getter(property, plural)
|
214
280
|
# Getter for whole array
|
215
|
-
unless instance_methods.include?
|
281
|
+
unless instance_methods.include? plural
|
216
282
|
code = <<-code
|
217
|
-
def #{
|
218
|
-
if a.
|
219
|
-
|
220
|
-
@properties["#{property}"]
|
221
|
-
else
|
222
|
-
[]
|
223
|
-
end
|
283
|
+
def #{plural}(a = nil)
|
284
|
+
if a.nil?
|
285
|
+
@properties["#{property}"] || []
|
224
286
|
else
|
225
|
-
self.#{
|
287
|
+
self.#{plural}=(a)
|
226
288
|
end
|
227
289
|
end
|
228
290
|
code
|
229
291
|
|
230
292
|
class_eval code, "component.rb", 186
|
231
293
|
end
|
294
|
+
end
|
232
295
|
|
296
|
+
def Component.generate_multi_setter(property, plural)
|
233
297
|
# Setter for whole array
|
234
|
-
unless instance_methods.include?
|
298
|
+
unless instance_methods.include? plural+'+'
|
235
299
|
code = <<-code
|
236
|
-
def #{
|
300
|
+
def #{plural}=(a)
|
237
301
|
if a.respond_to?(:to_ary)
|
238
302
|
a.to_ary.each do |val|
|
239
303
|
unless val.respond_to?(:to_ical)
|
@@ -242,27 +306,31 @@ module Icalendar
|
|
242
306
|
end
|
243
307
|
|
244
308
|
@properties["#{property}"] = a.to_ary
|
245
|
-
|
246
309
|
else
|
247
|
-
raise ArgumentError, "#{
|
310
|
+
raise ArgumentError, "#{plural} is a multi-property that must be an array! Use the add_[property] method to add single entries."
|
248
311
|
end
|
249
312
|
end
|
250
313
|
code
|
251
314
|
|
252
315
|
class_eval code, "component.rb", 198
|
253
316
|
end
|
317
|
+
end
|
254
318
|
|
319
|
+
def Component.generate_multi_query(property, plural)
|
255
320
|
# Query for any of these properties
|
256
|
-
unless instance_methods.include?
|
321
|
+
unless instance_methods.include? plural+'?'
|
257
322
|
code = <<-code
|
258
|
-
def #{
|
323
|
+
def #{plural}?
|
259
324
|
@properties.has_key?("#{property}")
|
260
325
|
end
|
261
326
|
code
|
262
327
|
|
263
328
|
class_eval code, "component.rb", 210
|
264
329
|
end
|
330
|
+
end
|
265
331
|
|
332
|
+
def Component.generate_multi_adder(property, singular)
|
333
|
+
adder = "add_"+singular.to_s
|
266
334
|
# Add another item to this properties array
|
267
335
|
unless instance_methods.include? adder
|
268
336
|
code = <<-code
|
@@ -271,6 +339,14 @@ module Icalendar
|
|
271
339
|
raise(NotImplementedError, "Property value object does not support to_ical method!")
|
272
340
|
end
|
273
341
|
|
342
|
+
unless params.nil?
|
343
|
+
# Extend with the parameter methods only if we have to...
|
344
|
+
unless val.respond_to?(:ical_params)
|
345
|
+
val.class.class_eval { attr_accessor :ical_params }
|
346
|
+
end
|
347
|
+
val.ical_params = params
|
348
|
+
end
|
349
|
+
|
274
350
|
if @properties.has_key?("#{property}")
|
275
351
|
@properties["#{property}"] << val
|
276
352
|
else
|
@@ -279,52 +355,50 @@ module Icalendar
|
|
279
355
|
end
|
280
356
|
code
|
281
357
|
|
282
|
-
class_eval code, "component.rb",
|
358
|
+
class_eval code, "component.rb", 289
|
283
359
|
alias_method("add_#{property.downcase}", "#{adder}")
|
284
360
|
end
|
361
|
+
end
|
285
362
|
|
363
|
+
def Component.generate_multi_remover(property, singular)
|
286
364
|
# Remove an item from this properties array
|
287
|
-
unless instance_methods.include?
|
365
|
+
unless instance_methods.include? "remove_#{singular}"
|
288
366
|
code = <<-code
|
289
|
-
def #{
|
367
|
+
def remove_#{singular}(a)
|
290
368
|
if @properties.has_key?("#{property}")
|
291
369
|
@properties["#{property}"].delete(a)
|
292
370
|
end
|
293
371
|
end
|
294
372
|
code
|
295
373
|
|
296
|
-
class_eval code, "component.rb",
|
297
|
-
alias_method("remove_#{property.downcase}", "#{
|
374
|
+
class_eval code, "component.rb", 303
|
375
|
+
alias_method("remove_#{property.downcase}", "remove_#{singular}")
|
298
376
|
end
|
299
|
-
|
300
377
|
end
|
301
378
|
|
302
379
|
def method_missing(method_name, *args)
|
380
|
+
@@logger.debug("Inside method_missing...")
|
303
381
|
method_name = method_name.to_s.downcase
|
304
382
|
|
305
383
|
unless method_name =~ /x_.*/
|
306
|
-
raise NoMethodError
|
307
|
-
end
|
308
|
-
|
309
|
-
val = args.first
|
310
|
-
|
311
|
-
unless val.respond_to?(:to_ical)
|
312
|
-
raise(NotImplementedError, "Value of type (" + val.class.to_s + ") does not support to_ical method!")
|
384
|
+
raise NoMethodError, "Method Name: #{method_name}"
|
313
385
|
end
|
314
386
|
|
315
|
-
|
316
|
-
|
317
|
-
|
387
|
+
# x-properties are accessed with underscore but stored with a dash so
|
388
|
+
# they output correctly and we don't have to special case the
|
389
|
+
# output code, which would require checking every property.
|
390
|
+
if args.size > 0 # Its a setter
|
391
|
+
# Pull off the possible equals
|
392
|
+
@properties[method_name[/x_[^=]*/].gsub('x_', 'x-')] = args.first
|
318
393
|
else # Or its a getter
|
319
|
-
|
320
|
-
return @properties[method_name]
|
394
|
+
return @properties[method_name.gsub('x_', 'x-')]
|
321
395
|
end
|
322
396
|
end
|
323
397
|
|
324
398
|
public
|
325
399
|
|
326
400
|
def respond_to?(method_name)
|
327
|
-
unless method_name.to_s.downcase =~ /
|
401
|
+
unless method_name.to_s.downcase =~ /x_.*/
|
328
402
|
super
|
329
403
|
end
|
330
404
|
|