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.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.sabre.md +59 -2
  3. data/Gemfile +1 -8
  4. data/Gemfile.lock +18 -12
  5. data/LICENSE +1 -1
  6. data/LICENSE.sabre +1 -1
  7. data/lib/tilia/v_object.rb +1 -0
  8. data/lib/tilia/v_object/birthday_calendar_generator.rb +11 -11
  9. data/lib/tilia/v_object/cli.rb +39 -38
  10. data/lib/tilia/v_object/component.rb +47 -50
  11. data/lib/tilia/v_object/component/available.rb +4 -37
  12. data/lib/tilia/v_object/component/v_alarm.rb +6 -18
  13. data/lib/tilia/v_object/component/v_availability.rb +6 -39
  14. data/lib/tilia/v_object/component/v_calendar.rb +66 -98
  15. data/lib/tilia/v_object/component/v_card.rb +42 -69
  16. data/lib/tilia/v_object/component/v_event.rb +5 -17
  17. data/lib/tilia/v_object/component/v_free_busy.rb +4 -16
  18. data/lib/tilia/v_object/component/v_journal.rb +16 -16
  19. data/lib/tilia/v_object/component/v_time_zone.rb +2 -14
  20. data/lib/tilia/v_object/component/v_todo.rb +17 -36
  21. data/lib/tilia/v_object/date_time_parser.rb +24 -24
  22. data/lib/tilia/v_object/document.rb +25 -25
  23. data/lib/tilia/v_object/free_busy_data.rb +7 -7
  24. data/lib/tilia/v_object/free_busy_generator.rb +73 -75
  25. data/lib/tilia/v_object/i_tip.rb +1 -0
  26. data/lib/tilia/v_object/i_tip/broker.rb +134 -116
  27. data/lib/tilia/v_object/i_tip/i_tip_exception.rb +1 -1
  28. data/lib/tilia/v_object/i_tip/message.rb +13 -13
  29. data/lib/tilia/v_object/invalid_data_exception.rb +8 -0
  30. data/lib/tilia/v_object/node.rb +22 -27
  31. data/lib/tilia/v_object/parameter.rb +22 -22
  32. data/lib/tilia/v_object/parse_exception.rb +1 -1
  33. data/lib/tilia/v_object/parser.rb +1 -0
  34. data/lib/tilia/v_object/parser/json.rb +9 -19
  35. data/lib/tilia/v_object/parser/mime_dir.rb +73 -39
  36. data/lib/tilia/v_object/parser/parser.rb +9 -14
  37. data/lib/tilia/v_object/parser/xml.rb +33 -50
  38. data/lib/tilia/v_object/parser/xml/element.rb +1 -0
  39. data/lib/tilia/v_object/parser/xml/element/key_value.rb +2 -2
  40. data/lib/tilia/v_object/property.rb +52 -52
  41. data/lib/tilia/v_object/property/binary.rb +10 -10
  42. data/lib/tilia/v_object/property/boolean.rb +6 -6
  43. data/lib/tilia/v_object/property/flat_text.rb +3 -3
  44. data/lib/tilia/v_object/property/float_value.rb +10 -10
  45. data/lib/tilia/v_object/property/i_calendar.rb +1 -0
  46. data/lib/tilia/v_object/property/i_calendar/cal_address.rb +3 -3
  47. data/lib/tilia/v_object/property/i_calendar/date_time.rb +29 -57
  48. data/lib/tilia/v_object/property/i_calendar/duration.rb +6 -6
  49. data/lib/tilia/v_object/property/i_calendar/period.rb +10 -10
  50. data/lib/tilia/v_object/property/i_calendar/recur.rb +16 -24
  51. data/lib/tilia/v_object/property/integer_value.rb +8 -8
  52. data/lib/tilia/v_object/property/text.rb +21 -36
  53. data/lib/tilia/v_object/property/time.rb +29 -6
  54. data/lib/tilia/v_object/property/unknown.rb +2 -2
  55. data/lib/tilia/v_object/property/uri.rb +24 -5
  56. data/lib/tilia/v_object/property/utc_offset.rb +5 -5
  57. data/lib/tilia/v_object/property/v_card.rb +1 -0
  58. data/lib/tilia/v_object/property/v_card/date.rb +3 -3
  59. data/lib/tilia/v_object/property/v_card/date_and_or_time.rb +30 -42
  60. data/lib/tilia/v_object/property/v_card/date_time.rb +1 -1
  61. data/lib/tilia/v_object/property/v_card/language_tag.rb +4 -4
  62. data/lib/tilia/v_object/property/v_card/time_stamp.rb +5 -5
  63. data/lib/tilia/v_object/reader.rb +12 -11
  64. data/lib/tilia/v_object/recur.rb +2 -0
  65. data/lib/tilia/v_object/recur/event_iterator.rb +30 -27
  66. data/lib/tilia/v_object/recur/max_instances_exceeded_exception.rb +10 -0
  67. data/lib/tilia/v_object/recur/no_instances_exception.rb +1 -1
  68. data/lib/tilia/v_object/recur/r_date_iterator.rb +15 -41
  69. data/lib/tilia/v_object/recur/r_rule_iterator.rb +23 -156
  70. data/lib/tilia/v_object/settings.rb +16 -0
  71. data/lib/tilia/v_object/splitter.rb +1 -0
  72. data/lib/tilia/v_object/splitter/i_calendar.rb +5 -5
  73. data/lib/tilia/v_object/splitter/splitter_interface.rb +2 -2
  74. data/lib/tilia/v_object/splitter/v_card.rb +5 -5
  75. data/lib/tilia/v_object/string_util.rb +25 -9
  76. data/lib/tilia/v_object/time_zone_data.rb +1 -0
  77. data/lib/tilia/v_object/time_zone_util.rb +6 -6
  78. data/lib/tilia/v_object/uuid_util.rb +3 -3
  79. data/lib/tilia/v_object/v_card_converter.rb +24 -21
  80. data/lib/tilia/v_object/version.rb +1 -1
  81. data/lib/tilia/v_object/writer.rb +7 -7
  82. data/test/test_helper.rb +3 -3
  83. data/test/v_object/birthday_calendar_generator_test.rb +22 -0
  84. data/test/v_object/component/v_alarm_test.rb +3 -1
  85. data/test/v_object/component/v_calendar_test.rb +40 -4
  86. data/test/v_object/component/v_card_test.rb +1 -1
  87. data/test/v_object/component_test.rb +5 -3
  88. data/test/v_object/date_time_parser_test.rb +15 -5
  89. data/test/v_object/free_busy_generator_test.rb +5 -5
  90. data/test/v_object/i_tip/broker_attendee_reply_test.rb +19 -0
  91. data/test/v_object/i_tip/broker_delete_event_test.rb +146 -2
  92. data/test/v_object/i_tip/broker_new_event_test.rb +21 -0
  93. data/test/v_object/i_tip/broker_process_reply_test.rb +10 -0
  94. data/test/v_object/i_tip/broker_tester.rb +1 -1
  95. data/test/v_object/i_tip/broker_update_event_test.rb +36 -0
  96. data/test/v_object/issue259_test.rb +24 -0
  97. data/test/v_object/issue40_test.rb +3 -1
  98. data/test/v_object/j_cal_test.rb +15 -12
  99. data/test/v_object/parser/json_test.rb +5 -5
  100. data/test/v_object/parser/mime_dir_test.rb +109 -0
  101. data/test/v_object/property/binary_test.rb +4 -2
  102. data/test/v_object/property/i_calendar/date_time_test.rb +3 -1
  103. data/test/v_object/property/uri_test.rb +23 -0
  104. data/test/v_object/recur/event_iterator/by_month_in_daily_test.rb +1 -1
  105. data/test/v_object/recur/event_iterator/by_set_pos_hang_test.rb +1 -1
  106. data/test/v_object/recur/event_iterator/expand_floating_times_test.rb +9 -9
  107. data/test/v_object/recur/event_iterator/handle_r_date_expand_test.rb +51 -0
  108. data/test/v_object/recur/event_iterator/incorrect_expand_test.rb +3 -5
  109. data/test/v_object/recur/event_iterator/infinite_loop_problem_test.rb +3 -1
  110. data/test/v_object/{issue26_test.rb → recur/event_iterator/issue26_test.rb} +3 -1
  111. data/test/v_object/recur/event_iterator/main_test.rb +9 -3
  112. data/test/v_object/recur/event_iterator/max_instances_test.rb +38 -0
  113. data/test/v_object/recur/event_iterator/missing_overridden_test.rb +3 -5
  114. data/test/v_object/recur/event_iterator/no_instances_test.rb +5 -3
  115. data/test/v_object/recur/event_iterator/override_first_event_test.rb +9 -9
  116. data/test/v_object/recur/r_date_iterator_test.rb +18 -0
  117. data/test/v_object/recur/r_rule_iterator_test.rb +4 -4
  118. data/test/v_object/splitter/i_calendar_test.rb +27 -7
  119. data/test/v_object/splitter/v_card_test.rb +5 -3
  120. data/test/v_object/test_case.rb +14 -4
  121. data/tilia-vobject.gemspec +2 -2
  122. metadata +17 -11
