icalendar 0.95 → 0.96

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 (64) hide show
  1. data/README +9 -4
  2. data/Rakefile +4 -3
  3. data/docs/examples/parse_cal.rb +1 -1
  4. data/lib/icalendar/calendar.rb +15 -51
  5. data/lib/icalendar/component.rb +75 -21
  6. data/lib/icalendar/component/event.rb +60 -11
  7. data/lib/icalendar/component/timezone.rb +31 -7
  8. data/lib/icalendar/component/todo.rb +1 -1
  9. data/lib/icalendar/conversions.rb +3 -1
  10. data/lib/icalendar/foo.rb +394 -0
  11. data/lib/icalendar/parser.rb +29 -22
  12. data/test/calendar_test.rb +37 -37
  13. data/test/component/event_test.rb +1 -1
  14. data/test/component_test.rb +56 -56
  15. data/test/interactive.rb +15 -0
  16. data/test/life.ics +45 -0
  17. data/test/parameter_test.rb +20 -0
  18. metadata +23 -70
  19. data/docs/api/classes/Array.html +0 -146
  20. data/docs/api/classes/Date.html +0 -157
  21. data/docs/api/classes/DateTime.html +0 -178
  22. data/docs/api/classes/Fixnum.html +0 -146
  23. data/docs/api/classes/Float.html +0 -146
  24. data/docs/api/classes/Icalendar/Alarm.html +0 -184
  25. data/docs/api/classes/Icalendar/Base.html +0 -118
  26. data/docs/api/classes/Icalendar/Calendar.html +0 -411
  27. data/docs/api/classes/Icalendar/Component.html +0 -306
  28. data/docs/api/classes/Icalendar/DateProp.html +0 -187
  29. data/docs/api/classes/Icalendar/DateProp/ClassMethods.html +0 -195
  30. data/docs/api/classes/Icalendar/Event.html +0 -202
  31. data/docs/api/classes/Icalendar/Freebusy.html +0 -157
  32. data/docs/api/classes/Icalendar/InvalidComponentClass.html +0 -117
  33. data/docs/api/classes/Icalendar/InvalidPropertyValue.html +0 -117
  34. data/docs/api/classes/Icalendar/Journal.html +0 -190
  35. data/docs/api/classes/Icalendar/Parameter.html +0 -166
  36. data/docs/api/classes/Icalendar/Parser.html +0 -447
  37. data/docs/api/classes/Icalendar/Timezone.html +0 -197
  38. data/docs/api/classes/Icalendar/Todo.html +0 -199
  39. data/docs/api/classes/String.html +0 -160
  40. data/docs/api/classes/Time.html +0 -161
  41. data/docs/api/created.rid +0 -1
  42. data/docs/api/files/COPYING.html +0 -163
  43. data/docs/api/files/GPL.html +0 -531
  44. data/docs/api/files/README.html +0 -241
  45. data/docs/api/files/lib/icalendar/base_rb.html +0 -108
  46. data/docs/api/files/lib/icalendar/calendar_rb.html +0 -101
  47. data/docs/api/files/lib/icalendar/component/alarm_rb.html +0 -101
  48. data/docs/api/files/lib/icalendar/component/event_rb.html +0 -101
  49. data/docs/api/files/lib/icalendar/component/freebusy_rb.html +0 -101
  50. data/docs/api/files/lib/icalendar/component/journal_rb.html +0 -101
  51. data/docs/api/files/lib/icalendar/component/timezone_rb.html +0 -101
  52. data/docs/api/files/lib/icalendar/component/todo_rb.html +0 -101
  53. data/docs/api/files/lib/icalendar/component_rb.html +0 -101
  54. data/docs/api/files/lib/icalendar/conversions_rb.html +0 -108
  55. data/docs/api/files/lib/icalendar/helpers_rb.html +0 -101
  56. data/docs/api/files/lib/icalendar/parameter_rb.html +0 -101
  57. data/docs/api/files/lib/icalendar/parser_rb.html +0 -109
  58. data/docs/api/files/lib/icalendar_rb.html +0 -118
  59. data/docs/api/fr_class_index.html +0 -48
  60. data/docs/api/fr_file_index.html +0 -43
  61. data/docs/api/fr_method_index.html +0 -63
  62. data/docs/api/index.html +0 -24
  63. data/docs/api/rdoc-style.css +0 -208
  64. data/lib/icalendar/#helpers.rb# +0 -92
