icalendar 0.95 → 0.96

Sign up to get free protection for your applications and to get access to all the features.
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