@@ -11,7 +11,7 @@ module Tilia
11
11
  # This corresponds to the VALUE= parameter. Every property also has a
12
12
  # 'default' valueType.
13
13
  #
14
- # @return string
14
+ # @return [String]
15
15
  def value_type
16
16
  'DATE-TIME'
17
17
  end
@@ -11,16 +11,16 @@ module Tilia
11
11
  # This has been 'unfolded', so only 1 line will be passed. Unescaping is
12
12
  # not yet done, but parameters are not included.
13
13
  #
14
- # @param string val
14
+ # @param [String] val
15
15
  #
16
- # @return void
16
+ # @return [void]
17
17
  def raw_mime_dir_value=(val)
18
18
  self.value = val
19
19
  end
20
20
 
21
21
  # Returns a raw mime-dir representation of the value.
22
22
  #
23
- # @return string
23
+ # @return [String]
24
24
  def raw_mime_dir_value
25
25
  value
26
26
  end
@@ -30,7 +30,7 @@ module Tilia
30
30
  # This corresponds to the VALUE= parameter. Every property also has a
31
31
  # 'default' valueType.
32
32
  #
33
- # @return string
33
+ # @return [String]
34
34
  def value_type
35
35
  'LANGUAGE-TAG'
36
36
  end
@@ -9,7 +9,7 @@ module Tilia
9
9
  # In case this is a multi-value property. This string will be used as a
