icalendar 2.10.0 → 2.10.1

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
  SHA256:
3
- metadata.gz: 4a4c654b36ffe5a09f521ad3c012686f12e582ba5d380242c646334f47153360
4
- data.tar.gz: 184399a11e6e8a39b18ceeef59de8a9b9f7cd581f0c7169cce5c7dca63575e3b
3
+ metadata.gz: 7b9f7e30ef6614ad4175a9d282d1b03b57f140f98a2962b4e0268aa015f8f942
4
+ data.tar.gz: 7ebabfddd0f3d8e8e05e1ef82d2389007c1419c727c5404d2ec2c1c09565a8bb
5
5
  SHA512:
6
- metadata.gz: 61837b5d19193d80d72f37edff89290fc2e5ffa0c6b9ee500036de58b0fbd9aacb5e0e9bc9f1a0a4e1ce7a3ad494ed0147e87bf697b54523d8b799e9eaa275fa
7
- data.tar.gz: 00d54cc0ab4b7fc6acf616a537b426d110ddbe65dda1d6ab8ec938ba2df64e87def99023916c6193ab25d1885a2a60e8a1706617ed5a6e0adb5cb34671dae1ec
6
+ metadata.gz: 8d3221e4e5bd2120014ae11fe80a8e0a3b36af37b10aadd18f3bc6022e296efa47ea27d09572900bb6d6419fff64054caa6709e6b14e5182d32a188d0130b7f0
7
+ data.tar.gz: 5d7d996d53a12543de0830fdb8214e2ae39df4c19c649e81cd95ceb8d30d61f1f178b7a9a4f4e37adb591609eeac7e89d930cf5ffc24951c9cbfcb0b815c2a03
data/History.txt CHANGED
@@ -1,5 +1,8 @@
1
1
  === Unreleased
2
2
 
3
+ === 2.10.1 2023-12-01
4
+ * Parsing now handles VTIMEZONE blocks defined after their TZID is used in events and other components
5
+
3
6
  === 2.10.0 2023-11-01
4
7
  * Add changelog metadata to gemspec - Juri Hahn
5
8
  * Attempt to rescue timezone info when given a nonstandard tzid with no VTIMEZONE
data/icalendar.gemspec CHANGED
@@ -38,13 +38,13 @@ ActiveSupport is required for TimeWithZone support, but not required for general
38
38
 
39
39
  # test with all groups of tzinfo dependencies
40
40
  # tzinfo 2.x
41
- # s.add_development_dependency 'tzinfo', '~> 2.0'
42
- # s.add_development_dependency 'tzinfo-data', '~> 1.2020'
43
- # tzinfo 1.x
44
- s.add_development_dependency 'activesupport', '~> 6.0'
45
- s.add_development_dependency 'i18n', '~> 1.8'
46
- s.add_development_dependency 'tzinfo', '~> 1.2'
41
+ s.add_development_dependency 'activesupport', '~> 7.1'
42
+ s.add_development_dependency 'tzinfo', '~> 2.0'
47
43
  s.add_development_dependency 'tzinfo-data', '~> 1.2020'
44
+ # tzinfo 1.x
45
+ # s.add_development_dependency 'activesupport', '~> 6.0'
46
+ # s.add_development_dependency 'tzinfo', '~> 1.2'
47
+ # s.add_development_dependency 'tzinfo-data', '~> 1.2020'
48
48
  # tzinfo 0.x
49
49
  # s.add_development_dependency 'tzinfo', '~> 0.3'
50
50
  # end tzinfo
@@ -52,4 +52,5 @@ ActiveSupport is required for TimeWithZone support, but not required for general
52
52
  s.add_development_dependency 'timecop', '~> 0.9'
53
53
  s.add_development_dependency 'rspec', '~> 3.8'
54
54
  s.add_development_dependency 'simplecov', '~> 0.16'
55
+ s.add_development_dependency 'byebug'
55
56
  end
