viewpoint 0.1.27 → 1.0.0.beta.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.
- data/README.md +196 -0
- data/lib/ews/calendar_accessors.rb +34 -0
- data/lib/ews/connection.rb +117 -0
- data/lib/ews/connection_helper.rb +35 -0
- data/lib/ews/ews_client.rb +71 -0
- data/lib/ews/exceptions/exceptions.rb +59 -0
- data/lib/ews/folder_accessors.rb +199 -0
- data/lib/ews/item_accessors.rb +157 -0
- data/lib/ews/mailbox_accessors.rb +87 -0
- data/lib/ews/message_accessors.rb +86 -0
- data/lib/ews/push_subscription_accessors.rb +33 -0
- data/lib/ews/soap.rb +63 -0
- data/lib/ews/soap/builders/ews_builder.rb +1011 -0
- data/lib/ews/soap/ews_response.rb +83 -0
- data/lib/ews/soap/ews_soap_availability_response.rb +58 -0
- data/lib/ews/soap/ews_soap_free_busy_response.rb +109 -0
- data/lib/ews/soap/ews_soap_response.rb +103 -0
- data/lib/ews/soap/exchange_availability.rb +61 -0
- data/lib/ews/soap/exchange_data_services.rb +742 -0
- data/lib/ews/soap/exchange_notification.rb +146 -0
- data/lib/ews/soap/exchange_user_configuration.rb +33 -0
- data/lib/ews/soap/exchange_web_service.rb +294 -0
- data/lib/{model/attendee.rb → ews/soap/parsers/ews_parser.rb} +20 -14
- data/lib/ews/soap/parsers/ews_sax_document.rb +66 -0
- data/lib/ews/soap/response_message.rb +78 -0
- data/lib/ews/soap/responses/create_attachment_response_message.rb +46 -0
- data/lib/{model/meeting_message.rb → ews/soap/responses/create_item_response_message.rb} +7 -10
- 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 +58 -0
- data/lib/{model/attachment.rb → ews/soap/responses/subscribe_response_message.rb} +17 -13
- data/lib/ews/templates/forward_item.rb +24 -0
- data/lib/ews/templates/message.rb +66 -0
- data/lib/ews/templates/reply_to_item.rb +25 -0
- data/lib/ews/types.rb +146 -0
- data/lib/ews/types/attachment.rb +77 -0
- data/lib/{model/meeting_cancellation.rb → ews/types/attendee.rb} +9 -8
- data/lib/ews/types/calendar_folder.rb +8 -0
- data/lib/ews/types/calendar_item.rb +37 -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/{soap/handsoap/builder.rb → ews/types/created_event.rb} +5 -2
- data/lib/{model/meeting_response.rb → ews/types/deleted_event.rb} +6 -6
- data/lib/ews/types/distribution_list.rb +7 -0
- data/lib/ews/types/event.rb +62 -0
- data/lib/ews/types/file_attachment.rb +65 -0
- data/lib/ews/types/folder.rb +60 -0
- data/lib/{model/distribution_list.rb → ews/types/free_busy_changed_event.rb} +6 -6
- data/lib/ews/types/generic_folder.rb +352 -0
- data/lib/ews/types/item.rb +381 -0
- data/lib/ews/types/item_attachment.rb +46 -0
- data/lib/{model → ews/types}/item_field_uri_map.rb +2 -2
- 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/{model/item_attachment.rb → ews/types/moved_event.rb} +33 -15
- data/lib/ews/types/new_mail_event.rb +24 -0
- data/lib/ews/types/out_of_office.rb +147 -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 +7 -0
- data/lib/ews/types/tasks_folder.rb +8 -0
- data/lib/viewpoint.rb +82 -106
- metadata +99 -67
- data/README +0 -114
- data/lib/exceptions/exceptions.rb +0 -46
- data/lib/model/calendar_folder.rb +0 -67
- data/lib/model/calendar_item.rb +0 -267
- data/lib/model/contact.rb +0 -238
- data/lib/model/contacts_folder.rb +0 -46
- data/lib/model/event.rb +0 -116
- data/lib/model/file_attachment.rb +0 -53
- data/lib/model/folder.rb +0 -47
- data/lib/model/generic_folder.rb +0 -471
- data/lib/model/item.rb +0 -313
- data/lib/model/mailbox_user.rb +0 -146
- data/lib/model/meeting_request.rb +0 -39
- data/lib/model/message.rb +0 -142
- data/lib/model/model.rb +0 -269
- data/lib/model/search_folder.rb +0 -48
- data/lib/model/task.rb +0 -121
- data/lib/model/tasks_folder.rb +0 -44
- data/lib/soap/handsoap/builders/ews_build_helpers.rb +0 -383
- data/lib/soap/handsoap/builders/ews_builder.rb +0 -146
- data/lib/soap/handsoap/ews_service.rb +0 -813
- data/lib/soap/handsoap/parser.rb +0 -104
- data/lib/soap/handsoap/parsers/ews_parser.rb +0 -246
- data/lib/soap/soap_provider.rb +0 -64
|
@@ -0,0 +1,86 @@
|
|
|
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
|
+
module Viewpoint::EWS::MessageAccessors
|
|
19
|
+
include Viewpoint::EWS
|
|
20
|
+
|
|
21
|
+
# Send an E-mail message
|
|
22
|
+
#
|
|
23
|
+
# @param [Hash] opts A Hash with message params
|
|
24
|
+
# @option opts [String] :subject The message subject
|
|
25
|
+
# @option opts [String] :body The message body
|
|
26
|
+
# @option opts [Array] :to_recipients An array of e-mail addresses to send to
|
|
27
|
+
# @option opts [Array] :cc_recipients An array of e-mail addresses to send to
|
|
28
|
+
# @option opts [Array] :bcc_recipients An array of e-mail addresses to send to
|
|
29
|
+
# @option opts [Boolean] :draft if true it will save to the draft folder
|
|
30
|
+
# without sending the message.
|
|
31
|
+
# @option opts [String,Symbol,Hash] saved_item_folder_id Either a
|
|
32
|
+
# FolderId(String) or a DistinguishedFolderId(Symbol). You can also pass a
|
|
33
|
+
# Hash in the form: {id: <fold_id>, change_key: <change_key>}
|
|
34
|
+
# @option opts [Array<File>] :file_attachments an Array of File objects
|
|
35
|
+
# @return [Message,Boolean] Returns true if the message is sent, false if
|
|
36
|
+
# nothing is returned from EWS or if draft is true it will return the
|
|
37
|
+
# Message object. Finally, if something goes wrong, it raises an error
|
|
38
|
+
# with a message stating why the e-mail could not be sent.
|
|
39
|
+
# @todo Finish ItemAttachments
|
|
40
|
+
def send_message(opts = {}, &block)
|
|
41
|
+
msg = Template::Message.new opts.clone
|
|
42
|
+
yield msg if block_given?
|
|
43
|
+
if msg.has_attachments?
|
|
44
|
+
draft = msg.draft
|
|
45
|
+
msg.draft = true
|
|
46
|
+
resp = parse_create_item(ews.create_item(msg.to_ews))
|
|
47
|
+
msg.file_attachments.each do |f|
|
|
48
|
+
next unless f.kind_of?(File)
|
|
49
|
+
resp.add_file_attachment(f)
|
|
50
|
+
end
|
|
51
|
+
if draft
|
|
52
|
+
resp.submit_attachments!
|
|
53
|
+
resp
|
|
54
|
+
else
|
|
55
|
+
resp.submit!
|
|
56
|
+
end
|
|
57
|
+
else
|
|
58
|
+
resp = ews.create_item(msg.to_ews)
|
|
59
|
+
resp.response_messages ? parse_create_item(resp) : false
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# See #send_message for options
|
|
64
|
+
def draft_message(opts = {}, &block)
|
|
65
|
+
send_message opts.merge(draft: true), &block
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def parse_create_item(resp)
|
|
73
|
+
rm = resp.response_messages[0]
|
|
74
|
+
if(rm.status == 'Success')
|
|
75
|
+
rm.items.empty? ? true : parse_message(rm.items.first)
|
|
76
|
+
else
|
|
77
|
+
raise EwsError, "Could not send message. #{rm.code}: #{rm.message_text}"
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def parse_message(msg)
|
|
82
|
+
mtype = msg.keys.first
|
|
83
|
+
message = class_by_name(mtype).new(ews, msg[mtype])
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
end # Viewpoint::EWS::MessageAccessors
|
|
@@ -0,0 +1,33 @@
|
|
|
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::PushSubscriptionAccessors
|
|
20
|
+
include Viewpoint::EWS
|
|
21
|
+
|
|
22
|
+
def parse_send_notification(msg)
|
|
23
|
+
parser = Viewpoint::EWS::SOAP::EwsParser.new(msg)
|
|
24
|
+
resp = parser.parse response_class: Viewpoint::EWS::SOAP::EwsResponse
|
|
25
|
+
rmsg = resp.response_messages[0]
|
|
26
|
+
if rmsg.success?
|
|
27
|
+
rmsg
|
|
28
|
+
else
|
|
29
|
+
raise EwsSubscriptionError, "#{rmsg.code}: #{rmsg.message_text}"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end # Viewpoint::EWS::PushSubscriptionAccessors
|
data/lib/ews/soap.rb
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
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
|
+
# This module defines some constants and other niceties to make available to
|
|
20
|
+
# the underlying SOAP classes and modules that do the actual work.
|
|
21
|
+
module Viewpoint
|
|
22
|
+
module EWS
|
|
23
|
+
module SOAP
|
|
24
|
+
|
|
25
|
+
# CONSTANTS
|
|
26
|
+
|
|
27
|
+
NS_SOAP = 'soap'.freeze
|
|
28
|
+
NS_EWS_TYPES = 't'.freeze
|
|
29
|
+
NS_EWS_MESSAGES = 'm'.freeze
|
|
30
|
+
NAMESPACES = {
|
|
31
|
+
"xmlns:#{NS_SOAP}" => 'http://schemas.xmlsoap.org/soap/envelope/',
|
|
32
|
+
"xmlns:#{NS_EWS_TYPES}" => 'http://schemas.microsoft.com/exchange/services/2006/types',
|
|
33
|
+
"xmlns:#{NS_EWS_MESSAGES}" => 'http://schemas.microsoft.com/exchange/services/2006/messages',
|
|
34
|
+
}.freeze
|
|
35
|
+
|
|
36
|
+
# used in ResolveNames to determine where names are resolved
|
|
37
|
+
ActiveDirectory = 'ActiveDirectory'
|
|
38
|
+
ActiveDirectoryContacts = 'ActiveDirectoryContacts'
|
|
39
|
+
Contacts = 'Contacts'
|
|
40
|
+
ContactsActiveDirectory = 'ContactsActiveDirectory'
|
|
41
|
+
|
|
42
|
+
# Target specific Exchange Server versions
|
|
43
|
+
# @see http://msdn.microsoft.com/en-us/library/bb891876(v=exchg.140).aspx
|
|
44
|
+
VERSION_2007 = 'Exchange2007'
|
|
45
|
+
VERSION_2007_SP1 = 'Exchange2007_SP1'
|
|
46
|
+
VERSION_2010 = 'Exchange2010'
|
|
47
|
+
VERSION_2010_SP1 = 'Exchange2010_SP1'
|
|
48
|
+
VERSION_2010_SP2 = 'Exchange2010_SP2'
|
|
49
|
+
VERSION_2013 = 'Exchange2013'
|
|
50
|
+
VERSION_NONE = 'none'
|
|
51
|
+
|
|
52
|
+
HARD_DELETE = 'HardDelete'
|
|
53
|
+
SOFT_DELETE = 'SoftDelete'
|
|
54
|
+
MOVE_TO_DELETED_ITEMS = 'MoveToDeletedItems'
|
|
55
|
+
|
|
56
|
+
def initialize
|
|
57
|
+
@log = Logging.logger[self.class.name.to_s.to_sym]
|
|
58
|
+
@default_ns = NAMESPACES["xmlns:#{NS_EWS_MESSAGES}"]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
end # SOAP
|
|
62
|
+
end # EWS
|
|
63
|
+
end # Viewpoint
|
|
@@ -0,0 +1,1011 @@
|
|
|
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
|
+
module Viewpoint::EWS::SOAP
|
|
19
|
+
|
|
20
|
+
# This class includes the element builders. The idea is that each element should
|
|
21
|
+
# know how to build themselves so each parent element can delegate creation of
|
|
22
|
+
# subelements to a method of the same name with a '!' after it.
|
|
23
|
+
class EwsBuilder
|
|
24
|
+
|
|
25
|
+
attr_reader :nbuild
|
|
26
|
+
def initialize
|
|
27
|
+
@nbuild = Nokogiri::XML::Builder.new
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Build the SOAP envelope and yield this object so subelements can be built. Once
|
|
31
|
+
# you have the EwsBuilder object you can use the nbuild object like shown in the
|
|
32
|
+
# example for the Header section. The nbuild object is the underlying
|
|
33
|
+
# Nokogiri::XML::Builder object.
|
|
34
|
+
# @param [Hash] opts
|
|
35
|
+
# @option opts [String] :server_version The version string that should get
|
|
36
|
+
# set in the Header. See ExchangeWebService#initialize
|
|
37
|
+
# @example
|
|
38
|
+
# xb = EwsBuilder.new
|
|
39
|
+
# xb.build! do |part, b|
|
|
40
|
+
# if(part == :header)
|
|
41
|
+
# b.nbuild.MyVar('blablabla')
|
|
42
|
+
# else
|
|
43
|
+
# b.folder_shape!({:base_shape => 'Default'})
|
|
44
|
+
# end
|
|
45
|
+
# end
|
|
46
|
+
def build!(opts = {}, &block)
|
|
47
|
+
@nbuild.Envelope(NAMESPACES) do |node|
|
|
48
|
+
node.parent.namespace = parent_namespace(node)
|
|
49
|
+
node.Header {
|
|
50
|
+
set_version_header! opts[:server_version]
|
|
51
|
+
yield(:header, self) if block_given?
|
|
52
|
+
}
|
|
53
|
+
node.Body {
|
|
54
|
+
yield(:body, self) if block_given?
|
|
55
|
+
}
|
|
56
|
+
end
|
|
57
|
+
@nbuild.doc
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Build XML from a passed in Hash or Array in a specified format.
|
|
61
|
+
# @param [Array,Hash] elems The elements to add to the Builder. They must
|
|
62
|
+
# be specified like so:
|
|
63
|
+
# {:top =>
|
|
64
|
+
# { :xmlns => 'http://stonesthrow/soap',
|
|
65
|
+
# :sub_elements => [
|
|
66
|
+
# {:elem1 => {:text => 'inside'}},
|
|
67
|
+
# {:elem2 => {:text => 'inside2'}}
|
|
68
|
+
# ],
|
|
69
|
+
# :id => '3232', :tx_dd => 23, :asdf => 'turkey'
|
|
70
|
+
# }
|
|
71
|
+
# }
|
|
72
|
+
# or
|
|
73
|
+
# [ {:first => {:text => 'hello'}},
|
|
74
|
+
# {:second => {:text => 'world'}}
|
|
75
|
+
# ]
|
|
76
|
+
#
|
|
77
|
+
# NOTE: there are specialized keys for text (:text), child elements
|
|
78
|
+
# (:sub_elements) and namespaces (:xmlns).
|
|
79
|
+
def build_xml!(elems)
|
|
80
|
+
case elems.class.name
|
|
81
|
+
when 'Hash'
|
|
82
|
+
keys = elems.keys
|
|
83
|
+
vals = elems.values
|
|
84
|
+
if(keys.length > 1 && !vals.is_a?(Hash))
|
|
85
|
+
raise "invalid input: #{elems}"
|
|
86
|
+
end
|
|
87
|
+
vals = vals.first.clone
|
|
88
|
+
se = vals.delete(:sub_elements)
|
|
89
|
+
txt = vals.delete(:text)
|
|
90
|
+
|
|
91
|
+
@nbuild.send(keys.first.to_s.camel_case, txt, vals) {|x|
|
|
92
|
+
build_xml!(se) if se
|
|
93
|
+
}
|
|
94
|
+
when 'Array'
|
|
95
|
+
elems.each do |e|
|
|
96
|
+
build_xml!(e)
|
|
97
|
+
end
|
|
98
|
+
else
|
|
99
|
+
raise "Unsupported type: #{elems.class.name}"
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Build the FolderShape element
|
|
104
|
+
# @see http://msdn.microsoft.com/en-us/library/aa494311.aspx
|
|
105
|
+
# @param [Hash] folder_shape The folder shape structure to build from
|
|
106
|
+
# @todo need fully support all options
|
|
107
|
+
def folder_shape!(folder_shape)
|
|
108
|
+
@nbuild.FolderShape {
|
|
109
|
+
@nbuild.parent.default_namespace = @default_ns
|
|
110
|
+
base_shape!(folder_shape[:base_shape])
|
|
111
|
+
if(folder_shape[:additional_properties])
|
|
112
|
+
additional_properties!(folder_shape[:additional_properties])
|
|
113
|
+
end
|
|
114
|
+
}
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Build the ItemShape element
|
|
118
|
+
# @see http://msdn.microsoft.com/en-us/library/aa565261.aspx
|
|
119
|
+
# @param [Hash] item_shape The item shape structure to build from
|
|
120
|
+
# @todo need fully support all options
|
|
121
|
+
def item_shape!(item_shape)
|
|
122
|
+
@nbuild[NS_EWS_MESSAGES].ItemShape {
|
|
123
|
+
@nbuild.parent.default_namespace = @default_ns
|
|
124
|
+
base_shape!(item_shape[:base_shape])
|
|
125
|
+
body_type!(item_shape[:body_type]) if item_shape[:body_type]
|
|
126
|
+
if(item_shape[:additional_properties])
|
|
127
|
+
additional_properties!(item_shape[:additional_properties])
|
|
128
|
+
end
|
|
129
|
+
}
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Build the BaseShape element
|
|
133
|
+
# @see http://msdn.microsoft.com/en-us/library/aa580545.aspx
|
|
134
|
+
def base_shape!(base_shape)
|
|
135
|
+
@nbuild[NS_EWS_TYPES].BaseShape(base_shape.to_s.camel_case)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def body_type!(body_type)
|
|
139
|
+
body_type = body_type.to_s
|
|
140
|
+
if body_type =~ /html/i
|
|
141
|
+
body_type = body_type.upcase
|
|
142
|
+
else
|
|
143
|
+
body_type = body_type.downcase.capitalize
|
|
144
|
+
end
|
|
145
|
+
nbuild[NS_EWS_TYPES].BodyType(body_type)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# Build the ParentFolderIds element
|
|
149
|
+
# @see http://msdn.microsoft.com/en-us/library/aa565998.aspx
|
|
150
|
+
def parent_folder_ids!(pfids)
|
|
151
|
+
@nbuild[NS_EWS_MESSAGES].ParentFolderIds {
|
|
152
|
+
pfids.each do |pfid|
|
|
153
|
+
dispatch_folder_id!(pfid)
|
|
154
|
+
end
|
|
155
|
+
}
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Build the ParentFolderId element
|
|
159
|
+
# @see http://msdn.microsoft.com/en-us/library/aa563268.aspx
|
|
160
|
+
def parent_folder_id!(pfid)
|
|
161
|
+
@nbuild.ParentFolderId {
|
|
162
|
+
dispatch_folder_id!(pfid)
|
|
163
|
+
}
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Build the FolderIds element
|
|
167
|
+
# @see http://msdn.microsoft.com/en-us/library/aa580509.aspx
|
|
168
|
+
def folder_ids!(fids, act_as=nil)
|
|
169
|
+
ns = @nbuild.parent.name.match(/subscription/i) ? NS_EWS_TYPES : NS_EWS_MESSAGES
|
|
170
|
+
@nbuild[ns].FolderIds {
|
|
171
|
+
fids.each do |fid|
|
|
172
|
+
fid[:act_as] = act_as if act_as != nil
|
|
173
|
+
dispatch_folder_id!(fid)
|
|
174
|
+
end
|
|
175
|
+
}
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Build the SyncFolderId element
|
|
179
|
+
# @see http://msdn.microsoft.com/en-us/library/aa580296.aspx
|
|
180
|
+
def sync_folder_id!(fid)
|
|
181
|
+
@nbuild.SyncFolderId {
|
|
182
|
+
dispatch_folder_id!(fid)
|
|
183
|
+
}
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# Build the DistinguishedFolderId element
|
|
187
|
+
# @see http://msdn.microsoft.com/en-us/library/aa580808.aspx
|
|
188
|
+
# @todo add support for the Mailbox child object
|
|
189
|
+
def distinguished_folder_id!(dfid, change_key = nil, act_as = nil)
|
|
190
|
+
attribs = {'Id' => dfid.to_s}
|
|
191
|
+
attribs['ChangeKey'] = change_key if change_key
|
|
192
|
+
@nbuild[NS_EWS_TYPES].DistinguishedFolderId(attribs) {
|
|
193
|
+
if ! act_as.nil?
|
|
194
|
+
mailbox!({:email_address => act_as})
|
|
195
|
+
end
|
|
196
|
+
}
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# Build the FolderId element
|
|
200
|
+
# @see http://msdn.microsoft.com/en-us/library/aa579461.aspx
|
|
201
|
+
def folder_id!(fid, change_key = nil)
|
|
202
|
+
attribs = {'Id' => fid}
|
|
203
|
+
attribs['ChangeKey'] = change_key if change_key
|
|
204
|
+
@nbuild[NS_EWS_TYPES].FolderId(attribs)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# @see http://msdn.microsoft.com/en-us/library/aa563525(v=EXCHG.140).aspx
|
|
208
|
+
def item_ids!(item_ids)
|
|
209
|
+
@nbuild.ItemIds {
|
|
210
|
+
item_ids.each do |iid|
|
|
211
|
+
dispatch_item_id!(iid)
|
|
212
|
+
end
|
|
213
|
+
}
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def parent_item_id!(id)
|
|
217
|
+
nbuild.ParentItemId {|x|
|
|
218
|
+
x.parent['Id'] = id[:id]
|
|
219
|
+
x.parent['ChangeKey'] = id[:change_key] if id[:change_key]
|
|
220
|
+
}
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# @see http://msdn.microsoft.com/en-us/library/aa580234(v=EXCHG.140).aspx
|
|
224
|
+
def item_id!(id)
|
|
225
|
+
nbuild[NS_EWS_TYPES].ItemId {|x|
|
|
226
|
+
x.parent['Id'] = id[:id]
|
|
227
|
+
x.parent['ChangeKey'] = id[:change_key] if id[:change_key]
|
|
228
|
+
}
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# @see http://msdn.microsoft.com/en-us/library/aa580744(v=EXCHG.140).aspx
|
|
232
|
+
def occurrence_item_id!(id)
|
|
233
|
+
@nbuild[NS_EWS_TYPES].OccurrenceItemId {|x|
|
|
234
|
+
x.parent['RecurringMasterId'] = id[:recurring_master_id]
|
|
235
|
+
x.parent['ChangeKey'] = id[:change_key] if id[:change_key]
|
|
236
|
+
x.parent['InstanceIndex'] = id[:instance_index]
|
|
237
|
+
}
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
# @see http://msdn.microsoft.com/en-us/library/aa581019(v=EXCHG.140).aspx
|
|
241
|
+
def recurring_master_item_id!(id)
|
|
242
|
+
@nbuild[NS_EWS_TYPES].RecurringMasterItemId {|x|
|
|
243
|
+
x.parent['OccurrenceId'] = id[:occurrence_id]
|
|
244
|
+
x.parent['ChangeKey'] = id[:change_key] if id[:change_key]
|
|
245
|
+
}
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# @see http://msdn.microsoft.com/en-us/library/aa565020(v=EXCHG.140).aspx
|
|
249
|
+
def to_folder_id!(to_fid)
|
|
250
|
+
@nbuild[NS_EWS_MESSAGES].ToFolderId {
|
|
251
|
+
dispatch_folder_id!(to_fid)
|
|
252
|
+
}
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# @see http://msdn.microsoft.com/en-us/library/aa564009.aspx
|
|
256
|
+
def folders!(folders)
|
|
257
|
+
@nbuild.Folders {|x|
|
|
258
|
+
folders.each do |fold|
|
|
259
|
+
fold.each_pair do |ftype, vars| # convenience, should only be one pair
|
|
260
|
+
ftype = "#{ftype}!".to_sym
|
|
261
|
+
if self.respond_to? ftype
|
|
262
|
+
self.send ftype, vars
|
|
263
|
+
else
|
|
264
|
+
raise Viewpoint::EWS::EwsNotImplemented,
|
|
265
|
+
"#{ftype} not implemented as a builder."
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
}
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
def folder!(folder, type = :Folder)
|
|
273
|
+
nbuild[NS_EWS_TYPES].send(type) {|x|
|
|
274
|
+
folder.each_pair do |e,v|
|
|
275
|
+
ftype = "#{e}!".to_sym
|
|
276
|
+
if e == :folder_id
|
|
277
|
+
dispatch_folder_id!(v)
|
|
278
|
+
elsif self.respond_to?(ftype)
|
|
279
|
+
self.send ftype, v
|
|
280
|
+
else
|
|
281
|
+
raise Viewpoint::EWS::EwsNotImplemented,
|
|
282
|
+
"#{ftype} not implemented as a builder."
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
}
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
def calendar_folder!(folder)
|
|
289
|
+
folder! folder, :CalendarFolder
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
def contacts_folder!(folder)
|
|
293
|
+
folder! folder, :ContactsFolder
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
def search_folder!(folder)
|
|
297
|
+
folder! folder, :SearchFolder
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
def tasks_folder!(folder)
|
|
301
|
+
folder! folder, :TasksFolder
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
def display_name!(name)
|
|
305
|
+
nbuild[NS_EWS_TYPES].DisplayName(name)
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
# Build the AdditionalProperties element
|
|
309
|
+
# @see http://msdn.microsoft.com/en-us/library/aa563810.aspx
|
|
310
|
+
def additional_properties!(addprops)
|
|
311
|
+
@nbuild[NS_EWS_TYPES].AdditionalProperties {
|
|
312
|
+
addprops.each_pair {|k,v|
|
|
313
|
+
dispatch_field_uri!({k => v})
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
# Build the Mailbox element.
|
|
319
|
+
# This element is commonly used for delegation. Typically passing an
|
|
320
|
+
# email_address is sufficient
|
|
321
|
+
# @see http://msdn.microsoft.com/en-us/library/aa565036.aspx
|
|
322
|
+
# @param [Hash] mailbox A well-formated hash
|
|
323
|
+
def mailbox!(mbox)
|
|
324
|
+
nbuild[NS_EWS_TYPES].Mailbox {
|
|
325
|
+
name!(mbox[:name]) if mbox[:name]
|
|
326
|
+
email_address!(mbox[:email_address]) if mbox[:email_address]
|
|
327
|
+
address!(mbox[:address]) if mbox[:address] # for Availability query
|
|
328
|
+
routing_type!(mbox[:routing_type]) if mbox[:routing_type]
|
|
329
|
+
mailbox_type!(mbox[:mailbox_type]) if mbox[:mailbox_type]
|
|
330
|
+
item_id!(mbox[:item_id]) if mbox[:item_id]
|
|
331
|
+
}
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
def name!(name)
|
|
335
|
+
nbuild[NS_EWS_TYPES].Name(name)
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
def email_address!(email)
|
|
339
|
+
nbuild[NS_EWS_TYPES].EmailAddress(email)
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
def address!(email)
|
|
343
|
+
nbuild[NS_EWS_TYPES].Address(email)
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
# This is stupid. The only valid value is "SMTP"
|
|
347
|
+
def routing_type!(type)
|
|
348
|
+
nbuild[NS_EWS_TYPES].RoutingType(type)
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
def mailbox_type!(type)Standard
|
|
352
|
+
nbuild[NS_EWS_TYPES].MailboxType(type)
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
def user_oof_settings!(opts)
|
|
356
|
+
nbuild[NS_EWS_TYPES].UserOofSettings {
|
|
357
|
+
nbuild.OofState(opts[:oof_state].to_s.camel_case)
|
|
358
|
+
nbuild.ExternalAudience(opts[:external_audience].to_s.camel_case) if opts[:external_audience]
|
|
359
|
+
duration!(opts[:duration]) if opts[:duration]
|
|
360
|
+
nbuild.InternalReply {
|
|
361
|
+
nbuild.Message(opts[:internal_reply])
|
|
362
|
+
} if opts[:external_reply]
|
|
363
|
+
nbuild.ExternalReply {
|
|
364
|
+
nbuild.Message(opts[:external_reply])
|
|
365
|
+
} if opts[:external_reply]
|
|
366
|
+
}
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
def duration!(opts)
|
|
370
|
+
nbuild.Duration {
|
|
371
|
+
nbuild.StartTime(opts[:start_time].new_offset(0).strftime('%FT%H:%M:%SZ'))
|
|
372
|
+
nbuild.EndTime(opts[:end_time].new_offset(0).strftime('%FT%H:%M:%SZ'))
|
|
373
|
+
}
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
def mailbox_data!(md)
|
|
377
|
+
nbuild[NS_EWS_TYPES].MailboxData {
|
|
378
|
+
nbuild.Email {
|
|
379
|
+
mbox = md[:email]
|
|
380
|
+
name!(mbox[:name]) if mbox[:name]
|
|
381
|
+
address!(mbox[:address]) if mbox[:address] # for Availability query
|
|
382
|
+
routing_type!(mbox[:routing_type]) if mbox[:routing_type]
|
|
383
|
+
}
|
|
384
|
+
nbuild.AttendeeType 'Required'
|
|
385
|
+
}
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
def free_busy_view_options!(opts)
|
|
389
|
+
nbuild[NS_EWS_TYPES].FreeBusyViewOptions {
|
|
390
|
+
nbuild.TimeWindow {
|
|
391
|
+
nbuild.StartTime(opts[:time_window][:start_time])
|
|
392
|
+
nbuild.EndTime(opts[:time_window][:end_time])
|
|
393
|
+
}
|
|
394
|
+
nbuild.RequestedView(opts[:requested_view][:requested_free_busy_view].to_s.camel_case)
|
|
395
|
+
}
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
def suggestions_view_options!(opts)
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
def time_zone!(zone)
|
|
402
|
+
nbuild[NS_EWS_TYPES].TimeZone {
|
|
403
|
+
nbuild.Bias(480)
|
|
404
|
+
nbuild.StandardTime {
|
|
405
|
+
nbuild.Bias(0)
|
|
406
|
+
nbuild.Time("02:00:00")
|
|
407
|
+
nbuild.DayOrder(5)
|
|
408
|
+
nbuild.Month(10)
|
|
409
|
+
nbuild.DayOfWeek('Sunday')
|
|
410
|
+
}
|
|
411
|
+
nbuild.DaylightTime {
|
|
412
|
+
nbuild.Bias(-60)
|
|
413
|
+
nbuild.Time("02:00:00")
|
|
414
|
+
nbuild.DayOrder(1)
|
|
415
|
+
nbuild.Month(4)
|
|
416
|
+
nbuild.DayOfWeek('Sunday')
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
end
|
|
420
|
+
|
|
421
|
+
# Build the Restriction element
|
|
422
|
+
# @see http://msdn.microsoft.com/en-us/library/aa563791.aspx
|
|
423
|
+
# @param [Hash] restriction a well-formatted Hash that can be fed to #build_xml!
|
|
424
|
+
def restriction!(restriction)
|
|
425
|
+
@nbuild[NS_EWS_MESSAGES].Restriction {
|
|
426
|
+
restriction.each_pair do |k,v|
|
|
427
|
+
self.send normalize_type(k), v
|
|
428
|
+
end
|
|
429
|
+
}
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
def and_r(expr)
|
|
433
|
+
and_or('And', expr)
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
def or_r(expr)
|
|
437
|
+
and_or('Or', expr)
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
def and_or(type, expr)
|
|
441
|
+
@nbuild[NS_EWS_TYPES].send(type) {
|
|
442
|
+
expr.each do |e|
|
|
443
|
+
type = e.keys.first
|
|
444
|
+
self.send normalize_type(type), e[type]
|
|
445
|
+
end
|
|
446
|
+
}
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
def not_r(expr)
|
|
450
|
+
@nbuild[NS_EWS_TYPES].Not {
|
|
451
|
+
type = expr.keys.first
|
|
452
|
+
self.send(type, expr[type])
|
|
453
|
+
}
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
def contains(expr)
|
|
457
|
+
@nbuild[NS_EWS_TYPES].Contains(
|
|
458
|
+
'ContainmentMode' => expr.delete(:containment_mode),
|
|
459
|
+
'ContainmentComparison' => expr.delete(:containment_comparison)) {
|
|
460
|
+
c = expr.delete(:constant) # remove constant 1st for ordering
|
|
461
|
+
type = expr.keys.first
|
|
462
|
+
self.send(type, expr[type])
|
|
463
|
+
constant(c)
|
|
464
|
+
}
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
def excludes(expr)
|
|
468
|
+
@nbuild[NS_EWS_TYPES].Excludes {
|
|
469
|
+
b = expr.delete(:bitmask) # remove bitmask 1st for ordering
|
|
470
|
+
type = expr.keys.first
|
|
471
|
+
self.send(type, expr[type])
|
|
472
|
+
bitmask(b)
|
|
473
|
+
}
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
def exists(expr)
|
|
477
|
+
@nbuild[NS_EWS_TYPES].Exists {
|
|
478
|
+
type = expr.keys.first
|
|
479
|
+
self.send(type, expr[type])
|
|
480
|
+
}
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
def bitmask(expr)
|
|
484
|
+
@nbuild[NS_EWS_TYPES].Bitmask('Value' => expr[:value])
|
|
485
|
+
end
|
|
486
|
+
|
|
487
|
+
def is_equal_to(expr)
|
|
488
|
+
restriction_compare('IsEqualTo',expr)
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
def is_greater_than(expr)
|
|
492
|
+
restriction_compare('IsGreaterThan',expr)
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
def is_greater_than_or_equal_to(expr)
|
|
496
|
+
restriction_compare('IsGreaterThanOrEqualTo',expr)
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
def is_less_than(expr)
|
|
500
|
+
restriction_compare('IsLessThan',expr)
|
|
501
|
+
end
|
|
502
|
+
|
|
503
|
+
def is_less_than_or_equal_to(expr)
|
|
504
|
+
restriction_compare('IsLessThanOrEqualTo',expr)
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
def is_not_equal_to(expr)
|
|
508
|
+
restriction_compare('IsNotEqualTo',expr)
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
def restriction_compare(type,expr)
|
|
512
|
+
nbuild[NS_EWS_TYPES].send(type) {
|
|
513
|
+
expr.each do |e|
|
|
514
|
+
e.each_pair do |k,v|
|
|
515
|
+
self.send(k, v)
|
|
516
|
+
end
|
|
517
|
+
end
|
|
518
|
+
}
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
def field_uRI(expr)
|
|
522
|
+
nbuild[NS_EWS_TYPES].FieldURI('FieldURI' => expr[:field_uRI])
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
def indexed_field_uRI(expr)
|
|
526
|
+
nbuild[NS_EWS_TYPES].IndexedFieldURI(
|
|
527
|
+
'FieldURI' => expr[:field_uRI],
|
|
528
|
+
'FieldIndex' => expr[:field_index]
|
|
529
|
+
)
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
def extended_field_uRI(expr)
|
|
533
|
+
nbuild[NS_EWS_TYPES].ExtendedFieldURI {
|
|
534
|
+
nbuild.parent['DistinguishedPropertySetId'] = expr[:distinguished_property_set_id] if expr[:distinguished_property_set_id]
|
|
535
|
+
nbuild.parent['PropertySetId'] = expr[:property_set_id] if expr[:property_set_id]
|
|
536
|
+
nbuild.parent['PropertyTag'] = expr[:property_tag] if expr[:property_tag]
|
|
537
|
+
nbuild.parent['PropertyName'] = expr[:property_name] if expr[:property_name]
|
|
538
|
+
nbuild.parent['PropertyId'] = expr[:property_id] if expr[:property_id]
|
|
539
|
+
nbuild.parent['PropertyType'] = expr[:property_type] if expr[:property_type]
|
|
540
|
+
}
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
def field_uRI_or_constant(expr)
|
|
544
|
+
nbuild[NS_EWS_TYPES].FieldURIOrConstant {
|
|
545
|
+
type = expr.keys.first
|
|
546
|
+
self.send(type, expr[type])
|
|
547
|
+
}
|
|
548
|
+
end
|
|
549
|
+
|
|
550
|
+
def constant(expr)
|
|
551
|
+
nbuild[NS_EWS_TYPES].Constant('Value' => expr[:value])
|
|
552
|
+
end
|
|
553
|
+
|
|
554
|
+
# Build the CalendarView element
|
|
555
|
+
def calendar_view!(cal_view)
|
|
556
|
+
attribs = {}
|
|
557
|
+
cal_view.each_pair {|k,v| attribs[k.to_s.camel_case] = v.to_s}
|
|
558
|
+
@nbuild[NS_EWS_MESSAGES].CalendarView(attribs)
|
|
559
|
+
end
|
|
560
|
+
|
|
561
|
+
# Build the ContactsView element
|
|
562
|
+
def contacts_view!(con_view)
|
|
563
|
+
attribs = {}
|
|
564
|
+
con_view.each_pair {|k,v| attribs[k.to_s.camel_case] = v.to_s}
|
|
565
|
+
@nbuild[NS_EWS_MESSAGES].ContactsView(attribs)
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
# @see http://msdn.microsoft.com/en-us/library/aa579678(v=EXCHG.140).aspx
|
|
569
|
+
def event_types!(evtypes)
|
|
570
|
+
@nbuild[NS_EWS_TYPES].EventTypes {
|
|
571
|
+
evtypes.each do |et|
|
|
572
|
+
@nbuild[NS_EWS_TYPES].EventType(et.to_s.camel_case)
|
|
573
|
+
end
|
|
574
|
+
}
|
|
575
|
+
end
|
|
576
|
+
|
|
577
|
+
# @see http://msdn.microsoft.com/en-us/library/aa565886(v=EXCHG.140).aspx
|
|
578
|
+
def watermark!(wmark, ns = NS_EWS_TYPES)
|
|
579
|
+
@nbuild[ns].Watermark(wmark)
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
# @see http://msdn.microsoft.com/en-us/library/aa565201(v=EXCHG.140).aspx
|
|
583
|
+
def timeout!(tout)
|
|
584
|
+
@nbuild[NS_EWS_TYPES].Timeout(tout)
|
|
585
|
+
end
|
|
586
|
+
|
|
587
|
+
# @see http://msdn.microsoft.com/en-us/library/aa564048(v=EXCHG.140).aspx
|
|
588
|
+
def status_frequency!(freq)
|
|
589
|
+
@nbuild[NS_EWS_TYPES].StatusFrequency(freq)
|
|
590
|
+
end
|
|
591
|
+
|
|
592
|
+
# @see http://msdn.microsoft.com/en-us/library/aa566309(v=EXCHG.140).aspx
|
|
593
|
+
def uRL!(url)
|
|
594
|
+
@nbuild[NS_EWS_TYPES].URL(url)
|
|
595
|
+
end
|
|
596
|
+
|
|
597
|
+
# @see http://msdn.microsoft.com/en-us/library/aa563790(v=EXCHG.140).aspx
|
|
598
|
+
def subscription_id!(subid)
|
|
599
|
+
@nbuild.SubscriptionId(subid)
|
|
600
|
+
end
|
|
601
|
+
|
|
602
|
+
# @see http://msdn.microsoft.com/en-us/library/aa563455(v=EXCHG.140).aspx
|
|
603
|
+
def pull_subscription_request(subopts)
|
|
604
|
+
subscribe_all = subopts[:subscribe_to_all_folders] ? 'true' : 'false'
|
|
605
|
+
@nbuild.PullSubscriptionRequest('SubscribeToAllFolders' => subscribe_all) {
|
|
606
|
+
folder_ids!(subopts[:folder_ids]) if subopts[:folder_ids]
|
|
607
|
+
event_types!(subopts[:event_types]) if subopts[:event_types]
|
|
608
|
+
watermark!(subopts[:watermark]) if subopts[:watermark]
|
|
609
|
+
timeout!(subopts[:timeout]) if subopts[:timeout]
|
|
610
|
+
}
|
|
611
|
+
end
|
|
612
|
+
|
|
613
|
+
# @see http://msdn.microsoft.com/en-us/library/aa563599(v=EXCHG.140).aspx
|
|
614
|
+
def push_subscription_request(subopts)
|
|
615
|
+
subscribe_all = subopts[:subscribe_to_all_folders] ? 'true' : 'false'
|
|
616
|
+
@nbuild.PushSubscriptionRequest('SubscribeToAllFolders' => subscribe_all) {
|
|
617
|
+
folder_ids!(subopts[:folder_ids]) if subopts[:folder_ids]
|
|
618
|
+
event_types!(subopts[:event_types]) if subopts[:event_types]
|
|
619
|
+
watermark!(subopts[:watermark]) if subopts[:watermark]
|
|
620
|
+
status_frequency!(subopts[:status_frequency]) if subopts[:status_frequency]
|
|
621
|
+
uRL!(subopts[:uRL]) if subopts[:uRL]
|
|
622
|
+
}
|
|
623
|
+
end
|
|
624
|
+
|
|
625
|
+
# @see http://msdn.microsoft.com/en-us/library/ff406182(v=EXCHG.140).aspx
|
|
626
|
+
def streaming_subscription_request(subopts)
|
|
627
|
+
subscribe_all = subopts[:subscribe_to_all_folders] ? 'true' : 'false'
|
|
628
|
+
@nbuild.StreamingSubscriptionRequest('SubscribeToAllFolders' => subscribe_all) {
|
|
629
|
+
folder_ids!(subopts[:folder_ids]) if subopts[:folder_ids]
|
|
630
|
+
event_types!(subopts[:event_types]) if subopts[:event_types]
|
|
631
|
+
}
|
|
632
|
+
end
|
|
633
|
+
|
|
634
|
+
# @see http://msdn.microsoft.com/en-us/library/aa565970(v=EXCHG.140).aspx
|
|
635
|
+
def sync_state!(syncstate)
|
|
636
|
+
@nbuild.SyncState(syncstate)
|
|
637
|
+
end
|
|
638
|
+
|
|
639
|
+
# @see http://msdn.microsoft.com/en-us/library/aa563785(v=EXCHG.140).aspx
|
|
640
|
+
def ignore!(item_ids)
|
|
641
|
+
@nbuild.Ignore {
|
|
642
|
+
item_ids.each do |iid|
|
|
643
|
+
item_id!(iid)
|
|
644
|
+
end
|
|
645
|
+
}
|
|
646
|
+
end
|
|
647
|
+
|
|
648
|
+
# @see http://msdn.microsoft.com/en-us/library/aa566325(v=EXCHG.140).aspx
|
|
649
|
+
def max_changes_returned!(cnum)
|
|
650
|
+
@nbuild[NS_EWS_MESSAGES].MaxChangesReturned(cnum)
|
|
651
|
+
end
|
|
652
|
+
|
|
653
|
+
# @see http://msdn.microsoft.com/en-us/library/dd899531(v=EXCHG.140).aspx
|
|
654
|
+
def sync_scope!(scope)
|
|
655
|
+
@nbuild.SyncScope(scope)
|
|
656
|
+
end
|
|
657
|
+
|
|
658
|
+
# @see http://msdn.microsoft.com/en-us/library/aa580758(v=EXCHG.140).aspx
|
|
659
|
+
def saved_item_folder_id!(fid)
|
|
660
|
+
@nbuild.SavedItemFolderId {
|
|
661
|
+
dispatch_folder_id!(fid)
|
|
662
|
+
}
|
|
663
|
+
end
|
|
664
|
+
|
|
665
|
+
# @see http://msdn.microsoft.com/en-us/library/aa565652(v=exchg.140).aspx
|
|
666
|
+
def item!(item)
|
|
667
|
+
nbuild.Item {
|
|
668
|
+
item.each_pair {|k,v|
|
|
669
|
+
self.send("#{k}!", v)
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
end
|
|
673
|
+
|
|
674
|
+
def message!(item)
|
|
675
|
+
nbuild[NS_EWS_TYPES].Message {
|
|
676
|
+
item.each_pair {|k,v|
|
|
677
|
+
self.send("#{k}!", v)
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
end
|
|
681
|
+
|
|
682
|
+
def calendar_item!(item)
|
|
683
|
+
nbuild[NS_EWS_TYPES].CalendarItem {
|
|
684
|
+
item.each_pair {|k,v|
|
|
685
|
+
self.send("#{k}!", v)
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
end
|
|
689
|
+
|
|
690
|
+
def forward_item!(item)
|
|
691
|
+
nbuild[NS_EWS_TYPES].ForwardItem {
|
|
692
|
+
item.each_pair {|k,v|
|
|
693
|
+
self.send("#{k}!", v)
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
end
|
|
697
|
+
|
|
698
|
+
def reply_to_item!(item)
|
|
699
|
+
nbuild[NS_EWS_TYPES].ReplyToItem {
|
|
700
|
+
item.each_pair {|k,v|
|
|
701
|
+
self.send("#{k}!", v)
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
end
|
|
705
|
+
|
|
706
|
+
def reply_all_to_item!(item)
|
|
707
|
+
nbuild[NS_EWS_TYPES].ReplyAllToItem {
|
|
708
|
+
item.each_pair {|k,v|
|
|
709
|
+
self.send("#{k}!", v)
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
end
|
|
713
|
+
|
|
714
|
+
def reference_item_id!(id)
|
|
715
|
+
nbuild[NS_EWS_TYPES].ReferenceItemId {|x|
|
|
716
|
+
x.parent['Id'] = id[:id]
|
|
717
|
+
x.parent['ChangeKey'] = id[:change_key] if id[:change_key]
|
|
718
|
+
}
|
|
719
|
+
end
|
|
720
|
+
|
|
721
|
+
def subject!(sub)
|
|
722
|
+
nbuild[NS_EWS_TYPES].Subject(sub)
|
|
723
|
+
end
|
|
724
|
+
|
|
725
|
+
def body!(b)
|
|
726
|
+
nbuild[NS_EWS_TYPES].Body(b[:text]) {|x|
|
|
727
|
+
x.parent['BodyType'] = b[:body_type] if b[:body_type]
|
|
728
|
+
}
|
|
729
|
+
end
|
|
730
|
+
|
|
731
|
+
def new_body_content!(b)
|
|
732
|
+
nbuild[NS_EWS_TYPES].NewBodyContent(b[:text]) {|x|
|
|
733
|
+
x.parent['BodyType'] = b[:body_type] if b[:body_type]
|
|
734
|
+
}
|
|
735
|
+
end
|
|
736
|
+
|
|
737
|
+
# @see http://msdn.microsoft.com/en-us/library/aa563719(v=exchg.140).aspx
|
|
738
|
+
# @param [Array] r An array of Mailbox type hashes to send to #mailbox!
|
|
739
|
+
def to_recipients!(r)
|
|
740
|
+
nbuild[NS_EWS_TYPES].ToRecipients {
|
|
741
|
+
r.each {|mbox| mailbox!(mbox[:mailbox]) }
|
|
742
|
+
}
|
|
743
|
+
end
|
|
744
|
+
|
|
745
|
+
def cc_recipients!(r)
|
|
746
|
+
nbuild[NS_EWS_TYPES].CcRecipients {
|
|
747
|
+
r.each {|mbox| mailbox!(mbox[:mailbox]) }
|
|
748
|
+
}
|
|
749
|
+
end
|
|
750
|
+
|
|
751
|
+
def bcc_recipients!(r)
|
|
752
|
+
nbuild[NS_EWS_TYPES].BccRecipients {
|
|
753
|
+
r.each {|mbox| mailbox!(mbox[:mailbox]) }
|
|
754
|
+
}
|
|
755
|
+
end
|
|
756
|
+
|
|
757
|
+
def required_attendees!(attendees)
|
|
758
|
+
nbuild[NS_EWS_TYPES].RequiredAttendees {
|
|
759
|
+
attendees.each {|a| attendee!(a[:attendee])}
|
|
760
|
+
}
|
|
761
|
+
end
|
|
762
|
+
|
|
763
|
+
def optional_attendees!(attendees)
|
|
764
|
+
nbuild[NS_EWS_TYPES].OptionalAttendees {
|
|
765
|
+
attendees.each {|a| attendee!(a[:attendee])}
|
|
766
|
+
}
|
|
767
|
+
end
|
|
768
|
+
|
|
769
|
+
def resources!(attendees)
|
|
770
|
+
nbuild[NS_EWS_TYPES].Resources {
|
|
771
|
+
attendees.each {|a| attendee!(a[:attendee])}
|
|
772
|
+
}
|
|
773
|
+
end
|
|
774
|
+
|
|
775
|
+
def attendee!(a)
|
|
776
|
+
nbuild[NS_EWS_TYPES].Attendee {
|
|
777
|
+
mailbox!(a[:mailbox])
|
|
778
|
+
#@todo support ResponseType, LastResponseTime: http://msdn.microsoft.com/en-us/library/aa580339.aspx
|
|
779
|
+
}
|
|
780
|
+
end
|
|
781
|
+
|
|
782
|
+
def start!(st)
|
|
783
|
+
nbuild[NS_EWS_TYPES].Start(st[:text])
|
|
784
|
+
end
|
|
785
|
+
|
|
786
|
+
def end!(et)
|
|
787
|
+
nbuild[NS_EWS_TYPES].End(et[:text])
|
|
788
|
+
end
|
|
789
|
+
|
|
790
|
+
# @see http://msdn.microsoft.com/en-us/library/aa565428(v=exchg.140).aspx
|
|
791
|
+
def item_changes!(changes)
|
|
792
|
+
nbuild.ItemChanges {
|
|
793
|
+
changes.each do |chg|
|
|
794
|
+
item_change!(chg)
|
|
795
|
+
end
|
|
796
|
+
}
|
|
797
|
+
end
|
|
798
|
+
|
|
799
|
+
# @see http://msdn.microsoft.com/en-us/library/aa581081(v=exchg.140).aspx
|
|
800
|
+
def item_change!(change)
|
|
801
|
+
@nbuild[NS_EWS_TYPES].ItemChange {
|
|
802
|
+
updates = change.delete(:updates) # Remove updates so dispatch_item_id works correctly
|
|
803
|
+
dispatch_item_id!(change)
|
|
804
|
+
updates!(updates)
|
|
805
|
+
}
|
|
806
|
+
end
|
|
807
|
+
|
|
808
|
+
# @see http://msdn.microsoft.com/en-us/library/aa581074(v=exchg.140).aspx
|
|
809
|
+
def updates!(updates)
|
|
810
|
+
@nbuild[NS_EWS_TYPES].Updates {
|
|
811
|
+
updates.each do |update|
|
|
812
|
+
dispatch_update_type!(update)
|
|
813
|
+
end
|
|
814
|
+
}
|
|
815
|
+
end
|
|
816
|
+
|
|
817
|
+
# @see http://msdn.microsoft.com/en-us/library/aa581317(v=exchg.140).aspx
|
|
818
|
+
def append_to_item_field!(upd)
|
|
819
|
+
uri = upd.select {|k,v| k =~ /_uri/i}
|
|
820
|
+
raise EwsBadArgumentError, "Bad argument given for AppendToItemField." if uri.keys.length != 1
|
|
821
|
+
upd.delete(uri.keys.first)
|
|
822
|
+
@nbuild.AppendToItemField {
|
|
823
|
+
dispatch_field_uri!(uri)
|
|
824
|
+
dispatch_field_item!(upd)
|
|
825
|
+
}
|
|
826
|
+
end
|
|
827
|
+
|
|
828
|
+
# @see http://msdn.microsoft.com/en-us/library/aa581487(v=exchg.140).aspx
|
|
829
|
+
def set_item_field!(upd)
|
|
830
|
+
uri = upd.select {|k,v| k =~ /_uri/i}
|
|
831
|
+
raise EwsBadArgumentError, "Bad argument given for SetItemField." if uri.keys.length != 1
|
|
832
|
+
upd.delete(uri.keys.first)
|
|
833
|
+
@nbuild.SetItemField {
|
|
834
|
+
dispatch_field_uri!(uri)
|
|
835
|
+
dispatch_field_item!(upd)
|
|
836
|
+
}
|
|
837
|
+
end
|
|
838
|
+
|
|
839
|
+
# @see http://msdn.microsoft.com/en-us/library/aa580330(v=exchg.140).aspx
|
|
840
|
+
def delete_item_field!(upd)
|
|
841
|
+
uri = upd.select {|k,v| k =~ /_uri/i}
|
|
842
|
+
raise EwsBadArgumentError, "Bad argument given for SetItemField." if uri.keys.length != 1
|
|
843
|
+
@nbuild.DeleteItemField {
|
|
844
|
+
dispatch_field_uri!(uri)
|
|
845
|
+
}
|
|
846
|
+
end
|
|
847
|
+
|
|
848
|
+
# @see http://msdn.microsoft.com/en-us/library/ff709497(v=exchg.140).aspx
|
|
849
|
+
def return_new_item_ids!(retval)
|
|
850
|
+
@nbuild.ReturnNewItemIds(retval)
|
|
851
|
+
end
|
|
852
|
+
|
|
853
|
+
def file_attachment!(fa)
|
|
854
|
+
@nbuild[NS_EWS_TYPES].FileAttachment {
|
|
855
|
+
@nbuild.Name(fa.name)
|
|
856
|
+
@nbuild.Content(fa.content)
|
|
857
|
+
}
|
|
858
|
+
end
|
|
859
|
+
|
|
860
|
+
def item_attachment!(ia)
|
|
861
|
+
@nbuild[NS_EWS_TYPES].ItemAttachment {
|
|
862
|
+
@nbuild.Name(ia.name)
|
|
863
|
+
@nbuild.Item {
|
|
864
|
+
item_id!(ia.item)
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
end
|
|
868
|
+
|
|
869
|
+
# Build the AttachmentIds element
|
|
870
|
+
# @see http://msdn.microsoft.com/en-us/library/aa580686.aspx
|
|
871
|
+
def attachment_ids!(aids)
|
|
872
|
+
@nbuild.AttachmentIds {
|
|
873
|
+
@nbuild.parent.default_namespace = @default_ns
|
|
874
|
+
aids.each do |aid|
|
|
875
|
+
attachment_id!(aid)
|
|
876
|
+
end
|
|
877
|
+
}
|
|
878
|
+
end
|
|
879
|
+
|
|
880
|
+
# Build the AttachmentId element
|
|
881
|
+
# @see http://msdn.microsoft.com/en-us/library/aa580764.aspx
|
|
882
|
+
def attachment_id!(aid)
|
|
883
|
+
attribs = {'Id' => aid}
|
|
884
|
+
@nbuild[NS_EWS_TYPES].AttachmentId(attribs)
|
|
885
|
+
end
|
|
886
|
+
|
|
887
|
+
def user_configuration_name!(cfg_name)
|
|
888
|
+
attribs = {'Name' => cfg_name.delete(:name)}
|
|
889
|
+
@nbuild[NS_EWS_MESSAGES].UserConfigurationName(attribs) {
|
|
890
|
+
fid = cfg_name.keys.first
|
|
891
|
+
self.send "#{fid}!", cfg_name[fid][:id], cfg_name[fid][:change_key]
|
|
892
|
+
}
|
|
893
|
+
end
|
|
894
|
+
|
|
895
|
+
def user_configuration_properties!(cfg_prop)
|
|
896
|
+
@nbuild[NS_EWS_MESSAGES].UserConfigurationProperties(cfg_prop)
|
|
897
|
+
end
|
|
898
|
+
|
|
899
|
+
# ---------------------- Helpers -------------------- #
|
|
900
|
+
|
|
901
|
+
# A helper method to dispatch to a FolderId or DistinguishedFolderId correctly
|
|
902
|
+
# @param [Hash] fid A folder_id
|
|
903
|
+
# Ex: {:id => myid, :change_key => ck}
|
|
904
|
+
def dispatch_folder_id!(fid)
|
|
905
|
+
if(fid[:id].is_a?(String))
|
|
906
|
+
folder_id!(fid[:id], fid[:change_key])
|
|
907
|
+
elsif(fid[:id].is_a?(Symbol))
|
|
908
|
+
distinguished_folder_id!(fid[:id], fid[:change_key], fid[:act_as])
|
|
909
|
+
else
|
|
910
|
+
raise EwsBadArgumentError, "Bad argument given for a FolderId. #{fid[:id].class}"
|
|
911
|
+
end
|
|
912
|
+
end
|
|
913
|
+
|
|
914
|
+
# A helper method to dispatch to an ItemId, OccurrenceItemId, or a RecurringMasterItemId
|
|
915
|
+
# @param [Hash] iid The item id of some type
|
|
916
|
+
def dispatch_item_id!(iid)
|
|
917
|
+
type = iid.keys.first
|
|
918
|
+
item = iid[type]
|
|
919
|
+
case type
|
|
920
|
+
when :item_id
|
|
921
|
+
item_id!(item)
|
|
922
|
+
when :occurrence_item_id
|
|
923
|
+
occurrence_item_id!(
|
|
924
|
+
item[:recurring_master_id], item[:change_key], item[:instance_index])
|
|
925
|
+
when :recurring_master_item_id
|
|
926
|
+
recurring_master_item_id!(item[:occurrence_id], item[:change_key])
|
|
927
|
+
else
|
|
928
|
+
raise EwsBadArgumentError, "Bad ItemId type. #{type}"
|
|
929
|
+
end
|
|
930
|
+
end
|
|
931
|
+
|
|
932
|
+
# A helper method to dispatch to a AppendToItemField, SetItemField, or
|
|
933
|
+
# DeleteItemField
|
|
934
|
+
# @param [Hash] update An update of some type
|
|
935
|
+
def dispatch_update_type!(update)
|
|
936
|
+
type = update.keys.first
|
|
937
|
+
upd = update[type]
|
|
938
|
+
case type
|
|
939
|
+
when :append_to_item_field
|
|
940
|
+
append_to_item_field!(upd)
|
|
941
|
+
when :set_item_field
|
|
942
|
+
set_item_field!(upd)
|
|
943
|
+
when :delete_item_field
|
|
944
|
+
delete_item_field!(upd)
|
|
945
|
+
else
|
|
946
|
+
raise EwsBadArgumentError, "Bad Update type. #{type}"
|
|
947
|
+
end
|
|
948
|
+
end
|
|
949
|
+
|
|
950
|
+
# A helper to dispatch to a FieldURI, IndexedFieldURI, or an ExtendedFieldURI
|
|
951
|
+
# @todo Implement ExtendedFieldURI
|
|
952
|
+
def dispatch_field_uri!(uri)
|
|
953
|
+
type = uri.keys.first
|
|
954
|
+
vals = uri[type].is_a?(Array) ? uri[type] : [uri[type]]
|
|
955
|
+
case type
|
|
956
|
+
when :field_uRI, :field_uri
|
|
957
|
+
vals.each do |val|
|
|
958
|
+
nbuild.FieldURI('FieldURI' => val[:field_uRI])
|
|
959
|
+
end
|
|
960
|
+
when :indexed_field_uRI, :indexed_field_uri
|
|
961
|
+
vals.each do |val|
|
|
962
|
+
nbuild.IndexedFieldURI('FieldURI' => val[:field_uRI], 'FieldIndex' => val[:field_index])
|
|
963
|
+
end
|
|
964
|
+
when :extended_field_uRI, :extended_field_uri
|
|
965
|
+
vals.each do |val|
|
|
966
|
+
nbuild.ExtendedFieldURI {
|
|
967
|
+
nbuild.parent['DistinguishedPropertySetId'] = val[:distinguished_property_set_id] if val[:distinguished_property_set_id]
|
|
968
|
+
nbuild.parent['PropertySetId'] = val[:property_set_id] if val[:property_set_id]
|
|
969
|
+
nbuild.parent['PropertyTag'] = val[:property_tag] if val[:property_tag]
|
|
970
|
+
nbuild.parent['PropertyName'] = val[:property_name] if val[:property_name]
|
|
971
|
+
nbuild.parent['PropertyId'] = val[:property_id] if val[:property_id]
|
|
972
|
+
nbuild.parent['PropertyType'] = val[:property_type] if val[:property_type]
|
|
973
|
+
}
|
|
974
|
+
end
|
|
975
|
+
else
|
|
976
|
+
raise EwsBadArgumentError, "Bad URI type. #{type}"
|
|
977
|
+
end
|
|
978
|
+
|
|
979
|
+
end
|
|
980
|
+
|
|
981
|
+
def dispatch_field_item!(item)
|
|
982
|
+
build_xml!(item)
|
|
983
|
+
end
|
|
984
|
+
|
|
985
|
+
|
|
986
|
+
private
|
|
987
|
+
|
|
988
|
+
def parent_namespace(node)
|
|
989
|
+
node.parent.namespace_definitions.find {|ns| ns.prefix == NS_SOAP}
|
|
990
|
+
end
|
|
991
|
+
|
|
992
|
+
def set_version_header!(version)
|
|
993
|
+
if version && !(version == 'none')
|
|
994
|
+
nbuild[NS_EWS_TYPES].RequestServerVersion {|x|
|
|
995
|
+
x.parent['Version'] = version
|
|
996
|
+
}
|
|
997
|
+
end
|
|
998
|
+
end
|
|
999
|
+
|
|
1000
|
+
# some methods need special naming so they use the '_r' suffix like 'and'
|
|
1001
|
+
def normalize_type(type)
|
|
1002
|
+
case type
|
|
1003
|
+
when :and, :or, :not
|
|
1004
|
+
"#{type}_r".to_sym
|
|
1005
|
+
else
|
|
1006
|
+
type
|
|
1007
|
+
end
|
|
1008
|
+
end
|
|
1009
|
+
|
|
1010
|
+
end # EwsBuilder
|
|
1011
|
+
end # Viewpoint::EWS::SOAP
|