mumboe-vpim 0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. data/CHANGES +510 -0
  2. data/COPYING +58 -0
  3. data/README +185 -0
  4. data/lib/vpim/address.rb +219 -0
  5. data/lib/vpim/agent/atomize.rb +104 -0
  6. data/lib/vpim/agent/base.rb +73 -0
  7. data/lib/vpim/agent/calendars.rb +173 -0
  8. data/lib/vpim/agent/handler.rb +26 -0
  9. data/lib/vpim/agent/ics.rb +161 -0
  10. data/lib/vpim/attachment.rb +102 -0
  11. data/lib/vpim/date.rb +222 -0
  12. data/lib/vpim/dirinfo.rb +277 -0
  13. data/lib/vpim/duration.rb +119 -0
  14. data/lib/vpim/enumerator.rb +32 -0
  15. data/lib/vpim/field.rb +614 -0
  16. data/lib/vpim/icalendar.rb +384 -0
  17. data/lib/vpim/maker/vcard.rb +16 -0
  18. data/lib/vpim/property/base.rb +193 -0
  19. data/lib/vpim/property/common.rb +315 -0
  20. data/lib/vpim/property/location.rb +38 -0
  21. data/lib/vpim/property/priority.rb +43 -0
  22. data/lib/vpim/property/recurrence.rb +69 -0
  23. data/lib/vpim/property/resources.rb +24 -0
  24. data/lib/vpim/repo.rb +261 -0
  25. data/lib/vpim/rfc2425.rb +367 -0
  26. data/lib/vpim/rrule.rb +591 -0
  27. data/lib/vpim/time.rb +40 -0
  28. data/lib/vpim/vcard.rb +1456 -0
  29. data/lib/vpim/version.rb +18 -0
  30. data/lib/vpim/vevent.rb +187 -0
  31. data/lib/vpim/view.rb +90 -0
  32. data/lib/vpim/vjournal.rb +58 -0
  33. data/lib/vpim/vpim.rb +65 -0
  34. data/lib/vpim/vtodo.rb +103 -0
  35. data/lib/vpim.rb +13 -0
  36. data/samples/README.mutt +93 -0
  37. data/samples/ab-query.rb +57 -0
  38. data/samples/agent.ru +10 -0
  39. data/samples/cmd-itip.rb +156 -0
  40. data/samples/ex_cpvcard.rb +55 -0
  41. data/samples/ex_get_vcard_photo.rb +22 -0
  42. data/samples/ex_mkv21vcard.rb +34 -0
  43. data/samples/ex_mkvcard.rb +64 -0
  44. data/samples/ex_mkyourown.rb +29 -0
  45. data/samples/ics-dump.rb +210 -0
  46. data/samples/ics-to-rss.rb +84 -0
  47. data/samples/mutt-aliases-to-vcf.rb +45 -0
  48. data/samples/osx-wrappers.rb +86 -0
  49. data/samples/reminder.rb +209 -0
  50. data/samples/rrule.rb +71 -0
  51. data/samples/tabbed-file-to-vcf.rb +390 -0
  52. data/samples/vcf-dump.rb +86 -0
  53. data/samples/vcf-lines.rb +61 -0
  54. data/samples/vcf-to-ics.rb +22 -0
  55. data/samples/vcf-to-mutt.rb +121 -0
  56. data/test/test_agent_atomize.rb +84 -0
  57. data/test/test_agent_calendars.rb +128 -0
  58. data/test/test_agent_ics.rb +96 -0
  59. data/test/test_all.rb +17 -0
  60. data/test/test_date.rb +120 -0
  61. data/test/test_dur.rb +41 -0
  62. data/test/test_field.rb +156 -0
  63. data/test/test_ical.rb +437 -0
  64. data/test/test_misc.rb +13 -0
  65. data/test/test_repo.rb +129 -0
  66. data/test/test_rrule.rb +1030 -0
  67. data/test/test_vcard.rb +973 -0
  68. data/test/test_view.rb +79 -0
  69. metadata +140 -0
