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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8a1a061b2cdba8b3b5058a77d5a3f6c06a795c34
4
- data.tar.gz: a404fedca32cb195c8f939b42e384114a227611d
3
+ metadata.gz: 3bb514e630455e28b49f977bb6c316dc470cb98f
4
+ data.tar.gz: 02953a2e8e74af0680d02e6ae889dd30fee8cedb
5
5
  SHA512:
6
- metadata.gz: 825777c1bd1bd283931d9ed8b81305ba0bfa2ffc6114054452b2ea47f300114d3c1704cf53a15a21abbb81ba5b2ff5190c14797aece6d0f56de6288194f45967
7
- data.tar.gz: 6f568404d5a15e36d83294552076135504b964516780f856aa60e3d7a3ba40f6a93dde4bd1e95c658d8c3cb00818d2ae761e3aae21a0d7d6b11073ddb1c82fbb
6
+ metadata.gz: 107461d20bf35d2f4df715e52605126a55a532c8dabb51c6b35eda16828fe50220a073b7c76b09dda00165c34745414b5172206a422aeeee4e9fc2ba7df46cef
7
+ data.tar.gz: 66694d2dd3cc7f70d3ddcbd81d6682fca411dffe57bd76afacc015f6c1328b0f6f67ffed512c42b08d500644d8d8e514502c2c438e32644b43c66f9c2976bde9
data/.gitignore CHANGED
@@ -3,3 +3,5 @@
3
3
  .ruby-gemset
4
4
  Gemfile.lock
5
5
  pkg/
6
+ .bundle
7
+ vendor/
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 1.9.3
5
+ script: bundle exec rake test
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
@@ -1,6 +1,8 @@
1
1
  iCalendar -- Internet calendaring, Ruby style
2
2
  ===
3
3
 
4
+ [![Build Status](https://travis-ci.org/icalendar/icalendar.png)](https://travis-ci.org/icalendar/icalendar)
5
+
4
6
  <http://github.com/icalendar/icalendar>
5
7
 
6
8
  DESCRIPTION
data/icalendar.gemspec CHANGED
@@ -25,5 +25,6 @@ Gem::Specification.new do |s|
25
25
  s.add_development_dependency 'rake', '~> 10.0'
26
26
  s.add_development_dependency 'bundler', '~> 1.3'
27
27
  s.add_development_dependency 'tzinfo', '~> 0.3'
28
+ s.add_development_dependency 'timecop', '~> 0.6.3'
28
29
  end
29
30
 
@@ -11,7 +11,7 @@ require 'logger'
11
11
 
12
12
  module Icalendar #:nodoc:
13
13
 
14
- VERSION = '1.4.3'
14
+ VERSION = '1.4.4'
15
15
 
16
16
  # A simple error class to differentiate iCalendar library exceptions
17
17
  # from ruby language exceptions or others.
@@ -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
@@ -176,7 +176,7 @@ module Icalendar
176
176
  # Replace dashes with underscores
177
177
  name = name.gsub('-', '_')
178
178
 
179
- if component.multi_property?(name)
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
- begin
335
- if params["VALUE"] && params["VALUE"].first == "DATE"
336
- result = Date.parse(value)
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
- result = DateTime.parse(value)
339
- if /Z$/ =~ value
340
- timezone = "UTC"
361
+ dt = DateTime.parse val
362
+ if /Z$/ =~ val
363
+ timezone = 'UTC'
341
364
  else
342
- timezone = params["TZID"].first if params["TZID"]
365
+ timezone = tzid
343
366
  end
344
- result.icalendar_tzid = timezone
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
@@ -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
- match ? DateTime.parse(match[1]) : nil
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)
@@ -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?
@@ -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:20121012T170000Z,20121102T170000Z
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 Date.parse("2006-07-20")
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.gsub("\n", "\r\n"), @cal.to_ical)
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:19120201T000712
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.3
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-09-18 00:00:00.000000000 Z
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