zimbra-soap-api 0.0.7.9

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 (66) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.irbrc +6 -0
  4. data/Gemfile +6 -0
  5. data/README +21 -0
  6. data/Rakefile +1 -0
  7. data/lib/zimbra.rb +94 -0
  8. data/lib/zimbra/account.rb +94 -0
  9. data/lib/zimbra/acl.rb +63 -0
  10. data/lib/zimbra/alias.rb +4 -0
  11. data/lib/zimbra/appointment.rb +274 -0
  12. data/lib/zimbra/appointment/alarm.rb +101 -0
  13. data/lib/zimbra/appointment/attendee.rb +97 -0
  14. data/lib/zimbra/appointment/invite.rb +360 -0
  15. data/lib/zimbra/appointment/recur_exception.rb +83 -0
  16. data/lib/zimbra/appointment/recur_rule.rb +184 -0
  17. data/lib/zimbra/appointment/reply.rb +91 -0
  18. data/lib/zimbra/auth.rb +46 -0
  19. data/lib/zimbra/base.rb +217 -0
  20. data/lib/zimbra/calendar.rb +27 -0
  21. data/lib/zimbra/common_elements.rb +51 -0
  22. data/lib/zimbra/cos.rb +124 -0
  23. data/lib/zimbra/delegate_auth_token.rb +49 -0
  24. data/lib/zimbra/directory.rb +175 -0
  25. data/lib/zimbra/distribution_list.rb +147 -0
  26. data/lib/zimbra/domain.rb +63 -0
  27. data/lib/zimbra/ext/handsoap_curb_driver.rb +21 -0
  28. data/lib/zimbra/ext/hash.rb +72 -0
  29. data/lib/zimbra/ext/string.rb +10 -0
  30. data/lib/zimbra/extra/date_helpers.rb +111 -0
  31. data/lib/zimbra/folder.rb +100 -0
  32. data/lib/zimbra/handsoap_account_service.rb +44 -0
  33. data/lib/zimbra/handsoap_service.rb +75 -0
  34. data/lib/zimbra/version.rb +3 -0
  35. data/spec/fixtures/xml_api_requests/appointments/create.xml +84 -0
  36. data/spec/fixtures/xml_api_responses/alarms/15_minutes_before.xml +26 -0
  37. data/spec/fixtures/xml_api_responses/alarms/using_all_intervals.xml +26 -0
  38. data/spec/fixtures/xml_api_responses/appointments/appointment_response_1.xml +40 -0
  39. data/spec/fixtures/xml_api_responses/attendees/one_attendee_and_one_reply.xml +27 -0
  40. data/spec/fixtures/xml_api_responses/attendees/three_attendees_response_1.xml +30 -0
  41. data/spec/fixtures/xml_api_responses/multiple_invites/recurring_with_exceptions.xml +109 -0
  42. data/spec/fixtures/xml_api_responses/recur_rules/day_27_of_every_2_months.xml +27 -0
  43. data/spec/fixtures/xml_api_responses/recur_rules/every_2_days.xml +26 -0
  44. data/spec/fixtures/xml_api_responses/recur_rules/every_3_weeks_on_tuesday_and_friday.xml +30 -0
  45. data/spec/fixtures/xml_api_responses/recur_rules/every_day_50_instances.xml +27 -0
  46. data/spec/fixtures/xml_api_responses/recur_rules/every_monday_wednesday_friday.xml +31 -0
  47. data/spec/fixtures/xml_api_responses/recur_rules/every_tuesday.xml +29 -0
  48. data/spec/fixtures/xml_api_responses/recur_rules/every_weekday_with_end_date.xml +34 -0
  49. data/spec/fixtures/xml_api_responses/recur_rules/every_year_on_february_2.xml +28 -0
  50. data/spec/fixtures/xml_api_responses/recur_rules/first_day_of_every_month.xml +36 -0
  51. data/spec/fixtures/xml_api_responses/recur_rules/first_monday_of_every_february.xml +31 -0
  52. data/spec/fixtures/xml_api_responses/recur_rules/first_weekend_day_of_every_month.xml +31 -0
  53. data/spec/fixtures/xml_api_responses/recur_rules/last_day_of_every_month.xml +36 -0
  54. data/spec/fixtures/xml_api_responses/recur_rules/second_day_of_every_2_months.xml +36 -0
  55. data/spec/fixtures/xml_api_responses/recur_rules/second_wednesday_of_every_month.xml +29 -0
  56. data/spec/fixtures/xml_api_responses/recur_rules/weekly_with_an_exception.xml +44 -0
  57. data/spec/spec_helper.rb +32 -0
  58. data/spec/zimbra/acl_spec.rb +11 -0
  59. data/spec/zimbra/appointment/alarm_spec.rb +33 -0
  60. data/spec/zimbra/appointment/invite_spec.rb +62 -0
  61. data/spec/zimbra/appointment/recur_rule_spec.rb +307 -0
  62. data/spec/zimbra/appointment_spec.rb +175 -0
  63. data/spec/zimbra/common_elements_spec.rb +33 -0
  64. data/spec/zimbra/distribution_list_spec.rb +54 -0
  65. data/zimbra.gemspec +28 -0
  66. metadata +197 -0
