rubyredrick-ri_cal 0.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.
Files changed (123) hide show
  1. data/History.txt +3 -0
  2. data/Manifest.txt +122 -0
  3. data/README.txt +271 -0
  4. data/Rakefile +31 -0
  5. data/bin/ri_cal +8 -0
  6. data/component_attributes/alarm.yml +10 -0
  7. data/component_attributes/calendar.yml +4 -0
  8. data/component_attributes/component_property_defs.yml +180 -0
  9. data/component_attributes/event.yml +45 -0
  10. data/component_attributes/freebusy.yml +16 -0
  11. data/component_attributes/journal.yml +35 -0
  12. data/component_attributes/timezone.yml +3 -0
  13. data/component_attributes/timezone_period.yml +11 -0
  14. data/component_attributes/todo.yml +46 -0
  15. data/copyrights.txt +2 -0
  16. data/docs/draft-ietf-calsify-2446bis-08.txt +7280 -0
  17. data/docs/draft-ietf-calsify-rfc2445bis-09.txt +10416 -0
  18. data/docs/incrementers.txt +7 -0
  19. data/docs/rfc2445.pdf +0 -0
  20. data/lib/ri_cal/component/alarm.rb +22 -0
  21. data/lib/ri_cal/component/calendar.rb +199 -0
  22. data/lib/ri_cal/component/event.rb +30 -0
  23. data/lib/ri_cal/component/freebusy.rb +19 -0
  24. data/lib/ri_cal/component/journal.rb +22 -0
  25. data/lib/ri_cal/component/t_z_info_timezone.rb +124 -0
  26. data/lib/ri_cal/component/timezone/daylight_period.rb +26 -0
  27. data/lib/ri_cal/component/timezone/standard_period.rb +24 -0
  28. data/lib/ri_cal/component/timezone/timezone_period.rb +54 -0
  29. data/lib/ri_cal/component/timezone.rb +193 -0
  30. data/lib/ri_cal/component/todo.rb +26 -0
  31. data/lib/ri_cal/component.rb +224 -0
  32. data/lib/ri_cal/core_extensions/array/conversions.rb +15 -0
  33. data/lib/ri_cal/core_extensions/array.rb +7 -0
  34. data/lib/ri_cal/core_extensions/date/conversions.rb +27 -0
  35. data/lib/ri_cal/core_extensions/date.rb +13 -0
  36. data/lib/ri_cal/core_extensions/date_time/conversions.rb +27 -0
  37. data/lib/ri_cal/core_extensions/date_time.rb +13 -0
  38. data/lib/ri_cal/core_extensions/object/conversions.rb +20 -0
  39. data/lib/ri_cal/core_extensions/object.rb +8 -0
  40. data/lib/ri_cal/core_extensions/string/conversions.rb +32 -0
  41. data/lib/ri_cal/core_extensions/string.rb +8 -0
  42. data/lib/ri_cal/core_extensions/time/calculations.rb +153 -0
  43. data/lib/ri_cal/core_extensions/time/conversions.rb +27 -0
  44. data/lib/ri_cal/core_extensions/time/week_day_predicates.rb +88 -0
  45. data/lib/ri_cal/core_extensions/time.rb +11 -0
  46. data/lib/ri_cal/core_extensions.rb +6 -0
  47. data/lib/ri_cal/invalid_timezone_identifer.rb +20 -0
  48. data/lib/ri_cal/occurrence_enumerator.rb +172 -0
  49. data/lib/ri_cal/parser.rb +138 -0
  50. data/lib/ri_cal/properties/alarm.rb +390 -0
  51. data/lib/ri_cal/properties/calendar.rb +164 -0
  52. data/lib/ri_cal/properties/event.rb +1526 -0
  53. data/lib/ri_cal/properties/freebusy.rb +594 -0
  54. data/lib/ri_cal/properties/journal.rb +1240 -0
  55. data/lib/ri_cal/properties/timezone.rb +151 -0
  56. data/lib/ri_cal/properties/timezone_period.rb +416 -0
  57. data/lib/ri_cal/properties/todo.rb +1562 -0
  58. data/lib/ri_cal/property_value/array.rb +19 -0
  59. data/lib/ri_cal/property_value/cal_address.rb +12 -0
  60. data/lib/ri_cal/property_value/date.rb +119 -0
  61. data/lib/ri_cal/property_value/date_time/additive_methods.rb +43 -0
  62. data/lib/ri_cal/property_value/date_time/time_machine.rb +180 -0
  63. data/lib/ri_cal/property_value/date_time/timezone_support.rb +65 -0
  64. data/lib/ri_cal/property_value/date_time.rb +324 -0
  65. data/lib/ri_cal/property_value/duration.rb +106 -0
  66. data/lib/ri_cal/property_value/geo.rb +12 -0
  67. data/lib/ri_cal/property_value/integer.rb +13 -0
  68. data/lib/ri_cal/property_value/occurrence_list.rb +82 -0
  69. data/lib/ri_cal/property_value/period.rb +63 -0
  70. data/lib/ri_cal/property_value/recurrence_rule/enumeration_support_methods.rb +98 -0
  71. data/lib/ri_cal/property_value/recurrence_rule/enumerator.rb +77 -0
  72. data/lib/ri_cal/property_value/recurrence_rule/initialization_methods.rb +149 -0
  73. data/lib/ri_cal/property_value/recurrence_rule/negative_setpos_enumerator.rb +54 -0
  74. data/lib/ri_cal/property_value/recurrence_rule/numbered_span.rb +32 -0
  75. data/lib/ri_cal/property_value/recurrence_rule/occurence_incrementer.rb +794 -0
  76. data/lib/ri_cal/property_value/recurrence_rule/recurring_day.rb +132 -0
  77. data/lib/ri_cal/property_value/recurrence_rule/recurring_month_day.rb +61 -0
  78. data/lib/ri_cal/property_value/recurrence_rule/recurring_numbered_week.rb +34 -0
  79. data/lib/ri_cal/property_value/recurrence_rule/recurring_year_day.rb +50 -0
  80. data/lib/ri_cal/property_value/recurrence_rule/validations.rb +126 -0
  81. data/lib/ri_cal/property_value/recurrence_rule.rb +146 -0
  82. data/lib/ri_cal/property_value/text.rb +41 -0
  83. data/lib/ri_cal/property_value/uri.rb +12 -0
  84. data/lib/ri_cal/property_value/utc_offset.rb +34 -0
  85. data/lib/ri_cal/property_value.rb +110 -0
  86. data/lib/ri_cal/required_timezones.rb +56 -0
  87. data/lib/ri_cal/time_with_floating_timezone.rb +59 -0
  88. data/lib/ri_cal.rb +134 -0
  89. data/ri_cal.gemspec +47 -0
  90. data/sample_ical_files/from_ical_dot_app/test1.ics +38 -0
  91. data/script/console +10 -0
  92. data/script/destroy +14 -0
  93. data/script/generate +14 -0
  94. data/script/txt2html +71 -0
  95. data/spec/ri_cal/component/alarm_spec.rb +13 -0
  96. data/spec/ri_cal/component/calendar_spec.rb +55 -0
  97. data/spec/ri_cal/component/event_spec.rb +157 -0
  98. data/spec/ri_cal/component/freebusy_spec.rb +13 -0
  99. data/spec/ri_cal/component/journal_spec.rb +13 -0
  100. data/spec/ri_cal/component/t_z_info_timezone_spec.rb +37 -0
  101. data/spec/ri_cal/component/timezone_spec.rb +155 -0
  102. data/spec/ri_cal/component/todo_spec.rb +61 -0
  103. data/spec/ri_cal/component_spec.rb +212 -0
  104. data/spec/ri_cal/core_extensions/time/calculations_spec.rb +189 -0
  105. data/spec/ri_cal/core_extensions/time/week_day_predicates_spec.rb +46 -0
  106. data/spec/ri_cal/occurrence_enumerator_spec.rb +218 -0
  107. data/spec/ri_cal/parser_spec.rb +304 -0
  108. data/spec/ri_cal/property_value/date_spec.rb +22 -0
  109. data/spec/ri_cal/property_value/date_time_spec.rb +448 -0
  110. data/spec/ri_cal/property_value/duration_spec.rb +80 -0
  111. data/spec/ri_cal/property_value/period_spec.rb +50 -0
  112. data/spec/ri_cal/property_value/recurrence_rule/recurring_year_day_spec.rb +22 -0
  113. data/spec/ri_cal/property_value/recurrence_rule_spec.rb +1815 -0
  114. data/spec/ri_cal/property_value/text_spec.rb +14 -0
  115. data/spec/ri_cal/property_value/utc_offset_spec.rb +49 -0
  116. data/spec/ri_cal/property_value_spec.rb +111 -0
  117. data/spec/ri_cal/required_timezones_spec.rb +68 -0
  118. data/spec/ri_cal_spec.rb +54 -0
  119. data/spec/spec.opts +4 -0
  120. data/spec/spec_helper.rb +24 -0
  121. data/tasks/ri_cal.rake +403 -0
  122. data/tasks/spec.rake +35 -0
  123. metadata +201 -0
