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
@@ -11,8 +11,8 @@ module Tilia
|
|
11
11
|
class RRuleIterator
|
12
12
|
# Creates the Iterator.
|
13
13
|
#
|
14
|
-
# @param
|
15
|
-
# @param
|
14
|
+
# @param [String|array] rrule
|
15
|
+
# @param [Time] start
|
16
16
|
def initialize(rrule, start)
|
17
17
|
@week_start = 'MO'
|
18
18
|
@counter = 0
|
@@ -48,7 +48,7 @@ module Tilia
|
|
48
48
|
|
49
49
|
# Returns the current item number.
|
50
50
|
#
|
51
|
-
# @return
|
51
|
+
# @return [Fixnum]
|
52
52
|
def key
|
53
53
|
@counter
|
54
54
|
end
|
@@ -57,7 +57,7 @@ module Tilia
|
|
57
57
|
# iterator. This will return false if we've gone beyond the UNTIL or COUNT
|
58
58
|
# statements.
|
59
59
|
#
|
60
|
-
# @return
|
60
|
+
# @return [Boolean]
|
61
61
|
def valid
|
62
62
|
return @counter < @count if @count
|
63
63
|
@until.nil? || @current_date <= @until
|
@@ -65,7 +65,7 @@ module Tilia
|
|
65
65
|
|
66
66
|
# Resets the iterator.
|
67
67
|
#
|
68
|
-
# @return void
|
68
|
+
# @return [void]
|
69
69
|
def rewind
|
70
70
|
@current_date = @start_date.clone
|
71
71
|
@counter = 0
|
@@ -73,7 +73,7 @@ module Tilia
|
|
73
73
|
|
74
74
|
# Goes on to the next iteration.
|
75
75
|
#
|
76
|
-
# @return void
|
76
|
+
# @return [void]
|
77
77
|
def next
|
78
78
|
# Otherwise, we find the next event in the normal RRULE
|
79
79
|
# sequence.
|
@@ -95,7 +95,7 @@ module Tilia
|
|
95
95
|
|
96
96
|
# Returns true if this recurring event never ends.
|
97
97
|
#
|
98
|
-
# @return
|
98
|
+
# @return [Boolean]
|
99
99
|
def infinite?
|
100
100
|
!@count && !@until
|
101
101
|
end
|
@@ -103,153 +103,25 @@ module Tilia
|
|
103
103
|
# This method allows you to quickly go to the next occurrence after the
|
104
104
|
# specified date.
|
105
105
|
#
|
106
|
-
# @param
|
106
|
+
# @param [Time] dt
|
107
107
|
#
|
108
|
-
# @return void
|
108
|
+
# @return [void]
|
109
109
|
def fast_forward(dt)
|
110
110
|
self.next while valid && @current_date < dt
|
111
111
|
end
|
112
112
|
|
113
113
|
protected
|
114
114
|
|
115
|
-
# The reference start date/time for the rrule.
|
116
|
-
#
|
117
|
-
# All calculations are based on this initial date.
|
118
|
-
#
|
119
|
-
# @var DateTimeInterface
|
120
|
-
# RUBY attr_accessor :start_date
|
121
|
-
|
122
|
-
# The date of the current iteration. You can get this by calling
|
123
|
-
# .current.
|
124
|
-
#
|
125
|
-
# @var DateTimeInterface
|
126
|
-
# RUBY attr_accessor :current_date
|
127
|
-
|
128
|
-
# Frequency is one of: secondly, minutely, hourly, daily, weekly, monthly,
|
129
|
-
# yearly.
|
130
|
-
#
|
131
|
-
# @var string
|
132
|
-
# RUBY attr_accessor :frequency
|
133
|
-
|
134
|
-
# The number of recurrences, or 'null' if infinitely recurring.
|
135
|
-
#
|
136
|
-
# @var int
|
137
|
-
# RUBY attr_accessor :count
|
138
|
-
|
139
|
-
# The interval.
|
140
|
-
#
|
141
|
-
# If for example frequency is set to daily, interval = 2 would mean every
|
142
|
-
# 2 days.
|
143
|
-
#
|
144
|
-
# @var int
|
145
|
-
# RUBY attr_accessor :interval
|
146
|
-
|
147
|
-
# The last instance of this recurrence, inclusively.
|
148
|
-
#
|
149
|
-
# @var DateTimeInterface|null
|
150
|
-
# RUBY attr_accessor :until
|
151
|
-
|
152
|
-
# Which seconds to recur.
|
153
|
-
#
|
154
|
-
# This is an array of integers (between 0 and 60)
|
155
|
-
#
|
156
|
-
# @var array
|
157
|
-
# RUBY attr_accessor :by_second
|
158
|
-
|
159
|
-
# Which minutes to recur.
|
160
|
-
#
|
161
|
-
# This is an array of integers (between 0 and 59)
|
162
|
-
#
|
163
|
-
# @var array
|
164
|
-
# RUBY attr_accessor :by_minute
|
165
|
-
|
166
|
-
# Which hours to recur.
|
167
|
-
#
|
168
|
-
# This is an array of integers (between 0 and 23)
|
169
|
-
#
|
170
|
-
# @var array
|
171
|
-
# RUBY attr_accessor :by_hour
|
172
|
-
|
173
|
-
# The current item in the list.
|
174
|
-
#
|
175
|
-
# You can get this number with the key method.
|
176
|
-
#
|
177
|
-
# @var int
|
178
|
-
# RUBY attr_accessor :counter
|
179
|
-
|
180
|
-
# Which weekdays to recur.
|
181
|
-
#
|
182
|
-
# This is an array of weekdays
|
183
|
-
#
|
184
|
-
# This may also be preceeded by a positive or negative integer. If present,
|
185
|
-
# this indicates the nth occurrence of a specific day within the monthly or
|
186
|
-
# yearly rrule. For instance, -2TU indicates the second-last tuesday of
|
187
|
-
# the month, or year.
|
188
|
-
#
|
189
|
-
# @var array
|
190
|
-
# RUBY attr_accessor :by_day
|
191
|
-
|
192
|
-
# Which days of the month to recur.
|
193
|
-
#
|
194
|
-
# This is an array of days of the months (1-31). The value can also be
|
195
|
-
# negative. -5 for instance means the 5th last day of the month.
|
196
|
-
#
|
197
|
-
# @var array
|
198
|
-
# RUBY attr_accessor :by_month_day
|
199
|
-
|
200
|
-
# Which days of the year to recur.
|
201
|
-
#
|
202
|
-
# This is an array with days of the year (1 to 366). The values can also
|
203
|
-
# be negative. For instance, -1 will always represent the last day of the
|
204
|
-
# year. (December 31st).
|
205
|
-
#
|
206
|
-
# @var array
|
207
|
-
# RUBY attr_accessor :by_year_day
|
208
|
-
|
209
|
-
# Which week numbers to recur.
|
210
|
-
#
|
211
|
-
# This is an array of integers from 1 to 53. The values can also be
|
212
|
-
# negative. -1 will always refer to the last week of the year.
|
213
|
-
#
|
214
|
-
# @var array
|
215
|
-
# RUBY attr_accessor :by_week_no
|
216
|
-
|
217
|
-
# Which months to recur.
|
218
|
-
#
|
219
|
-
# This is an array of integers from 1 to 12.
|
220
|
-
#
|
221
|
-
# @var array
|
222
|
-
# RUBY attr_accessor :by_month
|
223
|
-
|
224
|
-
# Which items in an existing st to recur.
|
225
|
-
#
|
226
|
-
# These numbers work together with an existing by* rule. It specifies
|
227
|
-
# exactly which items of the existing by-rule to filter.
|
228
|
-
#
|
229
|
-
# Valid values are 1 to 366 and -1 to -366. As an example, this can be
|
230
|
-
# used to recur the last workday of the month.
|
231
|
-
#
|
232
|
-
# This would be done by setting frequency to 'monthly', byDay to
|
233
|
-
# 'MO,TU,WE,TH,FR' and bySetPos to -1.
|
234
|
-
#
|
235
|
-
# @var array
|
236
|
-
# RUBY attr_accessor :by_set_pos
|
237
|
-
|
238
|
-
# When the week starts.
|
239
|
-
#
|
240
|
-
# @var string
|
241
|
-
# RUBY attr_accessor :week_start
|
242
|
-
|
243
115
|
# Does the processing for advancing the iterator for hourly frequency.
|
244
116
|
#
|
245
|
-
# @return void
|
117
|
+
# @return [void]
|
246
118
|
def next_hourly
|
247
119
|
@current_date += @interval.hours
|
248
120
|
end
|
249
121
|
|
250
122
|
# Does the processing for advancing the iterator for daily frequency.
|
251
123
|
#
|
252
|
-
# @return void
|
124
|
+
# @return [void]
|
253
125
|
def next_daily
|
254
126
|
unless @by_hour || @by_day
|
255
127
|
@current_date += @interval.days
|
@@ -290,7 +162,7 @@ module Tilia
|
|
290
162
|
|
291
163
|
# Does the processing for advancing the iterator for weekly frequency.
|
292
164
|
#
|
293
|
-
# @return void
|
165
|
+
# @return [void]
|
294
166
|
def next_weekly
|
295
167
|
if !@by_hour && !@by_day
|
296
168
|
@current_date += @interval.weeks
|
@@ -334,7 +206,7 @@ module Tilia
|
|
334
206
|
|
335
207
|
# Does the processing for advancing the iterator for monthly frequency.
|
336
208
|
#
|
337
|
-
# @return void
|
209
|
+
# @return [void]
|
338
210
|
def next_monthly
|
339
211
|
current_day_of_month = @current_date.day
|
340
212
|
unless @by_month_day || @by_day
|
@@ -376,7 +248,7 @@ module Tilia
|
|
376
248
|
# If we made it all the way here, it means there were no
|
377
249
|
# valid occurrences, and we need to advance to the next
|
378
250
|
# month.
|
379
|
-
@current_date
|
251
|
+
@current_date -= (@current_date.day - 1).days
|
380
252
|
@current_date += @interval.months
|
381
253
|
|
382
254
|
# This goes to 0 because we need to start counting at the
|
@@ -389,7 +261,7 @@ module Tilia
|
|
389
261
|
|
390
262
|
# Does the processing for advancing the iterator for yearly frequency.
|
391
263
|
#
|
392
|
-
# @return void
|
264
|
+
# @return [void]
|
393
265
|
def next_yearly
|
394
266
|
current_month = @current_date.month
|
395
267
|
current_year = @current_date.year
|
@@ -502,9 +374,9 @@ module Tilia
|
|
502
374
|
# This method receives a string from an RRULE property, and populates this
|
503
375
|
# class with all the values.
|
504
376
|
#
|
505
|
-
# @param
|
377
|
+
# @param [String|array] rrule
|
506
378
|
#
|
507
|
-
# @return void
|
379
|
+
# @return [void]
|
508
380
|
def parse_r_rule(rrule)
|
509
381
|
if rrule.is_a?(String)
|
510
382
|
rrule = Property::ICalendar::Recur.string_to_array(rrule)
|
@@ -516,7 +388,7 @@ module Tilia
|
|
516
388
|
when 'FREQ'
|
517
389
|
value = value.downcase
|
518
390
|
unless ['secondly', 'minutely', 'hourly', 'daily', 'weekly', 'monthly', 'yearly'].include?(value)
|
519
|
-
fail
|
391
|
+
fail InvalidDataException, "Unknown value for FREQ=#{value.upcase}"
|
520
392
|
end
|
521
393
|
@frequency = value
|
522
394
|
when 'UNTIL'
|
@@ -534,7 +406,7 @@ module Tilia
|
|
534
406
|
when 'INTERVAL', 'COUNT'
|
535
407
|
val = value.to_i
|
536
408
|
if val < 1
|
537
|
-
fail
|
409
|
+
fail InvalidDataException, "#{key.upcase} in RRULE must be a positive integer!"
|
538
410
|
end
|
539
411
|
key = key.downcase
|
540
412
|
key == 'interval' ? @interval = val : @count = val
|
@@ -548,7 +420,7 @@ module Tilia
|
|
548
420
|
value = value.is_a?(Array) ? value : [value]
|
549
421
|
value.each do |part|
|
550
422
|
unless part =~ /^ (-|\+)? ([1-5])? (MO|TU|WE|TH|FR|SA|SU) $/xi
|
551
|
-
fail
|
423
|
+
fail InvalidDataException, "Invalid part in BYDAY clause: #{part}"
|
552
424
|
end
|
553
425
|
end
|
554
426
|
@by_day = value
|
@@ -565,22 +437,17 @@ module Tilia
|
|
565
437
|
when 'WKST'
|
566
438
|
@week_start = value.upcase
|
567
439
|
else
|
568
|
-
fail
|
440
|
+
fail InvalidDataException, "Not supported: #{key.upcase}"
|
569
441
|
end
|
570
442
|
end
|
571
443
|
end
|
572
444
|
|
573
|
-
# Mappings between the day number and english day name.
|
574
|
-
#
|
575
|
-
# @var array
|
576
|
-
# RUBY: attr_accessor :day_names
|
577
|
-
|
578
445
|
# Returns all the occurrences for a monthly frequency with a 'byDay' or
|
579
446
|
# 'byMonthDay' expansion for the current month.
|
580
447
|
#
|
581
448
|
# The returned list is an array of integers with the day of month (1-31).
|
582
449
|
#
|
583
|
-
# @return array
|
450
|
+
# @return [array]
|
584
451
|
def monthly_occurrences
|
585
452
|
start_date = @current_date.clone
|
586
453
|
|
@@ -682,7 +549,7 @@ module Tilia
|
|
682
549
|
|
683
550
|
# Simple mapping from iCalendar day names to day numbers.
|
684
551
|
#
|
685
|
-
# @
|
552
|
+
# @return [array]
|
686
553
|
# RUBY: attr_accessor :day_map
|
687
554
|
|
688
555
|
def hours
|
@@ -23,9 +23,25 @@ module Tilia
|
|
23
23
|
# appointments made for many years to come.
|
24
24
|
@max_date = '2100-01-01'
|
25
25
|
|
26
|
+
# The maximum number of recurrences that will be generated.
|
27
|
+
#
|
28
|
+
# This setting limits the maximum of recurring events that this library
|
29
|
+
# generates in its recurrence iterators.
|
30
|
+
#
|
31
|
+
# This is a security measure. Without this, it would be possible to craft
|
32
|
+
# specific events that recur many, many times, potentially DDOSing the
|
33
|
+
# server.
|
34
|
+
#
|
35
|
+
# The default (3500) allows creation of a dialy event that goes on for 10
|
36
|
+
# years, which is hopefully long enough for most.
|
37
|
+
#
|
38
|
+
# Set this value to -1 to disable this control altogether.
|
39
|
+
@max_recurrences = 3500
|
40
|
+
|
26
41
|
class << self
|
27
42
|
attr_accessor :min_date
|
28
43
|
attr_accessor :max_date
|
44
|
+
attr_accessor :max_recurrences
|
29
45
|
end
|
30
46
|
end
|
31
47
|
end
|
@@ -14,20 +14,20 @@ module Tilia
|
|
14
14
|
|
15
15
|
# Timezones.
|
16
16
|
#
|
17
|
-
# @
|
17
|
+
# @return [array]
|
18
18
|
# RUBY: attr_accessor :vtimezones
|
19
19
|
|
20
20
|
# iCalendar objects.
|
21
21
|
#
|
22
|
-
# @
|
22
|
+
# @return [array]
|
23
23
|
# RUBY: attr_accessor :objects
|
24
24
|
|
25
25
|
# Constructor.
|
26
26
|
#
|
27
27
|
# The splitter should receive an readable file stream as it's input.
|
28
28
|
#
|
29
|
-
# @param resource input
|
30
|
-
# @param
|
29
|
+
# @param [resource] input
|
30
|
+
# @param [Fixnum] options Parser options, see the OPTIONS constants.
|
31
31
|
def initialize(input, options = 0)
|
32
32
|
@vtimezones = {}
|
33
33
|
@objects = {}
|
@@ -65,7 +65,7 @@ module Tilia
|
|
65
65
|
#
|
66
66
|
# When the end is reached, null will be returned.
|
67
67
|
#
|
68
|
-
# @return Sabre\VObject\Component
|
68
|
+
# @return [Sabre\VObject\Component, nil]
|
69
69
|
def next
|
70
70
|
key = @objects.keys.first
|
71
71
|
|
@@ -13,7 +13,7 @@ module Tilia
|
|
13
13
|
#
|
14
14
|
# The splitter should receive an readable file stream as it's input.
|
15
15
|
#
|
16
|
-
# @param resource input
|
16
|
+
# @param [resource] input
|
17
17
|
def initialize(_input)
|
18
18
|
end
|
19
19
|
|
@@ -22,7 +22,7 @@ module Tilia
|
|
22
22
|
#
|
23
23
|
# When the end is reached, null will be returned.
|
24
24
|
#
|
25
|
-
# @return Sabre\VObject\Component
|
25
|
+
# @return [Sabre\VObject\Component, nil]
|
26
26
|
def next
|
27
27
|
end
|
28
28
|
end
|
@@ -12,20 +12,20 @@ module Tilia
|
|
12
12
|
include SplitterInterface
|
13
13
|
# File handle.
|
14
14
|
#
|
15
|
-
# @
|
15
|
+
# @return [resource]
|
16
16
|
# RUBY: attr_accessor :input
|
17
17
|
|
18
18
|
# Persistent parser.
|
19
19
|
#
|
20
|
-
# @
|
20
|
+
# @return [MimeDir]
|
21
21
|
# RUBY: attr_accessor :parser
|
22
22
|
|
23
23
|
# Constructor.
|
24
24
|
#
|
25
25
|
# The splitter should receive an readable file stream as it's input.
|
26
26
|
#
|
27
|
-
# @param resource input
|
28
|
-
# @param
|
27
|
+
# @param [resource] input
|
28
|
+
# @param [Fixnum] options Parser options, see the OPTIONS constants.
|
29
29
|
def initialize(input, options = 0)
|
30
30
|
@input = input
|
31
31
|
@parser = Parser::MimeDir.new(input, options)
|
@@ -36,7 +36,7 @@ module Tilia
|
|
36
36
|
#
|
37
37
|
# When the end is reached, null will be returned.
|
38
38
|
#
|
39
|
-
# @return Sabre\VObject\Component
|
39
|
+
# @return [Sabre\VObject\Component, nil]
|
40
40
|
def next
|
41
41
|
begin
|
42
42
|
object = @parser.parse
|
@@ -4,9 +4,9 @@ module Tilia
|
|
4
4
|
class StringUtil
|
5
5
|
# Returns true or false depending on if a string is valid UTF-8.
|
6
6
|
#
|
7
|
-
# @param
|
7
|
+
# @param [String] str
|
8
8
|
#
|
9
|
-
# @return
|
9
|
+
# @return [Boolean]
|
10
10
|
def self.utf8?(str)
|
11
11
|
fail ArgumentError, 'str needs to be a String' unless str.is_a?(String)
|
12
12
|
# Control characters
|
@@ -20,22 +20,38 @@ module Tilia
|
|
20
20
|
# Currently only ISO-5991-1 input and UTF-8 input is supported, but this
|
21
21
|
# may be expanded upon if we receive other examples.
|
22
22
|
#
|
23
|
-
# @param
|
23
|
+
# @param [String] str
|
24
24
|
#
|
25
|
-
# @return
|
25
|
+
# @return [String]
|
26
26
|
def self.convert_to_utf8(str)
|
27
|
+
str = str.encode('UTF-8', guess_encoding(str))
|
28
|
+
|
29
|
+
# Removing any control characters
|
30
|
+
str.gsub(/(?:[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F])/, '')
|
31
|
+
end
|
32
|
+
|
33
|
+
# Detects the encoding of a string
|
34
|
+
#
|
35
|
+
# Currently only supports 'UTF-8', 'ISO-5991-1' and 'Windows-1252'.
|
36
|
+
#
|
37
|
+
# @param [String] str
|
38
|
+
# @return [String] encoding
|
39
|
+
def self.guess_encoding(str)
|
27
40
|
cd = CharDet.detect(str)
|
28
41
|
|
29
42
|
# Best solution I could find ...
|
30
43
|
if cd['confidence'] > 0.4 && cd['encoding'] =~ /(?:windows|iso)/i
|
31
|
-
|
44
|
+
cd['encoding']
|
45
|
+
else
|
46
|
+
'UTF-8'
|
32
47
|
end
|
33
|
-
|
34
|
-
# Removing any control characters
|
35
|
-
str.gsub(/(?:[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F])/, '')
|
36
48
|
end
|
37
49
|
|
38
|
-
#
|
50
|
+
# Cuts the string after a certain bytelength
|
51
|
+
#
|
52
|
+
# @param [String] string
|
53
|
+
# @param [Fixnum] length
|
54
|
+
# @return [String] cut string
|
39
55
|
def self.mb_strcut(string, length)
|
40
56
|
return '' if string == ''
|
41
57
|
|