data/README CHANGED
@@ -56,8 +56,8 @@ Now for some examples:
56
56
  # Create a calendar with a single event (Method 3)
57
57
  cal3 = Icalendar::Calendar.new
58
58
  cal3.event do
59
- user_id "joe-bob@somewhere.net"
60
- event.timestamp DateTime.now
59
+ user_id "joe-bob@somewhere.net"
60
+ timestamp DateTime.now
61
61
  end
62
62
 
63
63
  # We can output the calendars as strings to write to a file,
@@ -88,17 +88,22 @@ Now for some examples:
88
88
 
89
89
  begin
90
90
  require 'rubygems'
91
- require_gem 'icalendar', ">= 0.95"
91
+ require_gem 'icalendar', ">= 0.96"
92
92
  rescue LoadError
93
93
  require 'icalendar'
94
94
  end
95
95
 
96
96
  == Download
97
97
 
98
- The latest version of this library can be found at
98
+ The latest release version of this library can be found at
99
99
 
100
100
  * http://rubyforge.org/projects/icalendar/
101
101
 
102
+ If you would like to help with development or use the most current version
103
+ you can check out the tree from the subversion repository:
104
+
105
+ * svn co https://rosejn.net/svn/icalendar icalendar
106
+
102
107
  Documentation can be found at
103
108
 
104
109
  * http://icalendar.rubyforge.org/
data/Rakefile CHANGED
@@ -3,7 +3,7 @@ require 'rake'
3
3
  require 'rake/testtask'
4
4
  require 'rake/rdoctask'
5
5
 
6
- PKG_VERSION = "0.95"
6
+ PKG_VERSION = "0.96"
7
7
 
8
8
  $VERBOSE = nil
9
9
  TEST_CHANGES_SINCE = Time.now - 600 # Recent tests = changed in last 10 minutes
@@ -47,8 +47,9 @@ Rake::RDocTask.new(:doc) { |rdoc|
47
47
  rdoc.rdoc_files.include('GPL', 'COPYING')
48
48
  rdoc.rdoc_dir = 'docs/api'
49
49
  rdoc.title = "iCalendar -- Internet Calendaring for Ruby"
50
- rdoc.options << "--include examples/ --line-numbers --inline-source "
51
- rdoc.options << ""
50
+ rdoc.options << "--include examples/ --line-numbers --inline-source --diagram "
51
+ #rdoc.options << "--accessor=ical_property=iCalendar property,ical_multi_property=iCalendar property where multiple instances can occur"
52
+ rdoc.options << "--accessor=ical_property,ical_multi_property"
52
53
  }
53
54
 
54
55
  Gem::manage_gems
@@ -5,7 +5,7 @@ require 'icalendar'
5
5
  require 'date'
6
6
 
7
7
  # Open a file or string to parse
8
- cal_file = File.open("single_event.ics")
8
+ cal_file = File.open("../../test/life.ics")
9
9
 
10
10
  # Parser returns an array of calendars because a single file
11
11
  # can have multiple calendar objects.
@@ -8,37 +8,29 @@
8
8
 
9
9
  module Icalendar
10
10
 
11
-
12
11
  class Calendar < Component
13
- attr_accessor :events, :todos, :journals, :freebusys, :timezones
12
+ ical_component :events, :todos, :journals, :freebusys, :timezones
14
13
 
15
14
  ical_property :calscale, :calendar_scale
16
15
  ical_property :prodid, :product_id
17
16
  ical_property :version
18
17
  ical_property :method
19
-
18
+
20
19
  def initialize()
21
20
  super("VCALENDAR")
22
21
  @properties = {}
23
22
  @property_params = {}
24
-
25
- @events = []
26
- @todos = []
27
- @journals = []
28
- @freebusys = []
29
- @timezones = []
30
-
23
+
31
24
  # Set some defaults
32
25
  self.calscale = "GREGORIAN" # Who knows, but this is the only one in the spec.
33
26
  self.prodid = "iCalendar-Ruby" # Current product... Should be overwritten
34
27
  self.version = "2.0" # Version of the specification
35
-
36
28
  end
37
29
 
38
30
  def event(&block)
39
31
  e = Event.new
40
- self.add e
41
-
32
+ self.add_component e
33
+
42
34
  e.instance_eval &block if block
43
35
 