@@ -211,7 +211,7 @@ module Icalendar
211
211
  param_value = param_value.gsub(PVALUE_GSUB_REGEX, '')
212
212
  params[param_name] << param_value
213
213
  if param_name == 'tzid'
214
- params['x-tz-info'] = timezone_store.retrieve param_value
214
+ params['x-tz-store'] = timezone_store
215
215
  end
216
216
  end
217
217
  end
@@ -108,15 +108,17 @@ module Icalendar
108
108
 
109
109
  def standard_for(local)
110
110
  possible = standards.map do |std|
111
- [std.previous_occurrence(local.to_time), std]
112
- end
111
+ prev = std.previous_occurrence(local.to_time)
112
+ [prev, std] unless prev.nil?
113
+ end.compact
113
114
  possible.sort_by(&:first).last
114
115
  end
115
116
 
116
117
  def daylight_for(local)
117
118
  possible = daylights.map do |day|
118
- [day.previous_occurrence(local.to_time), day]
119
- end
119
+ prev = day.previous_occurrence(local.to_time)
120
+ [prev, day] unless prev.nil?
121
+ end.compact
120
122
  possible.sort_by(&:first).last
121
123
  end
122
124
  end
@@ -10,7 +10,7 @@ module Icalendar
10
10
 
11
11
  def initialize(value, params = {})
12
12
  params.delete 'tzid'
13
- params.delete 'x-tz-info'
13
+ params.delete 'x-tz-store'
14
14
  if value.is_a? String
15
15
  begin
16
16
  parsed_date = ::Date.strptime(value, FORMAT)
@@ -20,22 +20,45 @@ module Icalendar
20
20
  module Values
21
21
  module Helpers
22
22
  module TimeWithZone
23
- attr_reader :tz_utc
23
+ attr_reader :tz_utc, :timezone_store
24
24
 
25
25
  def initialize(value, params = {})
26
26
  params = Icalendar::DowncasedHash(params)
27
27
  @tz_utc = params['tzid'] == 'UTC'
28
- x_tz_info = params.delete 'x-tz-info'
28
+ @timezone_store = params.delete 'x-tz-store'
29
+ super (offset_value(value, params) || value), params
30
+ end
31
+
32
+ def __getobj__
33
+ orig_value = super
34
+ if set_offset?
35
+ orig_value
36
+ else
37
+ offset = offset_value(orig_value, ical_params)
38
+ __setobj__(offset) unless offset.nil?
39
+ offset || orig_value
40
+ end
41
+ end
29
42
 
30
- offset_value = unless params['tzid'].nil?
43
+ def params_ical
44
+ ical_params.delete 'tzid' if tz_utc
45
+ super
46
+ end
47
+
48
+ private
49
+
50
+ def offset_value(value, params)
51
+ @offset_value = unless params.nil? || params['tzid'].nil?
31
52
  tzid = params['tzid'].is_a?(::Array) ? params['tzid'].first : params['tzid']
32
53
  support_classes_defined = defined?(ActiveSupport::TimeZone) && defined?(ActiveSupportTimeWithZoneAdapter)
33
54
  if support_classes_defined && (tz = ActiveSupport::TimeZone[tzid])
55
+ Icalendar.logger.debug("Plan a - parsing #{value}/#{tzid} as ActiveSupport::TimeWithZone")
34
56
  # plan a - use ActiveSupport::TimeWithZone
35
57
  ActiveSupportTimeWithZoneAdapter.new(nil, tz, value)
36
- elsif !x_tz_info.nil?
58
+ elsif !timezone_store.nil? && !(x_tz_info = timezone_store.retrieve(tzid)).nil?
37
59
  # plan b - use definition from provided `VTIMEZONE`
38
60
  offset = x_tz_info.offset_for_local(value).to_s
61
+ Icalendar.logger.debug("Plan b - parsing #{value} with offset: #{offset}")
39
62
  if value.respond_to?(:change)
40
63
  value.change offset: offset
41
64
  else