@@ -0,0 +1,101 @@
1
+ module Zimbra
2
+ class Appointment
3
+ class Alarm
4
+ class << self
5
+ def new_from_zimbra_attributes(zimbra_attributes)
6
+ new(parse_zimbra_attributes(zimbra_attributes))
7
+ end
8
+
9
+ # <alarm action="DISPLAY">
10
+ # <trigger>
11
+ # <rel neg="1" m="5" related="START"/>
12
+ # </trigger>
13
+ # <desc/>
14
+ # </alarm>
15
+ def parse_zimbra_attributes(zimbra_attributes)
16
+ attrs = { appointment_invite: zimbra_attributes[:appointment_invite] }
17
+ zimbra_attributes = Zimbra::Hash.symbolize_keys(zimbra_attributes.dup, true)
18
+ zimbra_attributes = zimbra_attributes[:trigger][:rel][:attributes]
19
+
20
+ duration_negative = (zimbra_attributes[:neg] && zimbra_attributes[:neg] == 1) ? true : false
21
+
22
+ attrs.merge({
23
+ duration_negative: duration_negative,
24
+ weeks: zimbra_attributes[:w],
25
+ days: zimbra_attributes[:d],
26
+ hours: zimbra_attributes[:h],
27
+ minutes: zimbra_attributes[:m],
28
+ seconds: zimbra_attributes[:s],
29
+ when: zimbra_attributes[:related] == "START" ? :start : :end,
30
+ repeat_count: zimbra_attributes[:count],
31
+ })
32
+ end
33
+ end
34
+
35
+ ATTRS = [:appointment_invite, :duration_negative, :weeks, :days, :hours, :minutes, :seconds, :when, :repeat_count] unless const_defined?(:ATTRS)
36
+
37
+ attr_accessor *ATTRS
38
+
39
+ def initialize(args = {})
40
+ @duration_negative = true
41
+ @when = :start
42
+ self.attributes = args
43
+ end
44
+
45
+ # take attributes by the xml name or our more descriptive name
46
+ def attributes=(args = {})
47
+ ATTRS.each do |attr_name|
48
+ if args.has_key?(attr_name)
49
+ self.send(:"#{attr_name}=", args[attr_name])
50
+ elsif args.has_key?(attr_name.to_s)
51
+ self.send(:"#{attr_name}=", args[attr_name.to_s])
52
+ end
53
+ end
54
+ end
55
+
56
+ def to_hash(options = {})
57
+ hash = ATTRS.inject({}) do |attr_hash, attr_name|
58
+ attr_hash[attr_name] = self.send(:"#{attr_name}")
59
+ attr_hash
60
+ end
61
+ hash.reject! { |key, value| options[:except].include?(key.to_sym) || options[:except].include?(key.to_s) } if options[:except]
62
+ hash.reject! { |key, value| !options[:only].include?(key.to_sym) && !options[:only].include?(key.to_s) } if options[:only]
63
+ hash
64
+ end
65
+
66
+ def create_xml(document)
67
+ document.add "trigger" do |trigger_element|
68
+ trigger_element.add "rel" do |rel_element|
69
+ rel_element.set_attr "neg", duration_negative ? 1 : 0
70
+ rel_element.set_attr "w", weeks if weeks && weeks > 0
71
+ rel_element.set_attr "d", days if days && days > 0
72
+ rel_element.set_attr "h", hours if hours && hours > 0
73
+ rel_element.set_attr "m", minutes if minutes && minutes > 0
74
+ rel_element.set_attr "s", seconds if seconds && seconds > 0
75
+ rel_element.set_attr "related", self.when.to_s.upcase
76
+ rel_element.set_attr "count", repeat_count if repeat_count && repeat_count > 0
77
+ end
78
+ end
79
+ end
80
+
81
+ def date_time_of_alarm
82
+ return nil if appointment_invite.nil?
83
+
84
+ date_to_calc_from = if self.when == :start
85
+ appointment_invite.start_date_time
86
+ else
87
+ appointment_invite.end_date_time
88
+ end
89
+
90
+ total_seconds = seconds || 0
91
+ total_seconds += minutes * 60 if minutes
92
+ total_seconds += hours * 3600 if hours
93
+ total_seconds += days * 86400 if days
94
+ total_seconds += weeks * 86400 * 7 if weeks
95
+ total_seconds *= -1 if duration_negative
96
+
97
+ date_to_calc_from + total_seconds
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,97 @@
1
+ module Zimbra
2
+ class Appointment
3
+ class Attendee
4
+ ATTRS = [
5
+ :email_address, :friendly_name, :rsvp, :role, :participation_status
6
+ ] unless const_defined?(:ATTRS)
7
+
8
+ attr_accessor *ATTRS
9
+
10
+ class << self
11
+ def new_from_zimbra_attributes(zimbra_attributes)
12
+ new(parse_zimbra_attributes(zimbra_attributes))
13
+ end
14
+
15
+ def parse_zimbra_attributes(zimbra_attributes)
16
+ zimbra_attributes = Zimbra::Hash.symbolize_keys(zimbra_attributes.dup, true)
17
+
18
+ {
19
+ :email_address => zimbra_attributes[:a],
20
+ :friendly_name => zimbra_attributes[:d],
21
+ :rsvp => zimbra_attributes[:rsvp],
22
+ :role => zimbra_attributes[:role],
23
+ :participation_status => zimbra_attributes[:ptst]
24
+ }
25
+ end
26
+ end
27
+
28
+ def initialize(args = {})
29
+ self.attributes = args
30
+ end
31
+
32
+ # take attributes by the xml name or our more descriptive name
33
+ def attributes=(args = {})
34
+ ATTRS.each do |attr_name|
35
+ if args.has_key?(attr_name)
36
+ self.send(:"#{attr_name}=", args[attr_name])
37
+ elsif args.has_key?(attr_name.to_s)
38
+ self.send(:"#{attr_name}=", args[attr_name.to_s])
39
+ end
40
+ end
41
+ end
42
+
43
+ def participation_status=(val)
44
+ @participation_status = parse_participation_status(val)
45
+ end
46
+
47
+ def participation_status_to_zimbra
48
+ possible_participation_status_values.find { |k, v| v == participation_status }.first rescue participiation_status
49
+ end
50
+
51
+ def to_hash(options = {})
52
+ hash = {
53
+ :email_address => email_address,
54
+ :friendly_name => friendly_name,
55
+ :rsvp => rsvp,
56
+ :role => role,
57
+ :participation_status => participation_status
58
+ }
59
+ hash.reject! { |key, value| options[:except].include?(key.to_sym) || options[:except].include?(key.to_s) } if options[:except]
60
+ hash.reject! { |key, value| !options[:only].include?(key.to_sym) && !options[:only].include?(key.to_s) } if options[:only]
61
+ hash
62
+ end
63
+
64
+ def create_xml(document)
65
+ document.add "at" do |at_element|
66
+ at_element.set_attr "a", email_address
67
+ at_element.set_attr "d", friendly_name
68
+ at_element.set_attr "ptst", participation_status_to_zimbra
69
+ end
70
+ end
71
+
72
+ private
73
+
74
+ def possible_participation_status_values
75
+ @possible_participation_status_values ||= {
76
+ 'NE' => :needs_action,
77
+ 'AC' => :accept,
78
+ 'TE' => :tentative,
79
+ 'DE' => :declined,
80
+ 'DG' => :delegated,
81
+ 'CO' => :completed,
82
+ 'IN' => :in_process,
83
+ 'WE' => :waiting,
84
+ 'DF' => :deferred,
85
+ 'New' => :needs_action,
86
+ 'Accepted' => :accept,
87
+ 'Declined' => :declined
88
+ }
89
+ end
90
+
91
+ def parse_participation_status(status)
92
+ possible_participation_status_values[status] || status
93
+ end
94
+
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,360 @@
1
+ module Zimbra
2
+ class Appointment
3
+ class Invite
4
+ ATTRS = [
5
+ :appointment,
6
+ :id, :recurrence_id, :sequence_number,
7
+
8
+ :start_date_time, :end_date_time, :date,
9
+ :name, :fragment, :description, :alarm, :alarm_zimbra_attributes, :alarm_attributes, :recurrence_rule, :recurrence_rule_zimbra_attributes, :recurrence_rule_attributes,
10
+ :attendees, :attendees_attributes, :attendees_zimbra_attributes,
11
+ :organizer_email_address, :is_organizer, :computed_free_busy_status,
12
+ :free_busy_setting, :invite_status, :all_day, :visibility, :location,
13
+ :transparency, :replies, :never_sent,
14
+
15
+ :comment, :recurrence_id_utc, :exception
16
+ ] unless const_defined?(:ATTRS)
17
+
18
+ attr_accessor *ATTRS
19
+
20
+ class << self
21
+ def new_from_zimbra_attributes(zimbra_attributes)
22
+ new(parse_zimbra_attributes(zimbra_attributes))
23
+ end
24
+
25
+ def parse_zimbra_attributes(zimbra_attributes)
26
+ zimbra_attributes = Zimbra::Hash.symbolize_keys(zimbra_attributes.dup, true)
27
+
28
+ attrs = {}
29
+
30
+ attrs[:appointment] = zimbra_attributes[:appointment] if zimbra_attributes.has_key?(:appointment)
31
+
32
+ if zimbra_attributes.has_key?(:attributes)
33
+ attrs.merge!({
34
+ :id => zimbra_attributes[:attributes][:id],
35
+ :recurrence_id => zimbra_attributes[:attributes][:recurId],
36
+ :sequence_number => zimbra_attributes[:attributes][:seq],
37
+ })
38
+ end
39
+
40
+ zimbra_attributes = zimbra_attributes[:comp]
41
+ return attrs unless zimbra_attributes
42
+
43
+ attrs.merge!({
44
+ :fragment => zimbra_attributes[:fr],
45
+ :description => zimbra_attributes[:desc],
46
+ :comment => zimbra_attributes[:comment],
47
+ :alarm_zimbra_attributes => zimbra_attributes[:alarm],
48
+ :recurrence_rule_zimbra_attributes => zimbra_attributes[:recur],
49
+ :attendees_zimbra_attributes => zimbra_attributes[:at],
50
+ :never_sent => zimbra_attributes[:neverSent]
51
+ })
52
+
53
+ if zimbra_attributes[:s]
54
+ attrs[:start_date_time] = zimbra_attributes[:s][:attributes][:u]
55
+ else
56
+
57
+ end
58
+
59
+ if zimbra_attributes[:e]
60
+ attrs[:end_date_time] = zimbra_attributes[:e][:attributes][:u]
61
+ end
62
+
63
+ if zimbra_attributes[:exceptId] && zimbra_attributes[:exceptId][:attributes]
64
+ attrs[:exception] = zimbra_attributes[:exceptId][:attributes]
65
+ end
66
+
67
+ attrs[:organizer_email_address] = zimbra_attributes[:or][:attributes][:a] rescue nil
68
+
69
+ return attrs unless zimbra_attributes.has_key?(:attributes)
70
+
71
+ attrs.merge!({
72
+ :name => zimbra_attributes[:attributes][:name],
73
+ :computed_free_busy_status => zimbra_attributes[:attributes][:fba],
74
+ :free_busy_setting => zimbra_attributes[:attributes][:fb],
75
+ :date => zimbra_attributes[:attributes][:d],
76
+ :invite_status => zimbra_attributes[:attributes][:status],
77
+ :all_day => zimbra_attributes[:attributes][:allDay],
78
+ :visibility => zimbra_attributes[:attributes][:class],
79
+ :location => zimbra_attributes[:attributes][:loc],
80
+ :date => zimbra_attributes[:attributes][:d],
81
+ :transparency => zimbra_attributes[:attributes][:transp],
82
+ :is_organizer => zimbra_attributes[:attributes][:isOrg],
83
+ :recurrence_id_utc => zimbra_attributes[:attributes][:ridZ]
84
+ })
85
+
86
+ attrs
87
+ end
88
+ end
89
+
90
+ def initialize(args = {})
91
+ self.attributes = args
92
+ end
93
+
94
+ # take attributes by the xml name or our more descriptive name
95
+ def attributes=(args = {})
96
+ ATTRS.each do |attr_name|
97
+ if args.has_key?(attr_name)
98
+ self.send(:"#{attr_name}=", args[attr_name])
99
+ elsif args.has_key?(attr_name.to_s)
100
+ self.send(:"#{attr_name}=", args[attr_name.to_s])
101
+ end
102
+ end
103
+ end
104
+
105
+ def save
106
+ return false unless appointment
107
+
108
+ if appointment.new_record?
109
+ appointment.save
110
+ else
111
+ Zimbra::AppointmentService.update(appointment, id)
112
+ end
113
+ end
114
+
115
+ def cancel
116
+ return false unless appointment
117
+ return false if appointment.new_record?
118
+
119
+ Zimbra::AppointmentService.cancel(appointment, id)
120
+ end
121
+
122
+ def exception=(exception_attributes)
123
+ return @exception = nil unless exception_attributes
124
+
125
+ @exception = Zimbra::Appointment::RecurException.new_from_zimbra_attributes(exception_attributes)
126
+ end
127
+
128
+ def recurrence_rule_attributes=(attributes)
129
+ @recurrence_rule = attributes ? Zimbra::Appointment::RecurRule.new(attributes) : nil
130
+ end
131
+
132
+ def recurrence_rule_zimbra_attributes=(attributes)
133
+ @recurrence_rule = attributes ? Zimbra::Appointment::RecurRule.new_from_zimbra_attributes(attributes) : nil
134
+ end
135
+
136
+ def attendees_zimbra_attributes=(attributes)
137
+ return @attendees = [] unless attributes
138
+
139
+ attributes = attributes.is_a?(Array) ? attributes : [attributes]
140
+ @attendees = attributes.collect { |attrs| Zimbra::Appointment::Attendee.new_from_zimbra_attributes(attrs[:attributes]) }
141
+ end
142
+
143
+ def attendees_attributes=(attributes)
144
+ return @attendees = [] unless attributes
145
+
146
+ attributes = attributes.is_a?(Array) ? attributes : [attributes]
147
+ @attendees = attributes.collect { |attrs| Zimbra::Appointment::Attendee.new(attrs) }
148
+ end
149
+
150
+ def alarm_attributes=(attributes)
151
+ @alarm = attributes ? Zimbra::Appointment::Alarm.new(attributes.merge(:appointment_invite => self)) : nil
152
+ end
153
+
154
+ def alarm_zimbra_attributes=(attributes)
155
+ @alarm = attributes ? Zimbra::Appointment::Alarm.new_from_zimbra_attributes(attributes.merge(:appointment_invite => self)) : nil
156
+ end
157
+
158
+ def computed_free_busy_status=(val)
159
+ @computed_free_busy_status = parse_free_busy_status(val)
160
+ end
161
+
162
+ def free_busy_setting_to_zimbra
163
+ possible_free_busy_status_values.find { |k ,v| v == free_busy_setting }.first rescue free_busy_setting
164
+ end
165
+
166
+ def free_busy_setting=(val)
167
+ @free_busy_setting = parse_free_busy_status(val)
168
+ end
169
+
170
+ def invite_status=(val)
171
+ @invite_status = parse_invite_status(val)
172
+ end
173
+
174
+ def invite_status_to_zimbra
175
+ possible_invite_status_values.find { |k, v| v == invite_status }.first rescue invite_status
176
+ end
177
+
178
+ def visibility=(val)
179
+ @visibility = parse_visibility_status(val)
180
+ end
181
+
182
+ def visibility_to_zimbra
183
+ possible_visibility_values.find { |k, v| v == visibility }.first rescue visibility
184
+ end
185
+
186
+ def transparency_to_zimbra
187
+ possible_transparency_status_values.find { |k, v| v == transparency }.first rescue transparency
188
+ end
189
+
190
+ def transparency=(val)
191
+ @transparency = parse_transparency_status(val)
192
+ end
193
+
194
+ def all_day=(val)
195
+ @all_day = parse_all_day(val)
196
+ end
197
+
198
+ def start_date_time=(val)
199
+ @start_date_time = val.is_a?(Integer) ? parse_date_in_seconds(val) : val
200
+ end
201
+
202
+ def end_date_time=(val)
203
+ @end_date_time = val.is_a?(Integer) ? parse_date_in_seconds(val) : val
204
+ end
205
+
206
+ def date=(val)
207
+ @date = val.is_a?(Integer) ? parse_date_in_seconds(val) : val
208
+ end
209
+
210
+ def create_xml(document)
211
+ document.set_attr "id", id if id
212
+ document.set_attr "status", invite_status_to_zimbra if invite_status
213
+ document.set_attr "isOrg", is_organizer ? 1 : 0
214
+ #document.set_attr "d", date.to_i * 1000 if date
215
+
216
+ document.add "comp" do |comp|
217
+ comp.set_attr "loc", location if location
218
+ comp.set_attr "allDay", all_day ? 1 : 0
219
+ comp.set_attr "class", visibility_to_zimbra if visibility
220
+ comp.set_attr "fb", free_busy_setting_to_zimbra if free_busy_setting
221
+ comp.set_attr "isOrg", is_organizer ? 1 : 0
222
+ comp.set_attr "name", name
223
+ comp.set_attr "transp", transparency_to_zimbra if transparency
224
+ comp.set_attr "d", date.to_i * 1000 if date
225
+
226
+ if is_organizer
227
+ comp.set_attr "neverSent", never_sent ? 1 : 0
228
+ end
229
+
230
+ if description && !description.empty?
231
+ comp.add "desc", description
232
+ end
233
+
234
+ if comment && !comment.empty?
235
+ comp.add "comment", comment
236
+ end
237
+
238
+ comp.add "s" do |s_element|
239
+ s_element.set_attr "u", start_date_time.to_i * 1000
240
+ s_element.set_attr "d", start_date_time.utc.strftime("%Y%m%dT%H%M%SZ")
241
+ end
242
+
243
+ comp.add "e" do |e_element|
244
+ e_element.set_attr "u", end_date_time.to_i * 1000
245
+ e_element.set_attr "d", end_date_time.utc.strftime("%Y%m%dT%H%M%SZ")
246
+ end
247
+
248
+ if alarm
249
+ comp.add "alarm" do |alarm_element|
250
+ alarm_element.set_attr "action", "DISPLAY"
251
+
252
+ alarm.create_xml(alarm_element)
253
+ end
254
+ end
255
+
256
+ if recurrence_rule
257
+ comp.add "recur" do |recur_element|
258
+ recur_element.add "add" do |add_element|
259
+ recurrence_rule.create_xml(add_element)
260
+ end
261
+ end
262
+ end
263
+
264
+ if attendees && attendees.count > 0
265
+ attendees.each do |attendee|
266
+ attendee.create_xml(comp)
267
+ end
268
+ end
269
+
270
+ if organizer_email_address
271
+ comp.add "or" do |or_element|
272
+ or_element.set_attr "a", organizer_email_address
273
+ end
274
+ end
275
+
276
+ if exception
277
+ exception.create_xml(comp)
278
+ end
279
+ end
280
+ #
281
+ # ATTRS = [
282
+ # :recurrence_id, :sequence_number, :replies,
283
+ #
284
+ # :, :recurrence_id_utc,
285
+ end
286
+
287
+ private
288
+
289
+ def parse_date_in_seconds(seconds)
290
+ Time.at(seconds / 1000)
291
+ end
292
+
293
+ def possible_all_day_values
294
+ @possible_all_day_values ||= {
295
+ 0 => false,
296
+ 1 => true
297
+ }
298
+ end
299
+
300
+ def parse_all_day(val)
301
+ return val if val == true || val == false
302
+ possible_all_day_values[val.to_i] || val
303
+ end
304
+
305
+ def possible_free_busy_status_values
306
+ @possible_free_busy_status_values ||= {
307
+ 'F' => :free,
308
+ 'B' => :busy,
309
+ 'T' => :busy_tentative,
310
+ 'U' => :busy_unavailable
311
+ }
312
+ end
313
+
314
+ def parse_free_busy_status(fb_status)
315
+ possible_free_busy_status_values[fb_status] || fb_status
316
+ end
317
+
318
+ def possible_invite_status_values
319
+ @possible_invite_status_values ||= {
320
+ 'TENT' => :tentative,
321
+ 'CONF' => :confirmed,
322
+ 'CANC' => :canceled,
323
+ 'NEED' => :need, # Not sure about this one, it's not documented
324
+ 'COMP' => :completed,
325
+ 'INPR' => :in_progress,
326
+ 'WAITING' => :waiting,
327
+ 'DEFERRED' => :deferred
328
+ }
329
+ end
330
+
331
+ def parse_invite_status(status)
332
+ possible_invite_status_values[status] || status
333
+ end
334
+
335
+ def possible_visibility_values
336
+ @possible_visibility_values ||= {
337
+ 'PUB' => :public,
338
+ 'PRI' => :private,
339
+ 'CON' => :confidential
340
+ }
341
+ end
342
+
343
+ def parse_visibility_status(status)
344
+ possible_visibility_values[status] || status
345
+ end
346
+
347
+ def possible_transparency_status_values
348
+ @possible_transparency_status_values ||= {
349
+ 'O' => :opaque,
350
+ 'T' => :transparent
351
+ }
352
+ end
353
+
354
+ def parse_transparency_status(status)
355
+ possible_transparency_status_values[status] || status
356
+ end
357
+
358
+ end
359
+ end
360
+ end