@@ -0,0 +1,315 @@
1
+ =begin
2
+ Copyright (C) 2008 Sam Roberts
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 'vpim/address'
10
+ require 'vpim/attachment'
11
+
12
+ module Vpim
13
+ class Icalendar
14
+ module Property
15
+
16
+ # Properties common to Vevent, Vtodo, and Vjournal.
17
+ module Common
18
+
19
+ # This property defines the access classification for a calendar
20
+ # component.
21
+ #
22
+ # An access classification is only one component of the general
23
+ # security system within a calendar application. It provides a method
24
+ # of capturing the scope of the access the calendar owner intends for
25
+ # information within an individual calendar entry. The access
26
+ # classification of an individual iCalendar component is useful when
27
+ # measured along with the other security components of a calendar
28
+ # system (e.g., calendar user authentication, authorization, access
29
+ # rights, access role, etc.). Hence, the semantics of the individual
30
+ # access classifications cannot be completely defined by this memo
31
+ # alone. Additionally, due to the "blind" nature of most exchange
32
+ # processes using this memo, these access classifications cannot serve
33
+ # as an enforcement statement for a system receiving an iCalendar
34
+ # object. Rather, they provide a method for capturing the intention of
35
+ # the calendar owner for the access to the calendar component.
36
+ #
37
+ # Property Name: CLASS
38
+ #
39
+ # Property Value: one of "PUBLIC", "PRIVATE", "CONFIDENTIAL", default
40
+ # is "PUBLIC" if no CLASS property is found.
41
+ def access_class
42
+ proptoken 'CLASS', ["PUBLIC", "PRIVATE", "CONFIDENTIAL"], "PUBLIC"
43
+ end
44
+
45
+ def created
46
+ proptime 'CREATED'
47
+ end
48
+
49
+ # Description of the calendar component, or nil if there is no
50
+ # description.
51
+ def description
52
+ proptext 'DESCRIPTION'
53
+ end
54
+
55
+ # Revision sequence number of the calendar component, or nil if there
56
+ # is no SEQUENCE; property.
57
+ def sequence
58
+ propinteger 'SEQUENCE'
59
+ end
60
+
61
+ # The time stamp for this calendar component.
62
+ def dtstamp
63
+ proptime 'DTSTAMP'
64
+ end
65
+
66
+ # The start time for this calendar component.
67
+ def dtstart
68
+ proptime 'DTSTART'
69
+ end
70
+
71
+ def lastmod
72
+ proptime 'LAST-MODIFIED'
73
+ end
74
+
75
+ # Return the event organizer, an object of Icalendar::Address (or nil if
76
+ # there is no ORGANIZER field).
77
+ def organizer
78
+ organizer = @properties.field('ORGANIZER')
79
+
80
+ if organizer
81
+ organizer = Icalendar::Address.decode(organizer)
82
+ end
83
+
84
+ organizer.freeze
85
+ end
86
+
87
+ =begin
88
+ recurid
89
+ seq
90
+ =end
91
+
92
+ # Status values are not rejected during decoding. However, if the
93
+ # status is requested, and it's value is not one of the defined
94
+ # allowable values, an exception is raised.
95
+ def status
96
+ case self
97
+ when Vpim::Icalendar::Vevent
98
+ proptoken 'STATUS', ['TENTATIVE', 'CONFIRMED', 'CANCELLED']
99
+
100
+ when Vpim::Icalendar::Vtodo
101
+ proptoken 'STATUS', ['NEEDS-ACTION', 'COMPLETED', 'IN-PROCESS', 'CANCELLED']
102
+
103
+ when Vpim::Icalendar::Vevent
104
+ proptoken 'STATUS', ['DRAFT', 'FINAL', 'CANCELLED']
105
+ end
106
+ end
107
+
108
+ # TODO - def status? ...
109
+
110
+ # TODO - def status= ...
111
+
112
+ # Summary description of the calendar component, or nil if there is no
113
+ # SUMMARY property.
114
+ def summary
115
+ proptext 'SUMMARY'
116
+ end
117
+
118
+ # The unique identifier of this calendar component, a string.
119
+ def uid
120
+ proptext 'UID'
121
+ end
122
+
123
+ def url
124
+ propvalue 'URL'
125
+ end
126
+
127
+ # Return an array of attendees, an empty array if there are none. The
128
+ # attendees are objects of Icalendar::Address. If +uri+ is specified
129
+ # only the return the attendees with this +uri+.
130
+ def attendees(uri = nil)
131
+ attendees = @properties.enum_by_name('ATTENDEE').map { |a| Icalendar::Address.decode(a) }
132
+ attendees.freeze
133
+ if uri
134
+ attendees.select { |a| a == uri }
135
+ else
136
+ attendees
137
+ end
138
+ end
139
+
140
+ # Return true if the +uri+, usually a mailto: URI, is an attendee.
141
+ def attendee?(uri)
142
+ attendees.include? uri
143
+ end
144
+
145
+ # This property defines the categories for a calendar component.
146
+ #
147
+ # Property Name: CATEGORIES
148
+ #
149
+ # Value Type: TEXT
150
+ #
151
+ # Ruby Type: Array of String
152
+ #
153
+ # This property is used to specify categories or subtypes of the
154
+ # calendar component. The categories are useful in searching for a
155
+ # calendar component of a particular type and category.
156
+ def categories
157
+ proptextlistarray 'CATEGORIES'
158
+ end
159
+
160
+ def comments
161
+ proptextarray 'COMMENT'
162
+ end
163
+
164
+ def contacts
165
+ proptextarray 'CONTACT'
166
+ end
167
+
168
+ # An Array of attachments, see Attachment for more information.
169
+ def attachments
170
+ @properties.enum_by_name('ATTACH').map do |f|
171
+ attachment = Attachment.decode(f, 'uri', 'FMTTYPE')
172
+ end
173
+ end
174
+ end
175
+
176
+ end
177
+
178
+ module Set
179
+
180
+ # Properties common to Vevent, Vtodo, and Vjournal.
181
+ module Common
182
+
183
+ # Set the access class of the component, see Icalendar::Property::Common#access_class.
184
+ def access_class(token)
185
+ set_token 'CLASS', ["PUBLIC", "PRIVATE", "CONFIDENTIAL"], "PUBLIC", token
186
+ end
187
+
188
+ # Set the creation time, see Icalendar::Property::Common#created
189
+ def created(time)
190
+ set_datetime 'CREATED', time
191
+ end
192
+
193
+ # Set the description, see Icalendar::Property::Common#description.
194
+ def description(text)
195
+ set_text 'DESCRIPTION', text
196
+ end
197
+
198
+ # Set the sequence number, see Icalendar::Property::Common#sequence.
199
+ # is no SEQUENCE; property.
200
+ def sequence(int)
201
+ set_integer 'SEQUENCE', int
202
+ end
203
+
204
+ # Set the timestamp, see Icalendar::Property::Common#timestamp.
205
+ def dtstamp(time)
206
+ set_datetime 'DTSTAMP', time
207
+ self
208
+ end
209
+
210
+ # The start time or date, see Icalendar::Property::Common#dtstart.
211
+ def dtstart(start)
212
+ set_date_or_datetime 'DTSTART', 'DATE-TIME', start
213
+ self
214
+ end
215
+
216
+ # Set the last modification time, see Icalendar::Property::Common#lastmod.
217
+ def lastmod(time)
218
+ set_datetime 'LAST-MODIFIED', time
219
+ self
220
+ end
221
+
222
+ # Set the event organizer, an Icalendar::Address, see Icalendar::Property::Common#organizer.
223
+ #
224
+ # Without an +adr+ it yields an Icalendar::Address that is a copy of
225
+ # the current organizer (if any), allowing it to be modified.
226
+ def organizer(adr=nil) #:yield: organizer
227
+ unless adr
228
+ adr = @comp.organizer
229
+ if adr
230
+ adr = adr.copy
231
+ else
232
+ adr = Icalendar::Address.create
233
+ end
234
+ yield adr
235
+ end
236
+ set_address('ORGANIZER', adr)
237
+ self
238
+ end
239
+
240
+ =begin
241
+ # Status values are not rejected during decoding. However, if the
242
+ # status is requested, and it's value is not one of the defined
243
+ # allowable values, an exception is raised.
244
+ def status
245
+ case self
246
+ when Vpim::Icalendar::Vevent
247
+ proptoken 'STATUS', ['TENTATIVE', 'CONFIRMED', 'CANCELLED']
248
+
249
+ when Vpim::Icalendar::Vtodo
250
+ proptoken 'STATUS', ['NEEDS-ACTION', 'COMPLETED', 'IN-PROCESS', 'CANCELLED']
251
+
252
+ when Vpim::Icalendar::Vevent
253
+ proptoken 'STATUS', ['DRAFT', 'FINAL', 'CANCELLED']
254
+ end
255
+ end
256
+ =end
257
+
258
+ # Set summary description of component, see Icalendar::Property::Common#summary.
259
+ def summary(text)
260
+ set_text 'SUMMARY', text
261
+ end
262
+
263
+ # Set the unique identifier of this calendar component, see Icalendar::Property::Common#uid.
264
+ def uid(uid)
265
+ set_text 'UID', uid
266
+ end
267
+
268
+ def url(url)
269
+ set_text 'URL', url
270
+ end
271
+
272
+ # Add an attendee Address, see Icalendar::Property::Common#attendees.
273
+ def add_attendee(adr)
274
+ add_address('ATTENDEE', adr)
275
+ end
276
+
277
+ # Set the categories, see Icalendar::Property::Common#attendees.
278
+ #
279
+ # If +cats+ is provided, the categories are set to cats, either a
280
+ # String or an Array of String. Otherwise, and array of the existing
281
+ # category strings is yielded, and it can be modified.
282
+ def categories(cats = nil) #:yield: categories
283
+ unless cats
284
+ cats = @comp.categories
285
+ yield cats
286
+ end
287
+ # TODO - strip the strings
288
+ set_text_list('CATEGORIES', cats)
289
+ end
290
+
291
+ # Set the comment, see Icalendar::Property::Common#comments.
292
+ def comment(value)
293
+ set_text 'COMMENT', value
294
+ end
295
+
296
+ =begin
297
+ def contacts
298
+ proptextarray 'CONTACT'
299
+ end
300
+
301
+ # An Array of attachments, see Attachment for more information.
302
+ def attachments
303
+ @properties.enum_by_name('ATTACH').map do |f|
304
+ attachment = Attachment.decode(f, 'uri', 'FMTTYPE')
305
+ end
306
+ end
307
+ =end
308
+
309
+ end
310
+
311
+ end
312
+ end
313
+ end
314
+
315
+
@@ -0,0 +1,38 @@
1
+ =begin
2
+ Copyright (C) 2008 Sam Roberts
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 Vpim
10
+ class Icalendar
11
+ module Property
12
+ module Location
13
+ # Physical location information relevant to the component, or nil if
14
+ # there is no LOCATION property.
15
+ def location
16
+ proptext 'LOCATION'
17
+ end
18
+
19
+ # Array of Float, +[ latitude, longitude]+.
20
+ #
21
+ # North of the equator is positive latitude, east of the meridian is
22
+ # positive longitude.
23
+ #
24
+ # See RFC2445 for more info... there are lots of special cases.
25
+ def geo
26
+ prop = @properties.detect { |f| f.name? 'GEO' }
27
+ if prop
28
+ prop = Vpim.decode_list(prop.value_raw, ';') do |item| item.to_f end
29
+ end
30
+ prop
31
+ end
32
+
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+
@@ -0,0 +1,43 @@
1
+ =begin
2
+ Copyright (C) 2008 Sam Roberts
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 Vpim
10
+ class Icalendar
11
+ module Property
12
+ module Priority
13
+
14
+ # +priority+ is a number from 1 to 9, with 1 being the highest
15
+ # priority, 9 being the lowest. 0 means "no priority", equivalent to
16
+ # not specifying the PRIORITY field.
17
+ #
18
+ # The other integer values are reserved by RFC2445.
19
+ #
20
+ # TODO
21
+ # - methods to compare priorities?
22
+ # - return as class Priority, with #to_i, and #to_s, and appropriate
23
+ # comparison operators?
24
+ def priority
25
+ p = @properties.detect { |f| f.name? 'PRIORITY' }
26
+
27
+ if !p
28
+ p = 0
29
+ else
30
+ p = p.value.to_i
31
+
32
+ if( p < 0 || p > 9 )
33
+ raise Vpim::InvalidEncodingError, 'Invalid priority #{@priority} - it must be 0-9!'
34
+ end
35
+ end
36
+ p
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+
@@ -0,0 +1,69 @@
1
+ =begin
2
+ Copyright (C) 2008 Sam Roberts
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 "enumerator"
10
+
11
+ module Vpim
12
+ class Icalendar
13
+ module Property
14
+
15
+ # Occurrences are calculated from DTSTART and RRULE. If there is no
16
+ # RRULE, the component occurs only once, at the start time.
17
+ #
18
+ # Limitations:
19
+ #
20
+ # Only a single RRULE: is currently supported, this is the most common
21
+ # case.
22
+ module Recurrence
23
+ def rrule #:nodoc:
24
+ start = dtstart
25
+ unless start
26
+ raise ArgumentError, "Components without a DTSTART don't have occurrences!"
27
+ end
28
+ Vpim::Rrule.new(start, propvalue('RRULE'))
29
+ end
30
+
31
+ # The times this components occurs. If a block is not provided, returns
32
+ # an enumerator.
33
+ #
34
+ # Occurrences may be infinite, +dountil+ can be provided to limit the
35
+ # iterations, see Rrule#each.
36
+ def occurrences(dountil = nil, &block) #:yield: occurrence time
37
+ rr = rrule
38
+ unless block_given?
39
+ return Enumerable::Enumerator.new(self, :occurrences, dountil)
40
+ end
41
+
42
+ rr.each(dountil, &block)
43
+ end
44
+
45
+ alias occurences occurrences #:nodoc: backwards compatibility
46
+
47
+ # True if this components occurs in a time period later than +t0+, but
48
+ # earlier than +t1+.
49
+ def occurs_in?(t0, t1)
50
+ # TODO - deprecate this, its a hack
51
+ occurrences(t1).detect do |tend|
52
+ if respond_to? :duration
53
+ tend += duration || 0
54
+ end
55
+ tend >= t0
56
+ end
57
+ end
58
+
59
+ def rdates #:nodoc:
60
+ # TODO - this is a hack, remove it
61
+ Vpim.decode_date_time_list(propvalue('RDATE'))
62
+ end
63
+
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+
@@ -0,0 +1,24 @@
1
+ =begin
2
+ Copyright (C) 2008 Sam Roberts
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 Vpim
10
+ class Icalendar
11
+ module Property
12
+
13
+ module Resources
14
+
15
+ def resources
16
+ proptextlistarray 'RESOURCES'
17
+ end
18
+
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+