@@ -43,17 +66,19 @@ module Icalendar
43
66
  end
44
67
  elsif support_classes_defined && (tz = ActiveSupport::TimeZone[tzid.split.first])
45
68
  # plan c - try to find an ActiveSupport::TimeWithZone based on the first word of the tzid
69
+ Icalendar.logger.debug("Plan c - parsing #{value}/#{tz.tzinfo.name} as ActiveSupport::TimeWithZone")
46
70
  params['tzid'] = [tz.tzinfo.name]
47
71
  ActiveSupportTimeWithZoneAdapter.new(nil, tz, value)
72
+ else
73
+ # plan d - just ignore the tzid
74
+ Icalendar.logger.info("Ignoring timezone #{tzid} for time #{value}")
75
+ nil
48
76
  end
49
- # plan d - just ignore the tzid
50
77
  end
51
- super((offset_value || value), params)
52
78
  end
53
79
 
54
- def params_ical
55
- ical_params.delete 'tzid' if tz_utc
56
- super
80
+ def set_offset?
81
+ !!@offset_value
57
82
  end
58
83
  end
59
84
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Icalendar
4
4
 
5
- VERSION = '2.10.0'
5
+ VERSION = '2.10.1'
6
6
 
7
7
  end
@@ -0,0 +1,143 @@
1
+ BEGIN:VCALENDAR
2
+ VERSION:2.0
3
+ X-WR-CALNAME:My Calendar
4
+ X-APPLE-CALENDAR-COLOR:#44A703
5
+ BEGIN:VEVENT
6
+ CREATED:20231026T211915Z
7
+ DTEND;TZID=NONSTANDARDTZ:20231025T180000
8
+ DTSTAMP:20231026T211916Z
9
+ DTSTART;TZID=NONSTANDARDTZ:20231025T163000
10
+ LAST-MODIFIED:20231026T211915Z
11
+ LOCATION:Somewhere
12
+ SEQUENCE:0
13
+ SUMMARY:Summary summary summary
14
+ UID:some-unique-uid
15
+ END:VEVENT
16
+ BEGIN:VTIMEZONE
17
+ TZID:NONSTANDARDTZ
18
+ X-LIC-LOCATION:NONSTANDARDTZ
19
+ BEGIN:STANDARD
20
+ DTSTART:18831118T120702
21
+ RDATE:18831118T120702
22
+ TZNAME:PST
23
+ TZOFFSETFROM:-075258
24
+ TZOFFSETTO:-0800
25
+ END:STANDARD
26
+ BEGIN:DAYLIGHT
27
+ DTSTART:19180331T020000
28
+ RRULE:FREQ=YEARLY;UNTIL=19190330T100000Z;BYMONTH=3;BYDAY=-1SU
29
+ TZNAME:PDT
30
+ TZOFFSETFROM:-0800
31
+ TZOFFSETTO:-0700
32
+ END:DAYLIGHT
33
+ BEGIN:STANDARD
34
+ DTSTART:19181027T020000
35
+ RRULE:FREQ=YEARLY;UNTIL=19191026T090000Z;BYMONTH=10;BYDAY=-1SU
36
+ TZNAME:PST
37
+ TZOFFSETFROM:-0700
38
+ TZOFFSETTO:-0800
39
+ END:STANDARD
40
+ BEGIN:DAYLIGHT
41
+ DTSTART:19420209T020000
42
+ RDATE:19420209T020000
43
+ TZNAME:PWT
44
+ TZOFFSETFROM:-0800
45
+ TZOFFSETTO:-0700
46
+ END:DAYLIGHT
47
+ BEGIN:DAYLIGHT
48
+ DTSTART:19450814T160000
49
+ RDATE:19450814T160000
50
+ TZNAME:PPT
51
+ TZOFFSETFROM:-0700
52
+ TZOFFSETTO:-0700
53
+ END:DAYLIGHT
54
+ BEGIN:STANDARD
55
+ DTSTART:19450930T020000
56
+ RDATE:19450930T020000
57
+ RDATE:19490101T020000
58
+ TZNAME:PST
59
+ TZOFFSETFROM:-0700
60
+ TZOFFSETTO:-0800
61
+ END:STANDARD
62
+ BEGIN:STANDARD
63
+ DTSTART:19460101T000000
64
+ RDATE:19460101T000000
65
+ RDATE:19670101T000000
66
+ TZNAME:PST
67
+ TZOFFSETFROM:-0800
68
+ TZOFFSETTO:-0800
69
+ END:STANDARD
70
+ BEGIN:DAYLIGHT
71
+ DTSTART:19480314T020100
72
+ RDATE:19480314T020100
73
+ RDATE:19740106T020000
74
+ RDATE:19750223T020000
75
+ TZNAME:PDT
76
+ TZOFFSETFROM:-0800
77
+ TZOFFSETTO:-0700
78
+ END:DAYLIGHT
79
+ BEGIN:DAYLIGHT
80
+ DTSTART:19500430T010000
81
+ RRULE:FREQ=YEARLY;UNTIL=19660424T090000Z;BYMONTH=4;BYDAY=-1SU
82
+ TZNAME:PDT
83
+ TZOFFSETFROM:-0800
84
+ TZOFFSETTO:-0700
85
+ END:DAYLIGHT
86
+ BEGIN:STANDARD
87
+ DTSTART:19500924T020000
88
+ RRULE:FREQ=YEARLY;UNTIL=19610924T090000Z;BYMONTH=9;BYDAY=-1SU
89
+ TZNAME:PST
90
+ TZOFFSETFROM:-0700
91
+ TZOFFSETTO:-0800
92
+ END:STANDARD
93
+ BEGIN:STANDARD
94
+ DTSTART:19621028T020000
95
+ RRULE:FREQ=YEARLY;UNTIL=19661030T090000Z;BYMONTH=10;BYDAY=-1SU
96
+ TZNAME:PST
97
+ TZOFFSETFROM:-0700
98
+ TZOFFSETTO:-0800
99
+ END:STANDARD
100
+ BEGIN:DAYLIGHT
101
+ DTSTART:19670430T020000
102
+ RRULE:FREQ=YEARLY;UNTIL=19730429T100000Z;BYMONTH=4;BYDAY=-1SU
103
+ TZNAME:PDT
104
+ TZOFFSETFROM:-0800
105
+ TZOFFSETTO:-0700
106
+ END:DAYLIGHT
107
+ BEGIN:STANDARD
108
+ DTSTART:19671029T020000
109
+ RRULE:FREQ=YEARLY;UNTIL=20061029T090000Z;BYMONTH=10;BYDAY=-1SU
110
+ TZNAME:PST
111
+ TZOFFSETFROM:-0700
112
+ TZOFFSETTO:-0800
113
+ END:STANDARD
114
+ BEGIN:DAYLIGHT
115
+ DTSTART:19760425T020000
116
+ RRULE:FREQ=YEARLY;UNTIL=19860427T100000Z;BYMONTH=4;BYDAY=-1SU
117
+ TZNAME:PDT
118
+ TZOFFSETFROM:-0800
119
+ TZOFFSETTO:-0700
120
+ END:DAYLIGHT
121
+ BEGIN:DAYLIGHT
122
+ DTSTART:19870405T020000
123
+ RRULE:FREQ=YEARLY;UNTIL=20060402T100000Z;BYMONTH=4;BYDAY=1SU
124
+ TZNAME:PDT
125
+ TZOFFSETFROM:-0800
126
+ TZOFFSETTO:-0700
127
+ END:DAYLIGHT
128
+ BEGIN:DAYLIGHT
129
+ DTSTART:20070311T020000
130
+ RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
131
+ TZNAME:PDT
132
+ TZOFFSETFROM:-0800
133
+ TZOFFSETTO:-0700
134
+ END:DAYLIGHT
135
+ BEGIN:STANDARD
136
+ DTSTART:20071104T020000
137
+ RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
138
+ TZNAME:PST
139
+ TZOFFSETFROM:-0700
140
+ TZOFFSETTO:-0800
141
+ END:STANDARD
142
+ END:VTIMEZONE
143
+ END:VCALENDAR
data/spec/parser_spec.rb CHANGED
@@ -5,6 +5,15 @@ describe Icalendar::Parser do
5
5
  let(:source) { File.read File.join(File.dirname(__FILE__), 'fixtures', fn) }
