curzonj-icalendar 1.0.2.1 → 1.1.0.2

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.
@@ -0,0 +1,126 @@
1
+ =begin
2
+ Copyright (C) 2008 Rick (http://github.com/rubyredrick)
3
+
4
+ This library is free software; you can redistribute it and/or modify it
5
+ under the same terms as the ruby language itself, see the file COPYING for
6
+ details.
7
+ =end
8
+
9
+ require 'date'
10
+ require 'uri'
11
+ require 'stringio'
12
+
13
+ module Icalendar
14
+
15
+ # This class is not yet fully functional..
16
+ #
17
+ # Gem versions < 1.1.0.0 used to return a string for the recurrence_rule component,
18
+ # but now it returns this Icalendar::RRule class. ie It's not backwards compatible!
19
+ #
20
+ # To get the original RRULE value from a parsed feed, use the 'orig_value' property.
21
+ #
22
+ # Example:
23
+ # rules = event.recurrence_rules.map{ |rule| rule.orig_value }
24
+
25
+ class RRule < Icalendar::Base
26
+
27
+ class Weekday
28
+ def initialize(day, position)
29
+ @day, @position = day, position
30
+ end
31
+
32
+ def to_s
33
+ "#{@position}#{@day}"
34
+ end
35
+ end
36
+
37
+ def initialize(name, params, value, parser)
38
+ @value = value
39
+ frequency_match = value.match(/FREQ=(SECONDLY|MINUTELY|HOURLY|DAILY|WEEKLY|MONTHLY|YEARLY)/)
40
+ raise Icalendar::InvalidPropertyValue.new("FREQ must be specified for RRULE values") unless frequency_match
41
+ @frequency = frequency_match[1]
42
+ @until = parse_date_val("UNTIL", value)
43
+ @count = parse_int_val("COUNT", value)
44
+ raise Icalendar::InvalidPropertyValue.new("UNTIL and COUNT must not both be specified for RRULE values") if [@until, @count].compact.length > 1
45
+ @interval = parse_int_val("INTERVAL", value)
46
+ @by_list = {:bysecond => parse_int_list("BYSECOND", value)}
47
+ @by_list[:byminute] = parse_int_list("BYMINUTE",value)
48
+ @by_list[:byhour] = parse_int_list("BYHOUR", value)
49
+ @by_list[:byday] = parse_weekday_list("BYDAY", value)
50
+ @by_list[:bymonthday] = parse_int_list("BYMONTHDAY", value)
51
+ @by_list[:byyearday] = parse_int_list("BYYEARDAY", value)
52
+ @by_list[:byweekno] = parse_int_list("BYWEEKNO", value)
53
+ @by_list[:bymonth] = parse_int_list("BYMONTH", value)
54
+ @by_list[:bysetpos] = parse_int_list("BYSETPOS", value)
55
+ @wkst = parse_wkstart(value)
56
+ end
57
+
58
+ # Returns the original pre-parsed RRULE value.
59
+ def orig_value
60
+ @value
61
+ end
62
+
63
+ def to_ical
64
+ result = ["FREQ=#{@frequency}"]
65
+ result << ";UNTIL=#{@until.to_ical}" if @until
66
+ result << ";COUNT=#{@count}" if @count
67
+ result << ";INTERVAL=#{@interval}" if @interval
68
+ @by_list.each do |key, value|
69
+ result << ";#{key.to_s.upcase}=#{value}" if value
70
+ end
71
+ result << ";WKST=#{@wkst}" if @wkst
72
+ result.join
73
+ end
74
+
75
+ def parse_date_val(name, string)
76
+ match = string.match(/;#{name}=(.*?)(;|$)/)
77
+ match ? DateTime.parse(match[1]) : nil
78
+ end
79
+
80
+ def parse_int_val(name, string)
81
+ match = string.match(/;#{name}=(\d+)(;|$)/)
82
+ match ? match[1].to_i : nil
83
+ end
84
+
85
+ def parse_int_list(name, string)
86
+ match = string.match(/;#{name}=([+-]?.*?)(;|$)/)
87
+ if match
88
+ match[1].split(",").map {|int| int.to_i}
89
+ else
90
+ nil
91
+ end
92
+ end
93
+
94
+ def parse_weekday_list(name, string)
95
+ match = string.match(/;#{name}=(.*?)(;|$)/)
96
+ if match
97
+ match[1].split(",").map {|weekday|
98
+ wd_match = weekday.match(/([+-]?\d*)(SU|MO|TU|WE|TH|FR|SA)/)
99
+ Weekday.new(wd_match[2], wd_match[1])
100
+ }
101
+ else
102
+ nil
103
+ end
104
+ end
105
+
106
+ def parse_wkstart(string)
107
+ match = string.match(/;WKSTART=(SU|MO|TU|WE|TH|FR|SA)(;|$)/)
108
+ if match
109
+ %w{SU MO TU WE TH FR SA}.index(match[1])
110
+ else
111
+ nil
112
+ end
113
+ end
114
+
115
+ # TODO: Incomplete
116
+ def occurrences_of_event_starting(event, datetime)
117
+ initial_start = event.dtstart
118
+ (0...@count).map {|day_offset|
119
+ occurrence = event.clone
120
+ occurrence.dtstart = initial_start + day_offset
121
+ occurrence.clone
122
+ }
123
+ end
124
+ end
125
+
126
+ end
@@ -0,0 +1,121 @@
1
+ =begin
2
+ Copyright (C) 2008 Sean Dague
3
+
4
+ This library is free software; you can redistribute it and/or modify it
5
+ under the same terms as the ruby language itself, see the file COPYING for
6
+ details.
7
+ =end
8
+
9
+ # The following adds a bunch of mixins to the tzinfo class, with the
10
+ # intent on making it very easy to load in tzinfo data for generating
11
+ # ical events. With this you can do the following:
12
+ #
13
+ # require "icalendar/tzinfo"
14
+ #
15
+ # estart = DateTime.new(2008, 12, 29, 8, 0, 0)
16
+ # eend = DateTime.new(2008, 12, 29, 11, 0, 0)
17
+ # tstring = "America/Chicago"
18
+ #
19
+ # tz = TZInfo::Timezone.get(tstring)
20
+ # cal = Calendar.new
21
+ # # the mixins now generate all the timezone info for the date in question
22
+ # timezone = tz.ical_timezone(estart)
23
+ # cal.add(timezone)
24
+ #
25
+ # cal.event do
26
+ # dtstart estart
27
+ # dtend eend
28
+ # summary "Meeting with the man."
29
+ # description "Have a long lunch meeting and decide nothing..."
30
+ # klass "PRIVATE"
31
+ # end
32
+ #
33
+ # puts cal.to_ical
34
+ #
35
+ # The recurance rule calculations are hacky, and only start at the
36
+ # beginning of the current dst transition. I doubt this works for non
37
+ # dst areas yet. However, for a standard dst flipping zone, this
38
+ # seems to work fine (tested in Mozilla Thunderbird + Lightning).
39
+ # Future goal would be making this better.
40
+
41
+ # require "rubygems"
42
+ # require "tzinfo"
43
+
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
54
+ 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
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
119
+ end
120
+ end
121
+ end
metadata CHANGED
@@ -1,12 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: curzonj-icalendar
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2.1
4
+ version: 1.1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Rose
8
8
  autorequire: icalendar
9
- bindir: bin
9
+ bindir:
10
10
  cert_chain:
11
11
  date: 2007-11-23 22:00:00 -08:00
12
12
  default_executable:
@@ -48,11 +48,13 @@ files:
48
48
  - lib/icalendar/component/timezone.rb
49
49
  - lib/icalendar/component/todo.rb
50
50
  - lib/icalendar/conversions.rb
51
+ - lib/icalendar/tzinfo.rb
51
52
  - lib/icalendar/parameter.rb
52
53
  - lib/icalendar/component.rb
53
54
  - lib/icalendar/helpers.rb
54
55
  - lib/icalendar/parser.rb
55
56
  - lib/icalendar/calendar.rb
57
+ - lib/icalendar/rrule.rb
56
58
  - lib/icalendar/base.rb
57
59
  - lib/hash_attrs.rb
58
60
  - lib/icalendar.rb
@@ -80,7 +82,6 @@ rdoc_options:
80
82
  - --main
81
83
  - README
82
84
  require_paths:
83
- - bin
84
85
  - lib
85
86
  required_ruby_version: !ruby/object:Gem::Requirement
86
87
  requirements: