icalendar 1.5.4 → 2.0.0.beta.1

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.
Files changed (100) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -1
  3. data/.rspec +2 -0
  4. data/.travis.yml +1 -2
  5. data/History.txt +2 -7
  6. data/README.md +82 -107
  7. data/Rakefile +6 -7
  8. data/icalendar.gemspec +10 -9
  9. data/lib/icalendar.rb +17 -33
  10. data/lib/icalendar/alarm.rb +35 -0
  11. data/lib/icalendar/calendar.rb +17 -100
  12. data/lib/icalendar/component.rb +41 -403
  13. data/lib/icalendar/event.rb +51 -0
  14. data/lib/icalendar/freebusy.rb +27 -0
  15. data/lib/icalendar/has_components.rb +83 -0
  16. data/lib/icalendar/has_properties.rb +156 -0
  17. data/lib/icalendar/journal.rb +39 -0
  18. data/lib/icalendar/parser.rb +75 -403
  19. data/lib/icalendar/timezone.rb +53 -0
  20. data/lib/icalendar/todo.rb +52 -0
  21. data/lib/icalendar/tzinfo.rb +30 -30
  22. data/lib/icalendar/value.rb +80 -0
  23. data/lib/icalendar/values/array.rb +43 -0
  24. data/lib/icalendar/values/binary.rb +31 -0
  25. data/lib/icalendar/values/boolean.rb +17 -0
  26. data/lib/icalendar/values/cal_address.rb +8 -0
  27. data/lib/icalendar/values/date.rb +26 -0
  28. data/lib/icalendar/values/date_time.rb +34 -0
  29. data/lib/icalendar/values/duration.rb +48 -0
  30. data/lib/icalendar/values/float.rb +17 -0
  31. data/lib/icalendar/values/integer.rb +17 -0
  32. data/lib/icalendar/values/period.rb +46 -0
  33. data/lib/icalendar/values/recur.rb +63 -0
  34. data/lib/icalendar/values/text.rb +26 -0
  35. data/lib/icalendar/values/time.rb +34 -0
  36. data/lib/icalendar/values/time_with_zone.rb +31 -0
  37. data/lib/icalendar/values/uri.rb +19 -0
  38. data/lib/icalendar/values/utc_offset.rb +39 -0
  39. data/lib/icalendar/version.rb +5 -0
  40. data/spec/alarm_spec.rb +108 -0
  41. data/spec/calendar_spec.rb +167 -0
  42. data/spec/event_spec.rb +108 -0
  43. data/{test/fixtures/folding.ics → spec/fixtures/nondefault_values.ics} +2 -2
  44. data/{test → spec}/fixtures/single_event.ics +11 -14
  45. data/spec/fixtures/timezone.ics +35 -0
  46. data/spec/freebusy_spec.rb +7 -0
  47. data/spec/journal_spec.rb +7 -0
  48. data/spec/parser_spec.rb +26 -0
  49. data/spec/roundtrip_spec.rb +40 -0
  50. data/spec/spec_helper.rb +25 -0
  51. data/spec/timezone_spec.rb +31 -0
  52. data/spec/todo_spec.rb +24 -0
  53. data/spec/tzinfo_spec.rb +85 -0
  54. data/spec/values/date_time_spec.rb +80 -0
  55. data/spec/values/duration_spec.rb +67 -0
  56. data/spec/values/period_spec.rb +47 -0
  57. data/spec/values/recur_spec.rb +47 -0
  58. data/spec/values/text_spec.rb +72 -0
  59. data/spec/values/utc_offset_spec.rb +41 -0
  60. metadata +129 -88
  61. data/GPL +0 -340
  62. data/examples/create_cal.rb +0 -45
  63. data/examples/parse_cal.rb +0 -20
  64. data/examples/single_event.ics +0 -18
  65. data/lib/hash_attrs.rb +0 -34
  66. data/lib/icalendar/base.rb +0 -47
  67. data/lib/icalendar/component/alarm.rb +0 -47
  68. data/lib/icalendar/component/event.rb +0 -131
  69. data/lib/icalendar/component/freebusy.rb +0 -38
  70. data/lib/icalendar/component/journal.rb +0 -60
  71. data/lib/icalendar/component/timezone.rb +0 -91
  72. data/lib/icalendar/component/todo.rb +0 -64
  73. data/lib/icalendar/conversions.rb +0 -107
  74. data/lib/icalendar/helpers.rb +0 -109
  75. data/lib/icalendar/parameter.rb +0 -33
  76. data/lib/icalendar/rrule.rb +0 -133
  77. data/lib/meta.rb +0 -32
  78. data/script/console +0 -10
  79. data/script/recur1.ics +0 -38
  80. data/script/tryit.rb +0 -13
  81. data/test/component/test_event.rb +0 -253
  82. data/test/component/test_timezone.rb +0 -74
  83. data/test/component/test_todo.rb +0 -31
  84. data/test/fixtures/life.ics +0 -46
  85. data/test/fixtures/nonstandard.ics +0 -25
  86. data/test/fixtures/simplecal.ics +0 -119
  87. data/test/interactive.rb +0 -17
  88. data/test/read_write.rb +0 -23
  89. data/test/test_calendar.rb +0 -167
  90. data/test/test_component.rb +0 -102
  91. data/test/test_conversions.rb +0 -104
  92. data/test/test_helper.rb +0 -7
  93. data/test/test_parameter.rb +0 -91
  94. data/test/test_parser.rb +0 -100
  95. data/test/test_tzinfo.rb +0 -83
  96. data/website/index.html +0 -70
  97. data/website/index.txt +0 -38
  98. data/website/javascripts/rounded_corners_lite.inc.js +0 -285
  99. data/website/stylesheets/screen.css +0 -159
  100. data/website/template.html.erb +0 -50
