viewpoint_reloaded 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/Changelog.txt +1004 -0
  3. data/README.md +201 -0
  4. data/TODO +17 -0
  5. data/lib/ews/calendar_accessors.rb +34 -0
  6. data/lib/ews/connection.rb +130 -0
  7. data/lib/ews/connection_helper.rb +35 -0
  8. data/lib/ews/convert_accessors.rb +56 -0
  9. data/lib/ews/errors.rb +56 -0
  10. data/lib/ews/ews_client.rb +103 -0
  11. data/lib/ews/exceptions/exceptions.rb +61 -0
  12. data/lib/ews/folder_accessors.rb +264 -0
  13. data/lib/ews/impersonation.rb +30 -0
  14. data/lib/ews/item_accessors.rb +231 -0
  15. data/lib/ews/mailbox_accessors.rb +92 -0
  16. data/lib/ews/message_accessors.rb +93 -0
  17. data/lib/ews/push_subscription_accessors.rb +33 -0
  18. data/lib/ews/room_accessors.rb +48 -0
  19. data/lib/ews/roomlist_accessors.rb +47 -0
  20. data/lib/ews/soap.rb +64 -0
  21. data/lib/ews/soap/builders/ews_builder.rb +1266 -0
  22. data/lib/ews/soap/ews_response.rb +84 -0
  23. data/lib/ews/soap/ews_soap_availability_response.rb +58 -0
  24. data/lib/ews/soap/ews_soap_free_busy_response.rb +119 -0
  25. data/lib/ews/soap/ews_soap_response.rb +103 -0
  26. data/lib/ews/soap/ews_soap_room_response.rb +53 -0
  27. data/lib/ews/soap/ews_soap_roomlist_response.rb +54 -0
  28. data/lib/ews/soap/exchange_availability.rb +61 -0
  29. data/lib/ews/soap/exchange_data_services.rb +780 -0
  30. data/lib/ews/soap/exchange_notification.rb +146 -0
  31. data/lib/ews/soap/exchange_synchronization.rb +93 -0
  32. data/lib/ews/soap/exchange_time_zones.rb +56 -0
  33. data/lib/ews/soap/exchange_user_configuration.rb +33 -0
  34. data/lib/ews/soap/exchange_web_service.rb +264 -0
  35. data/lib/ews/soap/parsers/ews_parser.rb +43 -0
  36. data/lib/ews/soap/parsers/ews_sax_document.rb +70 -0
  37. data/lib/ews/soap/response_message.rb +80 -0
  38. data/lib/ews/soap/responses/create_attachment_response_message.rb +47 -0
  39. data/lib/ews/soap/responses/create_item_response_message.rb +25 -0
  40. data/lib/ews/soap/responses/find_item_response_message.rb +80 -0
  41. data/lib/ews/soap/responses/get_events_response_message.rb +53 -0
  42. data/lib/ews/soap/responses/send_notification_response_message.rb +59 -0
  43. data/lib/ews/soap/responses/subscribe_response_message.rb +35 -0
  44. data/lib/ews/soap/responses/sync_folder_hierarchy_response_message.rb +36 -0
  45. data/lib/ews/soap/responses/sync_folder_items_response_message.rb +36 -0
  46. data/lib/ews/templates/calendar_item.rb +79 -0
  47. data/lib/ews/templates/forward_item.rb +24 -0
  48. data/lib/ews/templates/message.rb +73 -0
  49. data/lib/ews/templates/reply_to_item.rb +25 -0
  50. data/lib/ews/templates/task.rb +74 -0
  51. data/lib/ews/types.rb +194 -0
  52. data/lib/ews/types/attachment.rb +77 -0
  53. data/lib/ews/types/attendee.rb +27 -0
  54. data/lib/ews/types/calendar_folder.rb +50 -0
  55. data/lib/ews/types/calendar_item.rb +130 -0
  56. data/lib/ews/types/contact.rb +7 -0
  57. data/lib/ews/types/contacts_folder.rb +8 -0
  58. data/lib/ews/types/copied_event.rb +51 -0
  59. data/lib/ews/types/created_event.rb +24 -0
  60. data/lib/ews/types/deleted_event.rb +24 -0
  61. data/lib/ews/types/distribution_list.rb +7 -0
  62. data/lib/ews/types/event.rb +62 -0
  63. data/lib/ews/types/export_items_response_message.rb +52 -0
  64. data/lib/ews/types/file_attachment.rb +65 -0
  65. data/lib/ews/types/folder.rb +60 -0
  66. data/lib/ews/types/free_busy_changed_event.rb +24 -0
  67. data/lib/ews/types/generic_folder.rb +418 -0
  68. data/lib/ews/types/item.rb +441 -0
  69. data/lib/ews/types/item_attachment.rb +84 -0
  70. data/lib/ews/types/item_field_uri_map.rb +208 -0
  71. data/lib/ews/types/mailbox_user.rb +156 -0
  72. data/lib/ews/types/meeting_cancellation.rb +7 -0
  73. data/lib/ews/types/meeting_message.rb +7 -0
  74. data/lib/ews/types/meeting_request.rb +7 -0
  75. data/lib/ews/types/meeting_response.rb +7 -0
  76. data/lib/ews/types/message.rb +7 -0
  77. data/lib/ews/types/modified_event.rb +48 -0
  78. data/lib/ews/types/moved_event.rb +51 -0
  79. data/lib/ews/types/new_mail_event.rb +24 -0
  80. data/lib/ews/types/out_of_office.rb +147 -0
  81. data/lib/ews/types/search_folder.rb +8 -0
  82. data/lib/ews/types/status_event.rb +39 -0
  83. data/lib/ews/types/task.rb +41 -0
  84. data/lib/ews/types/tasks_folder.rb +27 -0
  85. data/lib/viewpoint.rb +109 -0
  86. data/lib/viewpoint/logging.rb +27 -0
  87. data/lib/viewpoint/logging/config.rb +24 -0
  88. data/lib/viewpoint/string_utils.rb +76 -0
  89. metadata +192 -0
