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