44
36
  e
@@ -46,8 +38,8 @@ module Icalendar
46
38
 
47
39
  def todo(&block)
48
40
  e = Todo.new
49
- self.add e
50
-
41
+ self.add_component e
42
+
51
43
  e.instance_eval &block if block
52
44
 
53
45
  e
@@ -55,8 +47,8 @@ module Icalendar
55
47
 
56
48
  def journal(&block)
57
49
  e = Journal.new
58
- self.add e
59
-
50
+ self.add_component e
51
+
60
52
  e.instance_eval &block if block
61
53
 
62
54
  e
@@ -64,8 +56,8 @@ module Icalendar
64
56
 
65
57
  def freebusy(&block)
66
58
  e = Freebusy.new
67
- self.add e
68
-
59
+ self.add_component e
60
+
69
61
  e.instance_eval &block if block
70
62
 
71
63
  e
@@ -73,40 +65,12 @@ module Icalendar
73
65
 
74
66
  def timezone(&block)
75
67
  e = Timezone.new
76
- self.add e
77
-
68
+ self.add_component e
69
+
78
70
  e.instance_eval &block if block
79
71
 
80
72
  e
81
73
  end
74
+ end # class Calendar
82
75
 
83
-
84
- #TODO: Implement the rest of these ^ methods for todo etc...
85
-
86
- def add(component)
87
- if component.is_a? Event
88
- @events << component
89
- elsif component.is_a? Todo
90
- @todos << component
91
- elsif component.is_a? Journal
92
- @journals << component
93
- elsif component.is_a? Freebusy
94
- @freebusys << component
95
- elsif component.is_a? Timezone
96
- @timezones << component
97
- else
98
- raise InvalidComponentClass
99
- end
100
- end
101
-
102
- def to_ical
103
- print_string do |s|
104
- @events.each { |event| s << event.to_ical }
105
- @todos.each { |todo| s << todo.to_ical }
106
- @journals.each { |journal| s << journal.to_ical }
107
- @freebusys.each { |freebusy| s << freebusy.to_ical }
108
- @timezones.each { |timezone| s << timezone.to_ical }
109
- end
110
- end
111
- end
112
- end
76
+ end # module Icalendar
@@ -6,6 +6,8 @@
6
6
  details.
7
7
  =end
8
8
 
9
+ require 'breakpoint'
10
+
9
11
  module Icalendar
10
12
  # The body of the iCalendar object consists of a sequence of calendar
11
13
  # properties and one or more calendar components. The calendar
@@ -22,15 +24,35 @@ module Icalendar
22
24
 
23
25
  def initialize(name)
24
26
  @name = name
27
+ @components = Hash.new([])
25
28
  @properties = {}
26
29
  @property_params = {}
27
30
 
28
31
  @@logger.info("New #{@name[1,@name.size].capitalize}...")
29
32
  end
30
-
33
+
34
+ # Add a sub-component to the current component object.
35
+ def add_component(component)
36
+ key = (component.class.to_s.downcase + 's').gsub('icalendar::', '').to_sym
37
+
38
+ unless @components.has_key? key
39
+ @components[key] = []
40
+ end
41
+
42
+ @components[key] << component
43
+ end
44
+
45
+ def to_ical
46
+ print_string do |s|
47
+ @components.each_value do |comps|
48
+ comps.each { |component| s << component.to_ical }
49
+ end
50
+ end
51
+ end
52
+
31
53
  def print_string
32
54
  s = ""
33
-
55
+
34
56
  # Begin a new component
35
57
  s << "BEGIN:#{@name.upcase}\r\n"
36
58
 
@@ -39,14 +61,14 @@ module Icalendar
39
61
  @properties.each do |key,value|
40
62
  # Property name
41
63
  s << "#{key.upcase}"
42
-
64
+
43
65
  # Possible parameters
44
66
  if @property_params.has_key?(key)
45
67
  params = @property_params[key]
46
68
  params.each do |key,val|
47
69
  s << ";#{key}"
48
70
  val = [ val ] unless val.respond_to?(:to_ary)
49
-
71
+
50
72
  # Possible parameter values
51
73
  unless val.empty?
52
74
  s << "="
@@ -67,7 +89,7 @@ module Icalendar
67
89
 
68
90
  # Any custom body of the derived component
69
91
  yield(s)
70
-
92
+
71
93
  # End of this component