10
10
  # delimiter.
11
11
  #
12
- # @var string|null
12
+ # @return [String, nil]
13
13
  attr_accessor :delimiter
14
14
 
15
15
  # Returns the type of value.
@@ -17,7 +17,7 @@ module Tilia
17
17
  # This corresponds to the VALUE= parameter. Every property also has a
18
18
  # 'default' valueType.
19
19
  #
20
- # @return string
20
+ # @return [String]
21
21
  def value_type
22
22
  'TIMESTAMP'
23
23
  end
@@ -26,7 +26,7 @@ module Tilia
26
26
  #
27
27
  # This method must always return an array.
28
28
  #
29
- # @return array
29
+ # @return [array]
30
30
  def json_value
31
31
  parts = DateTimeParser.parse_v_card_date_time(value)
32
32
 
@@ -51,9 +51,9 @@ module Tilia
51
51
  # This method serializes only the value of a property. This is used to
52
52
  # create xCard or xCal documents.
53
53
  #
54
- # @param Xml\Writer writer XML writer.
54
+ # @param [Xml\Writer] writer XML writer.
55
55
  #
56
- # @return void
56
+ # @return [void]
57
57
  def xml_serialize_value(writer)
58
58
  # xCard is the only XML and JSON format that has the same date and time
59
59
  # format than vCard.
@@ -20,12 +20,13 @@ module Tilia
20
20
  #
21
21
  # You can either supply a string, or a readable stream for input.
22
22
  #
23
- # @param string|resource data
24
- # @param int options
25
- #
26
- # @return Document
27
- def self.read(data, options = 0)
23
+ # @param [String, #read] data
24
+ # @param [Fixnum] options
25
+ # @param [String] charset
26
+ # @return [Document]
27
+ def self.read(data, options = 0, charset = 'UTF-8')
28
28
  parser = Parser::MimeDir.new
29
+ parser.charset = charset
29
30
  result = parser.parse(data, options)
30
31
 
31
32
  result