@@ -1,91 +0,0 @@
1
- =begin
2
- Copyright (C) 2005 Jeff Rose
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
- module Icalendar
9
- # A Timezone is unambiguously defined by the set of time
10
- # measurement rules determined by the governing body for a given
11
- # geographic area. These rules describe at a minimum the base offset
12
- # from UTC for the time zone, often referred to as the Standard Time
13
- # offset. Many locations adjust their Standard Time forward or backward
14
- # by one hour, in order to accommodate seasonal changes in number of
15
- # daylight hours, often referred to as Daylight Saving Time. Some
16
- # locations adjust their time by a fraction of an hour. Standard Time
17
- # is also known as Winter Time. Daylight Saving Time is also known as
18
- # Advanced Time, Summer Time, or Legal Time in certain countries. The
19
- # following table shows the changes in time zone rules in effect for
20
- # New York City starting from 1967. Each line represents a description
21
- # or rule for a particular observance.
22
- class Timezone < Component
23
- # Single properties
24
- ical_property :dtstart, :start
25
- ical_property :tzoffsetto, :timezone_offset_to
26
- ical_property :tzoffsetfrom, :timezone_offset_from
27
- ical_property :tzid, :timezone_id
28
- ical_property :tzname, :timezone_name
29
- ical_property :tzurl, :timezone_url
30
-
31
- ical_property :created
32
- ical_property :last_modified
33
- ical_property :timestamp
34
- ical_property :sequence
35
-
36
- # Multi-properties
37
- ical_multi_property :comment, :comment, :comments
38
- ical_multi_property :rdate, :recurrence_date, :recurrence_dates
39
- ical_multi_property :rrule, :recurrence_rule, :recurrence_rules
40
-
41
- # Define a custom add component method because standard and daylight
42
- # are the only components that can occur just once with their parent.
43
- def add_component(component)
44
- key = component.class.to_s.downcase.gsub('icalendar::','').to_sym
45
- @components[key] = component
46
- end
47
-
48
- def initialize(name = "VTIMEZONE")
49
- super(name)
50
- end
51
-
52
- # Allow block syntax for declaration of standard and daylight components of timezone
53
- def standard(&block)
54
- e = Standard.new
55
- self.add_component e
56
-
57
- e.instance_eval(&block) if block
58
-
59
- e
60
- end
61
-
62
- def daylight(&block)
63
- e = Daylight.new
64
- self.add_component e
65
-
66
- e.instance_eval(&block) if block
67
-
68
- e
69
- end
70
- end
71
-
72
- # A Standard component is a sub-component of the Timezone component which
73
- # is used to describe the standard time offset.
74
- class Standard < Timezone
75
-
76
- def initialize()
77
- super("STANDARD")
78
- end
79
- end
80
-
81
- # A Daylight component is a sub-component of the Timezone component which
82
- # is used to describe the time offset for what is commonly known as
83
- # daylight savings time.
84
- class Daylight < Timezone
85
-
86
- def initialize()
87
- super("DAYLIGHT")
88
- end
89
- end
90
-
91
- end
@@ -1,64 +0,0 @@
1
- =begin
2
- Copyright (C) 2005 Jeff Rose
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
- module Icalendar
9
- # A Todo calendar component is a grouping of component
10
- # properties and possibly Alarm calendar components that represent
11
- # an action-item or assignment. For example, it can be used to
12
- # represent an item of work assigned to an individual; such as "turn in
13
- # travel expense today".
14
- class Todo < Component
15
- ical_component :alarms
16
-
17
- # Single properties
18
- ical_property :ip_class
19
- ical_property :completed
20
- ical_property :created
21
- ical_property :description
22
- ical_property :dtstamp, :timestamp
23
- ical_property :dtstart, :start
24
- ical_property :geo
25
- ical_property :last_modified
26
- ical_property :location
27
- ical_property :organizer
28
- ical_property :percent_complete, :percent
29
- ical_property :priority
30
- ical_property :recurid, :recurrence_id
31
- ical_property :sequence, :seq
32
- ical_property :status
33
- ical_property :summary
34
- ical_property :uid, :user_id
35
- ical_property :url
36
-
37
- # Single but mutually exclusive TODO: not testing anything yet
38
- ical_property :due
39
- ical_property :duration
40
-
41
- # Multi-properties
42
- ical_multiline_property :attach, :attachment, :attachments
43
- ical_multiline_property :attendee, :attendee, :attendees
44
- ical_multi_property :categories, :category, :categories
45
- ical_multi_property :comment, :comment, :comments
46
- ical_multi_property :contact, :contact, :contacts
47
- ical_multi_property :exdate, :exception_date, :exception_dates
48
- ical_multi_property :exrule, :exception_rule, :exception_rules
49
- ical_multi_property :rstatus, :request_status, :request_statuses
50
- ical_multi_property :related_to, :related_to, :related_tos
51
- ical_multi_property :resources, :resource, :resources
52
- ical_multi_property :rdate, :recurrence_date, :recurrence_dates
53
- ical_multi_property :rrule, :recurrence_rule, :recurrence_rules
54
-
55
- def initialize()
56
- super("VTODO")
57
-
58
- sequence 0
59
- timestamp Time.now.utc.to_datetime.tap { |t| t.icalendar_tzid = 'UTC' }
60
- uid new_uid
61
- end
62
-
63
- end
64
- end
@@ -1,107 +0,0 @@
1
- =begin
2
- Copyright (C) 2005 Jeff Rose
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
-
11
- ### Add some to_ical methods to classes
12
-
13
- # class Object
14
- # def to_ical
15
- # raise(NotImplementedError, "This object does not implement the to_ical method!")
16
- # end
17
- # end
18
-
19
- module Icalendar
20
- module TzidSupport
21
- attr_accessor :icalendar_tzid
22
- end
23
-
24
- require 'delegate'
25
- class FrozenProxy < SimpleDelegator
26
- attr_accessor :ical_params
27
- end
28
- end
29
-
30
- require 'uri/generic'
31
-
32
- class String
33
- def to_ical
34
- self
35
- end
36
- end
37
-
38
- class Fixnum
39
- def to_ical
40
- "#{self}"
41
- end
42
- end
43
-
44
- class Bignum
45
- def to_ical
46
- "#{self}"
47
- end
48
- end
49
-
50
- class Float
51
- def to_ical
52
- "#{self}"
53
- end
54
- end
55
-
56
- # From the spec: "Values in a list of values MUST be separated by a COMMA
57
- # character (US-ASCII decimal 44)."
58
- class Array
59
- def to_ical
60
- map{|elem| elem.to_ical}.join ','
61
- end
62
- end
63
-
64
- module URI
65
- class Generic
66
- def to_ical
67
- "#{self}"
68
- end
69
- end
70
- end
71
-
72
- class DateTime < Date
73
- attr_accessor :ical_params
74
- include Icalendar::TzidSupport
75
-
76
- def to_ical
77
- s = strftime '%Y%m%dT%H%M%S'
78
-
79
- # UTC time gets a Z suffix
80
- if icalendar_tzid == "UTC"
81
- s << "Z"
82
- end
83
-
84
- s
85
- end
86
- end
87
-
88
- class Date
89
- attr_accessor :ical_params
90
- def to_ical(utc = false)
91
- strftime '%Y%m%d'
92
- end
93
- end
94
-
95
- class Time
96
- attr_accessor :ical_params
97
- def to_ical(utc = false)
98
- s = strftime '%H%M%S'
99
-
100
- # UTC time gets a Z suffix
101
- if utc
102
- s << "Z"
103
- end
104
-
105
- s
106
- end
107
- end
@@ -1,109 +0,0 @@
1
- =begin
2
- Copyright (C) 2005 Jeff Rose
3
- Copyright (C) 2005 Sam Roberts
4
-
5
- This library is free software; you can redistribute it and/or modify it
6
- under the same terms as the ruby language itself, see the file COPYING for
7
- details.
8
- =end
9
-
10
- module Icalendar
11
- module DateProp
12
- # date = date-fullyear date-month date-mday
13
- # date-fullyear = 4 DIGIT
14
- # date-month = 2 DIGIT
15
- # date-mday = 2 DIGIT
16
- DATE = '(\d\d\d\d)(\d\d)(\d\d)'
17
-
18
- # time = time-hour [":"] time-minute [":"] time-second [time-secfrac] [time-zone]
19
- # time-hour = 2 DIGIT
20
- # time-minute = 2 DIGIT
21
- # time-second = 2 DIGIT
22
- # time-secfrac = "," 1*DIGIT
23
- # time-zone = "Z" / time-numzone
24
- # time-numzome = sign time-hour [":"] time-minute
25
- # TIME = '(\d\d)(\d\d)(\d\d)(Z)?'
26
- TIME = '(\d\d)(\d\d)(\d\d)'
27
-
28
- # This method is called automatically when the module is mixed in.
29
- # I guess you have to do this to mixin class methods rather than instance methods.
30
- def self.append_features(base)
31
- super
32
- klass.extend(ClassMethods)
33
- end
34
-
35
- # This is made a sub-module just so it can be added as class
36
- # methods rather than instance methods.
37
- module ClassMethods
38
- def date_property(dp, alias_name = nil)
39
- dp = "#{dp}".strip.downcase
40
- getter = dp
41
- setter = "#{dp}="
42
- query = "#{dp}?"
43
-
44
- unless instance_methods.include? getter
45
- code = <<-code
46
- def #{getter}(*a)
47
- if a.empty?
48
- @properties[#{dp.upcase}]
49
- else
50
- self.#{dp} = a.first
51
- end
52
- end
53
- code
54
-
55
- module_eval code
56
- end
57
-
58
- unless instance_methods.include? setter
59
- code = <<-code
60
- def #{setter} a
61
- @properties[#{dp.upcase}] = a
62
- end
63
- code
64
-
65
- module_eval code
66
- end
67
-
68
- unless instance_methods.include? query
69
- code = <<-code
70
- def #{query}
71
- @properties.has_key?(#{dp.upcase})
72
- end
73
- code
74
-
75
- module_eval code
76
- end
77
-
78
- # Define the getter
79
- getter = "get#{property.to_s.capitalize}"
80
- define_method(getter.to_sym) do
81
- puts "inside getting..."
82
- getDateProperty(property.to_s.upcase)
83
- end
84
-
85
- # Define the setter
86
- setter = "set#{property.to_s.capitalize}"
87
- define_method(setter.to_sym) do |*params|
88
- date = params[0]
89
- utc = params[1]
90
- puts "inside setting..."
91
- setDateProperty(property.to_s.upcase, date, utc)
92
- end
93
-
94
- # Create aliases if a name was specified
95
- # if not aliasName.nil?
96
- # gasym = "get#{aliasName.to_s.capitalize}".to_sym
97
- # gsym = getter.to_sym
98
- # alias gasym gsym
99
-
100
- # sasym = "set#{aliasName.to_s.capitalize}".to_sym
101
- # ssym = setter.to_sym
102
- # alias sasym ssym
103
- # end
104
- end
105
-
106
- end
107
-
108
- end
109
- end
@@ -1,33 +0,0 @@
1
- =begin
2
- Copyright (C) 2005 Jeff Rose
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
- module Icalendar
10
-
11
- # A property can have attributes associated with it. These "property
12
- # parameters" contain meta-information about the property or the
13
- # property value. Property parameters are provided to specify such
14
- # information as the location of an alternate text representation for a
15
- # property value, the language of a text property value, the data type
16
- # of the property value and other attributes.
17
- class Parameter < Icalendar::Content
18
-
19
- def to_s
20
- s = ""
21
-
22
- s << "#{@name}="
23
- if is_escapable?
24
- s << escape(print_value())
25
- else
26
- s << print_value
27
- end
28
-
29
- s
30
- end
31
-
32
- end
33
- end
@@ -1,133 +0,0 @@
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
- attr_accessor :frequency, :until, :count, :interval, :by_list, :wkst
38
-
39
- def initialize(name, params, value)
40
- @value = value
41
- frequency_match = value.match(/FREQ=(SECONDLY|MINUTELY|HOURLY|DAILY|WEEKLY|MONTHLY|YEARLY)/)
42
- @frequency = frequency_match[1]
43
- @until = parse_date_val("UNTIL", value)
44
- @count = parse_int_val("COUNT", value)
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
- raise Icalendar::InvalidPropertyValue.new("FREQ must be specified for RRULE values") unless frequency
65
- raise Icalendar::InvalidPropertyValue.new("UNTIL and COUNT must not both be specified for RRULE values") if [self.until, count].compact.length > 1
66
- result = ["FREQ=#{frequency}"]
67
- result << "UNTIL=#{self.until.to_ical}" if self.until
68
- result << "COUNT=#{count}" if count
69
- result << "INTERVAL=#{interval}" if interval
70
- by_list.each do |key, value|
71
- result << "#{key.to_s.upcase}=#{value.join ','}" if value
72
- end
73
- result << "WKST=#{wkst}" if wkst
74
- result.join ';'
75
- end
76
-
77
- def parse_date_val(name, string)
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
84
- end
85
-
86
- def parse_int_val(name, string)
87
- match = string.match(/;#{name}=(\d+)(;|$)/)
88
- match ? match[1].to_i : nil
89
- end
90
-
91
- def parse_int_list(name, string)
92
- match = string.match(/;#{name}=([+-]?.*?)(;|$)/)
93
- if match
94
- match[1].split(",").map {|int| int.to_i}
95
- else
96
- nil
97
- end
98
- end
99
-
100
- def parse_weekday_list(name, string)
101
- match = string.match(/;#{name}=(.*?)(;|$)/)
102
- if match
103
- return_array = match[1].split(",").map do |weekday|
104
- wd_match = weekday.match(/([+-]?\d*)(SU|MO|TU|WE|TH|FR|SA)/)
105
- Weekday.new(wd_match[2], wd_match[1])
106
- end
107
- else
108
- nil
109
- end
110
- return_array
111
- end
112
-
113
- def parse_wkstart(string)
114
- match = string.match(/;WKST=(SU|MO|TU|WE|TH|FR|SA)(;|$)/)
115
- if match
116
- match[1]
117
- else
118
- nil
119
- end
120
- end
121
-
122
- # TODO: Incomplete
123
- def occurrences_of_event_starting(event, datetime)
124
- initial_start = event.dtstart
125
- (0...count).map do |day_offset|
126
- occurrence = event.clone
127
- occurrence.dtstart = initial_start + day_offset
128
- occurrence.clone
129
- end
130
- end
131
- end
132
-
133
- end