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
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
|
|