icalendar 1.4.3 → 1.4.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.travis.yml +5 -0
- data/History.txt +7 -0
- data/README.md +2 -0
- data/icalendar.gemspec +1 -0
- data/lib/icalendar/base.rb +1 -1
- data/lib/icalendar/component.rb +12 -8
- data/lib/icalendar/parser.rb +40 -16
- data/lib/icalendar/rrule.rb +6 -2
- data/lib/icalendar/tzinfo.rb +2 -2
- data/test/test_conversions.rb +8 -8
- data/test/test_tzinfo.rb +27 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3bb514e630455e28b49f977bb6c316dc470cb98f
|
4
|
+
data.tar.gz: 02953a2e8e74af0680d02e6ae889dd30fee8cedb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 107461d20bf35d2f4df715e52605126a55a532c8dabb51c6b35eda16828fe50220a073b7c76b09dda00165c34745414b5172206a422aeeee4e9fc2ba7df46cef
|
7
|
+
data.tar.gz: 66694d2dd3cc7f70d3ddcbd81d6682fca411dffe57bd76afacc015f6c1328b0f6f67ffed512c42b08d500644d8d8e514502c2c438e32644b43c66f9c2976bde9
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/History.txt
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
=== 1.4.4 2013-11-05
|
2
|
+
* Allow user to handle TZInfo::AmbiguousTime error - David Bradford
|
3
|
+
* Better handling of multiple exdate and rdate values
|
4
|
+
|
5
|
+
=== 1.4.3 2013-09-18
|
6
|
+
* Fix concatenation of multiple BYWEEK or BYMONTH recurrence rules
|
7
|
+
|
1
8
|
=== 1.4.2 2013-09-11
|
2
9
|
* Double Quote parameter values that contain forbidden characters
|
3
10
|
* Update Component#respond_to? to match Ruby 2.0 - Keith Marcum
|
data/README.md
CHANGED
data/icalendar.gemspec
CHANGED
data/lib/icalendar/base.rb
CHANGED
data/lib/icalendar/component.rb
CHANGED
@@ -314,16 +314,24 @@ module Icalendar
|
|
314
314
|
# Getter for whole array
|
315
315
|
unless instance_methods.include? plural
|
316
316
|
code = <<-code
|
317
|
-
def #{plural}(a = nil)
|
317
|
+
def #{plural}(a = nil, params = nil)
|
318
318
|
if a.nil?
|
319
319
|
@properties["#{property}"] || []
|
320
320
|
else
|
321
|
-
self.#{plural}=(a)
|
321
|
+
self.#{plural}=(a).tap do |val|
|
322
|
+
unless params.nil?
|
323
|
+
unless val.respond_to?(:ical_params)
|
324
|
+
val.class.class_eval { attr_accessor :ical_params }
|
325
|
+
end
|
326
|
+
val.ical_params = params
|
327
|
+
end
|
328
|
+
end
|
322
329
|
end
|
323
330
|
end
|
324
331
|
code
|
325
332
|
|
326
333
|
class_eval code, "component.rb", 186
|
334
|
+
alias_method property, plural
|
327
335
|
end
|
328
336
|
end
|
329
337
|
|
@@ -333,13 +341,9 @@ module Icalendar
|
|
333
341
|
code = <<-code
|
334
342
|
def #{plural}=(a)
|
335
343
|
if a.respond_to?(:to_ary)
|
336
|
-
a.to_ary.each do |val|
|
337
|
-
unless val.respond_to?(:to_ical)
|
338
|
-
raise(NotImplementedError, "Property values do not support to_ical method!")
|
339
|
-
end
|
340
|
-
end
|
341
|
-
|
342
344
|
@properties["#{property}"] = a.to_ary
|
345
|
+
elsif a =~ /^[^"].*(?<!\\\\),.*[^"]$/
|
346
|
+
@properties["#{property}"] = a.split(/(?<!\\\\),/).to_ary
|
343
347
|
else
|
344
348
|
raise ArgumentError, "#{plural} is a multi-property that must be an array! Use the add_[property] method to add single entries."
|
345
349
|
end
|
data/lib/icalendar/parser.rb
CHANGED
@@ -176,7 +176,7 @@ module Icalendar
|
|
176
176
|
# Replace dashes with underscores
|
177
177
|
name = name.gsub('-', '_')
|
178
178
|
|
179
|
-
if component.
|
179
|
+
if component.multiline_property?(name)
|
180
180
|
adder = "add_" + name
|
181
181
|
if component.respond_to?(adder)
|
182
182
|
component.send(adder, value, params)
|
@@ -286,13 +286,15 @@ module Icalendar
|
|
286
286
|
@parsers["DUE"] = m
|
287
287
|
@parsers["DTSTART"] = m
|
288
288
|
@parsers["RECURRENCE-ID"] = m
|
289
|
-
@parsers["EXDATE"] = m
|
290
|
-
@parsers["RDATE"] = m
|
291
289
|
@parsers["CREATED"] = m
|
292
290
|
@parsers["DTSTAMP"] = m
|
293
291
|
@parsers["LAST-MODIFIED"] = m
|
294
292
|
@parsers["ACKNOWLEDGED"] = m
|
295
293
|
|
294
|
+
m = self.method(:parse_multi_datetime)
|
295
|
+
@parsers["EXDATE"] = m
|
296
|
+
@parsers["RDATE"] = m
|
297
|
+
|
296
298
|
# URI's
|
297
299
|
m = self.method(:parse_uri)
|
298
300
|
@parsers["TZURL"] = m
|
@@ -331,26 +333,48 @@ module Icalendar
|
|
331
333
|
# Dates, Date-Times & Times
|
332
334
|
# NOTE: invalid dates & times will be returned as strings...
|
333
335
|
def parse_datetime(name, params, value)
|
334
|
-
|
335
|
-
|
336
|
-
|
336
|
+
if params["VALUE"] && params["VALUE"].first == "DATE"
|
337
|
+
result = Date.parse(value)
|
338
|
+
else
|
339
|
+
result = DateTime.parse(value)
|
340
|
+
if /Z$/ =~ value
|
341
|
+
timezone = "UTC"
|
342
|
+
else
|
343
|
+
timezone = params["TZID"].first if params["TZID"]
|
344
|
+
end
|
345
|
+
result.icalendar_tzid = timezone
|
346
|
+
end
|
347
|
+
result
|
348
|
+
rescue Exception
|
349
|
+
value
|
350
|
+
end
|
351
|
+
|
352
|
+
# Multiple valued Dates
|
353
|
+
def parse_multi_datetime(name, params, value)
|
354
|
+
use_date = params['VALUE'] && params['VALUE'].first == 'DATE'
|
355
|
+
tzid = params['TZIID'].first if params['TZID']
|
356
|
+
result = []
|
357
|
+
value.split(/,/).each do |val|
|
358
|
+
if use_date
|
359
|
+
result << Date.parse(val)
|
337
360
|
else
|
338
|
-
|
339
|
-
if /Z$/ =~
|
340
|
-
timezone =
|
361
|
+
dt = DateTime.parse val
|
362
|
+
if /Z$/ =~ val
|
363
|
+
timezone = 'UTC'
|
341
364
|
else
|
342
|
-
timezone =
|
365
|
+
timezone = tzid
|
343
366
|
end
|
344
|
-
|
367
|
+
dt.icalendar_tzid = timezone
|
368
|
+
result << dt
|
345
369
|
end
|
346
|
-
result
|
347
|
-
rescue Exception
|
348
|
-
value
|
349
370
|
end
|
371
|
+
result
|
372
|
+
rescue Exception
|
373
|
+
[value]
|
350
374
|
end
|
351
|
-
|
375
|
+
|
352
376
|
def parse_recur(name, params, value)
|
353
|
-
::Icalendar::RRule.new(name, params, value)
|
377
|
+
[::Icalendar::RRule.new(name, params, value)]
|
354
378
|
end
|
355
379
|
|
356
380
|
# Durations
|
data/lib/icalendar/rrule.rb
CHANGED
@@ -75,8 +75,12 @@ module Icalendar
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def parse_date_val(name, string)
|
78
|
-
match = string.match(/;#{name}=(.*?)(;|$)/)
|
79
|
-
|
78
|
+
match = string.match(/;#{name}=(.*?)(Z)?(;|$)/)
|
79
|
+
if match
|
80
|
+
DateTime.parse(match[1]).tap do |dt|
|
81
|
+
dt.icalendar_tzid = 'UTC' unless match[2].nil?
|
82
|
+
end
|
83
|
+
end
|
80
84
|
end
|
81
85
|
|
82
86
|
def parse_int_val(name, string)
|
data/lib/icalendar/tzinfo.rb
CHANGED
@@ -43,8 +43,8 @@
|
|
43
43
|
|
44
44
|
module TZInfo
|
45
45
|
class Timezone
|
46
|
-
def ical_timezone(date)
|
47
|
-
period = period_for_local(date)
|
46
|
+
def ical_timezone(date, dst = Timezone.default_dst)
|
47
|
+
period = period_for_local(date, dst)
|
48
48
|
timezone = Icalendar::Timezone.new
|
49
49
|
timezone.timezone_id = identifier
|
50
50
|
if period.start_transition.nil?
|
data/test/test_conversions.rb
CHANGED
@@ -8,7 +8,7 @@ require 'date'
|
|
8
8
|
class TestConversions < Test::Unit::TestCase
|
9
9
|
include Icalendar
|
10
10
|
|
11
|
-
RESULT = <<EOS
|
11
|
+
RESULT = <<EOS.gsub("\n", "\r\n")
|
12
12
|
BEGIN:VCALENDAR
|
13
13
|
VERSION:2.0
|
14
14
|
CALSCALE:GREGORIAN
|
@@ -17,8 +17,8 @@ BEGIN:VEVENT
|
|
17
17
|
CATEGORIES:foo,bar,baz
|
18
18
|
DESCRIPTION:desc
|
19
19
|
DTSTAMP:20060720T174052
|
20
|
-
DTSTART:20060720
|
21
|
-
EXDATE:
|
20
|
+
DTSTART;VALUE=DATE:20060720
|
21
|
+
EXDATE;TZID=America/New_York:20121012T170000,20121102T170000
|
22
22
|
GEO:46.01;8.57
|
23
23
|
LAST-MODIFIED:19960817T133000
|
24
24
|
ORGANIZER:mailto:joe@example.com?subject=Ruby
|
@@ -56,7 +56,7 @@ EOS
|
|
56
56
|
organizer(URI::MailTo.build(['joe@example.com', 'subject=Ruby']))
|
57
57
|
|
58
58
|
# Date
|
59
|
-
start
|
59
|
+
start Date.parse("2006-07-20"), {'VALUE' => 'DATE'}
|
60
60
|
|
61
61
|
# DateTime
|
62
62
|
timestamp DateTime.parse("2006-07-20T17:40:52+0200")
|
@@ -67,12 +67,12 @@ EOS
|
|
67
67
|
uid "foobar"
|
68
68
|
|
69
69
|
add_rrule "FREQ=WEEKLY;UNTIL=20130220T180000Z;BYDAY=FR"
|
70
|
-
|
71
|
-
add_exdate "20121012T170000Z"
|
72
|
-
add_exdate "20121102T170000Z"
|
70
|
+
exception_dates %w(20121012T170000 20121102T170000), {'TZID' => 'America/New_York'}
|
73
71
|
end
|
74
72
|
|
75
|
-
assert_equal(RESULT
|
73
|
+
assert_equal(RESULT, @cal.to_ical)
|
74
|
+
# test round-trip
|
75
|
+
assert_equal(@cal.to_ical, Icalendar.parse(RESULT).to_ical)
|
76
76
|
end
|
77
77
|
|
78
78
|
def test_to_ical_folding
|
data/test/test_tzinfo.rb
CHANGED
@@ -4,6 +4,7 @@ require 'test/unit'
|
|
4
4
|
require 'icalendar'
|
5
5
|
require 'tzinfo'
|
6
6
|
require 'icalendar/tzinfo'
|
7
|
+
require 'timecop'
|
7
8
|
|
8
9
|
class TestTZInfoExt < Test::Unit::TestCase
|
9
10
|
def setup
|
@@ -31,7 +32,7 @@ class TestTZInfoExt < Test::Unit::TestCase
|
|
31
32
|
BEGIN:VTIMEZONE
|
32
33
|
TZID:America/Cayman
|
33
34
|
BEGIN:STANDARD
|
34
|
-
DTSTART:
|
35
|
+
DTSTART:19120201T000711
|
35
36
|
TZNAME:EST
|
36
37
|
TZOFFSETFROM:-0652
|
37
38
|
TZOFFSETTO:-0500
|
@@ -54,4 +55,29 @@ END:STANDARD
|
|
54
55
|
END:VTIMEZONE
|
55
56
|
EXPECTED
|
56
57
|
end
|
58
|
+
|
59
|
+
def test_dst_transition
|
60
|
+
tz = TZInfo::Timezone.get "America/Los_Angeles"
|
61
|
+
|
62
|
+
# DST transition in America/Los_Angeles
|
63
|
+
Timecop.freeze('2013-11-03T01:30:00-08:00') do
|
64
|
+
assert_raises(TZInfo::AmbiguousTime) { tz.ical_timezone( tz.now ) }
|
65
|
+
assert_raises(TZInfo::AmbiguousTime) { tz.ical_timezone( tz.now, nil ) }
|
66
|
+
assert_raises(TZInfo::AmbiguousTime) do
|
67
|
+
TZInfo::Timezone.default_dst = nil
|
68
|
+
tz.ical_timezone( tz.now )
|
69
|
+
end
|
70
|
+
|
71
|
+
assert_nothing_raised { tz.ical_timezone( tz.now, true ) }
|
72
|
+
assert_nothing_raised { tz.ical_timezone( tz.now, false ) }
|
73
|
+
assert_nothing_raised do
|
74
|
+
TZInfo::Timezone.default_dst = true
|
75
|
+
tz.ical_timezone( tz.now )
|
76
|
+
end
|
77
|
+
assert_nothing_raised do
|
78
|
+
TZInfo::Timezone.default_dst = false
|
79
|
+
tz.ical_timezone( tz.now )
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
57
83
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: icalendar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Ahearn
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-11-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ~>
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: timecop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.6.3
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.6.3
|
55
69
|
description: |2
|
56
70
|
Implements the iCalendar specification (RFC-2445) in Ruby. This allows
|
57
71
|
for the generation and parsing of .ics files, which are used by a
|
@@ -63,6 +77,7 @@ extensions: []
|
|
63
77
|
extra_rdoc_files: []
|
64
78
|
files:
|
65
79
|
- .gitignore
|
80
|
+
- .travis.yml
|
66
81
|
- COPYING
|
67
82
|
- GPL
|
68
83
|
- Gemfile
|