viewpoint 0.0.5 → 0.1.0
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 +84 -45
- data/Rakefile +7 -5
- data/TODO +6 -0
- data/VERSION +1 -1
- data/lib/exceptions/exceptions.rb +34 -0
- data/lib/extensions/string.rb +37 -0
- data/lib/model/calendar_folder.rb +45 -0
- data/lib/model/calendar_item.rb +145 -0
- data/lib/model/contact.rb +58 -0
- data/lib/model/contacts_folder.rb +35 -0
- data/lib/model/distribution_list.rb +26 -0
- data/lib/model/event.rb +118 -0
- data/lib/model/folder.rb +36 -0
- data/lib/model/generic_folder.rb +302 -0
- data/lib/model/item.rb +126 -0
- data/lib/model/mailbox_user.rb +107 -0
- data/lib/model/meeting_cancellation.rb +28 -0
- data/lib/{viewpoint/errors.rb → model/meeting_message.rb} +10 -14
- data/lib/model/meeting_request.rb +26 -0
- data/lib/model/meeting_response.rb +26 -0
- data/lib/model/message.rb +73 -0
- data/lib/model/model.rb +161 -0
- data/lib/model/search_folder.rb +36 -0
- data/lib/model/task.rb +62 -0
- data/lib/model/task_list.rb +19 -0
- data/lib/model/tasks_folder.rb +33 -0
- data/lib/soap/handsoap/builder.rb +22 -0
- data/lib/soap/handsoap/builders/ews_build_helpers.rb +317 -0
- data/lib/soap/handsoap/builders/ews_builder.rb +86 -0
- data/lib/soap/handsoap/ews_service.rb +646 -0
- data/lib/soap/handsoap/parser.rb +106 -0
- data/lib/soap/handsoap/parsers/ews_parser.rb +165 -0
- data/lib/soap/soap_provider.rb +75 -0
- data/lib/viewpoint.rb +98 -3
- data/preamble +1 -1
- data/test/spec/basic_functions.spec +51 -0
- data/test/spec/folder_subscriptions.spec +35 -0
- data/test/spec/folder_synchronization.spec +28 -0
- data/utils/ewsWSDL2rb.rb +29 -0
- metadata +101 -43
- data/lib/exchwebserv.rb +0 -6
- data/lib/soap/viewpoint.conf +0 -3
- data/lib/viewpoint/calendar.rb +0 -128
- data/lib/viewpoint/calendar_item.rb +0 -118
- data/lib/viewpoint/event.rb +0 -0
- data/lib/viewpoint/exchange_headers.rb +0 -49
- data/lib/viewpoint/exchwebserv.rb +0 -236
- data/lib/viewpoint/folder.rb +0 -358
- data/lib/viewpoint/item.rb +0 -101
- data/lib/viewpoint/mail.rb +0 -117
- data/lib/viewpoint/message.rb +0 -132
- data/lib/viewpoint/task.rb +0 -0
- data/lib/viewpoint/tasks.rb +0 -0
- data/lib/wsdl/defaultMappingRegistry.rb +0 -10680
- data/lib/wsdl/exchangeServiceBinding.rb +0 -349
- data/lib/wsdl/exchangeServiceTypes.rb +0 -11013
- data/test/spec/basic_features_spec.rb +0 -37
- data/test/test_client.rb +0 -13
- data/test/testrestrict.rb +0 -75
@@ -0,0 +1,86 @@
|
|
1
|
+
#############################################################################
|
2
|
+
# Copyright © 2010 Dan Wanek <dan.wanek@gmail.com>
|
3
|
+
#
|
4
|
+
#
|
5
|
+
# This file is part of Viewpoint.
|
6
|
+
#
|
7
|
+
# Viewpoint is free software: you can redistribute it and/or
|
8
|
+
# modify it under the terms of the GNU General Public License as published
|
9
|
+
# by the Free Software Foundation, either version 3 of the License, or (at
|
10
|
+
# your option) any later version.
|
11
|
+
#
|
12
|
+
# Viewpoint is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
15
|
+
# Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License along
|
18
|
+
# with Viewpoint. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#############################################################################
|
20
|
+
require 'builders/ews_build_helpers.rb'
|
21
|
+
module Viewpoint
|
22
|
+
module EWS
|
23
|
+
module SOAP
|
24
|
+
|
25
|
+
# This class includes all the build helpers and also contains some root
|
26
|
+
# level methods to help code reuse. The CreateItem operation is an example
|
27
|
+
# of this because the different item types share a lot but have a few subtle
|
28
|
+
# differences.
|
29
|
+
class EwsBuilder
|
30
|
+
include EwsBuildHelpers
|
31
|
+
|
32
|
+
def initialize(node, opts, &block)
|
33
|
+
@node, @opts = node, opts
|
34
|
+
instance_eval(&block) if block_given?
|
35
|
+
end
|
36
|
+
|
37
|
+
# @see ExchangeWebService#subscribe
|
38
|
+
def pull_subscription_request!(folder_ids, event_types, timeout)
|
39
|
+
@node.add("#{NS_EWS_MESSAGES}:PullSubscriptionRequest") do |ps|
|
40
|
+
folder_ids!(ps, folder_ids, nil, "#{NS_EWS_TYPES}:FolderIds")
|
41
|
+
event_types!(ps, event_types)
|
42
|
+
ps.add("#{NS_EWS_TYPES}:Timeout", timeout)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# @param [String] type The type of items in the items array message/calendar
|
47
|
+
# @todo Fix max_changes_returned to be more flexible
|
48
|
+
def create_item!(folder_id, items, message_disposition, send_invites, type)
|
49
|
+
@node.set_attr('MessageDisposition', message_disposition) if message_disposition
|
50
|
+
@node.set_attr('SendMeetingInvitations', send_invites) if send_invites
|
51
|
+
|
52
|
+
saved_item_folder_id!(@node, folder_id) unless folder_id.nil?
|
53
|
+
items!(@node, items, type)
|
54
|
+
end
|
55
|
+
|
56
|
+
def add_delegate!(owner, delegate, permissions)
|
57
|
+
d_user = {
|
58
|
+
:user_id => {:primary_smtp_address => {:text => delegate}},
|
59
|
+
:delegate_permissions => permissions
|
60
|
+
}
|
61
|
+
|
62
|
+
mailbox!(@node, {:email_address => {:text => owner}})
|
63
|
+
delegate_users!(@node, [d_user])
|
64
|
+
end
|
65
|
+
|
66
|
+
def remove_delegate!(owner, delegate)
|
67
|
+
mailbox!(@node, {:email_address => {:text => owner}})
|
68
|
+
@node.add("#{NS_EWS_MESSAGES}:UserIds") do |uids|
|
69
|
+
user_id!(uids, {:user_id => {:primary_smtp_address => {:text => delegate}}})
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# This is forthcoming in Exchange 2010. It will replace much of the Restriction
|
74
|
+
# based code.
|
75
|
+
# @param [Array] An array of query strings
|
76
|
+
# @see http://msdn.microsoft.com/en-us/library/ee693615.aspx
|
77
|
+
def query_strings!(query_strings)
|
78
|
+
query_strings.each do |qs|
|
79
|
+
@node.add("#{NS_EWS_MESSAGES}:QueryString", qs)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end # EwsBuilder
|
84
|
+
end # SOAP
|
85
|
+
end # EWS
|
86
|
+
end # Viewpoint
|
@@ -0,0 +1,646 @@
|
|
1
|
+
#############################################################################
|
2
|
+
# Copyright © 2010 Dan Wanek <dan.wanek@gmail.com>
|
3
|
+
#
|
4
|
+
#
|
5
|
+
# This file is part of Viewpoint.
|
6
|
+
#
|
7
|
+
# Viewpoint is free software: you can redistribute it and/or
|
8
|
+
# modify it under the terms of the GNU General Public License as published
|
9
|
+
# by the Free Software Foundation, either version 3 of the License, or (at
|
10
|
+
# your option) any later version.
|
11
|
+
#
|
12
|
+
# Viewpoint is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
15
|
+
# Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License along
|
18
|
+
# with Viewpoint. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#############################################################################
|
20
|
+
$: << File.dirname(__FILE__)
|
21
|
+
require 'handsoap'
|
22
|
+
require 'builder'
|
23
|
+
require 'parser'
|
24
|
+
|
25
|
+
|
26
|
+
Handsoap.http_driver = :http_client
|
27
|
+
|
28
|
+
module Viewpoint
|
29
|
+
module EWS
|
30
|
+
module SOAP
|
31
|
+
class ExchangeWebService < Handsoap::Service
|
32
|
+
|
33
|
+
SOAP_ACTION_PREFIX = "http://schemas.microsoft.com/exchange/services/2006/messages"
|
34
|
+
|
35
|
+
@@raw_soap = false
|
36
|
+
|
37
|
+
def initialize()
|
38
|
+
if $DEBUG
|
39
|
+
@debug = File.new('ews_debug.out', 'w')
|
40
|
+
@debug.sync = true
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.set_auth(user,pass)
|
45
|
+
@@user = user
|
46
|
+
@@pass = pass
|
47
|
+
end
|
48
|
+
|
49
|
+
# Turn off parsing and just return the soap response
|
50
|
+
def self.raw_soap!
|
51
|
+
@@raw_soap = true
|
52
|
+
end
|
53
|
+
|
54
|
+
# ********* Begin Hooks *********
|
55
|
+
def on_create_document(doc)
|
56
|
+
doc.alias NS_EWS_TYPES, 'http://schemas.microsoft.com/exchange/services/2006/types'
|
57
|
+
doc.alias NS_EWS_MESSAGES, 'http://schemas.microsoft.com/exchange/services/2006/messages'
|
58
|
+
header = doc.find('Header')
|
59
|
+
header.add("#{NS_EWS_TYPES}:RequestServerVersion") { |rsv| rsv.set_attr('Version','Exchange2007_SP1') }
|
60
|
+
end
|
61
|
+
|
62
|
+
# Adds knowledge of namespaces to the response object. These have to be identical to the
|
63
|
+
# URIs returned in the XML response. For example, I had some issues with the 'soap'
|
64
|
+
# namespace because my original URI did not end in a '/'
|
65
|
+
# @example
|
66
|
+
# Won't work: http://schemas.xmlsoap.org/soap/envelope
|
67
|
+
# Works: http://schemas.xmlsoap.org/soap/envelope/
|
68
|
+
def on_response_document(doc)
|
69
|
+
doc.add_namespace NS_SOAP, 'http://schemas.xmlsoap.org/soap/envelope/'
|
70
|
+
doc.add_namespace NS_EWS_TYPES, 'http://schemas.microsoft.com/exchange/services/2006/types'
|
71
|
+
doc.add_namespace NS_EWS_MESSAGES, 'http://schemas.microsoft.com/exchange/services/2006/messages'
|
72
|
+
end
|
73
|
+
|
74
|
+
def on_after_create_http_request(req)
|
75
|
+
req.set_auth @@user, @@pass
|
76
|
+
end
|
77
|
+
# ********** End Hooks **********
|
78
|
+
|
79
|
+
|
80
|
+
# Resolve ambiguous e-mail addresses and display names
|
81
|
+
# @see http://msdn.microsoft.com/en-us/library/aa565329.aspx ResolveNames
|
82
|
+
# @see http://msdn.microsoft.com/en-us/library/aa581054.aspx UnresolvedEntry
|
83
|
+
#
|
84
|
+
# @param [String] name an unresolved entry
|
85
|
+
# @param [Boolean] full_contact_data whether or not to return full contact info
|
86
|
+
# @param [Hash] opts optional parameters to this method
|
87
|
+
# @option opts [String] :search_scope where to seach for this entry, one of
|
88
|
+
# SOAP::Contacts, SOAP::ActiveDirectory, SOAP::ActiveDirectoryContacts (default),
|
89
|
+
# SOAP::ContactsActiveDirectory
|
90
|
+
# @option opts [String, FolderId] :parent_folder_id either the name of a folder or
|
91
|
+
# it's numerical ID. @see http://msdn.microsoft.com/en-us/library/aa565998.aspx
|
92
|
+
def resolve_names(name, full_contact_data = true, opts = {})
|
93
|
+
action = "#{SOAP_ACTION_PREFIX}/ResolveNames"
|
94
|
+
resp = invoke("#{NS_EWS_MESSAGES}:ResolveNames", :soap_action => action) do |root|
|
95
|
+
build!(root) do
|
96
|
+
root.set_attr('ReturnFullContactData',full_contact_data)
|
97
|
+
root.add("#{NS_EWS_MESSAGES}:UnresolvedEntry",name)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
parse!(resp)
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
# Exposes the full membership of distribution lists.
|
105
|
+
# @see http://msdn.microsoft.com/en-us/library/aa494152.aspx ExpandDL
|
106
|
+
#
|
107
|
+
# @param [String] dist_email The e-mail address associated with the Distribution List
|
108
|
+
# @todo Fully support all of the ExpandDL operations. Today it just supports
|
109
|
+
# taking an e-mail address as an argument
|
110
|
+
def expand_dl(dist_email)
|
111
|
+
action = "#{SOAP_ACTION_PREFIX}/ExpandDL"
|
112
|
+
resp = invoke("#{NS_EWS_MESSAGES}:ExpandDL", :soap_action => action) do |root|
|
113
|
+
build!(root) do
|
114
|
+
mailbox!(root, {:email_address => {:text => dist_email}})
|
115
|
+
end
|
116
|
+
end
|
117
|
+
parse!(resp)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Find subfolders of an identified folder
|
121
|
+
# @see http://msdn.microsoft.com/en-us/library/aa563918.aspx
|
122
|
+
#
|
123
|
+
# @param [Array] parent_folder_ids An Array of folder ids, either a
|
124
|
+
# DistinguishedFolderId (must me a Symbol) or a FolderId (String)
|
125
|
+
# @param [String] traversal Shallow/Deep/SoftDeleted
|
126
|
+
# @param [Hash] folder_shape defines the FolderShape node
|
127
|
+
# See: http://msdn.microsoft.com/en-us/library/aa494311.aspx
|
128
|
+
# @option folder_shape [String] :base_shape IdOnly/Default/AllProperties
|
129
|
+
# @option folder_shape :additional_properties
|
130
|
+
# See: http://msdn.microsoft.com/en-us/library/aa563810.aspx
|
131
|
+
# @param [Hash] opts optional parameters to this method
|
132
|
+
def find_folder(parent_folder_ids = [:root], traversal = 'Shallow', folder_shape = {:base_shape => 'Default'}, opts = {})
|
133
|
+
action = "#{SOAP_ACTION_PREFIX}/FindFolder"
|
134
|
+
resp = invoke("#{NS_EWS_MESSAGES}:FindFolder", :soap_action => action) do |root|
|
135
|
+
build!(root) do
|
136
|
+
root.set_attr('Traversal', traversal)
|
137
|
+
folder_shape!(root, folder_shape)
|
138
|
+
parent_folder_ids!(root, parent_folder_ids)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
parse!(resp)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Identifies items that are located in a specified folder
|
145
|
+
# @see http://msdn.microsoft.com/en-us/library/aa566107.aspx
|
146
|
+
#
|
147
|
+
# @param [Array] parent_folder_ids An Array of folder ids, either a
|
148
|
+
# DistinguishedFolderId (must me a Symbol) or a FolderId (String)
|
149
|
+
# @param [String] traversal Shallow/Deep/SoftDeleted
|
150
|
+
# @param [Hash] item_shape defines the FolderShape node
|
151
|
+
# See: http://msdn.microsoft.com/en-us/library/aa494311.aspx
|
152
|
+
# @option item_shape [String] :base_shape IdOnly/Default/AllProperties
|
153
|
+
# @option item_shape :additional_properties
|
154
|
+
# See: http://msdn.microsoft.com/en-us/library/aa563810.aspx
|
155
|
+
# @param [Hash] opts optional parameters to this method
|
156
|
+
# @option opts [Hash] :calendar_view Limit FindItem by a start and end date
|
157
|
+
# {:calendar_view => {:max_entries_returned => 2, :start => <DateTime Obj>, :end => <DateTime Obj>}}
|
158
|
+
def find_item(parent_folder_ids, traversal = 'Shallow', item_shape = {:base_shape => 'Default'}, opts = {})
|
159
|
+
action = "#{SOAP_ACTION_PREFIX}/FindItem"
|
160
|
+
resp = invoke("#{NS_EWS_MESSAGES}:FindItem", :soap_action => action) do |root|
|
161
|
+
build!(root) do
|
162
|
+
root.set_attr('Traversal', traversal)
|
163
|
+
item_shape!(root, item_shape)
|
164
|
+
query_strings = opts.delete(:query_string)
|
165
|
+
restriction = opts.delete(:restriction)
|
166
|
+
if(opts.has_key?(:calendar_view))
|
167
|
+
cal_view = opts[:calendar_view]
|
168
|
+
cal_view.each_pair do |k,v|
|
169
|
+
cal_view[k] = v.to_s
|
170
|
+
end
|
171
|
+
end
|
172
|
+
add_hierarchy!(root, opts, NS_EWS_MESSAGES)
|
173
|
+
#query_strings!(query_strings)
|
174
|
+
root.add("#{NS_EWS_MESSAGES}:Restriction") do |r|
|
175
|
+
add_hierarchy!(r, restriction)
|
176
|
+
end unless restriction.nil?
|
177
|
+
parent_folder_ids!(root, parent_folder_ids)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
parse!(resp)
|
181
|
+
end
|
182
|
+
|
183
|
+
# Gets folders from the Exchange store
|
184
|
+
# @see http://msdn.microsoft.com/en-us/library/aa580274.aspx
|
185
|
+
#
|
186
|
+
# @param [Array] folder_ids An Array of folder ids, either a
|
187
|
+
# DistinguishedFolderId (must me a Symbol) or a FolderId (String)
|
188
|
+
# @param [Hash] folder_shape defines the FolderShape node
|
189
|
+
# See: http://msdn.microsoft.com/en-us/library/aa494311.aspx
|
190
|
+
# @option folder_shape [String] :base_shape IdOnly/Default/AllProperties
|
191
|
+
# @option folder_shape :additional_properties
|
192
|
+
# See: http://msdn.microsoft.com/en-us/library/aa563810.aspx
|
193
|
+
# @param [String,nil] act_as User to act on behalf as. This user must have been
|
194
|
+
# given delegate access to this folder or else this operation will fail.
|
195
|
+
# @param [Hash] opts optional parameters to this method
|
196
|
+
def get_folder(folder_ids, folder_shape = {:base_shape => 'Default'}, act_as = nil)
|
197
|
+
action = "#{SOAP_ACTION_PREFIX}/GetFolder"
|
198
|
+
resp = invoke("#{NS_EWS_MESSAGES}:GetFolder", :soap_action => action) do |root|
|
199
|
+
build!(root) do
|
200
|
+
folder_shape!(root, folder_shape)
|
201
|
+
folder_ids!(root, folder_ids, act_as)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
parse!(resp)
|
205
|
+
end
|
206
|
+
|
207
|
+
def convert_id
|
208
|
+
action = "#{SOAP_ACTION_PREFIX}/ConvertId"
|
209
|
+
resp = invoke("#{NS_EWS_MESSAGES}:ConvertId", :soap_action => action) do |convert_id|
|
210
|
+
build_convert_id!(convert_id)
|
211
|
+
end
|
212
|
+
parse_convert_id(resp)
|
213
|
+
end
|
214
|
+
|
215
|
+
# Creates folders, calendar folders, contacts folders, tasks folders, and search folders.
|
216
|
+
# @see http://msdn.microsoft.com/en-us/library/aa563574.aspx CreateFolder
|
217
|
+
#
|
218
|
+
# @param [String,Symbol] parent_folder_id either the name of a folder or it's
|
219
|
+
# numerical ID. See: http://msdn.microsoft.com/en-us/library/aa565998.aspx
|
220
|
+
# @param [Array,String] folder_name The display name for the new folder or folders
|
221
|
+
def create_folder(parent_folder_id, folder_name)
|
222
|
+
action = "#{SOAP_ACTION_PREFIX}/CreateFolder"
|
223
|
+
resp = invoke("#{NS_EWS_MESSAGES}:CreateFolder", :soap_action => action) do |root|
|
224
|
+
build!(root) do
|
225
|
+
root.add("#{NS_EWS_MESSAGES}:ParentFolderId") do |pfid|
|
226
|
+
folder_id!(pfid, parent_folder_id)
|
227
|
+
end
|
228
|
+
folder_name = (folder_name.is_a?(Array)) ? folder_name : [folder_name]
|
229
|
+
root.add("#{NS_EWS_MESSAGES}:Folders") do |fids|
|
230
|
+
folder_name.each do |f|
|
231
|
+
add_hierarchy!(fids, {:folder => {:display_name => {:text => f}}})
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
parse!(resp)
|
237
|
+
end
|
238
|
+
|
239
|
+
# Deletes folders from a mailbox.
|
240
|
+
# @see http://msdn.microsoft.com/en-us/library/aa564767.aspx DeleteFolder
|
241
|
+
#
|
242
|
+
# @param [Array,String,Symbol] folder_id either the name of a folder or it's
|
243
|
+
# numerical ID. See: http://msdn.microsoft.com/en-us/library/aa565998.aspx
|
244
|
+
# @param [String,nil] delete_type Type of delete to do: HardDelete/SoftDelete/MoveToDeletedItems
|
245
|
+
def delete_folder(folder_id, delete_type = 'MoveToDeletedItems')
|
246
|
+
action = "#{SOAP_ACTION_PREFIX}/DeleteFolder"
|
247
|
+
resp = invoke("#{NS_EWS_MESSAGES}:DeleteFolder", :soap_action => action) do |root|
|
248
|
+
root.set_attr('DeleteType', delete_type)
|
249
|
+
build!(root) do
|
250
|
+
folder_id = (folder_id.is_a?(Array)) ? folder_id : [folder_id]
|
251
|
+
folder_ids!(root, folder_id)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
parse!(resp)
|
255
|
+
end
|
256
|
+
|
257
|
+
def update_folder
|
258
|
+
action = "#{SOAP_ACTION_PREFIX}/UpdateFolder"
|
259
|
+
resp = invoke("#{NS_EWS_MESSAGES}:UpdateFolder", :soap_action => action) do |update_folder|
|
260
|
+
build_update_folder!(update_folder)
|
261
|
+
end
|
262
|
+
parse_update_folder(resp)
|
263
|
+
end
|
264
|
+
|
265
|
+
def move_folder
|
266
|
+
action = "#{SOAP_ACTION_PREFIX}/MoveFolder"
|
267
|
+
resp = invoke("#{NS_EWS_MESSAGES}:MoveFolder", :soap_action => action) do |move_folder|
|
268
|
+
build_move_folder!(move_folder)
|
269
|
+
end
|
270
|
+
parse_move_folder(resp)
|
271
|
+
end
|
272
|
+
|
273
|
+
def copy_folder
|
274
|
+
action = "#{SOAP_ACTION_PREFIX}/CopyFolder"
|
275
|
+
resp = invoke("#{NS_EWS_MESSAGES}:CopyFolder", :soap_action => action) do |copy_folder|
|
276
|
+
build_copy_folder!(copy_folder)
|
277
|
+
end
|
278
|
+
parse_copy_folder(resp)
|
279
|
+
end
|
280
|
+
|
281
|
+
# Used to subscribe client applications to either push or pull notifications.
|
282
|
+
# @see http://msdn.microsoft.com/en-us/library/aa566188.aspx Subscribe on MSDN
|
283
|
+
#
|
284
|
+
# @param [Array] folder_ids An Array of folder ids, either a
|
285
|
+
# DistinguishedFolderId (must me a Symbol) or a FolderId (String)
|
286
|
+
# @param [Array] event_types An Array of EventTypes that we should track.
|
287
|
+
# Available types are, CopiedEvent, CreatedEvent, DeletedEvent, ModifiedEvent,
|
288
|
+
# MovedEvent, NewMailEvent, FreeBusyChangedEvent
|
289
|
+
# @param [Integer] timeout The number of minutes in which the subscription
|
290
|
+
# will timeout after not receiving a get_events operation.
|
291
|
+
# @todo Decide how/if to handle the optional SubscribeToAllFolders attribute of
|
292
|
+
# the PullSubscriptionRequest element.
|
293
|
+
def subscribe(folder_ids, event_types, timeout = 10)
|
294
|
+
action = "#{SOAP_ACTION_PREFIX}/Subscribe"
|
295
|
+
resp = invoke("#{NS_EWS_MESSAGES}:Subscribe", :soap_action => action) do |root|
|
296
|
+
build!(root) do
|
297
|
+
pull_subscription_request!(folder_ids, event_types, timeout)
|
298
|
+
end
|
299
|
+
end
|
300
|
+
parse!(resp)
|
301
|
+
end
|
302
|
+
|
303
|
+
# End a pull notification subscription.
|
304
|
+
# @see http://msdn.microsoft.com/en-us/library/aa564263.aspx
|
305
|
+
#
|
306
|
+
# @param [String] subscription_id The Id of the subscription
|
307
|
+
def unsubscribe(subscription_id)
|
308
|
+
action = "#{SOAP_ACTION_PREFIX}/Unsubscribe"
|
309
|
+
resp = invoke("#{NS_EWS_MESSAGES}:Unsubscribe", :soap_action => action) do |root|
|
310
|
+
build!(root) do
|
311
|
+
subscription_id!(root, subscription_id)
|
312
|
+
end
|
313
|
+
end
|
314
|
+
parse!(resp)
|
315
|
+
end
|
316
|
+
|
317
|
+
# Used by pull subscription clients to request notifications from the Client Access server
|
318
|
+
# @see http://msdn.microsoft.com/en-us/library/aa566199.aspx GetEvents on MSDN
|
319
|
+
#
|
320
|
+
# @param [String] subscription_id Subscription identifier
|
321
|
+
# @param [String] watermark Event bookmark in the events queue
|
322
|
+
def get_events(subscription_id, watermark)
|
323
|
+
action = "#{SOAP_ACTION_PREFIX}/GetEvents"
|
324
|
+
resp = invoke("#{NS_EWS_MESSAGES}:GetEvents", :soap_action => action) do |root|
|
325
|
+
build!(root) do
|
326
|
+
subscription_id!(root, subscription_id)
|
327
|
+
watermark!(root, watermark)
|
328
|
+
end
|
329
|
+
end
|
330
|
+
parse!(resp)
|
331
|
+
end
|
332
|
+
|
333
|
+
def sync_folder_hierarchy
|
334
|
+
action = "#{SOAP_ACTION_PREFIX}/SyncFolderHierarchy"
|
335
|
+
resp = invoke("#{NS_EWS_MESSAGES}:SyncFolderHierarchy", :soap_action => action) do |sync_folder_hierarchy|
|
336
|
+
build_sync_folder_hierarchy!(sync_folder_hierarchy)
|
337
|
+
end
|
338
|
+
parse_sync_folder_hierarchy(resp)
|
339
|
+
end
|
340
|
+
|
341
|
+
# Synchronizes items between the Exchange server and the client
|
342
|
+
# @see http://msdn.microsoft.com/en-us/library/aa563967.aspx
|
343
|
+
#
|
344
|
+
# @param [String, Symbol] folder_id either a DistinguishedFolderId
|
345
|
+
# (must me a Symbol) or a FolderId (String)
|
346
|
+
# @param [String] sync_state Base-64 encoded string used to determine
|
347
|
+
# where we are in the sync process.
|
348
|
+
# @param [Integer] max_changes The amount of items to sync per call
|
349
|
+
# to SyncFolderItems
|
350
|
+
# @param [Hash] item_shape defines the ItemShape node
|
351
|
+
# See: http://msdn.microsoft.com/en-us/library/aa565261.aspx
|
352
|
+
# @option item_shape [String] :base_shape IdOnly/Default/AllProperties
|
353
|
+
# @option item_shape :additional_properties
|
354
|
+
# See: http://msdn.microsoft.com/en-us/library/aa565261.aspx
|
355
|
+
# @param [Hash] opts optional parameters to this method
|
356
|
+
def sync_folder_items(folder_id, sync_state = nil, max_changes = 256, item_shape = {:base_shape => 'Default'}, opts = {})
|
357
|
+
action = "#{SOAP_ACTION_PREFIX}/SyncFolderItems"
|
358
|
+
resp = invoke("#{NS_EWS_MESSAGES}:SyncFolderItems", :soap_action => action) do |root|
|
359
|
+
build!(root) do
|
360
|
+
item_shape!(root, item_shape)
|
361
|
+
root.add("#{NS_EWS_MESSAGES}:SyncFolderId") do |sfid|
|
362
|
+
folder_id!(sfid, folder_id)
|
363
|
+
end
|
364
|
+
sync_state!(root, sync_state) unless sync_state.nil?
|
365
|
+
root.add("#{NS_EWS_MESSAGES}:MaxChangesReturned", max_changes)
|
366
|
+
end
|
367
|
+
end
|
368
|
+
parse!(resp)
|
369
|
+
end
|
370
|
+
|
371
|
+
# Gets items from the Exchange store
|
372
|
+
# @see http://msdn.microsoft.com/en-us/library/aa565934.aspx
|
373
|
+
#
|
374
|
+
# @param [Array] item_ids An Array of item ids
|
375
|
+
# @param [Hash] item_shape defines the ItemShape node
|
376
|
+
# See: http://msdn.microsoft.com/en-us/library/aa565261.aspx
|
377
|
+
# @option item_shape [String] :base_shape ('Default') IdOnly/Default/AllProperties
|
378
|
+
# @option item_shape :additional_properties
|
379
|
+
# See: http://msdn.microsoft.com/en-us/library/aa563810.aspx
|
380
|
+
# @param [Hash] opts optional parameters to this method
|
381
|
+
def get_item(item_ids, item_shape = {:base_shape => 'Default'})
|
382
|
+
action = "#{SOAP_ACTION_PREFIX}/GetItem"
|
383
|
+
resp = invoke("#{NS_EWS_MESSAGES}:GetItem", :soap_action => action) do |root|
|
384
|
+
build!(root) do
|
385
|
+
item_shape!(root, item_shape)
|
386
|
+
item_ids!(root, item_ids)
|
387
|
+
end
|
388
|
+
end
|
389
|
+
parse!(resp)
|
390
|
+
end
|
391
|
+
|
392
|
+
# Operation is used to create e-mail messages
|
393
|
+
# This is actually a CreateItem operation but they differ for different types
|
394
|
+
# of Exchange objects so it is named appropriately here.
|
395
|
+
# @see http://msdn.microsoft.com/en-us/library/aa566468.aspx
|
396
|
+
#
|
397
|
+
# @param [String, Symbol] folder_id The folder to save this message in. Either a
|
398
|
+
# DistinguishedFolderId (must me a Symbol) or a FolderId (String)
|
399
|
+
# @param [Hash, Array] items An array of item Hashes or a single item Hash. Hash
|
400
|
+
# This Hash will eventually be passed to add_hierarchy! in the builder so it is in that format.
|
401
|
+
# Values should be based on values found here: http://msdn.microsoft.com/en-us/library/aa494306.aspx
|
402
|
+
# @param [String] message_disposition "SaveOnly/SendOnly/SendAndSaveCopy"
|
403
|
+
# See: http://msdn.microsoft.com/en-us/library/aa565209.aspx
|
404
|
+
def create_message_item(folder_id, items, message_disposition = 'SaveOnly')
|
405
|
+
action = "#{SOAP_ACTION_PREFIX}/CreateItem"
|
406
|
+
resp = invoke("#{NS_EWS_MESSAGES}:CreateItem", :soap_action => action) do |node|
|
407
|
+
build!(node) do
|
408
|
+
create_item!(folder_id, items, message_disposition, send_invites=false, 'message')
|
409
|
+
end
|
410
|
+
end
|
411
|
+
parse!(resp)
|
412
|
+
end
|
413
|
+
|
414
|
+
# Operation is used to create calendar items
|
415
|
+
# @see http://msdn.microsoft.com/en-us/library/aa564690.aspx
|
416
|
+
#
|
417
|
+
# @param [String, Symbol] folder_id The folder to create this item in. Either a
|
418
|
+
# DistinguishedFolderId (must me a Symbol) or a FolderId (String)
|
419
|
+
# @param [Hash, Array] items An array of item Hashes or a single item Hash. Hash
|
420
|
+
# This Hash will eventually be passed to add_hierarchy! in the builder so it is in that format.
|
421
|
+
# Values should be based on values found here: http://msdn.microsoft.com/en-us/library/aa564765.aspx
|
422
|
+
# @param [String] send_invites "SendToNone/SendOnlyToAll/SendToAllAndSaveCopy"
|
423
|
+
def create_calendar_item(folder_id, items, send_invites = 'SendToAllAndSaveCopy')
|
424
|
+
action = "#{SOAP_ACTION_PREFIX}/CreateItem"
|
425
|
+
resp = invoke("#{NS_EWS_MESSAGES}:CreateItem", :soap_action => action) do |node|
|
426
|
+
build!(node) do
|
427
|
+
create_item!(folder_id, items, message_disposition=false, send_invites, 'calendar')
|
428
|
+
end
|
429
|
+
end
|
430
|
+
parse!(resp)
|
431
|
+
end
|
432
|
+
|
433
|
+
# Operation is used to create task items
|
434
|
+
# This is actually a CreateItem operation but they differ for different types
|
435
|
+
# of Exchange objects so it is named appropriately here.
|
436
|
+
# @see http://msdn.microsoft.com/en-us/library/aa563439.aspx
|
437
|
+
#
|
438
|
+
# @param [String, Symbol] folder_id The folder to save this task in. Either a
|
439
|
+
# DistinguishedFolderId (must me a Symbol) or a FolderId (String)
|
440
|
+
# @param [Hash, Array] items An array of item Hashes or a single item Hash. Hash
|
441
|
+
# values should be based on values found here: http://msdn.microsoft.com/en-us/library/aa494306.aspx
|
442
|
+
# This Hash will eventually be passed to add_hierarchy! in the builder so it is in that format.
|
443
|
+
# @param [String] message_disposition "SaveOnly/SendOnly/SendAndSaveCopy"
|
444
|
+
# See: http://msdn.microsoft.com/en-us/library/aa565209.aspx
|
445
|
+
def create_task_item(folder_id, items, message_disposition = 'SaveOnly')
|
446
|
+
action = "#{SOAP_ACTION_PREFIX}/CreateItem"
|
447
|
+
resp = invoke("#{NS_EWS_MESSAGES}:CreateItem", :soap_action => action) do |node|
|
448
|
+
build!(node) do
|
449
|
+
create_item!(folder_id, items, message_disposition, send_invites=false, 'task')
|
450
|
+
end
|
451
|
+
end
|
452
|
+
parse!(resp)
|
453
|
+
end
|
454
|
+
|
455
|
+
# Delete an item from a mailbox in the Exchange store
|
456
|
+
# @see http://msdn.microsoft.com/en-us/library/aa562961.aspx
|
457
|
+
# @param [Array] item_ids An Array of item ids
|
458
|
+
# @param [String] delete_type Type of deletion: "HardDelete/SoftDelete/MoveToDeletedItems"
|
459
|
+
# @param [String, nil] send_meeting_cancellations "SendToNone/SendOnlyToAll/SendToAllAndSaveCopy"
|
460
|
+
# This is only applicable to CalendarItems and should be nil otherwise, which is the default
|
461
|
+
# @param [String, nil] affected_task_occurrences "AllOccurrences/SpecifiedOccurrenceOnly"
|
462
|
+
# This is really only related to tasks and can be nil otherwise, which is the default.
|
463
|
+
def delete_item(item_ids, delete_type, send_meeting_cancellations = nil, affected_task_occurrences = nil)
|
464
|
+
action = "#{SOAP_ACTION_PREFIX}/DeleteItem"
|
465
|
+
resp = invoke("#{NS_EWS_MESSAGES}:DeleteItem", :soap_action => action) do |root|
|
466
|
+
build!(root) do
|
467
|
+
root.set_attr('DeleteType', delete_type)
|
468
|
+
root.set_attr('SendMeetingCancellations', send_meeting_cancellations) unless send_meeting_cancellations.nil?
|
469
|
+
root.set_attr('AffectedTaskOccurrences', affected_task_occurrences) unless affected_task_occurrences.nil?
|
470
|
+
item_ids!(root, item_ids)
|
471
|
+
end
|
472
|
+
end
|
473
|
+
parse!(resp)
|
474
|
+
end
|
475
|
+
|
476
|
+
def update_item
|
477
|
+
action = "#{SOAP_ACTION_PREFIX}/UpdateItem"
|
478
|
+
resp = invoke("#{NS_EWS_MESSAGES}:UpdateItem", :soap_action => action) do |update_item|
|
479
|
+
build_update_item!(update_item)
|
480
|
+
end
|
481
|
+
parse_update_item(resp)
|
482
|
+
end
|
483
|
+
|
484
|
+
def send_item
|
485
|
+
action = "#{SOAP_ACTION_PREFIX}/SendItem"
|
486
|
+
resp = invoke("#{NS_EWS_MESSAGES}:SendItem", :soap_action => action) do |send_item|
|
487
|
+
build_send_item!(send_item)
|
488
|
+
end
|
489
|
+
parse_send_item(resp)
|
490
|
+
end
|
491
|
+
|
492
|
+
def move_item
|
493
|
+
action = "#{SOAP_ACTION_PREFIX}/MoveItem"
|
494
|
+
resp = invoke("#{NS_EWS_MESSAGES}:MoveItem", :soap_action => action) do |move_item|
|
495
|
+
build_move_item!(move_item)
|
496
|
+
end
|
497
|
+
parse_move_item(resp)
|
498
|
+
end
|
499
|
+
|
500
|
+
def copy_item
|
501
|
+
action = "#{SOAP_ACTION_PREFIX}/CopyItem"
|
502
|
+
resp = invoke("#{NS_EWS_MESSAGES}:CopyItem", :soap_action => action) do |copy_item|
|
503
|
+
build_copy_item!(copy_item)
|
504
|
+
end
|
505
|
+
parse_copy_item(resp)
|
506
|
+
end
|
507
|
+
|
508
|
+
def create_attachment
|
509
|
+
action = "#{SOAP_ACTION_PREFIX}/CreateAttachment"
|
510
|
+
resp = invoke("#{NS_EWS_MESSAGES}:CreateAttachment", :soap_action => action) do |create_attachment|
|
511
|
+
build_create_attachment!(create_attachment)
|
512
|
+
end
|
513
|
+
parse_create_attachment(resp)
|
514
|
+
end
|
515
|
+
|
516
|
+
def delete_attachment
|
517
|
+
action = "#{SOAP_ACTION_PREFIX}/DeleteAttachment"
|
518
|
+
resp = invoke("#{NS_EWS_MESSAGES}:DeleteAttachment", :soap_action => action) do |delete_attachment|
|
519
|
+
build_delete_attachment!(delete_attachment)
|
520
|
+
end
|
521
|
+
parse_delete_attachment(resp)
|
522
|
+
end
|
523
|
+
|
524
|
+
def get_attachment
|
525
|
+
action = "#{SOAP_ACTION_PREFIX}/GetAttachment"
|
526
|
+
resp = invoke("#{NS_EWS_MESSAGES}:GetAttachment", :soap_action => action) do |get_attachment|
|
527
|
+
build_get_attachment!(get_attachment)
|
528
|
+
end
|
529
|
+
parse_get_attachment(resp)
|
530
|
+
end
|
531
|
+
|
532
|
+
def create_managed_folder
|
533
|
+
action = "#{SOAP_ACTION_PREFIX}/CreateManagedFolder"
|
534
|
+
resp = invoke("#{NS_EWS_MESSAGES}:CreateManagedFolder", :soap_action => action) do |create_managed_folder|
|
535
|
+
build_create_managed_folder!(create_managed_folder)
|
536
|
+
end
|
537
|
+
parse_create_managed_folder(resp)
|
538
|
+
end
|
539
|
+
|
540
|
+
# Retrieves the delegate settings for a specific mailbox.
|
541
|
+
# @see http://msdn.microsoft.com/en-us/library/bb799735.aspx
|
542
|
+
#
|
543
|
+
# @param [String] owner The user that is delegating permissions
|
544
|
+
def get_delegate(owner)
|
545
|
+
action = "#{SOAP_ACTION_PREFIX}/GetDelegate"
|
546
|
+
resp = invoke("#{NS_EWS_MESSAGES}:GetDelegate", :soap_action => action) do |root|
|
547
|
+
root.set_attr('IncludePermissions', 'true')
|
548
|
+
build!(root) do
|
549
|
+
mailbox!(root, {:email_address => {:text => owner}})
|
550
|
+
end
|
551
|
+
end
|
552
|
+
parse!(resp)
|
553
|
+
end
|
554
|
+
|
555
|
+
# Adds one or more delegates to a principal's mailbox and sets specific access permissions.
|
556
|
+
# @see http://msdn.microsoft.com/en-us/library/bb856527.aspx
|
557
|
+
#
|
558
|
+
# @param [String] owner The user that is delegating permissions
|
559
|
+
# @param [String] delegate The user that is being given delegate permission
|
560
|
+
# @param [Hash] permissions A hash of permissions that will be delegated.
|
561
|
+
# This Hash will eventually be passed to add_hierarchy! in the builder so it is in that format.
|
562
|
+
def add_delegate(owner, delegate, permissions)
|
563
|
+
action = "#{SOAP_ACTION_PREFIX}/AddDelegate"
|
564
|
+
resp = invoke("#{NS_EWS_MESSAGES}:AddDelegate", :soap_action => action) do |root|
|
565
|
+
build!(root) do
|
566
|
+
add_delegate!(owner, delegate, permissions)
|
567
|
+
end
|
568
|
+
end
|
569
|
+
parse!(resp)
|
570
|
+
end
|
571
|
+
|
572
|
+
# Removes one or more delegates from a user's mailbox.
|
573
|
+
# @see http://msdn.microsoft.com/en-us/library/bb856564.aspx
|
574
|
+
#
|
575
|
+
# @param [String] owner The user that is delegating permissions
|
576
|
+
# @param [String] delegate The user that is being given delegate permission
|
577
|
+
def remove_delegate(owner, delegate)
|
578
|
+
action = "#{SOAP_ACTION_PREFIX}/RemoveDelegate"
|
579
|
+
resp = invoke("#{NS_EWS_MESSAGES}:RemoveDelegate", :soap_action => action) do |root|
|
580
|
+
build!(root) do
|
581
|
+
remove_delegate!(owner, delegate)
|
582
|
+
end
|
583
|
+
end
|
584
|
+
parse!(resp)
|
585
|
+
end
|
586
|
+
|
587
|
+
# Updates delegate permissions on a principal's mailbox
|
588
|
+
# @see http://msdn.microsoft.com/en-us/library/bb856529.aspx
|
589
|
+
#
|
590
|
+
# @param [String] owner The user that is delegating permissions
|
591
|
+
# @param [String] delegate The user that is being given delegate permission
|
592
|
+
# @param [Hash] permissions A hash of permissions that will be delegated.
|
593
|
+
# This Hash will eventually be passed to add_hierarchy! in the builder so it is in that format.
|
594
|
+
def update_delegate(owner, delegate, permissions)
|
595
|
+
action = "#{SOAP_ACTION_PREFIX}/UpdateDelegate"
|
596
|
+
resp = invoke("#{NS_EWS_MESSAGES}:UpdateDelegate", :soap_action => action) do |root|
|
597
|
+
build!(root) do
|
598
|
+
add_delegate!(owner, delegate, permissions)
|
599
|
+
end
|
600
|
+
end
|
601
|
+
parse!(resp)
|
602
|
+
end
|
603
|
+
|
604
|
+
def get_user_availability
|
605
|
+
action = "#{SOAP_ACTION_PREFIX}/GetUserAvailability"
|
606
|
+
resp = invoke("#{NS_EWS_MESSAGES}:GetUserAvailability", :soap_action => action) do |get_user_availability|
|
607
|
+
build_get_user_availability!(get_user_availability)
|
608
|
+
end
|
609
|
+
parse_get_user_availability(resp)
|
610
|
+
end
|
611
|
+
|
612
|
+
def get_user_oof_settings
|
613
|
+
action = "#{SOAP_ACTION_PREFIX}/GetUserOofSettings"
|
614
|
+
resp = invoke("#{NS_EWS_MESSAGES}:GetUserOofSettings", :soap_action => action) do |get_user_oof_settings|
|
615
|
+
build_get_user_oof_settings!(get_user_oof_settings)
|
616
|
+
end
|
617
|
+
parse_get_user_oof_settings(resp)
|
618
|
+
end
|
619
|
+
|
620
|
+
def set_user_oof_settings
|
621
|
+
action = "#{SOAP_ACTION_PREFIX}/SetUserOofSettings"
|
622
|
+
resp = invoke("#{NS_EWS_MESSAGES}:SetUserOofSettings", :soap_action => action) do |set_user_oof_settings|
|
623
|
+
build_set_user_oof_settings!(set_user_oof_settings)
|
624
|
+
end
|
625
|
+
parse_set_user_oof_settings(resp)
|
626
|
+
end
|
627
|
+
|
628
|
+
|
629
|
+
|
630
|
+
# Private Methods (Builders and Parsers)
|
631
|
+
private
|
632
|
+
|
633
|
+
|
634
|
+
def build!(node, opts = {}, &block)
|
635
|
+
EwsBuilder.new(node, opts, &block)
|
636
|
+
end
|
637
|
+
|
638
|
+
def parse!(response, opts = {})
|
639
|
+
return response if @@raw_soap
|
640
|
+
EwsParser.new(response).parse(opts)
|
641
|
+
end
|
642
|
+
|
643
|
+
end # class ExchangeWebService
|
644
|
+
end # module SOAP
|
645
|
+
end # EWS
|
646
|
+
end # Viewpoint
|