@@ -0,0 +1,110 @@
1
+ module RiCal
2
+ #- ©2009 Rick DeNatale
3
+ #- All rights reserved. Refer to the file README.txt for the license
4
+ #
5
+ # PropertyValue provides common implementation of various RFC 2445 property value types
6
+ class PropertyValue
7
+
8
+ attr_writer :params, :value #:nodoc:
9
+ attr_reader :timezone_finder #:nodoc:
10
+ def initialize(timezone_finder, options={}) # :nodoc:
11
+ @timezone_finder = timezone_finder
12
+ validate_value(options)
13
+ ({:params => {}}).merge(options).each do |attribute, val|
14
+ unless attribute == :name
15
+ setter = :"#{attribute.to_s}="
16
+ send(setter, val)
17
+ end
18
+ end
19
+ end
20
+
21
+ def validate_value(options) #:nodoc:
22
+ val = options[:value]
23
+ raise "Invalid property value #{val.inspect}" if val.kind_of?(String) && /^;/.match(val)
24
+ end
25
+
26
+ # return a hash containing the parameters and values, if any
27
+ def params
28
+ @params ||= {}
29
+ end
30
+
31
+ def to_options_hash #:nodoc:
32
+ options_hash = {:value => value}
33
+ options_hash[:params] = params unless params.empty?
34
+ end
35
+
36
+ def self.date_or_date_time(parent, separated_line) # :nodoc:
37
+ match = separated_line[:value].match(/(\d\d\d\d)(\d\d)(\d\d)((T?)((\d\d)(\d\d)(\d\d))(Z?))?/)
38
+ raise Exception.new("Invalid date") unless match
39
+ if match[5] == "T" # date-time
40
+ time = Time.utc(match[1].to_i, match[2].to_i, match[3].to_i, match[7].to_i, match[8].to_i, match[9].to_i)
41
+ parms = (separated_line[:params] ||{}).dup
42
+ if match[10] == "Z"
43
+ raise Exception.new("Invalid time, cannot combine Zulu with timezone reference") if parms[:tzid]
44
+ parms['TZID'] = "UTC"
45
+ end
46
+ PropertyValue::DateTime.new(parent, separated_line.merge(:params => parms))
47
+ else
48
+ PropertyValue::Date.new(parent, separated_line)
49
+ end
50
+ end
51
+
52
+ def self.from_string(string) # :nodoc:
53
+ new(nil, :value => string)
54
+ end
55
+
56
+ def self.convert(parent, value) #:nodoc:
57
+ new(parent, :value => value)
58
+ end
59
+
60
+ # Determine if another object is equivalent to the receiver.
61
+ def ==(o)
62
+ if o.class == self.class
63
+ equality_value == o.equality_value
64
+ else
65
+ super
66
+ end
67
+ end
68
+
69
+ # Return the string value
70
+ def value
71
+ @value
72
+ end
73
+
74
+ def equality_value #:nodoc:
75
+ value
76
+ end
77
+
78
+ def visible_params # :nodoc:
79
+ params
80
+ end
81
+
82
+ def parms_string #:nodoc:
83
+ if (vp = visible_params) && !vp.empty?
84
+ # We only sort for testability reasons
85
+ vp.keys.sort.map {|key| ";#{key}=#{vp[key]}"}.join
86
+ else
87
+ ""
88
+ end
89
+ end
90
+
91
+ # Return a string representing the receiver in RFC 2445 format
92
+ def to_s #:nodoc:
93
+ "#{parms_string}:#{value}"
94
+ end
95
+
96
+ # return the ruby value
97
+ def ruby_value
98
+ self.value
99
+ end
100
+
101
+ def to_ri_cal_property_value #:nodoc:
102
+ self
103
+ end
104
+ end
105
+ end
106
+
107
+ Dir[File.dirname(__FILE__) + "/property_value/*.rb"].sort.each do |path|
108
+ filename = File.basename(path)
109
+ require path
110
+ end
@@ -0,0 +1,56 @@
1
+ module RiCal
2
+ #- ©2009 Rick DeNatale
3
+ #- All rights reserved. Refer to the file README.txt for the license
4
+ #
5
+ # RequireTimezones collects the timezones used by a given calendar component or set of calendar components
6
+ # For each timezone we collect it's id, and the earliest and latest times which reference the zone
7
+ class RequiredTimezones #:nodoc:
8
+
9
+
10
+ # A required timezone represents a single timezone and the earliest and latest times which reference it.
11
+ class RequiredTimezone #:nodoc:
12
+
13
+ attr_reader :first_time, :last_time, :timezone
14
+
15
+ def initialize(tzid)
16
+ @timezone = RiCal::Component::TZInfoTimezone.new(TZInfo::Timezone.get(tzid))
17
+ end
18
+
19
+ def tzid
20
+ @timezone.identifier
21
+ end
22
+
23
+ def add_datetime(date_time)
24
+ if @first_time
25
+ @first_time = date_time if date_time < @first_time
26
+ else
27
+ @first_time = date_time
28
+ end
29
+ if @last_time
30
+ @last_time = date_time if date_time > @last_time
31
+ else
32
+ @last_time = date_time
33
+ end
34
+ end
35
+ end
36
+
37
+ def required_timezones
38
+ @required_zones ||= {}
39
+ end
40
+
41
+ def required_zones
42
+ required_timezones.values
43
+ end
44
+
45
+ def export_to(export_stream)
46
+ required_zones.each do |z|
47
+ tzinfo_timezone =z.timezone
48
+ tzinfo_timezone.export_local_to(export_stream, z.first_time, z.last_time)
49
+ end
50
+ end
51
+
52
+ def add_datetime(date_time, tzid)
53
+ (required_timezones[tzid] ||= RequiredTimezone.new(tzid)).add_datetime(date_time)
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,59 @@
1
+ module RiCal
2
+ #- ©2009 Rick DeNatale
3
+ #- All rights reserved. Refer to the file README.txt for the license
4
+ #
5
+ # FloatingTimezone represents the 'time zone' for a time or date time with no timezone
6
+ # Times with floating timezones are always interpreted in the timezone of the observer
7
+ class FloatingTimezone
8
+
9
+ def self.identifier #:nodoc:
10
+ nil
11
+ end
12
+
13
+ def self.tzinfo_timezone #:nodoc:
14
+ nil
15
+ end
16
+
17
+ # Return the time unchanged #:nodoc:
18
+ def self.utc_to_local(time)
19
+ time.with_floating_timezone.to_ri_cal_date_time_value
20
+ end
21
+
22
+ # Return the time unchanged #:nodoc:
23
+ def self.local_to_utc(time)
24
+ time.with_floating_timezone.to_ri_cal_date_time_value
25
+ end
26
+ end
27
+
28
+ class TimeWithFloatingTimezone #:nodoc:
29
+ def initialize(time) #:nodoc:
30
+ @time = time
31
+ end
32
+
33
+ def acts_like_time? #:nodoc:
34
+ true
35
+ end
36
+
37
+ def time_zone
38
+ FloatingTimezone #:nodoc:
39
+ end
40
+
41
+ def strftime(format) #:nodoc:
42
+ @time.strftime(format)
43
+ end
44
+
45
+ def with_floating_timezone #:nodoc:
46
+ self
47
+ end
48
+
49
+ def to_ri_cal_date_time_value #:nodoc:
50
+ ::RiCal::PropertyValue::DateTime.new(nil, :value => @time, :params => {'TZID' => nil})
51
+ end
52
+
53
+ alias_method :to_ri_cal_date_or_date_time_value, :to_ri_cal_date_time_value #:nodoc:
54
+
55
+ def method_missing(selector, *args) #:nodoc:
56
+ @time.send(selector, *args)
57
+ end
58
+ end
59
+ end
data/lib/ri_cal.rb ADDED
@@ -0,0 +1,134 @@
1
+ #- ©2009 Rick DeNatale
2
+ #- All rights reserved. Refer to the file README.txt for the license
3
+ #
4
+ # The RiCal module provides the outermost namespace, along with several convenience methods for parsing
5
+ # and building calendars and calendar components.
6
+ module RiCal
7
+
8
+ my_dir = File.dirname(__FILE__)
9
+
10
+ autoload :Component, "#{my_dir}/ri_cal/component.rb"
11
+ autoload :TimezonePeriod, "#{my_dir}/ri_cal/properties/timezone_period.rb"
12
+ autoload :OccurrenceEnumerator, "#{my_dir}/ri_cal/occurrence_enumerator.rb"
13
+
14
+ # :stopdoc:
15
+ VERSION = '0.0.3'
16
+ LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
17
+ PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
18
+
19
+ # Returns the version string for the library.
20
+ #
21
+ def self.version
22
+ VERSION
23
+ end
24
+
25
+ # Returns the library path for the module. If any arguments are given,
26
+ # they will be joined to the end of the libray path using
27
+ # <tt>File.join</tt>.
28
+ #
29
+ def self.libpath( *args )
30
+ args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
31
+ end
32
+
33
+ # Returns the lpath for the module. If any arguments are given,
34
+ # they will be joined to the end of the path using
35
+ # <tt>File.join</tt>.
36
+ #
37
+ def self.path( *args )
38
+ args.empty? ? PATH : ::File.join(PATH, args.flatten)
39
+ end
40
+
41
+ # Utility method used to rquire all files ending in .rb that lie in the
42
+ # directory below this file that has the same name as the filename passed
43
+ # in. Optionally, a specific _directory_ name can be passed in such that
44
+ # the _filename_ does not have to be equivalent to the directory.
45
+ #
46
+ def self.require_all_libs_relative_to( fname, dir = nil )
47
+ dir ||= ::File.basename(fname, '.*')
48
+ search_me = ::File.expand_path(::File.join(::File.dirname(fname), dir, '**', '*.rb'))
49
+ Dir.glob(search_me).sort.each {|rb|
50
+ require rb}
51
+ end
52
+
53
+ # :startdoc:
54
+
55
+ # Parse an io stream and return an array of iCalendar entities.
56
+ # Normally this will be an array of RiCal::Component::Calendar instances
57
+ def self.parse(io)
58
+ Parser.new(io).parse
59
+ end
60
+
61
+ # Parse a string and return an array of iCalendar entities.
62
+ # see RiCal.parse
63
+ def self.parse_string(string)
64
+ parse(StringIO.new(string))
65
+ end
66
+
67
+ def self.debug # :nodoc:
68
+ @debug
69
+ end
70
+
71
+ def self.debug=(val) # :nodoc:
72
+ @debug = val
73
+ end
74
+
75
+ # return a new Alarm event or todo component. If a block is provided it will will be executed in
76
+ # the context of a builder object which can be used to initialize the properties of the
77
+ # new Alarm.
78
+ def self.Alarm(&init_block)
79
+ Component::Alarm.new(&init_block)
80
+ end
81
+
82
+ # return a new Calendar. If a block is provided it will will be executed in
83
+ # the context of a builder object which can be used to initialize the properties and components of the
84
+ # new calendar.
85
+ def self.Calendar(&init_block)
86
+ Component::Calendar.new(&init_block)
87
+ end
88
+
89
+ # return a new Event calendar component. If a block is provided it will will be executed in
90
+ # the context of a builder object which can be used to initialize the properties and alarms of the
91
+ # new Event.
92
+ def self.Event(&init_block)
93
+ Component::Event.new(&init_block)
94
+ end
95
+
96
+ # return a new Freebusy calendar component. If a block is provided it will will be executed in
97
+ # the context of a builder object which can be used to initialize the properties and components of the
98
+ # new Freebusy.
99
+ def self.Freebusy(&init_block)
100
+ Component::Freebusy.new(&init_block)
101
+ end
102
+
103
+ # return a new Journal calendar component. If a block is provided it will will be executed in
104
+ # the context of a builder object which can be used to initialize the properties and components of the
105
+ # new Event.
106
+ def self.Journal(&init_block)
107
+ Component::Journal.new(&init_block)
108
+ end
109
+
110
+ # return a new Timezone calendar component. If a block is provided it will will be executed in
111
+ # the context of a builder object which can be used to initialize the properties and timezone periods of the
112
+ # new Timezone.
113
+ def self.Timezone(&init_block)
114
+ Component::Timezone.new(&init_block)
115
+ end
116
+
117
+ # return a new TimezonePeriod timezone component. If a block is provided it will will be executed in
118
+ # the context of a builder object which can be used to initialize the properties of the
119
+ # new TimezonePeriod.
120
+ def self.TimezonePeriod(&init_block)
121
+ Component::TimezonePeriod.new(&init_block)
122
+ end
123
+
124
+ # return a new Todo calendar component. If a block is provided it will will be executed in
125
+ # the context of a builder object which can be used to initialize the properties and alarms of the
126
+ # new Todo.
127
+ def self.Todo(&init_block)
128
+ Component::Todo.new(&init_block)
129
+ end
130
+ end # module RiCal
131
+
132
+ RiCal.require_all_libs_relative_to(__FILE__)
133
+
134
+ # EOF
data/ri_cal.gemspec ADDED
@@ -0,0 +1,47 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{ri_cal}
5
+ s.version = "0.0.2"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["author=Rick DeNatale"]
9
+ s.date = %q{2009-05-06}
10
+ s.default_executable = %q{ri_cal}
11
+ s.description = %q{This is an UNOFFICIAL version. The public official version will be released on RubyForge. Github will be used
12
+ for interim versions. USE THIS VERSION AT YOUR OWN RISK.
13
+
14
+ A new Ruby implementation of RFC2445 iCalendar.
15
+
16
+ The existing Ruby iCalendar libraries (e.g. icalendar, vpim) provide for parsing and generating icalendar files,
17
+ but do not support important things like enumerating occurrences of repeating events.
18
+
19
+ This is a clean-slate implementation of RFC2445.}
20
+ s.email = ["rick.denatale@gmail.com"]
21
+ s.executables = ["ri_cal"]
22
+ s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt", "copyrights.txt", "docs/draft-ietf-calsify-2446bis-08.txt", "docs/draft-ietf-calsify-rfc2445bis-09.txt", "docs/incrementers.txt"]
23
+ s.files = ["History.txt", "Manifest.txt", "README.txt", "Rakefile", "bin/ri_cal", "component_attributes/alarm.yml", "component_attributes/calendar.yml", "component_attributes/component_property_defs.yml", "component_attributes/event.yml", "component_attributes/freebusy.yml", "component_attributes/journal.yml", "component_attributes/timezone.yml", "component_attributes/timezone_period.yml", "component_attributes/todo.yml", "copyrights.txt", "docs/draft-ietf-calsify-2446bis-08.txt", "docs/draft-ietf-calsify-rfc2445bis-09.txt", "docs/incrementers.txt", "docs/rfc2445.pdf", "lib/ri_cal.rb", "lib/ri_cal/component.rb", "lib/ri_cal/component/alarm.rb", "lib/ri_cal/component/calendar.rb", "lib/ri_cal/component/event.rb", "lib/ri_cal/component/freebusy.rb", "lib/ri_cal/component/journal.rb", "lib/ri_cal/component/t_z_info_timezone.rb", "lib/ri_cal/component/timezone.rb", "lib/ri_cal/component/timezone/daylight_period.rb", "lib/ri_cal/component/timezone/standard_period.rb", "lib/ri_cal/component/timezone/timezone_period.rb", "lib/ri_cal/component/todo.rb", "lib/ri_cal/core_extensions.rb", "lib/ri_cal/core_extensions/array.rb", "lib/ri_cal/core_extensions/array/conversions.rb", "lib/ri_cal/core_extensions/date.rb", "lib/ri_cal/core_extensions/date/conversions.rb", "lib/ri_cal/core_extensions/date_time.rb", "lib/ri_cal/core_extensions/date_time/conversions.rb", "lib/ri_cal/core_extensions/object.rb", "lib/ri_cal/core_extensions/object/conversions.rb", "lib/ri_cal/core_extensions/string.rb", "lib/ri_cal/core_extensions/string/conversions.rb", "lib/ri_cal/core_extensions/time.rb", "lib/ri_cal/core_extensions/time/calculations.rb", "lib/ri_cal/core_extensions/time/conversions.rb", "lib/ri_cal/core_extensions/time/week_day_predicates.rb", "lib/ri_cal/invalid_timezone_identifer.rb", "lib/ri_cal/occurrence_enumerator.rb", "lib/ri_cal/parser.rb", "lib/ri_cal/properties/alarm.rb", "lib/ri_cal/properties/calendar.rb", "lib/ri_cal/properties/event.rb", "lib/ri_cal/properties/freebusy.rb", "lib/ri_cal/properties/journal.rb", "lib/ri_cal/properties/timezone.rb", "lib/ri_cal/properties/timezone_period.rb", "lib/ri_cal/properties/todo.rb", "lib/ri_cal/property_value.rb", "lib/ri_cal/property_value/array.rb", "lib/ri_cal/property_value/cal_address.rb", "lib/ri_cal/property_value/date.rb", "lib/ri_cal/property_value/date_time.rb", "lib/ri_cal/property_value/date_time/additive_methods.rb", "lib/ri_cal/property_value/date_time/time_machine.rb", "lib/ri_cal/property_value/date_time/timezone_support.rb", "lib/ri_cal/property_value/duration.rb", "lib/ri_cal/property_value/geo.rb", "lib/ri_cal/property_value/integer.rb", "lib/ri_cal/property_value/occurrence_list.rb", "lib/ri_cal/property_value/period.rb", "lib/ri_cal/property_value/recurrence_rule.rb", "lib/ri_cal/property_value/recurrence_rule/enumeration_support_methods.rb", "lib/ri_cal/property_value/recurrence_rule/enumerator.rb", "lib/ri_cal/property_value/recurrence_rule/initialization_methods.rb", "lib/ri_cal/property_value/recurrence_rule/negative_setpos_enumerator.rb", "lib/ri_cal/property_value/recurrence_rule/numbered_span.rb", "lib/ri_cal/property_value/recurrence_rule/occurence_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/recurring_day.rb", "lib/ri_cal/property_value/recurrence_rule/recurring_month_day.rb", "lib/ri_cal/property_value/recurrence_rule/recurring_numbered_week.rb", "lib/ri_cal/property_value/recurrence_rule/recurring_year_day.rb", "lib/ri_cal/property_value/recurrence_rule/validations.rb", "lib/ri_cal/property_value/text.rb", "lib/ri_cal/property_value/uri.rb", "lib/ri_cal/property_value/utc_offset.rb", "lib/ri_cal/required_timezones.rb", "lib/ri_cal/time_with_floating_timezone.rb", "ri_cal.gemspec", "sample_ical_files/from_ical_dot_app/test1.ics", "script/console", "script/destroy", "script/generate", "script/txt2html", "spec/ri_cal/component/alarm_spec.rb", "spec/ri_cal/component/calendar_spec.rb", "spec/ri_cal/component/event_spec.rb", "spec/ri_cal/component/freebusy_spec.rb", "spec/ri_cal/component/journal_spec.rb", "spec/ri_cal/component/t_z_info_timezone_spec.rb", "spec/ri_cal/component/timezone_spec.rb", "spec/ri_cal/component/todo_spec.rb", "spec/ri_cal/component_spec.rb", "spec/ri_cal/core_extensions/time/calculations_spec.rb", "spec/ri_cal/core_extensions/time/week_day_predicates_spec.rb", "spec/ri_cal/occurrence_enumerator_spec.rb", "spec/ri_cal/parser_spec.rb", "spec/ri_cal/property_value/date_spec.rb", "spec/ri_cal/property_value/date_time_spec.rb", "spec/ri_cal/property_value/duration_spec.rb", "spec/ri_cal/property_value/period_spec.rb", "spec/ri_cal/property_value/recurrence_rule/recurring_year_day_spec.rb", "spec/ri_cal/property_value/recurrence_rule_spec.rb", "spec/ri_cal/property_value/text_spec.rb", "spec/ri_cal/property_value/utc_offset_spec.rb", "spec/ri_cal/property_value_spec.rb", "spec/ri_cal/required_timezones_spec.rb", "spec/ri_cal_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/ri_cal.rake", "tasks/spec.rake"]
24
+ s.has_rdoc = true
25
+ s.homepage = %q{http://rical.rubyforge.org/}
26
+ s.rdoc_options = ["--main", "README.txt"]
27
+ s.require_paths = ["lib"]
28
+ s.rubyforge_project = %q{rical}
29
+ s.rubygems_version = %q{1.3.2}
30
+ s.summary = %q{This is an UNOFFICIAL version}
31
+
32
+ if s.respond_to? :specification_version then
33
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
34
+ s.specification_version = 3
35
+
36
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
37
+ s.add_development_dependency(%q<newgem>, [">= 1.3.0"])
38
+ s.add_development_dependency(%q<hoe>, [">= 1.8.0"])
39
+ else
40
+ s.add_dependency(%q<newgem>, [">= 1.3.0"])
41
+ s.add_dependency(%q<hoe>, [">= 1.8.0"])
42
+ end
43
+ else
44
+ s.add_dependency(%q<newgem>, [">= 1.3.0"])
45
+ s.add_dependency(%q<hoe>, [">= 1.8.0"])
46
+ end
47
+ end
@@ -0,0 +1,38 @@
1
+ BEGIN:VCALENDAR
2
+ METHOD:PUBLISH
3
+ X-WR-TIMEZONE:America/New_York
4
+ PRODID:-//Apple Inc.//iCal 3.0//EN
5
+ CALSCALE:GREGORIAN
6
+ X-WR-CALNAME:test
7
+ VERSION:2.0
8
+ X-WR-RELCALID:1884C7F8-BC8E-457F-94AC-297871967D5E
9
+ X-APPLE-CALENDAR-COLOR:#2CA10B
10
+ BEGIN:VTIMEZONE
11
+ TZID:US/Eastern
12
+ BEGIN:DAYLIGHT
13
+ TZOFFSETFROM:-0500
14
+ TZOFFSETTO:-0400
15
+ DTSTART:20070311T020000
16
+ RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
17
+ TZNAME:EDT
18
+ END:DAYLIGHT
19
+ BEGIN:STANDARD
20
+ TZOFFSETFROM:-0400
21
+ TZOFFSETTO:-0500
22
+ DTSTART:20071104T020000
23
+ RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
24
+ TZNAME:EST
25
+ END:STANDARD
26
+ END:VTIMEZONE
27
+ BEGIN:VEVENT
28
+ SEQUENCE:5
29
+ TRANSP:OPAQUE
30
+ UID:00481E53-9258-4EA7-9F8D-947D3041A3F2
31
+ DTSTART;TZID=US/Eastern:20090224T090000
32
+ DTSTAMP:20090225T000908Z
33
+ SUMMARY:Test Event
34
+ CREATED:20090225T000839Z
35
+ DTEND;TZID=US/Eastern:20090224T100000
36
+ RRULE:FREQ=DAILY;INTERVAL=1;UNTIL=20090228T045959Z
37
+ END:VEVENT
38
+ END:VCALENDAR
data/script/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/ri_cal_newgem.rb'}"
9
+ puts "Loading ri_cal_newgem gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
data/script/txt2html ADDED
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ load File.dirname(__FILE__) + "/../Rakefile"
4
+ require 'rubyforge'
5
+ require 'redcloth'
6
+ require 'syntax/convertors/html'
7
+ require 'erb'
8
+
9
+ download = "http://rubyforge.org/projects/#{$hoe.rubyforge_name}"
10
+ version = $hoe.version
11
+
12
+ def rubyforge_project_id
13
+ RubyForge.new.configure.autoconfig["group_ids"][$hoe.rubyforge_name]
14
+ end
15
+
16
+ class Fixnum #:nodoc:
17
+ def ordinal
18
+ # teens
19
+ return 'th' if (10..19).include?(self % 100)
20
+ # others
21
+ case self % 10
22
+ when 1: return 'st'
23
+ when 2: return 'nd'
24
+ when 3: return 'rd'
25
+ else return 'th'
26
+ end
27
+ end
28
+ end
29
+
30
+ class Time
31
+ def pretty
32
+ return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
33
+ end
34
+ end
35
+
36
+ def convert_syntax(syntax, source)
37
+ return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
38
+ end
39
+
40
+ if ARGV.length >= 1
41
+ src, template = ARGV
42
+ template ||= File.join(File.dirname(__FILE__), '/../website/template.html.erb')
43
+ else
44
+ puts("Usage: #{File.split($0).last} source.txt [template.html.erb] > output.html")
45
+ exit!
46
+ end
47
+
48
+ template = ERB.new(File.open(template).read)
49
+
50
+ title = nil
51
+ body = nil
52
+ File.open(src) do |fsrc|
53
+ title_text = fsrc.readline
54
+ body_text_template = fsrc.read
55
+ body_text = ERB.new(body_text_template).result(binding)
56
+ syntax_items = []
57
+ body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
58
+ ident = syntax_items.length
59
+ element, syntax, source = $1, $2, $3
60
+ syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
61
+ "syntax-temp-#{ident}"
62
+ }
63
+ title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
64
+ body = RedCloth.new(body_text).to_html
65
+ body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
66
+ end
67
+ stat = File.stat(src)
68
+ created = stat.ctime
69
+ modified = stat.mtime
70
+
71
+ $stdout << template.result(binding)
@@ -0,0 +1,13 @@
1
+ #- ©2009 Rick DeNatale
2
+ #- All rights reserved
3
+
4
+ require File.join(File.dirname(__FILE__), %w[.. .. spec_helper])
5
+
6
+ describe RiCal::Component::Alarm do
7
+
8
+ describe ".entity_name" do
9
+ it "should be VALARM" do
10
+ RiCal::Component::Alarm.entity_name.should == "VALARM"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,55 @@
1
+ #- ©2009 Rick DeNatale
2
+ #- All rights reserved
3
+
4
+ require File.join(File.dirname(__FILE__), %w[.. .. spec_helper])
5
+
6
+ describe RiCal::Component::Calendar do
7
+
8
+ context ".entity_name" do
9
+ it "should be VCALENDAR" do
10
+ RiCal::Component::Calendar.entity_name.should == "VCALENDAR"
11
+ end
12
+ end
13
+
14
+ context "a new instance" do
15
+ before(:each) do
16
+ @it = RiCal.Calendar
17
+ end
18
+
19
+ it "should have a tz_source of 'TZ_INFO" do
20
+ @it.tz_source.should == "TZINFO"
21
+ end
22
+
23
+ it "should export a product id with an X-RICAL-TZSOURCE parameter of TZINFO" do
24
+ @it.export.should match(%r{\nPRODID;X-RICAL-TZSOURCE=TZINFO:-//com.denhaven2/NONSGML ri_cal gem//EN\n})
25
+ end
26
+ end
27
+
28
+ context "an imported instance with a tzinfo source" do
29
+ before(:each) do
30
+ @it = RiCal.parse_string("BEGIN:VCALENDAR\nPRODID;X-RICAL-TZSOURCE=TZINFO:-\/\/com.denhaven2\/NONSGML ri_cal gem\/\/EN\nCALSCALE:GREGORIAN\nVERSION:2.0\nEND:VCALENDAR\n").first
31
+ end
32
+
33
+ it "should have a tz_source of 'TZ_INFO" do
34
+ @it.tz_source.should == "TZINFO"
35
+ end
36
+
37
+ it "should export a product id with an X-RICAL-TZSOURCE parameter of TZINFO" do
38
+ @it.export.should match(%r{\nPRODID;X-RICAL-TZSOURCE=TZINFO:-//com.denhaven2/NONSGML ri_cal gem//EN\n})
39
+ end
40
+ end
41
+
42
+ context "an imported instance without a tzinfo source" do
43
+ before(:each) do
44
+ @it = RiCal.parse_string("BEGIN:VCALENDAR\nPRODID:-//Apple Inc.//iCal 3.0//EN\nEND:VCALENDAR\n").first
45
+ end
46
+
47
+ it "should have a tz_source of nil" do
48
+ @it.tz_source.should be_nil
49
+ end
50
+
51
+ it "should export not export a product id with an X-RICAL-TZSOURCE parameter of TZINFO" do
52
+ @it.export.should_not match(%r{X-RICAL-TZSOURCE=TZINFO:})
53
+ end
54
+ end
55
+ end