@@ -40,10 +41,10 @@ module Tilia
40
41
  # Specifying the array is useful if json_decode was already called on the
41
42
  # input.
42
43
  #
43
- # @param string|resource|array data
44
- # @param int options
44
+ # @param [String, |resource|array] data
45
+ # @param [Fixnum] options
45
46
  #
46
- # @return Document
47
+ # @return [Document]
47
48
  def self.read_json(data, options = 0)
48
49
  parser = Parser::Json.new
49
50
  result = parser.parse(data, options)
@@ -58,10 +59,10 @@ module Tilia
58
59
  #
59
60
  # You can either supply a string, or a readable stream for input.
60
61
  #
61
- # @param string|resource data
62
- # @param int options
62
+ # @param [String|resource] data
63
+ # @param [Fixnum] options
63
64
  #
64
- # @return Document
65
+ # @return [Document]
65
66
  def self.read_xml(data, options = 0)
66
67
  parser = Parser::Xml.new
67
68
  result = parser.parse(data, options)
@@ -1,6 +1,8 @@
1
1
  module Tilia
2
2
  module VObject
3
+ # Namespace of the recurrence functionality
3
4
  module Recur
5
+ require 'tilia/v_object/recur/max_instances_exceeded_exception'
4
6
  require 'tilia/v_object/recur/no_instances_exception'
5
7
  require 'tilia/v_object/recur/event_iterator'
6
8
  require 'tilia/v_object/recur/r_date_iterator'
@@ -44,12 +44,12 @@ module Tilia
44
44
  class EventIterator
45
45
  # Reference timeZone for floating dates and times.
46
46
  #
47
- # @var DateTimeZone
47
+ # @return [ActiveSupport::TimeZone]
48
48
  # RUBY: attr_accessor :time_zone
49
49
 
50
50
  # True if we're iterating an all-day event.
51
51
  #
52
- # @var bool
52
+ # @return [Boolean]
53
53
  # RUBY: attr_accessor :all_day
54
54
 
55
55
  # Creates the iterator.
@@ -65,9 +65,9 @@ module Tilia
65
65
  #
66
66
  # The uid parameter is only required for the first method.
67
67
  #
68
- # @param Component|array input
69
- # @param string|null uid
70
- # @param DateTimeZone time_zone Reference timezone for floating dates and
68
+ # @param [Component|array] input
69
+ # @param [String, nil] uid
70
+ # @param [ActiveSupport::TimeZone] time_zone Reference timezone for floating dates and
71
71
  # times.
72
72
  def initialize(input, uid = nil, time_zone = nil)
73
73
  @overridden_events = []
@@ -161,14 +161,12 @@ module Tilia
161
161
 
162
162
  rewind
163
163
 
164
- unless valid
165
- fail Recur::NoInstancesException, 'This recurrence rule does not generate any valid instances'
166
- end
164
+ fail Recur::NoInstancesException, 'This recurrence rule does not generate any valid instances' unless valid
167
165
  end
168
166
 
169
167
  # Returns the date for the current position of the iterator.
170
168
  #
171
- # @return DateTimeImmutable
169
+ # @return [Time]
172
170
  def current
173
171
  @current_date.clone if @current_date
174
172
  end
@@ -176,7 +174,7 @@ module Tilia
176
174
  # This method returns the start date for the current iteration of the
177
175
  # event.
178
176
  #
179
- # @return DateTimeImmutable
177
+ # @return [Time]
180
178
  def dt_start
181
179
  @current_date.clone if @current_date
182
180
  end
@@ -184,7 +182,7 @@ module Tilia
184
182
  # This method returns the end date for the current iteration of the
185
183
  # event.
186
184
  #
187
- # @return DateTimeImmutable
185
+ # @return [Time]
188
186
  def dt_end
189
187
  return nil unless valid
190
188
 
@@ -196,7 +194,7 @@ module Tilia
196
194
  # This VEVENT will have a recurrence id, and it's DTSTART and DTEND
197
195
  # altered.
198
196
  #
199
- # @return VEvent
197
+ # @return [VEvent]
200
198
  def event_object
201
199
  return @current_overridden_event if @current_overridden_event
202
200
 
@@ -234,7 +232,7 @@ module Tilia
234
232
  #
235
233
  # This is for us simply a 0-based index.
