icalendar 0.96 → 0.96.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 (77) hide show
  1. data/README +3 -3
  2. data/Rakefile +3 -4
  3. data/docs/api/classes/Array.html +148 -0
  4. data/docs/api/classes/Date.html +159 -0
  5. data/docs/api/classes/DateTime.html +180 -0
  6. data/docs/api/classes/Fixnum.html +148 -0
  7. data/docs/api/classes/Float.html +148 -0
  8. data/docs/api/classes/HashAttrs.html +199 -0
  9. data/docs/api/classes/Icalendar/Alarm.html +228 -0
  10. data/docs/api/classes/Icalendar/Base.html +120 -0
  11. data/docs/api/classes/Icalendar/Calendar.html +365 -0
  12. data/docs/api/classes/Icalendar/Component.html +689 -0
  13. data/docs/api/classes/Icalendar/DateProp.html +187 -0
  14. data/docs/api/classes/Icalendar/DateProp/ClassMethods.html +195 -0
  15. data/docs/api/classes/Icalendar/Daylight.html +156 -0
  16. data/docs/api/classes/Icalendar/Event.html +650 -0
  17. data/docs/api/classes/Icalendar/Freebusy.html +297 -0
  18. data/docs/api/classes/Icalendar/InvalidPropertyValue.html +117 -0
  19. data/docs/api/classes/Icalendar/Journal.html +459 -0
  20. data/docs/api/classes/Icalendar/Parameter.html +166 -0
  21. data/docs/api/classes/Icalendar/Parser.html +447 -0
  22. data/docs/api/classes/Icalendar/Standard.html +156 -0
  23. data/docs/api/classes/Icalendar/Timezone.html +351 -0
  24. data/docs/api/classes/Icalendar/Todo.html +496 -0
  25. data/docs/api/classes/Icalendar/UnknownComponentClass.html +117 -0
  26. data/docs/api/classes/Icalendar/UnknownPropertyMethod.html +117 -0
  27. data/docs/api/classes/Object.html +270 -0
  28. data/docs/api/classes/String.html +148 -0
  29. data/docs/api/classes/Time.html +163 -0
  30. data/docs/api/classes/URI.html +111 -0
  31. data/docs/api/classes/URI/Generic.html +148 -0
  32. data/docs/api/created.rid +1 -0
  33. data/docs/api/files/COPYING.html +163 -0
  34. data/docs/api/files/GPL.html +531 -0
  35. data/docs/api/files/README.html +254 -0
  36. data/docs/api/files/lib/hash_attrs_rb.html +107 -0
  37. data/docs/api/files/lib/icalendar/base_rb.html +108 -0
  38. data/docs/api/files/lib/icalendar/calendar_rb.html +101 -0
  39. data/docs/api/files/lib/icalendar/component/alarm_rb.html +101 -0
  40. data/docs/api/files/lib/icalendar/component/event_rb.html +101 -0
  41. data/docs/api/files/lib/icalendar/component/freebusy_rb.html +101 -0
  42. data/docs/api/files/lib/icalendar/component/journal_rb.html +101 -0
  43. data/docs/api/files/lib/icalendar/component/timezone_rb.html +101 -0
  44. data/docs/api/files/lib/icalendar/component/todo_rb.html +101 -0
  45. data/docs/api/files/lib/icalendar/component_rb.html +101 -0
  46. data/docs/api/files/lib/icalendar/conversions_rb.html +109 -0
  47. data/docs/api/files/lib/icalendar/helpers_rb.html +101 -0
  48. data/docs/api/files/lib/icalendar/parameter_rb.html +101 -0
  49. data/docs/api/files/lib/icalendar/parser_rb.html +109 -0
  50. data/docs/api/files/lib/icalendar_rb.html +120 -0
  51. data/docs/api/files/lib/meta_rb.html +107 -0
  52. data/docs/api/fr_class_index.html +55 -0
  53. data/docs/api/fr_file_index.html +45 -0
  54. data/docs/api/fr_method_index.html +79 -0
  55. data/docs/api/index.html +24 -0
  56. data/docs/api/rdoc-style.css +208 -0
  57. data/{docs/examples → examples}/create_cal.rb +6 -2
  58. data/{docs/examples → examples}/parse_cal.rb +3 -2
  59. data/{docs/examples → examples}/single_event.ics +0 -0
  60. data/lib/hash_attrs.rb +29 -0
  61. data/lib/icalendar.rb +11 -2
  62. data/lib/icalendar/base.rb +6 -2
  63. data/lib/icalendar/calendar.rb +1 -1
  64. data/lib/icalendar/component.rb +98 -71
  65. data/lib/icalendar/component/alarm.rb +5 -3
  66. data/lib/icalendar/component/event.rb +1 -1
  67. data/lib/icalendar/component/freebusy.rb +23 -23
  68. data/lib/icalendar/component/journal.rb +1 -5
  69. data/lib/icalendar/component/timezone.rb +7 -0
  70. data/lib/icalendar/component/todo.rb +1 -6
  71. data/lib/icalendar/conversions.rb +10 -0
  72. data/lib/icalendar/parser.rb +82 -85
  73. data/lib/meta.rb +32 -0
  74. data/test/component_test.rb +69 -64
  75. metadata +74 -12
  76. data/lib/icalendar/foo.rb +0 -394
  77. data/test/property_helpers.rb +0 -35
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: icalendar
5
5
  version: !ruby/object:Gem::Version