6
6
 
7
7
  describe '#parse' do
8
+ context 'reversed_timezone.ics' do
9
+ let(:fn) { 'reversed_timezone.ics' }
10
+
11
+ it 'correctly parses the event timezone' do
12
+ event = subject.parse.first.events.first
13
+ expect(event.dtstart.utc_offset).to eq -25200
14
+ end
15
+ end
16
+
8
17
  context 'single_event.ics' do
9
18
  let(:fn) { 'single_event.ics' }
10
19
 
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: 2.10.0
4
+ version: 2.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Ahearn
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-01 00:00:00.000000000 Z
11
+ date: 2023-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ice_cube
@@ -58,42 +58,28 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '6.0'
61
+ version: '7.1'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '6.0'
69
- - !ruby/object:Gem::Dependency
70
- name: i18n
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '1.8'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '1.8'
68
+ version: '7.1'
83
69
  - !ruby/object:Gem::Dependency
84
70
  name: tzinfo
85
71
  requirement: !ruby/object:Gem::Requirement
86
72
  requirements:
87
73
  - - "~>"
88
74
  - !ruby/object:Gem::Version
89
- version: '1.2'
75
+ version: '2.0'
90
76
  type: :development
91
77
  prerelease: false
92
78
  version_requirements: !ruby/object:Gem::Requirement