@@ -0,0 +1,441 @@
1
+ module Viewpoint::EWS::Types
2
+ module Item
3
+ include Viewpoint::EWS
4
+ include Viewpoint::EWS::Types
5
+ include ItemFieldUriMap
6
+
7
+ def self.included(klass)
8
+ klass.extend ClassMethods
9
+ end
10
+
11
+ module ClassMethods
12
+ def init_simple_item(ews, id, change_key = nil, parent = nil)
13
+ ews_item = {item_id: {attribs: {id: id, change_key: change_key}}}
14
+ self.new ews, ews_item, parent
15
+ end
16
+ end
17
+
18
+ ITEM_KEY_PATHS = {
19
+ item_id: [:item_id, :attribs],
20
+ id: [:item_id, :attribs, :id],
21
+ change_key: [:item_id, :attribs, :change_key],
22
+ subject: [:subject, :text],
23
+ sensitivity: [:sensitivity, :text],
24
+ size: [:size, :text],
25
+ date_time_sent: [:date_time_sent, :text],
26
+ date_time_created: [:date_time_created, :text],
27
+ mime_content: [:mime_content, :text],
28
+ has_attachments?:[:has_attachments, :text],
29
+ is_associated?: [:is_associated, :text],
30
+ is_read?: [:is_read, :text],
31
+ is_draft?: [:is_draft, :text],
32
+ is_submitted?: [:is_submitted, :text],
33
+ conversation_id:[:conversation_id, :attribs, :id],
34
+ categories: [:categories, :elems],
35
+ internet_message_id:[:internet_message_id, :text],
36
+ internet_message_headers:[:internet_message_headers, :elems],
37
+ sender: [:sender, :elems, 0, :mailbox, :elems],
38
+ from: [:from, :elems, 0, :mailbox, :elems],
39
+ to_recipients: [:to_recipients, :elems],
40
+ cc_recipients: [:cc_recipients, :elems],
41
+ attachments: [:attachments, :elems],
42
+ importance: [:importance, :text],
43
+ conversation_index: [:conversation_index, :text],
44
+ conversation_topic: [:conversation_topic, :text],
45
+ body_type: [:body, :attribs, :body_type],
46
+ body: [:body, :text]
47
+ }
48
+
49
+ ITEM_KEY_TYPES = {
50
+ size: ->(str){str.to_i},
51
+ date_time_sent: ->(str){DateTime.parse(str)},
52
+ date_time_created: ->(str){DateTime.parse(str)},
53
+ has_attachments?: ->(str){str.downcase == 'true'},
54
+ is_associated?: ->(str){str.downcase == 'true'},
55
+ is_read?: ->(str){str.downcase == 'true'},
56
+ is_draft?: ->(str){str.downcase == 'true'},
57
+ is_submitted?: ->(str){str.downcase == 'true'},
58
+ categories: ->(obj){obj.collect{|s| s[:string][:text]}},
59
+ internet_message_headers: ->(obj){obj.collect{|h|
60
+ {h[:internet_message_header][:attribs][:header_name] =>
61
+ h[:internet_message_header][:text]} } },
62
+ sender: :build_mailbox_user,
63
+ from: :build_mailbox_user,
64
+ to_recipients: :build_mailbox_users,
65
+ cc_recipients: :build_mailbox_users,
66
+ attachments: :build_attachments,
67
+ }
68
+
69
+ ITEM_KEY_ALIAS = {
70
+ :read? => :is_read?,
71
+ :draft? => :is_draft?,
72
+ :submitted? => :is_submitted?,
73
+ :associated? => :is_associated?,
74
+ }
75
+
76
+ attr_reader :ews_item, :parent
77
+
78
+ # @param ews [SOAP::ExchangeWebService] the EWS reference
79
+ # @param ews_item [Hash] the EWS parsed response document
80
+ # @param parent [GenericFolder] an optional parent object
81
+ def initialize(ews, ews_item, parent = nil)
82
+ super(ews, ews_item)
83
+ @parent = parent
84
+ @body_type = false
85
+ simplify!
86
+ @new_file_attachments = []
87
+ @new_item_attachments = []
88
+ @new_inline_attachments = []
89
+ end
90
+
91
+ # Specify a body_type to fetch this item with if it hasn't already been fetched.
92
+ # @param body_type [String, Symbol, FalseClass] must be :best, :text, or
93
+ # :html. You can also set it to false to make it use the default.
94
+ def default_body_type=(body_type)
95
+ @body_type = body_type
96
+ end
97
+
98
+ def delete!(deltype = :hard, opts = {})
99
+ opts = {
100
+ :delete_type => delete_type(deltype),
101
+ :item_ids => [{:item_id => {:id => id}}]
102
+ }.merge(opts)
103
+
104
+ resp = @ews.delete_item(opts)
105
+ rmsg = resp.response_messages[0]
106
+ unless rmsg.success?
107
+ raise EwsError, "Could not delete #{self.class}. #{rmsg.response_code}: #{rmsg.message_text}"
108
+ end
109
+ true
110
+ end
111
+
112
+ def recycle!
113
+ delete! :recycle
114
+ end
115
+
116
+ def get_all_properties!
117
+ @ews_item = get_item(base_shape: 'AllProperties')
118
+ simplify!
119
+ end
120
+
121
+ # Mark an item as read or if you pass false, unread
122
+ # @param [Boolean] read mark read if true, unread if not.
123
+ def mark_read!(read = true)
124
+ resp = update_is_read_status read
125
+ end
126
+
127
+ # Move this item to a new folder
128
+ # @param [String,Symbol,GenericFolder] new_folder The new folder to move it to. This should
129
+ # be a subclass of GenericFolder, a DistinguishedFolderId (must me a Symbol) or a FolderId (String)
130
+ # @return [String] the new Id of the moved item
131
+ def move!(new_folder)
132
+ new_folder = new_folder.id if new_folder.kind_of?(GenericFolder)
133
+ move_opts = {
134
+ :to_folder_id => {:id => new_folder},
135
+ :item_ids => [{:item_id => {:id => self.id}}]
136
+ }
137
+ resp = @ews.move_item(move_opts)
138
+ rmsg = resp.response_messages[0]
139
+
140
+ if rmsg.success?
141
+ obj = rmsg.items.first
142
+ itype = obj.keys.first
143
+ obj[itype][:elems][0][:item_id][:attribs][:id]
144
+ else
145
+ raise EwsError, "Could not move item. #{resp.code}: #{resp.message}"
146
+ end
147
+ end
148
+
149
+ # Copy this item to a new folder
150
+ # @param [String,Symbol,GenericFolder] new_folder The new folder to move it to. This should
151
+ # be a subclass of GenericFolder, a DistinguishedFolderId (must me a Symbol) or a FolderId (String)
152
+ # @return [String] the new Id of the copied item
153
+ def copy(new_folder)
154
+ new_folder = new_folder.id if new_folder.kind_of?(GenericFolder)
155
+ copy_opts = {
156
+ :to_folder_id => {:id => new_folder},
157
+ :item_ids => [{:item_id => {:id => self.id}}]
158
+ }
159
+ resp = @ews.copy_item(copy_opts)
160
+ rmsg = resp.response_messages[0]
161
+
162
+ if rmsg.success?
163
+ obj = rmsg.items.first
164
+ itype = obj.keys.first
165
+ obj[itype][:elems][0][:item_id][:attribs][:id]
166
+ else
167
+ raise EwsError, "Could not copy item. #{rmsg.response_code}: #{rmsg.message_text}"
168
+ end
169
+ end
170
+
171
+ def add_file_attachment(file)
172
+ fa = OpenStruct.new
173
+ fa.name = File.basename(file.path)
174
+ fa.content = Base64.encode64(file.read)
175
+ @new_file_attachments << fa
176
+ end
177
+
178
+ def add_item_attachment(other_item, name = nil)
179
+ ia = OpenStruct.new
180
+ ia.name = (name ? name : other_item.subject)
181
+ ia.item = {id: other_item.id, change_key: other_item.change_key}
182
+ @new_item_attachments << ia
183
+ end
184
+
185
+ def add_inline_attachment(file)
186
+ fi = OpenStruct.new
187
+ fi.name = File.basename(file.path)
188
+ fi.content = Base64.encode64(file.read)
189
+ @new_inline_attachments << fi
190
+ end
191
+
192
+ def submit!
193
+ if draft?
194
+ submit_attachments!
195
+ resp = ews.send_item(item_ids: [{item_id: {id: self.id, change_key: self.change_key}}])
196
+ rm = resp.response_messages[0]
197
+ if rm.success?
198
+ true
199
+ else
200
+ raise EwsSendItemError, "#{rm.code}: #{rm.message_text}"
201
+ end
202
+ else
203
+ false
204
+ end
205
+ end
206
+
207
+ def submit_attachments!
208
+ return false unless draft? && !(@new_file_attachments.empty? && @new_item_attachments.empty? && @new_inline_attachments.empty?)
209
+
210
+ opts = {
211
+ parent_id: {id: self.id, change_key: self.change_key},
212
+ files: @new_file_attachments,
213
+ items: @new_item_attachments,
214
+ inline_files: @new_inline_attachments
215
+ }
216
+ resp = ews.create_attachment(opts)
217
+ set_change_key resp.response_messages[0].attachments[0].parent_change_key
218
+ @new_file_attachments = []
219
+ @new_item_attachments = []
220
+ @new_inline_attachments = []
221
+ end
222
+
223
+ # If you want to add to the body set #new_body_content. If you set #body
224
+ # it will override the body that is there.
225
+ # @see MessageAccessors#send_message for options
226
+ # additional options:
227
+ # :new_body_content, :new_body_type
228
+ # @example
229
+ # item.forward do |i|
230
+ # i.new_body_content = "Add this to the top"
231
+ # i.to_recipients << 'test@example.com'
232
+ # end
233
+ def forward(opts = {})
234
+ msg = Template::ForwardItem.new opts.clone
235
+ yield msg if block_given?
236
+ msg.reference_item_id = {id: self.id, change_key: self.change_key}
237
+ dispatch_create_item! msg
238
+ end
239
+
240
+ def reply_to(opts = {})
241
+ msg = Template::ReplyToItem.new opts.clone
242
+ yield msg if block_given?
243
+ msg.reference_item_id = {id: self.id, change_key: self.change_key}
244
+ dispatch_create_item! msg
245
+ end
246
+
247
+ def reply_to_all(opts = {})
248
+ msg = Template::ReplyToItem.new opts.clone
249
+ yield msg if block_given?
250
+ msg.reference_item_id = {id: self.id, change_key: self.change_key}
251
+ msg.ews_type = :reply_all_to_item
252
+ dispatch_create_item! msg
253
+ end
254
+
255
+
256
+ private
257
+
258
+ def key_paths
259
+ super.merge(ITEM_KEY_PATHS)
260
+ end
261
+
262
+ def key_types
263
+ super.merge(ITEM_KEY_TYPES)
264
+ end
265
+
266
+ def key_alias
267
+ super.merge(ITEM_KEY_ALIAS)
268
+ end
269
+
270
+ def update_is_read_status(read)
271
+ field = :is_read
272
+ opts = {item_changes:
273
+ [
274
+ { item_id: {id: id, change_key: change_key},
275
+ updates: [
276
+ {set_item_field: {field_uRI: {field_uRI: FIELD_URIS[field][:text]},
277
+ message: {sub_elements: [{field => {text: read}}]}}}
278
+ ]
279
+ }
280
+ ]
281
+ }
282
+ resp = ews.update_item({conflict_resolution: 'AutoResolve'}.merge(opts))
283
+ rmsg = resp.response_messages[0]
284
+ unless rmsg.success?
285
+ raise EwsError, "#{rmsg.response_code}: #{rmsg.message_text}"
286
+ end
287
+ true
288
+ end
289
+
290
+ def simplify!
291
+ return unless @ews_item.has_key?(:elems)
292
+ @ews_item = @ews_item[:elems].inject({}) do |o,i|
293
+ key = i.keys.first
294
+ if o.has_key?(key)
295
+ if o[key].is_a?(Array)
296
+ o[key] << i[key]
297
+ else
298
+ o[key] = [o.delete(key), i[key]]
299
+ end
300
+ else
301
+ o[key] = i[key]
302
+ end
303
+ o
304
+ end
305
+ end
306
+
307
+ # Get a specific item by its ID.
308
+ # @param [Hash] opts Misc options to control request
309
+ # @option opts [String] :base_shape IdOnly/Default/AllProperties
310
+ # @raise [EwsError] raised when the backend SOAP method returns an error.
311
+ def get_item(opts = {})
312
+ args = get_item_args(opts)
313
+ resp = ews.get_item(args)
314
+ get_item_parser(resp)
315
+ end
316
+
317
+ # Build up the arguements for #get_item
318
+ # @todo: should we really pass the ChangeKey or do we want the freshest obj?
319
+ def get_item_args(opts)
320
+ opts[:base_shape] ||= 'Default'
321
+ default_args = {
322
+ item_shape: {base_shape: opts[:base_shape]},
323
+ item_ids: [{item_id:{id: id, change_key: change_key}}]
324
+ }
325
+ default_args[:item_shape][:body_type] = @body_type if @body_type
326
+ default_args
327
+ end
328
+
329
+ def get_item_parser(resp)
330
+ rm = resp.response_messages[0]
331
+ if(rm.status == 'Success')
332
+ rm.items[0].values.first
333
+ else
334
+ raise EwsError, "Could not retrieve #{self.class}. #{rm.code}: #{rm.message_text}"
335
+ end
336
+ end
337
+
338
+ # Map a delete type to what EWS expects
339
+ # @param [Symbol] type. Must be :hard, :soft, or :recycle
340
+ def delete_type(type)
341
+ case type
342
+ when :hard then 'HardDelete'
343
+ when :soft then 'SoftDelete'
344
+ when :recycle then 'MoveToDeletedItems'
345
+ else 'MoveToDeletedItems'
346
+ end
347
+ end
348
+
349
+ def build_deleted_occurrences(occurrences)
350
+ occurrences.collect{|a| DateTime.parse a[:deleted_occurrence][:elems][0][:start][:text]}
351
+ end
352
+
353
+ def build_modified_occurrences(occurrences)
354
+ {}.tap do |h|
355
+ occurrences.collect do |a|
356
+ elems = a[:occurrence][:elems]
357
+
358
+ h[DateTime.parse(elems.find{|e| e[:original_start]}[:original_start][:text])] = {
359
+ start: elems.find{|e| e[:start]}[:start][:text],
360
+ end: elems.find{|e| e[:end]}[:end][:text]
361
+ }
362
+ end
363
+ end
364
+ end
365
+
366
+ def build_mailbox_user(mbox_ews)
367
+ MailboxUser.new(ews, mbox_ews)
368
+ end
369
+
370
+ def build_mailbox_users(users)
371
+ return [] if users.nil?
372
+ users.collect{|u| build_mailbox_user(u[:mailbox][:elems])}
373
+ end
374
+
375
+ def build_attendees_users(users)
376
+ return [] if users.nil?
377
+ users.collect do |u|
378
+ u[:attendee][:elems].collect do |a|
379
+ build_mailbox_user(a[:mailbox][:elems]) if a[:mailbox]
380
+ end
381
+ end.flatten.compact
382
+ end
383
+
384
+ def build_attachments(attachments)
385
+ return [] if attachments.nil?
386
+ attachments.collect do |att|
387
+ key = att.keys.first
388
+ class_by_name(key).new(self, att[key])
389
+ end
390
+ end
391
+
392
+ def set_change_key(ck)
393
+ p = resolve_key_path(ews_item, key_paths[:change_key][0..-2])
394
+ p[:change_key] = ck
395
+ end
396
+
397
+ # Handles the CreateItem call for Forward, ReplyTo, and ReplyAllTo
398
+ # It will handle the neccessary actions for adding attachments.
399
+ def dispatch_create_item!(msg)
400
+ if msg.has_attachments?
401
+ draft = msg.draft
402
+ msg.draft = true
403
+ resp = validate_created_item(ews.create_item(msg.to_ews))
404
+ msg.file_attachments.each do |f|
405
+ next unless f.kind_of?(File)
406
+ resp.add_file_attachment(f)
407
+ end
408
+ if draft
409
+ resp.submit_attachments!
410
+ resp
411
+ else
412
+ resp.submit!
413
+ end
414
+ else
415
+ resp = ews.create_item(msg.to_ews)
416
+ validate_created_item resp
417
+ end
418
+ end
419
+
420
+ # validate the CreateItem response.
421
+ # @return [Boolean, Item] returns true if items is empty and status is
422
+ # "Success" if items is not empty it will return the first Item since
423
+ # we are only dealing with single items here.
424
+ # @raise EwsCreateItemError on failure
425
+ def validate_created_item(response)
426
+ msg = response.response_messages[0]
427
+
428
+ if(msg.status == 'Success')
429
+ msg.items.empty? ? true : parse_created_item(msg.items.first)
430
+ else
431
+ raise EwsCreateItemError, "#{msg.code}: #{msg.message_text}"
432
+ end
433
+ end
434
+
435
+ def parse_created_item(msg)
436
+ mtype = msg.keys.first
437
+ message = class_by_name(mtype).new(ews, msg[mtype])
438
+ end
439
+
440
+ end
441
+ end
@@ -0,0 +1,84 @@
1
+ =begin
2
+ This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3
+
4
+ Copyright © 2011 Dan Wanek <dan.wanek@gmail.com>
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+ =end
18
+
19
+ module Viewpoint::EWS::Types
20
+ class ItemAttachment < Attachment
21
+
22
+ ITEM_ATTACH_KEY_PATHS = {
23
+ item: [:item],
24
+ message: [:message],
25
+ calendar_item: [:calendar_item],
26
+ contact: [:contact],
27
+ task: [:task],
28
+ meeting_message: [:meeting_message],
29
+ meeting_request: [:meeting_request],
30
+ meeting_response: [:meeting_response],
31
+ meeting_cancellation: [:meeting_cancellation]
32
+ }
33
+
34
+ ITEM_ATTACH_KEY_TYPES = {
35
+ message: :build_message,
36
+ calendar_item: :build_calendar_item,
37
+ contact: :build_contact,
38
+ task: :build_task,
39
+ meeting_message: :build_meeting_message,
40
+ meeting_request: :build_meeting_request,
41
+ meeting_response: :build_meeting_response,
42
+ meeting_cancellation: :build_meeting_cancellation
43
+ }
44
+
45
+ ITEM_ATTACH_KEY_ALIAS = { }
46
+
47
+ def get_all_properties!
48
+ resp = ews.get_attachment attachment_ids: [self.id]
49
+ @ews_item.merge!(parse_response(resp))
50
+ end
51
+
52
+ private
53
+
54
+ def self.method_missing(method, *args, &block)
55
+ if method.to_s =~ /^build_(.+)$/
56
+ class_by_name($1).new(ews, args[0])
57
+ else
58
+ super
59
+ end
60
+ end
61
+
62
+ def key_paths
63
+ super.merge(ITEM_ATTACH_KEY_PATHS)
64
+ end
65
+
66
+ def key_types
67
+ super.merge(ITEM_ATTACH_KEY_TYPES)
68
+ end
69
+
70
+ def key_alias
71
+ super.merge(ITEM_ATTACH_KEY_ALIAS)
72
+ end
73
+
74
+ def parse_response(resp)
75
+ if(resp.status == 'Success')
76
+ resp.response_message[:elems][:attachments][:elems][0][:item_attachment][:elems].inject(&:merge)
77
+ else
78
+ raise EwsError, "Could not retrieve #{self.class}. #{resp.code}: #{resp.message}"
79
+ end
80
+ end
81
+
82
+ end
83
+ end
84
+