icalendar 1.2.4 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: aee422660be821b5fa0060bd0344282e673db97f
4
+ data.tar.gz: 95df849c43f1868e9cf7a9f644fffc9384afce97
5
+ SHA512:
6
+ metadata.gz: a3108d6a9d6474c9210e083653fbfd1fc9e9979f8c5093ea1bab7f03c6263c687c261c5cab8d8fecd5ff6b80d539d877f33c7b15ac782e9b75cb4c5e9c255f1b
7
+ data.tar.gz: 9f6d142d8f346c422ed99d56b2f386419647f1a502f7c77787a0c730dcf4287a0fe9463abc174957808ba89413549b3082a17672f22da3e4d00adc2ff169bde0
@@ -1,3 +1,8 @@
1
+ === 1.3.0 2013-03-31
2
+ * Lenient parsing mode ignores unknown properties - David Grandinetti
3
+ * VTIMEZONE positive offsets properly have "+" prepended (Fixed issue
4
+ #18) - Benjamin Jorgensen (sorry for misspelling your last name)
5
+
1
6
  === 1.2.4 2013-03-26
2
7
  * Proxy component values now frozen in Ruby 2.0 (Fixed issue #17)
3
8
  * Clean up gemspec for cleaner installing via bundler/git
@@ -215,13 +215,18 @@ Add `$KCODE = 'u'` to make icalender work correctly with Utf8 texts
215
215
  # can have multiple calendars.
216
216
  cals = Icalendar.parse(cal_file)
217
217
  cal = cals.first
218
-
218
+
219
219
  # Now you can access the cal object in just the same way I created it
220
220
  event = cal.events.first
221
221
 
222
222
  puts "start date-time: " + event.dtstart
223
223
  puts "summary: " + event.summary
224
224
 
225
+ # Some calendars contain non-standard parameters (e.g. Apple iCloud
226
+ # calendars). You can pass in a `strict` value when creating a new parser.
227
+ unstrict_parser = Icalendar::Parser.new(cal_file, false)
228
+ cal = unstrict_parser.parse()
229
+
225
230
  == Finders:
226
231
 
227
232
  Often times in web apps and other interactive applications you'll need to
@@ -16,5 +16,6 @@ Gem::Specification.new do |s|
16
16
  s.add_development_dependency 'newgem', '~> 1.5'
17
17
  s.add_development_dependency 'rubyforge', '~> 2.0'
18
18
  s.add_development_dependency 'rdoc', '~> 4.0'
19
+ s.add_development_dependency 'tzinfo', '~> 0.3'
19
20
  end
20
21
 
@@ -11,7 +11,7 @@ require 'logger'
11
11
 
12
12
  module Icalendar #:nodoc:
13
13
 
14
- VERSION = '1.2.4'
14
+ VERSION = '1.3.0'
15
15
 
16
16
  # A simple error class to differentiate iCalendar library exceptions
17
17
  # from ruby language exceptions or others.
@@ -39,9 +39,17 @@ module Icalendar
39
39
  # time-numzome = sign time-hour [":"] time-minute
40
40
  TIME = '(\d\d):?(\d\d):?(\d\d)(\.\d+)?(Z|[-+]\d\d:?\d\d)?'
41
41
 
42
- def initialize(src)
42
+ # Defines if this is a strict parser.
43
+ attr_accessor :strict
44
+
45
+ def initialize(src, strict = true)
43
46
  # Setup the parser method hash table
44
- setup_parsers()
47
+ setup_parsers
48
+
49
+ # The default behavior is to raise an error when the parser
50
+ # finds an unknown property. Set this to false to discard
51
+ # unknown properties instead of raising an error.
52
+ @strict = strict
45
53
 
46
54
  if src.respond_to?(:gets)
47
55
  @file = src
@@ -99,7 +107,7 @@ module Icalendar
99
107
 
100
108
  # Just iterate through until we find the beginning of a calendar object
101
109
  if fields[:name] == "BEGIN" and fields[:value] == "VCALENDAR"
102
- cal = parse_component
110
+ cal = parse_component Calendar.new
103
111
  @@logger.debug "Added parsed calendar..."
104
112
  calendars << cal
105
113
  end
@@ -173,13 +181,13 @@ module Icalendar
173
181
  if component.respond_to?(adder)
174
182
  component.send(adder, value, params)
175
183
  else
176
- raise(UnknownPropertyMethod, "Unknown property type: #{adder}")
184
+ raise(UnknownPropertyMethod, "Unknown property type: #{adder}") if strict
177
185
  end
178
186
  else
179
187
  if component.respond_to?(name)
180
188
  component.send(name, value, params)
181
189
  else
182
- raise(UnknownPropertyMethod, "Unknown property type: #{name}")
190
+ raise(UnknownPropertyMethod, "Unknown property type: #{name}") if strict
183
191
  end
184
192
  end
185
193
  end
@@ -42,80 +42,80 @@
42
42
  # require "tzinfo"
43
43
 
44
44
  module TZInfo
45
- class Timezone
46
- def ical_timezone(date)
47
- period = period_for_local(date)
48
- timezone = Icalendar::Timezone.new
49
- timezone.timezone_id = identifier
50
- timezone.add(period.daylight)
51
- timezone.add(period.standard)
52
- return timezone
53
- end
45
+ class Timezone
46
+ def ical_timezone(date)
47
+ period = period_for_local(date)
48
+ timezone = Icalendar::Timezone.new
49
+ timezone.timezone_id = identifier
50
+ timezone.add(period.daylight)
51
+ timezone.add(period.standard)
52
+ return timezone
54
53
  end
55
-
56
- class TimezoneTransitionInfo
57
- def offset_from
58
- a = previous_offset.utc_total_offset
59
- sprintf("%2.2d%2.2d", (a / 3600).to_i, ((a / 60) % 60).to_i)
60
- end
61
-
62
- def offset_to
63
- a = offset.utc_total_offset
64
- sprintf("%2.2d%2.2d", (a / 3600).to_i, ((a / 60) % 60).to_i)
65
- end
66
-
67
- def rrule
68
- start = local_start.to_datetime
69
- # this is somewhat of a hack, but seems to work ok
70
- [sprintf(
71
- "FREQ=YEARLY;BYMONTH=%d;BYDAY=%d%s",
72
- start.month,
73
- ((start.day - 1)/ 7).to_i + 1,
74
- start.strftime("%a").upcase[0,2]
75
- )]
76
- end
77
-
78
- def dtstart
79
- local_start.to_datetime.strftime("%Y%m%dT%H%M%S")
80
- end
54
+ end
81
55
 
56
+ class TimezoneTransitionInfo
57
+ def offset_from
58
+ a = previous_offset.utc_total_offset
59
+ sprintf("%+-2.2d%2.2d", (a / 3600).to_i, ((a / 60) % 60).to_i)
82
60
  end
83
-
84
- class TimezonePeriod
85
- def daylight
86
- day = Icalendar::Daylight.new
87
- if dst?
88
- day.timezone_name = abbreviation.to_s
89
- day.timezone_offset_from = start_transition.offset_from
90
- day.timezone_offset_to = start_transition.offset_to
91
- day.dtstart = start_transition.dtstart
92
- day.recurrence_rules = start_transition.rrule
93
- else
94
- day.timezone_name = abbreviation.to_s.sub("ST","DT")
95
- day.timezone_offset_from = end_transition.offset_from
96
- day.timezone_offset_to = end_transition.offset_to
97
- day.dtstart = end_transition.dtstart
98
- day.recurrence_rules = end_transition.rrule
99
- end
100
- return day
101
- end
102
-
103
- def standard
104
- std = Icalendar::Standard.new
105
- if dst?
106
- std.timezone_name = abbreviation.to_s.sub("DT","ST")
107
- std.timezone_offset_from = end_transition.offset_from
108
- std.timezone_offset_to = end_transition.offset_to
109
- std.dtstart = end_transition.dtstart
110
- std.recurrence_rules = end_transition.rrule
111
- else
112
- std.timezone_name = abbreviation.to_s
113
- std.timezone_offset_from = start_transition.offset_from
114
- std.timezone_offset_to = start_transition.offset_to
115
- std.dtstart = start_transition.dtstart
116
- std.recurrence_rules = start_transition.rrule
117
- end
118
- return std
119
- end
61
+
62
+ def offset_to
63
+ a = offset.utc_total_offset
64
+ sprintf("%+-2.2d%2.2d", (a / 3600).to_i, ((a / 60) % 60).to_i)
65
+ end
66
+
67
+ def rrule
68
+ start = local_start.to_datetime
69
+ # this is somewhat of a hack, but seems to work ok
70
+ [sprintf(
71
+ "FREQ=YEARLY;BYMONTH=%d;BYDAY=%d%s",
72
+ start.month,
73
+ ((start.day - 1)/ 7).to_i + 1,
74
+ start.strftime("%a").upcase[0,2]
75
+ )]
76
+ end
77
+
78
+ def dtstart
79
+ local_start.to_datetime.strftime("%Y%m%dT%H%M%S")
80
+ end
81
+
82
+ end
83
+
84
+ class TimezonePeriod
85
+ def daylight
86
+ day = Icalendar::Daylight.new
87
+ if dst?
88
+ day.timezone_name = abbreviation.to_s
89
+ day.timezone_offset_from = start_transition.offset_from
90
+ day.timezone_offset_to = start_transition.offset_to
91
+ day.dtstart = start_transition.dtstart
92
+ day.recurrence_rules = start_transition.rrule
93
+ else
94
+ day.timezone_name = abbreviation.to_s.sub("ST","DT")
95
+ day.timezone_offset_from = end_transition.offset_from
96
+ day.timezone_offset_to = end_transition.offset_to
97
+ day.dtstart = end_transition.dtstart
98
+ day.recurrence_rules = end_transition.rrule
99
+ end
100
+ return day
101
+ end
102
+
103
+ def standard
104
+ std = Icalendar::Standard.new
105
+ if dst?
106
+ std.timezone_name = abbreviation.to_s.sub("DT","ST")
107
+ std.timezone_offset_from = end_transition.offset_from
108
+ std.timezone_offset_to = end_transition.offset_to
109
+ std.dtstart = end_transition.dtstart
110
+ std.recurrence_rules = end_transition.rrule
111
+ else
112
+ std.timezone_name = abbreviation.to_s
113
+ std.timezone_offset_from = start_transition.offset_from
114
+ std.timezone_offset_to = start_transition.offset_to
115
+ std.dtstart = start_transition.dtstart
116
+ std.recurrence_rules = start_transition.rrule
117
+ end
118
+ return std
120
119
  end
120
+ end
121
121
  end
@@ -7,6 +7,7 @@ require 'icalendar'
7
7
  class TestIcalendarParser < Test::Unit::TestCase
8
8
 
9
9
  TEST_CAL = File.join(File.dirname(__FILE__), 'fixtures', 'single_event.ics')
10
+ NONSTANDARD = File.join(File.dirname(__FILE__), 'fixtures', 'nonstandard.ics')
10
11
 
11
12
  # First make sure that we can run the parser and get back objects.
12
13
  def test_new
@@ -43,6 +44,20 @@ class TestIcalendarParser < Test::Unit::TestCase
43
44
  do_asserts(cals)
44
45
  end
45
46
 
47
+ def test_strict_parser
48
+ File.open(NONSTANDARD) do |cal_file|
49
+ assert_raise(Icalendar::UnknownPropertyMethod) do
50
+ Icalendar::Parser.new(cal_file).parse
51
+ end
52
+ end
53
+ end
54
+
55
+ def test_lenient_parser
56
+ File.open(NONSTANDARD) do |cal_file|
57
+ do_asserts Icalendar::Parser.new(cal_file, false).parse
58
+ end
59
+ end
60
+
46
61
  # Just a helper method so we don't have to repeat the same tests.
47
62
  def do_asserts(cals)
48
63
  # Should just get one calendar back.
@@ -0,0 +1,27 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
2
+
3
+ require 'test/unit'
4
+ require 'icalendar'
5
+ require 'tzinfo'
6
+ require 'icalendar/tzinfo'
7
+
8
+ class TestTZInfoExt < Test::Unit::TestCase
9
+ def setup
10
+ tz = TZInfo::Timezone.get("Europe/Copenhagen")
11
+ @timezone = tz.ical_timezone(DateTime.new(1970))
12
+ end
13
+
14
+ def test_daylight_offset
15
+ tz_offset_from = @timezone.instance_variable_get("@components")[:daylights][0].properties["tzoffsetfrom"]
16
+ tz_offset_to = @timezone.instance_variable_get("@components")[:daylights][0].properties["tzoffsetto"]
17
+ assert_equal "+0100", tz_offset_from
18
+ assert_equal "+0200", tz_offset_to
19
+ end
20
+
21
+ def test_standard_offset
22
+ tz_offset_from = @timezone.instance_variable_get("@components")[:standards][0].properties["tzoffsetfrom"]
23
+ tz_offset_to = @timezone.instance_variable_get("@components")[:standards][0].properties["tzoffsetto"]
24
+ assert_equal "+0200", tz_offset_from
25
+ assert_equal "+0100", tz_offset_to
26
+ end
27
+ end
metadata CHANGED
@@ -1,36 +1,32 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: icalendar
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.4
5
- prerelease:
4
+ version: 1.3.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Ryan Ahearn
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-03-27 00:00:00.000000000 Z
11
+ date: 2013-04-01 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rubyforge
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: 2.0.4
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: 2.0.4
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rdoc
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ~>
36
32
  - !ruby/object:Gem::Version
@@ -38,7 +34,6 @@ dependencies:
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ~>
44
39
  - !ruby/object:Gem::Version
@@ -46,23 +41,20 @@ dependencies:
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: newgem
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - '>='
52
46
  - !ruby/object:Gem::Version
53
47
  version: 1.5.3
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - '>='
60
53
  - !ruby/object:Gem::Version
61
54
  version: 1.5.3
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: hoe
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
59
  - - ~>
68
60
  - !ruby/object:Gem::Version
@@ -70,12 +62,11 @@ dependencies:
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
66
  - - ~>
76
67
  - !ruby/object:Gem::Version
77
68
  version: '3.5'
78
- description: ! "This is a Ruby library for dealing with iCalendar files. Rather than\nexplaining
69
+ description: "This is a Ruby library for dealing with iCalendar files. Rather than\nexplaining
79
70
  myself, here is the introduction from RFC-2445, which\ndefines the format:\n\nThe
80
71
  use of calendaring and scheduling has grown considerably in the\nlast decade. Enterprise
81
72
  and inter-enterprise business has become\ndependent on rapid scheduling of events
@@ -162,9 +153,11 @@ files:
162
153
  - website/javascripts/rounded_corners_lite.inc.js
163
154
  - website/stylesheets/screen.css
164
155
  - website/template.html.erb
156
+ - test/test_tzinfo.rb
165
157
  - .gemtest
166
158
  homepage: http://github.com/icalendar/icalendar
167
159
  licenses: []
160
+ metadata: {}
168
161
  post_install_message:
169
162
  rdoc_options:
170
163
  - --main
@@ -172,22 +165,20 @@ rdoc_options:
172
165
  require_paths:
173
166
  - lib
174
167
  required_ruby_version: !ruby/object:Gem::Requirement
175
- none: false
176
168
  requirements:
177
- - - ! '>='
169
+ - - '>='
178
170
  - !ruby/object:Gem::Version
179
171
  version: '0'
180
172
  required_rubygems_version: !ruby/object:Gem::Requirement
181
- none: false
182
173
  requirements:
183
- - - ! '>='
174
+ - - '>='
184
175
  - !ruby/object:Gem::Version
185
176
  version: '0'
186
177
  requirements: []
187
178
  rubyforge_project: icalendar
188
- rubygems_version: 1.8.25
179
+ rubygems_version: 2.0.3
189
180
  signing_key:
190
- specification_version: 3
181
+ specification_version: 4
191
182
  summary: This is a Ruby library for dealing with iCalendar files
192
183
  test_files:
193
184
  - test/component/test_event.rb
@@ -199,3 +190,4 @@ test_files:
199
190
  - test/test_helper.rb
200
191
  - test/test_parameter.rb
201
192
  - test/test_parser.rb
193
+ - test/test_tzinfo.rb