tilia-vobject 4.0.0.pre.alpha5 → 4.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.sabre.md +59 -2
- data/Gemfile +1 -8
- data/Gemfile.lock +18 -12
- data/LICENSE +1 -1
- data/LICENSE.sabre +1 -1
- data/lib/tilia/v_object.rb +1 -0
- data/lib/tilia/v_object/birthday_calendar_generator.rb +11 -11
- data/lib/tilia/v_object/cli.rb +39 -38
- data/lib/tilia/v_object/component.rb +47 -50
- data/lib/tilia/v_object/component/available.rb +4 -37
- data/lib/tilia/v_object/component/v_alarm.rb +6 -18
- data/lib/tilia/v_object/component/v_availability.rb +6 -39
- data/lib/tilia/v_object/component/v_calendar.rb +66 -98
- data/lib/tilia/v_object/component/v_card.rb +42 -69
- data/lib/tilia/v_object/component/v_event.rb +5 -17
- data/lib/tilia/v_object/component/v_free_busy.rb +4 -16
- data/lib/tilia/v_object/component/v_journal.rb +16 -16
- data/lib/tilia/v_object/component/v_time_zone.rb +2 -14
- data/lib/tilia/v_object/component/v_todo.rb +17 -36
- data/lib/tilia/v_object/date_time_parser.rb +24 -24
- data/lib/tilia/v_object/document.rb +25 -25
- data/lib/tilia/v_object/free_busy_data.rb +7 -7
- data/lib/tilia/v_object/free_busy_generator.rb +73 -75
- data/lib/tilia/v_object/i_tip.rb +1 -0
- data/lib/tilia/v_object/i_tip/broker.rb +134 -116
- data/lib/tilia/v_object/i_tip/i_tip_exception.rb +1 -1
- data/lib/tilia/v_object/i_tip/message.rb +13 -13
- data/lib/tilia/v_object/invalid_data_exception.rb +8 -0
- data/lib/tilia/v_object/node.rb +22 -27
- data/lib/tilia/v_object/parameter.rb +22 -22
- data/lib/tilia/v_object/parse_exception.rb +1 -1
- data/lib/tilia/v_object/parser.rb +1 -0
- data/lib/tilia/v_object/parser/json.rb +9 -19
- data/lib/tilia/v_object/parser/mime_dir.rb +73 -39
- data/lib/tilia/v_object/parser/parser.rb +9 -14
- data/lib/tilia/v_object/parser/xml.rb +33 -50
- data/lib/tilia/v_object/parser/xml/element.rb +1 -0
- data/lib/tilia/v_object/parser/xml/element/key_value.rb +2 -2
- data/lib/tilia/v_object/property.rb +52 -52
- data/lib/tilia/v_object/property/binary.rb +10 -10
- data/lib/tilia/v_object/property/boolean.rb +6 -6
- data/lib/tilia/v_object/property/flat_text.rb +3 -3
- data/lib/tilia/v_object/property/float_value.rb +10 -10
- data/lib/tilia/v_object/property/i_calendar.rb +1 -0
- data/lib/tilia/v_object/property/i_calendar/cal_address.rb +3 -3
- data/lib/tilia/v_object/property/i_calendar/date_time.rb +29 -57
- data/lib/tilia/v_object/property/i_calendar/duration.rb +6 -6
- data/lib/tilia/v_object/property/i_calendar/period.rb +10 -10
- data/lib/tilia/v_object/property/i_calendar/recur.rb +16 -24
- data/lib/tilia/v_object/property/integer_value.rb +8 -8
- data/lib/tilia/v_object/property/text.rb +21 -36
- data/lib/tilia/v_object/property/time.rb +29 -6
- data/lib/tilia/v_object/property/unknown.rb +2 -2
- data/lib/tilia/v_object/property/uri.rb +24 -5
- data/lib/tilia/v_object/property/utc_offset.rb +5 -5
- data/lib/tilia/v_object/property/v_card.rb +1 -0
- data/lib/tilia/v_object/property/v_card/date.rb +3 -3
- data/lib/tilia/v_object/property/v_card/date_and_or_time.rb +30 -42
- data/lib/tilia/v_object/property/v_card/date_time.rb +1 -1
- data/lib/tilia/v_object/property/v_card/language_tag.rb +4 -4
- data/lib/tilia/v_object/property/v_card/time_stamp.rb +5 -5
- data/lib/tilia/v_object/reader.rb +12 -11
- data/lib/tilia/v_object/recur.rb +2 -0
- data/lib/tilia/v_object/recur/event_iterator.rb +30 -27
- data/lib/tilia/v_object/recur/max_instances_exceeded_exception.rb +10 -0
- data/lib/tilia/v_object/recur/no_instances_exception.rb +1 -1
- data/lib/tilia/v_object/recur/r_date_iterator.rb +15 -41
- data/lib/tilia/v_object/recur/r_rule_iterator.rb +23 -156
- data/lib/tilia/v_object/settings.rb +16 -0
- data/lib/tilia/v_object/splitter.rb +1 -0
- data/lib/tilia/v_object/splitter/i_calendar.rb +5 -5
- data/lib/tilia/v_object/splitter/splitter_interface.rb +2 -2
- data/lib/tilia/v_object/splitter/v_card.rb +5 -5
- data/lib/tilia/v_object/string_util.rb +25 -9
- data/lib/tilia/v_object/time_zone_data.rb +1 -0
- data/lib/tilia/v_object/time_zone_util.rb +6 -6
- data/lib/tilia/v_object/uuid_util.rb +3 -3
- data/lib/tilia/v_object/v_card_converter.rb +24 -21
- data/lib/tilia/v_object/version.rb +1 -1
- data/lib/tilia/v_object/writer.rb +7 -7
- data/test/test_helper.rb +3 -3
- data/test/v_object/birthday_calendar_generator_test.rb +22 -0
- data/test/v_object/component/v_alarm_test.rb +3 -1
- data/test/v_object/component/v_calendar_test.rb +40 -4
- data/test/v_object/component/v_card_test.rb +1 -1
- data/test/v_object/component_test.rb +5 -3
- data/test/v_object/date_time_parser_test.rb +15 -5
- data/test/v_object/free_busy_generator_test.rb +5 -5
- data/test/v_object/i_tip/broker_attendee_reply_test.rb +19 -0
- data/test/v_object/i_tip/broker_delete_event_test.rb +146 -2
- data/test/v_object/i_tip/broker_new_event_test.rb +21 -0
- data/test/v_object/i_tip/broker_process_reply_test.rb +10 -0
- data/test/v_object/i_tip/broker_tester.rb +1 -1
- data/test/v_object/i_tip/broker_update_event_test.rb +36 -0
- data/test/v_object/issue259_test.rb +24 -0
- data/test/v_object/issue40_test.rb +3 -1
- data/test/v_object/j_cal_test.rb +15 -12
- data/test/v_object/parser/json_test.rb +5 -5
- data/test/v_object/parser/mime_dir_test.rb +109 -0
- data/test/v_object/property/binary_test.rb +4 -2
- data/test/v_object/property/i_calendar/date_time_test.rb +3 -1
- data/test/v_object/property/uri_test.rb +23 -0
- data/test/v_object/recur/event_iterator/by_month_in_daily_test.rb +1 -1
- data/test/v_object/recur/event_iterator/by_set_pos_hang_test.rb +1 -1
- data/test/v_object/recur/event_iterator/expand_floating_times_test.rb +9 -9
- data/test/v_object/recur/event_iterator/handle_r_date_expand_test.rb +51 -0
- data/test/v_object/recur/event_iterator/incorrect_expand_test.rb +3 -5
- data/test/v_object/recur/event_iterator/infinite_loop_problem_test.rb +3 -1
- data/test/v_object/{issue26_test.rb → recur/event_iterator/issue26_test.rb} +3 -1
- data/test/v_object/recur/event_iterator/main_test.rb +9 -3
- data/test/v_object/recur/event_iterator/max_instances_test.rb +38 -0
- data/test/v_object/recur/event_iterator/missing_overridden_test.rb +3 -5
- data/test/v_object/recur/event_iterator/no_instances_test.rb +5 -3
- data/test/v_object/recur/event_iterator/override_first_event_test.rb +9 -9
- data/test/v_object/recur/r_date_iterator_test.rb +18 -0
- data/test/v_object/recur/r_rule_iterator_test.rb +4 -4
- data/test/v_object/splitter/i_calendar_test.rb +27 -7
- data/test/v_object/splitter/v_card_test.rb +5 -3
- data/test/v_object/test_case.rb +14 -4
- data/tilia-vobject.gemspec +2 -2
- metadata +17 -11
@@ -12,16 +12,16 @@ module Tilia
|
|
12
12
|
# if the non-UTC format is used. The argument is used as a reference, the
|
13
13
|
# returned DateTimeImmutable object will still be in the UTC timezone.
|
14
14
|
#
|
15
|
-
# @param
|
16
|
-
# @param
|
15
|
+
# @param [String] dt
|
16
|
+
# @param [ActiveSupport::TimeZone] tz
|
17
17
|
#
|
18
|
-
# @return
|
18
|
+
# @return [Time]
|
19
19
|
def self.parse_date_time(dt, tz = nil)
|
20
20
|
# Format is YYYYMMDD + "T" + hhmmss
|
21
21
|
matches = /^([0-9]{4})([0-1][0-9])([0-3][0-9])T([0-2][0-9])([0-5][0-9])([0-5][0-9])([Z]?)$/.match(dt)
|
22
22
|
|
23
23
|
unless matches
|
24
|
-
fail "The supplied iCalendar datetime value is incorrect: #{dt}"
|
24
|
+
fail InvalidDataException, "The supplied iCalendar datetime value is incorrect: #{dt}"
|
25
25
|
end
|
26
26
|
|
27
27
|
tz = ActiveSupport::TimeZone.new('UTC') if matches[7] == 'Z' || tz.nil?
|
@@ -32,16 +32,16 @@ module Tilia
|
|
32
32
|
|
33
33
|
# Parses an iCalendar (rfc5545) formatted date and returns a DateTimeImmutable object.
|
34
34
|
#
|
35
|
-
# @param
|
36
|
-
# @param
|
35
|
+
# @param [String] date
|
36
|
+
# @param [ActiveSupport::TimeZone] tz
|
37
37
|
#
|
38
|
-
# @return
|
38
|
+
# @return [Time]
|
39
39
|
def self.parse_date(date, tz = nil)
|
40
40
|
# Format is YYYYMMDD
|
41
41
|
matches = /^([0-9]{4})([0-1][0-9])([0-3][0-9])$/.match(date)
|
42
42
|
|
43
43
|
unless matches
|
44
|
-
fail "The supplied iCalendar date value is incorrect: #{date}"
|
44
|
+
fail InvalidDataException, "The supplied iCalendar date value is incorrect: #{date}"
|
45
45
|
end
|
46
46
|
|
47
47
|
tz = ActiveSupport::TimeZone.new('UTC') if tz.nil?
|
@@ -56,15 +56,15 @@ module Tilia
|
|
56
56
|
# This method will either return a DateTimeInterval object, or a string
|
57
57
|
# suitable for strtotime or DateTime::modify.
|
58
58
|
#
|
59
|
-
# @param
|
60
|
-
# @param
|
59
|
+
# @param [String] duration
|
60
|
+
# @param [Boolean] as_string
|
61
61
|
#
|
62
|
-
# @return DateInterval|string
|
62
|
+
# @return [DateInterval|string]
|
63
63
|
def self.parse_duration(duration, as_string = false)
|
64
64
|
matches = /^(?<plusminus>\+|-)?P((?<week>\d+)W)?((?<day>\d+)D)?(T((?<hour>\d+)H)?((?<minute>\d+)M)?((?<second>\d+)S)?)?$/.match(duration.to_s)
|
65
65
|
|
66
66
|
unless matches
|
67
|
-
fail "The supplied iCalendar duration value is incorrect: #{duration}"
|
67
|
+
fail InvalidDataException, "The supplied iCalendar duration value is incorrect: #{duration}"
|
68
68
|
end
|
69
69
|
|
70
70
|
unless as_string
|
@@ -122,10 +122,10 @@ module Tilia
|
|
122
122
|
|
123
123
|
# Parses either a Date or DateTime, or Duration value.
|
124
124
|
#
|
125
|
-
# @param
|
126
|
-
# @param
|
125
|
+
# @param [String] date
|
126
|
+
# @param [ActiveSupport::TimeZone|string] reference_tz
|
127
127
|
#
|
128
|
-
# @return DateTimeImmutable|DateInterval
|
128
|
+
# @return [DateTimeImmutable|DateInterval]
|
129
129
|
def self.parse(date, reference_tz = nil)
|
130
130
|
if date[0] == 'P' || (date[0] == '-' && date[1] == 'P')
|
131
131
|
parse_duration(date)
|
@@ -187,9 +187,9 @@ module Tilia
|
|
187
187
|
# Times may be postfixed by a timezone offset. This can be either 'Z' for
|
188
188
|
# UTC, or a string like -0500 or +1100.
|
189
189
|
#
|
190
|
-
# @param
|
190
|
+
# @param [String] date
|
191
191
|
#
|
192
|
-
# @return array
|
192
|
+
# @return [array]
|
193
193
|
def self.parse_v_card_date_time(date)
|
194
194
|
regex = /^
|
195
195
|
(?: # date part
|
@@ -241,7 +241,7 @@ module Tilia
|
|
241
241
|
|
242
242
|
matches = regex.match(date)
|
243
243
|
unless matches
|
244
|
-
fail
|
244
|
+
fail InvalidDataException, "Invalid vCard date-time string: #{date}"
|
245
245
|
end
|
246
246
|
end
|
247
247
|
|
@@ -310,9 +310,9 @@ module Tilia
|
|
310
310
|
# Times may be postfixed by a timezone offset. This can be either 'Z' for
|
311
311
|
# UTC, or a string like -0500 or +11:00.
|
312
312
|
#
|
313
|
-
# @param
|
313
|
+
# @param [String] date
|
314
314
|
#
|
315
|
-
# @return array
|
315
|
+
# @return [array]
|
316
316
|
def self.parse_v_card_time(date)
|
317
317
|
regex = /^
|
318
318
|
(?<hour> [0-9]{2} | -)
|
@@ -345,7 +345,7 @@ module Tilia
|
|
345
345
|
|
346
346
|
matches = regex.match(date)
|
347
347
|
unless matches
|
348
|
-
fail
|
348
|
+
fail InvalidDataException, "Invalid vCard time string: #{date}"
|
349
349
|
end
|
350
350
|
end
|
351
351
|
|
@@ -416,9 +416,9 @@ module Tilia
|
|
416
416
|
# Times may be postfixed by a timezone offset. This can be either 'Z' for
|
417
417
|
# UTC, or a string like -0500 or +1100.
|
418
418
|
#
|
419
|
-
# @param
|
419
|
+
# @param [String] date
|
420
420
|
#
|
421
|
-
# @return array
|
421
|
+
# @return [array]
|
422
422
|
def self.parse_v_card_date_and_or_time(date)
|
423
423
|
# \d{8}|\d{4}-\d\d|--\d\d(\d\d)?|---\d\d
|
424
424
|
value_date = /^(?:
|
@@ -452,7 +452,7 @@ module Tilia
|
|
452
452
|
matches = value_date_time.match(date) unless matches
|
453
453
|
matches = value_time.match(date) unless matches
|
454
454
|
unless matches
|
455
|
-
fail
|
455
|
+
fail InvalidDataException, "Invalid vCard date-time string: #{date}"
|
456
456
|
end
|
457
457
|
|
458
458
|
map = {
|
@@ -31,22 +31,22 @@ module Tilia
|
|
31
31
|
#
|
32
32
|
# This should be 'VCALENDAR' or 'VCARD'.
|
33
33
|
#
|
34
|
-
# @
|
35
|
-
@default_name
|
34
|
+
# @return [String]
|
35
|
+
@default_name = nil
|
36
36
|
|
37
37
|
# List of properties, and which classes they map to.
|
38
38
|
#
|
39
|
-
# @
|
39
|
+
# @return [array]
|
40
40
|
@property_map = {}
|
41
41
|
|
42
42
|
# List of components, along with which classes they map to.
|
43
43
|
#
|
44
|
-
# @
|
44
|
+
# @return [array]
|
45
45
|
@component_map = {}
|
46
46
|
|
47
47
|
# List of value-types, and which classes they map to.
|
48
48
|
#
|
49
|
-
# @
|
49
|
+
# @return [array]
|
50
50
|
@value_map = {}
|
51
51
|
|
52
52
|
class << self
|
@@ -69,9 +69,9 @@ module Tilia
|
|
69
69
|
# new Document(array children = [], defaults = true)
|
70
70
|
# new Document(string name, array children = [], defaults = true)
|
71
71
|
#
|
72
|
-
# @return void
|
72
|
+
# @return [void]
|
73
73
|
def initialize(*args)
|
74
|
-
if args.size == 0 || args[0].is_a?(Hash)
|
74
|
+
if args.size == 0 || args[0].is_a?(Hash) || args[0].is_a?(Array)
|
75
75
|
args.unshift(self.class.default_name)
|
76
76
|
args.unshift(self)
|
77
77
|
|
@@ -84,9 +84,9 @@ module Tilia
|
|
84
84
|
|
85
85
|
# Returns the current document type.
|
86
86
|
#
|
87
|
-
# @return
|
87
|
+
# @return [Fixnum]
|
88
88
|
def document_type
|
89
|
-
|
89
|
+
UNKNOWN
|
90
90
|
end
|
91
91
|
|
92
92
|
# Creates a new component or property.
|
@@ -94,10 +94,10 @@ module Tilia
|
|
94
94
|
# If it's a known component, we will automatically call createComponent.
|
95
95
|
# otherwise, we'll assume it's a property and call createProperty instead.
|
96
96
|
#
|
97
|
-
# @param
|
98
|
-
# @param
|
97
|
+
# @param [String] name
|
98
|
+
# @param [String] arg1,... Unlimited number of args
|
99
99
|
#
|
100
|
-
# @return mixed
|
100
|
+
# @return [mixed]
|
101
101
|
def create(name, *args)
|
102
102
|
if self.class.component_map.key?(name.upcase)
|
103
103
|
create_component(name, *args)
|
@@ -119,11 +119,11 @@ module Tilia
|
|
119
119
|
# an iCalendar object, this may be something like CALSCALE:GREGORIAN. To
|
120
120
|
# ensure that this does not happen, set defaults to false.
|
121
121
|
#
|
122
|
-
# @param
|
123
|
-
# @param array children
|
124
|
-
# @param
|
122
|
+
# @param [String] name
|
123
|
+
# @param [array] children
|
124
|
+
# @param [Boolean] defaults
|
125
125
|
#
|
126
|
-
# @return Component
|
126
|
+
# @return [Component]
|
127
127
|
def create_component(name, children = nil, defaults = true)
|
128
128
|
name = name.upcase
|
129
129
|
|
@@ -144,12 +144,12 @@ module Tilia
|
|
144
144
|
# parameters will automatically be created, or you can just pass a list of
|
145
145
|
# Parameter objects.
|
146
146
|
#
|
147
|
-
# @param
|
148
|
-
# @param
|
149
|
-
# @param array parameters
|
150
|
-
# @param
|
147
|
+
# @param [String] name
|
148
|
+
# @param value
|
149
|
+
# @param [array] parameters
|
150
|
+
# @param [String] value_type Force a specific valuetype, such as URI or TEXT
|
151
151
|
#
|
152
|
-
# @return Property
|
152
|
+
# @return [Property]
|
153
153
|
def create_property(name, value = nil, parameters = nil, value_type = nil)
|
154
154
|
parameters = {} unless parameters
|
155
155
|
|
@@ -190,9 +190,9 @@ module Tilia
|
|
190
190
|
#
|
191
191
|
# This method returns null if we don't have a specialized class.
|
192
192
|
#
|
193
|
-
# @param
|
193
|
+
# @param [String] value_param
|
194
194
|
#
|
195
|
-
# @return void
|
195
|
+
# @return [void]
|
196
196
|
def class_name_for_property_value(value_param)
|
197
197
|
value_param = value_param.upcase
|
198
198
|
|
@@ -203,9 +203,9 @@ module Tilia
|
|
203
203
|
|
204
204
|
# Returns the default class for a property name.
|
205
205
|
#
|
206
|
-
# @param
|
206
|
+
# @param [String] property_name
|
207
207
|
#
|
208
|
-
# @return
|
208
|
+
# @return [String]
|
209
209
|
def class_name_for_property_name(property_name)
|
210
210
|
if self.class.property_map.key?(property_name)
|
211
211
|
self.class.property_map[property_name]
|
@@ -4,17 +4,17 @@ module Tilia
|
|
4
4
|
class FreeBusyData
|
5
5
|
# Start timestamp
|
6
6
|
#
|
7
|
-
# @
|
7
|
+
# @return [Fixnum]
|
8
8
|
# RUBY: attr_accessor :start
|
9
9
|
|
10
10
|
# End timestamp
|
11
11
|
#
|
12
|
-
# @
|
12
|
+
# @return [Fixnum]
|
13
13
|
# RUBY: attr_accessor :end
|
14
14
|
|
15
15
|
# A list of free-busy times.
|
16
16
|
#
|
17
|
-
# @
|
17
|
+
# @return [array]
|
18
18
|
# RUBY: attr_accessor :data
|
19
19
|
|
20
20
|
def initialize(start, ending)
|
@@ -31,10 +31,10 @@ module Tilia
|
|
31
31
|
|
32
32
|
# Adds free or busytime to the data.
|
33
33
|
#
|
34
|
-
# @param
|
35
|
-
# @param
|
36
|
-
# @param
|
37
|
-
# @return void
|
34
|
+
# @param [Fixnum] start
|
35
|
+
# @param [Fixnum] end
|
36
|
+
# @param [String] type FREE, BUSY, BUSY-UNAVAILABLE or BUSY-TENTATIVE
|
37
|
+
# @return [void]
|
38
38
|
def add(start, ending, type)
|
39
39
|
if start > @end || ending < @start
|
40
40
|
# This new data is outside our timerange.
|
@@ -11,22 +11,22 @@ module Tilia
|
|
11
11
|
class FreeBusyGenerator
|
12
12
|
# Input objects.
|
13
13
|
#
|
14
|
-
# @
|
14
|
+
# @return [array]
|
15
15
|
# RUBY: attr_accessor :objects
|
16
16
|
|
17
17
|
# Start of range.
|
18
18
|
#
|
19
|
-
# @
|
19
|
+
# @return [DateTimeInterface, nil]
|
20
20
|
# RUBY: attr_accessor :start
|
21
21
|
|
22
22
|
# End of range.
|
23
23
|
#
|
24
|
-
# @
|
24
|
+
# @return [DateTimeInterface, nil]
|
25
25
|
# RUBY: attr_accessor :end
|
26
26
|
|
27
27
|
# VCALENDAR object.
|
28
28
|
#
|
29
|
-
# @
|
29
|
+
# @return [Document]
|
30
30
|
# RUBY: attr_accessor :base_object
|
31
31
|
|
32
32
|
# Reference timezone.
|
@@ -39,7 +39,7 @@ module Tilia
|
|
39
39
|
#
|
40
40
|
# This defaults to UTC.
|
41
41
|
#
|
42
|
-
# @
|
42
|
+
# @return [ActiveSupport::TimeZone]
|
43
43
|
# RUBY: attr_accessor :time_zone
|
44
44
|
|
45
45
|
# A VAVAILABILITY document.
|
@@ -47,7 +47,7 @@ module Tilia
|
|
47
47
|
# If this is set, it's information will be included when calculating
|
48
48
|
# freebusy time.
|
49
49
|
#
|
50
|
-
# @
|
50
|
+
# @return [Document]
|
51
51
|
# RUBY: attr_accessor :vavailability
|
52
52
|
|
53
53
|
# Creates the generator.
|
@@ -55,10 +55,10 @@ module Tilia
|
|
55
55
|
# Check the setTimeRange and setObjects methods for details about the
|
56
56
|
# arguments.
|
57
57
|
#
|
58
|
-
# @param
|
59
|
-
# @param
|
60
|
-
# @param
|
61
|
-
# @param
|
58
|
+
# @param [Time] start
|
59
|
+
# @param [Time] end
|
60
|
+
# @param objects
|
61
|
+
# @param [ActiveSupport::TimeZone] time_zone
|
62
62
|
def initialize(start = nil, ending = nil, objects = nil, time_zone = nil)
|
63
63
|
start = Time.zone.parse(Settings.min_date) unless start
|
64
64
|
ending = Time.zone.parse(Settings.max_date) unless ending
|
@@ -78,14 +78,14 @@ module Tilia
|
|
78
78
|
#
|
79
79
|
# The VFREEBUSY object will be automatically added though.
|
80
80
|
#
|
81
|
-
# @param Document vcalendar
|
82
|
-
# @return void
|
81
|
+
# @param [Document] vcalendar
|
82
|
+
# @return [void]
|
83
83
|
attr_writer :base_object
|
84
84
|
|
85
85
|
# Sets a VAVAILABILITY document.
|
86
86
|
#
|
87
|
-
# @param Document vcalendar
|
88
|
-
# @return void
|
87
|
+
# @param [Document] vcalendar
|
88
|
+
# @return [void]
|
89
89
|
def v_availability=(vcalendar)
|
90
90
|
@vavailability = vcalendar
|
91
91
|
end
|
@@ -96,9 +96,9 @@ module Tilia
|
|
96
96
|
# Component.
|
97
97
|
# It's also possible to specify multiple objects as an array.
|
98
98
|
#
|
99
|
-
# @param
|
99
|
+
# @param objects
|
100
100
|
#
|
101
|
-
# @return void
|
101
|
+
# @return [void]
|
102
102
|
def objects=(objects)
|
103
103
|
objects = [objects] unless objects.is_a?(Array)
|
104
104
|
|
@@ -118,10 +118,10 @@ module Tilia
|
|
118
118
|
#
|
119
119
|
# Any freebusy object falling outside of this time range will be ignored.
|
120
120
|
#
|
121
|
-
# @param
|
122
|
-
# @param
|
121
|
+
# @param [Time] start
|
122
|
+
# @param [Time] end
|
123
123
|
#
|
124
|
-
# @return void
|
124
|
+
# @return [void]
|
125
125
|
def time_range=(range)
|
126
126
|
@start = range.begin
|
127
127
|
@end = range.end
|
@@ -129,17 +129,15 @@ module Tilia
|
|
129
129
|
|
130
130
|
# Sets the reference timezone for floating times.
|
131
131
|
#
|
132
|
-
# @param
|
132
|
+
# @param [ActiveSupport::TimeZone] time_zone
|
133
133
|
#
|
134
|
-
# @return void
|
135
|
-
|
136
|
-
@time_zone = time_zone
|
137
|
-
end
|
134
|
+
# @return [void]
|
135
|
+
attr_writer :time_zone
|
138
136
|
|
139
137
|
# Parses the input data and returns a correct VFREEBUSY object, wrapped in
|
140
138
|
# a VCALENDAR.
|
141
139
|
#
|
142
|
-
# @return Component
|
140
|
+
# @return [Component]
|
143
141
|
def result
|
144
142
|
fb_data = FreeBusyData.new(@start.to_i, @end.to_i)
|
145
143
|
|
@@ -154,9 +152,9 @@ module Tilia
|
|
154
152
|
# This method takes a VAVAILABILITY component and figures out all the
|
155
153
|
# available times.
|
156
154
|
#
|
157
|
-
# @param FreeBusyData fb_data
|
158
|
-
# @param VCalendar vavailability
|
159
|
-
# @return void
|
155
|
+
# @param [FreeBusyData] fb_data
|
156
|
+
# @param [VCalendar] vavailability
|
157
|
+
# @return [void]
|
160
158
|
def calculate_availability(fb_data, vavailability)
|
161
159
|
vavail_comps = vavailability['VAVAILABILITY'].to_a
|
162
160
|
vavail_comps.sort! do |a, b|
|
@@ -201,13 +199,13 @@ module Tilia
|
|
201
199
|
skip = false
|
202
200
|
new.each do |higher_vavail|
|
203
201
|
(higher_start, higher_end) = higher_vavail.effective_start_end
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
202
|
+
|
203
|
+
next unless (higher_start.nil? || higher_start < comp_start) && (higher_end.nil? || higher_end > comp_end)
|
204
|
+
|
205
|
+
# Component is fully covered by a higher priority
|
206
|
+
# component. We can skip this component.
|
207
|
+
skip = true
|
208
|
+
break
|
211
209
|
end
|
212
210
|
next if skip
|
213
211
|
|
@@ -238,50 +236,50 @@ module Tilia
|
|
238
236
|
)
|
239
237
|
|
240
238
|
# Looping over the AVAILABLE components.
|
241
|
-
|
242
|
-
vavail['AVAILABLE'].each do |available|
|
243
|
-
(avail_start, avail_end) = available.effective_start_end
|
244
|
-
fb_data.add(
|
245
|
-
avail_start.to_i,
|
246
|
-
avail_end.to_i,
|
247
|
-
'FREE'
|
248
|
-
)
|
239
|
+
next unless vavail.key?('AVAILABLE')
|
249
240
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
241
|
+
vavail['AVAILABLE'].each do |available|
|
242
|
+
(avail_start, avail_end) = available.effective_start_end
|
243
|
+
fb_data.add(
|
244
|
+
avail_start.to_i,
|
245
|
+
avail_end.to_i,
|
246
|
+
'FREE'
|
247
|
+
)
|
256
248
|
|
257
|
-
|
249
|
+
next unless available['RRULE']
|
258
250
|
|
259
|
-
|
251
|
+
# Our favourite thing: recurrence!!
|
252
|
+
rrule_iterator = Recur::RRuleIterator.new(
|
253
|
+
available['RRULE'].value,
|
254
|
+
avail_start
|
255
|
+
)
|
260
256
|
|
261
|
-
|
262
|
-
recur_start = rrule_iterator.current
|
263
|
-
recur_end = recur_start + start_end_diff
|
257
|
+
rrule_iterator.fast_forward(vavail_start)
|
264
258
|
|
265
|
-
|
266
|
-
# We're beyond the legal timerange.
|
267
|
-
break
|
268
|
-
end
|
259
|
+
start_end_diff = avail_end - avail_start
|
269
260
|
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
recur_end = vavail_end
|
274
|
-
end
|
261
|
+
while rrule_iterator.valid
|
262
|
+
recur_start = rrule_iterator.current
|
263
|
+
recur_end = recur_start + start_end_diff
|
275
264
|
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
)
|
265
|
+
if recur_start > vavail_end
|
266
|
+
# We're beyond the legal timerange.
|
267
|
+
break
|
268
|
+
end
|
281
269
|
|
282
|
-
|
283
|
-
end
|
270
|
+
if recur_end > vavail_end
|
271
|
+
# Truncating the end if it exceeds the
|
272
|
+
# VAVAILABILITY end.
|
273
|
+
recur_end = vavail_end
|
284
274
|
end
|
275
|
+
|
276
|
+
fb_data.add(
|
277
|
+
recur_start.to_i,
|
278
|
+
recur_end.to_i,
|
279
|
+
'FREE'
|
280
|
+
)
|
281
|
+
|
282
|
+
rrule_iterator.next
|
285
283
|
end
|
286
284
|
end
|
287
285
|
end
|
@@ -290,8 +288,8 @@ module Tilia
|
|
290
288
|
# This method takes an array of iCalendar objects and applies its busy
|
291
289
|
# times on fbData.
|
292
290
|
#
|
293
|
-
# @param FreeBusyData fb_data
|
294
|
-
# @param VCalendar[] objects
|
291
|
+
# @param [FreeBusyData] fb_data
|
292
|
+
# @param [VCalendar[]] objects
|
295
293
|
def calculate_busy(fb_data, objects)
|
296
294
|
objects.each_with_index do |object, key|
|
297
295
|
object.base_components.each do |component|
|
@@ -317,7 +315,7 @@ module Tilia
|
|
317
315
|
if component.key?('RRULE')
|
318
316
|
begin
|
319
317
|
iterator = Recur::EventIterator.new(object, component['UID'].to_s, @time_zone)
|
320
|
-
rescue Recur::NoInstancesException
|
318
|
+
rescue Recur::NoInstancesException
|
321
319
|
# This event is recurring, but it doesn't have a single
|
322
320
|
# instance. We are skipping this event from the output
|
323
321
|
# entirely.
|
@@ -327,7 +325,7 @@ module Tilia
|
|
327
325
|
|
328
326
|
iterator.fast_forward(@start) if @start
|
329
327
|
|
330
|
-
max_recurrences =
|
328
|
+
max_recurrences = Settings.max_recurrences
|
331
329
|
|
332
330
|
while iterator.valid && max_recurrences > 0
|
333
331
|
max_recurrences -= 1
|
@@ -409,7 +407,7 @@ module Tilia
|
|
409
407
|
# This method takes a FreeBusyData object and generates the VCALENDAR
|
410
408
|
# object associated with it.
|
411
409
|
#
|
412
|
-
# @return VCalendar
|
410
|
+
# @return [VCalendar]
|
413
411
|
def generate_free_busy_calendar(fb_data)
|
414
412
|
if @base_object
|
415
413
|
calendar = @base_object
|