236
234
  #
237
- # @return int
235
+ # @return [Fixnum]
238
236
  def key
239
237
  # The counter is always 1 ahead.
240
238
  @counter - 1
@@ -243,9 +241,14 @@ module Tilia
243
241
  # This is called after next, to see if the iterator is still at a valid
244
242
  # position, or if it's at the end.
245
243
  #
246
- # @return bool
244
+ # @return [Boolean]
247
245
  def valid
248
- !!@current_date
246
+ if @counter > Settings.max_recurrences &&
247
+ Settings.max_recurrences != -1
248
+ fail MaxInstancesExceededException, "Recurring events are only allowed to generate #{Settings.max_recurrences}"
249
+ end
250
+
251
+ !@current_date.nil?
249
252
  end
250
253
 
251
254
  # Sets the iterator back to the starting point.
@@ -270,7 +273,7 @@ module Tilia
270
273
 
271
274
  # Advances the iterator with one step.
272
275
  #
273
- # @return void
276
+ # @return [void]
274
277
  def next
275
278
  @current_overridden_event = nil
276
279
  @counter += 1
@@ -318,21 +321,21 @@ module Tilia
318
321
 
319
322
  # Quickly jump to a date in the future.
320
323
  #
321
- # @param DateTimeInterface date_time
324
+ # @param [Time] date_time
322
325
  def fast_forward(date_time)
323
326
  self.next while valid && dt_end < date_time
324
327
  end
325
328
 
326
329
  # Returns true if this recurring event never ends.
327
330
  #
328
- # @return bool
331
+ # @return [Boolean]
329
332
  def infinite?
330
333
  @recur_iterator.infinite?
331
334
  end
332
335
 
333
336
  # RRULE parser.
334
337
  #
335
- # @var RRuleIterator
338
+ # @return [RRuleIterator]
336
339
  # RUBY: attr_accessor :recur_iterator
337
340
 
338
341
  # The duration, in seconds, of the master event.
@@ -342,12 +345,12 @@ module Tilia
342
345
 
343
346
  # A reference to the main (master) event.
344
347
  #
345
- # @var VEVENT
348
+ # @return [VEVENT]
346
349
  # RUBY: attr_accessor :master_event
347
350
 
348
351
  # List of overridden events.
349
352
  #
350
- # @var array
353
+ # @return [array]
351
354
  # RUBY: attr_accessor :overridden_events
352
355
 
353
356
  # Overridden event index.
@@ -355,28 +358,28 @@ module Tilia
355
358
  # Key is timestamp, value is the index of the item in the overridden_event
356
359
  # property.
357
360
  #
358
- # @var array
361
+ # @return [array]
359
362
  # RUBY: attr_accessor :overridden_events_index
360
363
 
361
364
  # A list of recurrence-id's that are either part of EXDATE, or are
362
365
  # overridden.
363
366
  #
364
- # @var array
367
+ # @return [array]
365
368
  # RUBY: attr_accessor :exceptions
366
369
 
367
370
  # Internal event counter.
368
371
  #
369
- # @var int
372
+ # @return [Fixnum]
370
373
  # RUBY: attr_accessor :counter
371
374
 
372
375
  # The very start of the iteration process.
373
376
  #
374
- # @var DateTimeImmutable
377
+ # @return [Time]
375
378
  # RUBY: attr_accessor :start_date
376
379
 
377
380
  # Where we are currently in the iteration process.
378
381
  #
379
- # @var DateTimeImmutable
382
+ # @return [Time]
380
383
  # RUBY: attr_accessor :current_date
381
384
 
382
385
  # The next date from the rrule parser.
@@ -384,7 +387,7 @@ module Tilia
384
387
  # Sometimes we need to temporary store the next date, because an
385
388
  # overridden event came before.
386
389
  #
387
- # @var DateTimeImmutable
390
+ # @return [Time]
388
391
  # RUBY: attr_accessor :next_date
389
392
 
390
393
  def to_a
@@ -0,0 +1,10 @@
1
+ module Tilia
2
+ module VObject
3
+ module Recur
4
+ # This exception will get thrown when a recurrence rule generated more than
5
+ # the maximum number of instances.
6
+ class MaxInstancesExceededException < StandardError
7
+ end
8
+ end
9
+ end
10
+ end
@@ -4,7 +4,7 @@ module Tilia
4
4
  # This exception gets thrown when a recurrence iterator produces 0 instances.