93
79
  requirements:
94
80
  - - "~>"
95
81
  - !ruby/object:Gem::Version
96
- version: '1.2'
82
+ version: '2.0'
97
83
  - !ruby/object:Gem::Dependency
98
84
  name: tzinfo-data
99
85
  requirement: !ruby/object:Gem::Requirement
@@ -150,6 +136,20 @@ dependencies:
150
136
  - - "~>"
151
137
  - !ruby/object:Gem::Version
152
138
  version: '0.16'
139
+ - !ruby/object:Gem::Dependency
140
+ name: byebug
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
153
  description: |
154
154
  Implements the iCalendar specification (RFC-5545) in Ruby. This allows
155
155
  for the generation and parsing of .ics files, which are used by a
@@ -216,6 +216,7 @@ files:
216
216
  - spec/fixtures/nondefault_values.ics
217
217
  - spec/fixtures/nonstandard.ics
218
218
  - spec/fixtures/recurrence.ics
219
+ - spec/fixtures/reversed_timezone.ics
219
220
  - spec/fixtures/single_event.ics
220
221
  - spec/fixtures/single_event_bad_dtstart.ics
221
222
  - spec/fixtures/single_event_bad_line.ics
@@ -267,7 +268,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
267
268
  - !ruby/object:Gem::Version
268
269
  version: '0'
269
270
  requirements: []
270
- rubygems_version: 3.4.10
271
+ rubygems_version: 3.3.26
271
272
  signing_key:
272
273
  specification_version: 4
273
274
  summary: A ruby implementation of the iCalendar specification (RFC-5545).
@@ -282,6 +283,7 @@ test_files:
282
283
  - spec/fixtures/nondefault_values.ics
283
284
  - spec/fixtures/nonstandard.ics
284
285
  - spec/fixtures/recurrence.ics
286
+ - spec/fixtures/reversed_timezone.ics
285
287
  - spec/fixtures/single_event.ics
286
288
  - spec/fixtures/single_event_bad_dtstart.ics
287
289
  - spec/fixtures/single_event_bad_line.ics