6
- version: "0.96"
7
- date: 2005-10-10 00:00:00 +02:00
6
+ version: 0.96.1
7
+ date: 2005-10-31 00:00:00 +01:00
8
8
  summary: A ruby implementation of the iCalendar specification (RFC-2445).
9
9
  require_paths:
10
10
  - lib
@@ -31,19 +31,20 @@ cert_chain:
31
31
  authors:
32
32
  - Jeff Rose
33
33
  files:
34
+ - test/parameter_test.rb
35
+ - test/interactive.rb
36
+ - test/single_event.ics
34
37
  - test/component
35
38
  - test/component_test.rb
36
- - test/single_event.ics
37
- - test/property_helpers.rb
38
39
  - test/simplecal.ics
39
- - test/life.ics
40
40
  - test/calendar_test.rb
41
+ - test/life.ics
41
42
  - test/parser_test.rb
42
- - test/parameter_test.rb
43
- - test/interactive.rb
44
43
  - test/component/event_test.rb
45
44
  - lib/icalendar
45
+ - lib/hash_attrs.rb
46
46
  - lib/icalendar.rb
47
+ - lib/meta.rb
47
48
  - lib/icalendar/component
48
49
  - lib/icalendar/conversions.rb
49
50
  - lib/icalendar/parameter.rb
@@ -52,7 +53,6 @@ files:
52
53
  - lib/icalendar/calendar.rb
53
54
  - lib/icalendar/base.rb
54
55
  - lib/icalendar/parser.rb
55
- - lib/icalendar/foo.rb
56
56
  - lib/icalendar/component/freebusy.rb
57
57
  - lib/icalendar/component/event.rb
58
58
  - lib/icalendar/component/journal.rb
@@ -60,16 +60,78 @@ files:
60
60
  - lib/icalendar/component/timezone.rb
61
61
  - lib/icalendar/component/alarm.rb
62
62
  - docs/rfcs
63
- - docs/examples
63
+ - docs/api
64
64
  - docs/rfcs/rfc2425.pdf
65
65
  - docs/rfcs/rfc2426.pdf
66
66
  - docs/rfcs/rfc2445.pdf
67
67
  - docs/rfcs/rfc2446.pdf
68
68
  - docs/rfcs/rfc2447.pdf
69
69
  - docs/rfcs/rfc3283.txt