5
5
  #
6
6
  # This may happen when every occurence in a rrule is also in EXDATE.
7
- class NoInstancesException < Exception
7
+ class NoInstancesException < StandardError
8
8
  end
9
9
  end
10
10
  end
@@ -13,8 +13,8 @@ module Tilia
13
13
 
14
14
  # Creates the Iterator.
15
15
  #
16
- # @param string|array rrule
17
- # @param DateTimeInterface start
16
+ # @param [String|array] rrule
17
+ # @param [Time] start
18
18
  def initialize(rrule, start)
19
19
  @counter = 0
20
20
  @dates = []
@@ -30,7 +30,7 @@ module Tilia
30
30
 
31
31
  # Returns the current item number.
32
32
  #
33
- # @return int
33
+ # @return [Fixnum]
34
34
  def key
35
35
  @counter
36
36
  end
@@ -38,14 +38,14 @@ module Tilia
38
38
  # Returns whether the current item is a valid item for the recurrence
39
39
  # iterator.
40
40
  #
41
- # @return bool
41
+ # @return [Boolean]
42
42
  def valid
43
43
  @counter <= @dates.size
44
44
  end
45
45
 
46
46
  # Resets the iterator.
47
47
  #
48
- # @return void
48
+ # @return [void]
49
49
  def rewind
50
50
  @current_date = @start_date.clone
51
51
  @counter = 0
@@ -53,20 +53,21 @@ module Tilia
53
53
 
54
54
  # Goes on to the next iteration.
55
55
  #
56
- # @return void
56
+ # @return [void]
57
57
  def next
58
58
  @counter += 1
59
59
 
60
60
  return nil unless valid
61
61
 
62
62
  @current_date = DateTimeParser.parse(
63
- @dates[@counter - 1]
63
+ @dates[@counter - 1],
64
+ @start_date.time_zone
64
65
  )
65
66
  end
66
67
 
67
68
  # Returns true if this recurring event never ends.
68
69
  #
69
- # @return bool
70
+ # @return [Boolean]
70
71
  def infinite?
71
72
  false
72
73
  end
@@ -74,58 +75,31 @@ module Tilia
74
75
  # This method allows you to quickly go to the next occurrence after the
75
76
  # specified date.
76
77
  #
77
- # @param DateTimeInterface dt
78
+ # @param [Time] dt
78
79
  #
79
- # @return void
80
+ # @return [void]
80
81
  def fast_forward(dt)
81
82
  self.next while valid && @current_date < dt
82
83
  end
83
84
 
84
- # The reference start date/time for the rrule.
85
- #
86
- # All calculations are based on this initial date.
87
- #
88
- # @var DateTimeInterface
89
- # RUBY: attr_accessor :start_date
90
-
91
- # The date of the current iteration. You can get this by calling
92
- # .current.
93
- #
94
- # @var DateTimeInterface
95
- # RUBY: attr_accessor :protected current_date
96
-
97
- # The current item in the list.
98
- #
99
- # You can get this number with the key method.
100
- #
101
- # @var int
102
- # RUBY: attr_accessor :counter
103
-
104
85
  protected
105
86
 
106
87
  # This method receives a string from an RRULE property, and populates this
107
88
  # class with all the values.
108
89
  #
109
- # @param string|array rrule
90
+ # @param [String|array] rrule
110
91
  #
111
- # @return void
92
+ # @return [void]
112
93
  def parse_r_date(rdate)
113
94
  rdate = rdate.split(',') if rdate.is_a?(String)
114
95
 
115
96
  @dates = rdate
116
97
  end
117
98
 
118
- # TODO
119
- #
120
- # TODO
121
- #
122
- # @var TODO
123
- # RUBY: attr_accessor :dates
124
-
125
99
  def each
126
- m = [@start_date]
100
+ m = [@start_date.clone]
127
101
  n = @dates.map do |d|
128
- DateTimeParser.parse(d)
102
+ DateTimeParser.parse(d, @start_date.time_zone)
129
103
  end
130
104
  m.concat n
131
105
  m.each do |d|