72
94
  s << "END:#{@name.upcase}\r\n"
73
95
  end
@@ -81,9 +103,41 @@ module Icalendar
81
103
  @@multi_properties.has_key?(name)
82
104
  end
83
105
 
106
+ private
107
+
108
+ def Component.hash_reader(hash, syms)
109
+ syms.each do |id|
110
+ class_eval <<-"stop"
111
+ def #{id.to_s.downcase}
112
+ return @#{hash.to_s}[:#{id.to_s.downcase}]
113
+ end
114
+ stop
115
+ puts "Creating method: #{id.to_s.downcase}"
116
+ end
117
+ end
118
+
119
+ def Component.hash_writer(hash, syms)
120
+ syms.each do |id|
121
+ class_eval <<-"stop"
122
+ def #{id.to_s.downcase}=(val)
123
+ return @#{hash.to_s}[:#{id.to_s.downcase}] = val
124
+ end
125
+ stop
126
+ end
127
+ end
128
+
129
+ def Component.hash_attr(hash, syms)
130
+ hash_reader(hash, syms)
131
+ hash_writer(hash, syms)
132
+ end
133
+
84
134
  # Make it protected so we can monitor usage...
85
135
  protected
86
136
 
137
+ def Component.ical_component(*syms)
138
+ hash_attr :components, syms
139
+ end
140
+
87
141
  # Define a set of methods supporting a new property
88
142
  def Component.ical_property(property, alias_name = nil, prop_name = nil)
89
143
  property = "#{property}".strip.downcase
@@ -94,7 +148,7 @@ module Icalendar
94
148
 
95
149
  # If a prop_name was given then we use that for the actual storage
96
150
  property = "#{prop_name}".strip.upcase unless prop_name.nil?
97
-
151
+
98
152
  # Change underscores in property name to a dash
99
153
  property[/_/] = '-' if property =~ /_/
100
154
 
@@ -112,35 +166,35 @@ module Icalendar
112
166
  end
113
167
  code
114
168
 
115
- class_eval code, "component.rb", 124
169
+ class_eval code, "component.rb", 155
116
170
 
117
171
  alias_method("#{alias_name}", "#{getter}") unless alias_name.nil?
118
172
  end
119
173
 
120
174
  unless instance_methods.include? setter
121
175
  code = <<-code
122
- def #{setter} a
123
- unless a.respond_to?(:to_ical)
176
+ def #{setter}(val)
177
+ unless val.respond_to?(:to_ical)
124
178
  raise(NotImplementedError, "Property value does not support to_ical method!")
125
179
  end
126
-
127
- @properties["#{property}"] = a
180
+
181
+ @properties["#{property}"] = val
128
182
  end
129
183
  code
130
-
131
- class_eval code, "component.rb", 134
184
+
185
+ class_eval code, "component.rb", 171
132
186
 
133
187
  alias_method("#{alias_name}=", "#{setter}") unless alias_name.nil?
134
188
  end
135
-
189
+
136
190
  unless instance_methods.include? query
137
191
  code = <<-code
138
192
  def #{query}
139
193
  @properties.has_key?("#{property}")
140
194
  end
141
195
  code
142
-
143
- class_eval code, "component.rb", 144
196
+
197
+ class_eval code, "component.rb", 183
144
198
 
145
199
  alias_method("#{alias_name}\?", "#{query}") unless alias_name.nil?
146
200
  end
@@ -195,16 +249,16 @@ module Icalendar
195
249
 
196
250
  @properties["#{property}"] = a.to_ary
197
251
 
198
-
252
+
199
253
  else
200
254
  raise ArgumentError, "#{getter} is a multi-property that must be an array! Use the #{adder} method to add single entries."
201
255
  end
202
256
  end
203
257
  code
204
-
258
+
205
259
  class_eval code, "component.rb", 198
206
260
  end
207
-
261
+
208
262
  # Query for any of these properties
209
263
  unless instance_methods.include? query
210
264
  code = <<-code
@@ -212,7 +266,7 @@ module Icalendar
212
266
  @properties.has_key?("#{property}")
213
267
  end
214
268
  code
215
-
269
+
216
270
  class_eval code, "component.rb", 210
217
271
  end
218
272
 
@@ -223,7 +277,7 @@ module Icalendar
223
277
  unless a.respond_to?(:to_ical)