70
- - docs/examples/single_event.ics
71
- - docs/examples/create_cal.rb
72
- - docs/examples/parse_cal.rb
70
+ - docs/api/created.rid
71
+ - docs/api/rdoc-style.css
72
+ - docs/api/files
73
+ - docs/api/classes
74
+ - docs/api/fr_file_index.html
75
+ - docs/api/fr_class_index.html
76
+ - docs/api/fr_method_index.html
77
+ - docs/api/index.html
78
+ - docs/api/files/lib
79
+ - docs/api/files/README.html
80
+ - docs/api/files/GPL.html
81
+ - docs/api/files/COPYING.html
82
+ - docs/api/files/lib/hash_attrs_rb.html
83
+ - docs/api/files/lib/icalendar_rb.html
84
+ - docs/api/files/lib/meta_rb.html
85
+ - docs/api/files/lib/icalendar
86
+ - docs/api/files/lib/icalendar/conversions_rb.html
87
+ - docs/api/files/lib/icalendar/parameter_rb.html
88
+ - docs/api/files/lib/icalendar/component_rb.html
89
+ - docs/api/files/lib/icalendar/helpers_rb.html
90
+ - docs/api/files/lib/icalendar/calendar_rb.html
91
+ - docs/api/files/lib/icalendar/base_rb.html
92
+ - docs/api/files/lib/icalendar/parser_rb.html
93
+ - docs/api/files/lib/icalendar/component
94
+ - docs/api/files/lib/icalendar/component/freebusy_rb.html
95
+ - docs/api/files/lib/icalendar/component/event_rb.html
96
+ - docs/api/files/lib/icalendar/component/journal_rb.html
97
+ - docs/api/files/lib/icalendar/component/todo_rb.html
98
+ - docs/api/files/lib/icalendar/component/timezone_rb.html
99
+ - docs/api/files/lib/icalendar/component/alarm_rb.html
100
+ - docs/api/classes/Time.html
101
+ - docs/api/classes/Array.html
102
+ - docs/api/classes/Float.html
103
+ - docs/api/classes/Date.html
104
+ - docs/api/classes/DateTime.html
105
+ - docs/api/classes/Object.html
106
+ - docs/api/classes/Fixnum.html
107
+ - docs/api/classes/String.html
108
+ - docs/api/classes/Icalendar
109
+ - docs/api/classes/URI.html
110
+ - docs/api/classes/URI
111
+ - docs/api/classes/HashAttrs.html
112
+ - docs/api/classes/Icalendar/DateProp.html
113
+ - docs/api/classes/Icalendar/DateProp
114
+ - docs/api/classes/Icalendar/Standard.html
115
+ - docs/api/classes/Icalendar/Journal.html
116
+ - docs/api/classes/Icalendar/Parser.html
117
+ - docs/api/classes/Icalendar/UnknownPropertyMethod.html
118
+ - docs/api/classes/Icalendar/InvalidPropertyValue.html
119
+ - docs/api/classes/Icalendar/UnknownComponentClass.html
120
+ - docs/api/classes/Icalendar/Alarm.html
121
+ - docs/api/classes/Icalendar/Todo.html
122
+ - docs/api/classes/Icalendar/Base.html
123
+ - docs/api/classes/Icalendar/Timezone.html
124
+ - docs/api/classes/Icalendar/Component.html
125
+ - docs/api/classes/Icalendar/Daylight.html
126
+ - docs/api/classes/Icalendar/Event.html
127
+ - docs/api/classes/Icalendar/Calendar.html
128
+ - docs/api/classes/Icalendar/Freebusy.html
129
+ - docs/api/classes/Icalendar/Parameter.html
130
+ - docs/api/classes/Icalendar/DateProp/ClassMethods.html
131
+ - docs/api/classes/URI/Generic.html
132
+ - examples/single_event.ics
133
+ - examples/create_cal.rb
134
+ - examples/parse_cal.rb
73
135
  - Rakefile
74
136
  - README
75
137
  - COPYING
