icalendar 1.4.3 → 1.4.4
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.
- 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
|