224
278
  raise(NotImplementedError, "Property value object does not support to_ical method!")
225
279
  end
226
-
280
+
227
281
  if @properties.has_key?("#{property}")
228
282
  @properties["#{property}"] << a
229
283
  else
@@ -14,55 +14,104 @@ module Icalendar
14
14
  # 8:00 AM to 9:00 AM, tomorrow. Generally, an event will take up time
15
15
  # on an individual calendar.
16
16
  class Event < Component
17
- attr_accessor :alarms
17
+ ical_component :alarms
18
18
 
19
- # Single properties
20
- ical_property :klass, nil, :class
19
+ ## Single instance properties
20
+
21
+ # Access classification (PUBLIC, PRIVATE, CONFIDENTIAL...)
22
+ ical_property :klass, nil, :class
23
+
24
+ # Date & time of creation
21
25
  ical_property :created
26
+
27
+ # Complete description of the calendar component
22
28
  ical_property :description
29
+
30
+ # Specifies date-time when calendar component begins
23
31
  ical_property :dtstart, :start
32
+
33
+ # Latitude & longitude for specified activity
24
34
  ical_property :geo
35
+
36
+ # Date & time this item was last modified
25
37
  ical_property :last_mod, :last_modification
38
+
39
+ # Specifies the intended venue for this activity
26
40
  ical_property :location
41
+
42
+ # Defines organizer of this item
27
43
  ical_property :organizer
44
+
45
+ # Defines relative priority for this item (1-9... 1 = best)
28
46
  ical_property :priority
47
+
48
+ # Indicate date & time when this item was created
29
49
  ical_property :dtstamp, :timestamp
50
+
51
+ # Revision sequence number for this item
30
52
  ical_property :seq, :sequence
53
+
54
+ # Defines overall status or confirmation of this item
31
55
  ical_property :status
32
56
  ical_property :summary
33
57
  ical_property :transp, :transparency
58
+
59
+ # Defines a persistent, globally unique id for this item
34
60
  ical_property :uid, :user_id
61
+
62
+ # Defines a URL associated with this item
35
63
  ical_property :url
36
64
  ical_property :recurid, :recurrence_id
37
65
 
38
- # Single but mutually exclusive TODO: not testing anything yet
66
+ ## Single but mutually exclusive properties (Not testing though)
67
+
68
+ # Specifies a date and time that this item ends
39
69
  ical_property :dtend, :end
70
+
71
+ # Specifies a positive duration time
40
72
  ical_property :duration
41
73
 
42
- # Multi-properties
74
+ ## Multi-instance properties
75
+
76
+ # Associates a URI or binary blob with this item
43
77
  ical_multi_property :attach, :attachment, :attachments
78
+
79
+ # Defines an attendee for this calendar item
44
80
  ical_multi_property :attendee, :attendee, :attendees
81
+
82
+ # Defines the categories for a calendar component (school, work...)
45
83
  ical_multi_property :categories, :category, :categories
84
+
85
+ # Simple comment for the calendar user.
46
86
  ical_multi_property :comment, :comment, :comments
87
+
88
+ # Contact information associated with this item.
47
89
  ical_multi_property :contact, :contact, :contacts
48
90
  ical_multi_property :exdate, :exception_date, :exception_dates
49
91
  ical_multi_property :exrule, :exception_rule, :exception_rules
50
92
  ical_multi_property :rstatus, :request_status, :request_statuses
93
+
94
+ # Used to represent a relationship between two calendar items
51
95
  ical_multi_property :related_to, :related_to, :related_tos
52
96
  ical_multi_property :resources, :resource, :resources
97
+
98
+ # Used with the UID & SEQUENCE to identify a specific instance of a
99
+ # recurring calendar item.
53
100
  ical_multi_property :rdate, :recurrence_date, :recurrence_dates
54
101
  ical_multi_property :rrule, :recurrence_rule, :recurrence_rules
55
102
 
56
103
  def initialize()
57
104
  super("VEVENT")
58
-
59
- @alarms = []
60
105
  end
61
106
 
62
- def to_ical
63
- print_string do |s|
64
- @alarms.each { |alarm| s << alarm.to_ical }
65
- end
107
+ def alarm(&block)
108
+ a = Alarm.new
109
+ self.add a
110
+
111
+ a.instance_eval &block if block
112
+
113
+ a
66
114
  end
115
+
67
116
  end
68
117
  end