@@ -1,394 +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
- require 'date'
11
- require 'uri'
12
-
13
- module Icalendar
14
- class Parser < Icalendar::Base
15
- # 1*(ALPHA / DIGIT / "=")
16
- NAME = '[-a-z0-9]+'
17
-
18
- # <"> <Any character except CTLs, DQUOTE> <">
19
- QSTR = '"[^"]*"'
20
-
21
- # *<Any character except CTLs, DQUOTE, ";", ":", ",">
22
- PTEXT = '[^";:,]*'
23
-
24
- # param-value = ptext / quoted-string
25
- PVALUE = "#{PTEXT}|#{QSTR}"
26
-
27
- # Contentline
28
- LINE = "(#{NAME})([^:]*)\:(.*)"
29
-
30
- # param = name "=" param-value *("," param-value)
31
- PARAM = ";(#{NAME})(=?)((?:#{PVALUE})(?:,#{PVALUE})*)"
32
-
33
- # date = date-fullyear ["-"] date-month ["-"] date-mday
34
- # date-fullyear = 4 DIGIT
35
- # date-month = 2 DIGIT
36
- # date-mday = 2 DIGIT
37
- DATE = '(\d\d\d\d)-?(\d\d)-?(\d\d)'
38
-
39
- # time = time-hour [":"] time-minute [":"] time-second [time-secfrac] [time-zone]
40
- # time-hour = 2 DIGIT
41
- # time-minute = 2 DIGIT
42
- # time-second = 2 DIGIT
43
- # time-secfrac = "," 1*DIGIT
44
- # time-zone = "Z" / time-numzone
45
- # time-numzome = sign time-hour [":"] time-minute
46
- TIME = '(\d\d):?(\d\d):?(\d\d)(\.\d+)?(Z|[-+]\d\d:?\d\d)?'
47
-
48
- def initialize(src)
49
- @@logger.debug("New Calendar Parser")
50
-
51
- # Setup the parser method hash table
52
- setup_parsers()
53
-
54
- # Define the next line method different depending on whether
55
- # this is a string or an IO object so we can be efficient about
56
- # parsing large files...
57
-
58
- # Just do the unfolding work in one shot if its a whole string
59
- if src.respond_to?(:split)
60
- @lines = []
61
- @index = 0
62
-
63
- puts "String here!!!!!!!!!!!!!!!"
64
- # Split into an array of lines, then unfold those into a new array
65
- src.split(/\r?\n/).each {|line| unfold(@lines, line) }
66
-
67
- # Now that we are unfolded we can just iterate through the array.
68
- # Dynamically define next line for a string.
69
- def next_line
70
- if @index == @lines.size
71
- return nil
72
- else
73
- line = @lines[@index]
74
- @index += 1
75
- return line
76
- end
77
- end
78
-
79
- # If its a file we need to read and unfold on the go to save from reading
80
- # large amounts of data into memory.
81
- elsif src.respond_to?(:gets)
82
- @file = src
83
- @prev_line = src.gets
84
-
85
- # Dynamically define next line for an IO object
86
- def next_line
87
- line = @prev_line
88
-
89
- # Loop through until we get to a non-continuation line...
90
- loop do
91
- nextLine = @file.gets
92
-
93
- unfold(@prev_line, nextLine)
94
- # If it's a continuation line, add it to the last.
95
- # If it's an empty line, drop it from the input.
96
- if( nextLine =~ /^[ \t]/ )
97
- line << nextLine[1, nextLine.size]
98
- elsif( nextLine =~ /^$/ )
99
- else
100
- @prev_line = nextLine
101
- break
102
- end
103
- end
104
- line
105
- end
106
- else
107
- raise ArgumentError, "CalendarParser.new cannot be called with a #{src.class} type!"
108
- end
109
- end
110
-
111
- # Unfold lines of an icalendar file to comply with specification.
112
- def unfold(last, line)
113
-
114
- # Get rid of newlines
115
- unless nextLine.nil?
116
- nextLine.chomp!
117
- end
118
-
119
- # If it's a continuation line, add it to the last.
120
- # If it's an empty line, drop it from the input.
121
- if( line =~ /^[ \t]/ )
122
- last << last.pop + line[1, line.size-1]
123
- elsif( line =~ /^$/ )
124
- else
125
- last << line
126
- end
127
- end
128
-
129
- # Parse the calendar into an object representation
130
- def parse
131
- calendars = []
132
-
133
- # Outer loop for Calendar objects
134
- #@src.each(/\r?\n/) do |line|
135
- while(line = next_line)
136
- fields = parse_line(line)
137
-
138
- # Just iterate through until we find the beginning of a calendar object
139
- if fields[:name] == "BEGIN" and fields[:value] == "VCALENDAR"
140
- cal = parse_component
141
- calendars << cal
142
- end
143
- end
144
-
145
- calendars
146
- end
147
-
148
- private
149
-
150
- # Parse a single VCALENDAR object
151
- # -- This should consist of the PRODID, VERSION, option METHOD & CALSCALE,
152
- # and then one or more calendar components: VEVENT, VTODO, VJOURNAL,
153
- # VFREEBUSY, VTIMEZONE
154
- def parse_component(component = Calendar.new)
155
- while (line = next_line)
156
- fields = parse_line(line)
157
-
158
- name = fields[:name]
159
-
160
- # Although properties are supposed to come before components, we should
161
- # be able to handle them in any order...
162
- if name == "END"
163
- break
164
- elsif name == "BEGIN" # New component
165
- case(fields[:value])
166
- when "VEVENT"
167
- component.events << parse_component(Event.new)
168
- when "VTODO"
169
- component.todos << parse_component(Todo.new)
170
- when "VJOURNAL"
171
- component.journals << parse_component(Journal.new)
172
- when "VFREEBUSY"
173
- component.freebusys << parse_component(Freebusy.new)
174
- when "VTIMEZONE"
175
- component.timezones << parse_component(Timezone.new)
176
- when "VALARM"
177
- component.alarms << parse_component(Alarm.new)
178
- end
179
- else # If its not a component then it should be a property
180
-
181
- # Just set the properties so that the parser can still
182
- # parse invalid files...
183
- @@logger.debug("Setting #{name} => #{fields[:value]}")
184
-
185
- # Lookup the property name to see if we have a string to
186
- # object parser for this property type.
187
- if @parsers.has_key?(name.upcase)
188
- val = @parsers[name.upcase].call(name, fields[:params], fields[:value])
189
- else
190
- val = fields[:value]
191
- end
192
-
193
- if component.multi_property?(name.upcase) && component.properties
194
- val = [val]
195
-
196
- if fields[:params].empty?
197
- params = [nil]
198
- else
199
- params = fields[:params]
200
- end
201
-
202
- if component.properties.has_key?(name)
203
- component.properties[name] += val
204
- component.property_params[name] += params
205
- else
206
- component.properties[name] = val
207
- component.property_params[name] = params
208
- end
209
-
210
- else
211
- component.properties[name] = val
212
-
213
- unless fields[:params].empty?
214
- component.property_params[name] = fields[:params]
215
- end
216
- end
217
- end
218
- end
219
-
220
- component
221
-
222
- end
223
-
224
- def parse_line(line)
225
- unless line =~ %r{#{LINE}}i # Case insensitive match for a valid line
226
- raise "Invalid line in calendar string!"
227
- end
228
-
229
- name = $1.upcase # The case insensitive part is upcased for easier comparison...
230
- paramslist = $2
231
- value = $3
232
-
233
- params = {}
234
-
235
- # Collect the params, if any.
236
- if paramslist.size > 1
237
-
238
- # v3.0 and v2.1 params
239
- paramslist.scan( %r{#{PARAM}}i ) do
240
-
241
- # param names are case-insensitive, and multi-valued
242
- pname = $1
243
- pvals = $3
244
-
245
- # v2.1 pvals have no '=' sign, figure out what kind of param it
246
- # is (either its a known encoding, or we treat it as a 'type'
247
- # param).
248
- if $2 == ""
249
- pvals = $1
250
- case $1
251
- when /quoted-printable/i
252
- pname = 'encoding'
253
-
254
- when /base64/i
255
- pname = 'encoding'
256
-
257
- else
258
- pname = 'type'
259
- end
260
- end
261
-
262
- unless params.key? pname
263
- params[pname] = []
264
- end
265
- pvals.scan( %r{(#{PVALUE})} ) do
266
- if $1.size > 0
267
- params[pname] << $1
268
- end
269
- end
270
- end
271
- end
272
-
273
- {:name => name, :params => params, :value => value}
274
- end
275
-
276
- ## Following is a collection of parsing functions for various
277
- ## icalendar property value data types... First we setup
278
- ## a hash with property names pointing to methods...
279
- def setup_parsers
280
- @parsers = {}
281
-
282
- # Integer properties
283
- m = self.method(:parse_integer)
284
- @parsers["PERCENT-COMPLETE"] = m
285
- @parsers["PRIORITY"] = m
286
- @parsers["REPEAT"] = m
287
- @parsers["SEQUENCE"] = m
288
-
289
- # Dates and Times
290
- m = self.method(:parse_datetime)
291
- @parsers["COMPLETED"] = m
292
- @parsers["DTEND"] = m
293
- @parsers["DUE"] = m
294
- @parsers["DTSTART"] = m
295
- @parsers["RECURRENCE-ID"] = m
296
- @parsers["EXDATE"] = m
297
- @parsers["RDATE"] = m
298
- @parsers["CREATED"] = m
299
- @parsers["DTSTAMP"] = m
300
- @parsers["LAST-MODIFIED"] = m
301
-
302
- # URI's
303
- m = self.method(:parse_uri)
304
- @parsers["TZURL"] = m
305
- @parsers["ATTENDEE"] = m
306
- @parsers["ORGANIZER"] = m
307
- @parsers["URL"] = m
308
-
309
- # This is a URI by default, and if its not a valid URI
310
- # it will be returned as a string which works for binary data
311
- # the other possible type.
312
- @parsers["ATTACH"] = m
313
-
314
- # GEO
315
- m = self.method(:parse_geo)
316
- @parsers["GEO"] = m
317
-
318
- end
319
-
320
- # Booleans
321
- # NOTE: It appears that although this is a valid data type
322
- # there aren't any properties that use it... Maybe get
323
- # rid of this in the future.
324
- def parse_boolean(name, params, value)
325
- if value.upcase == "FALSE"
326
- false
327
- else
328
- true
329
- end
330
- end
331
-
332
- # Dates, Date-Times & Times
333
- # NOTE: invalid dates & times will be returned as strings...
334
- def parse_datetime(name, params, value)
335
- begin
336
- DateTime.parse(value)
337
- rescue Exception
338
- value
339
- end
340
-
341
- end
342
-
343
- # Durations
344
- # TODO: Need to figure out the best way to represent durations
345
- # so just returning string for now.
346
- def parse_duration(name, params, value)
347
- value
348
- end
349
-
350
- # Floats
351
- # NOTE: returns 0.0 if it can't parse the value
352
- def parse_float(name, params, value)
353
- value.to_f
354
- end
355
-
356
- # Integers
357
- # NOTE: returns 0 if it can't parse the value
358
- def parse_integer(name, params, value)
359
- value.to_i
360
- end
361
-
362
- # Periods
363
- # TODO: Got to figure out how to represent periods also...
364
- def parse_period(name, params, value)
365
- value
366
- end
367
-
368
- # Calendar Address's & URI's
369
- # NOTE: invalid URI's will be returned as strings...
370
- def parse_uri(name, params, value)
371
- begin
372
- URI.parse(value)
373
- rescue Exception
374
- value
375
- end
376
- end
377
-
378
- # Geographical location (GEO)
379
- # NOTE: returns an array with two floats (long & lat)
380
- # if the parsing fails return the string
381
- def parse_geo(name, params, value)
382
- strloc = value.split(';')
383
- if strloc.size != 2
384
- return value
385
- end
386
-
387
- val = []
388
- val[0] = strloc[0].to_f
389
- val[1] = strloc[1].to_f
390
- val
391
- end
392
-
393
- end
394
- end