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.
Files changed (93) hide show
  1. data/README.md +196 -0
  2. data/lib/ews/calendar_accessors.rb +34 -0
  3. data/lib/ews/connection.rb +117 -0
  4. data/lib/ews/connection_helper.rb +35 -0
  5. data/lib/ews/ews_client.rb +71 -0
  6. data/lib/ews/exceptions/exceptions.rb +59 -0
  7. data/lib/ews/folder_accessors.rb +199 -0
  8. data/lib/ews/item_accessors.rb +157 -0
  9. data/lib/ews/mailbox_accessors.rb +87 -0
  10. data/lib/ews/message_accessors.rb +86 -0
  11. data/lib/ews/push_subscription_accessors.rb +33 -0
  12. data/lib/ews/soap.rb +63 -0
  13. data/lib/ews/soap/builders/ews_builder.rb +1011 -0
  14. data/lib/ews/soap/ews_response.rb +83 -0
  15. data/lib/ews/soap/ews_soap_availability_response.rb +58 -0
  16. data/lib/ews/soap/ews_soap_free_busy_response.rb +109 -0
  17. data/lib/ews/soap/ews_soap_response.rb +103 -0
  18. data/lib/ews/soap/exchange_availability.rb +61 -0
  19. data/lib/ews/soap/exchange_data_services.rb +742 -0
  20. data/lib/ews/soap/exchange_notification.rb +146 -0
  21. data/lib/ews/soap/exchange_user_configuration.rb +33 -0
  22. data/lib/ews/soap/exchange_web_service.rb +294 -0
  23. data/lib/{model/attendee.rb → ews/soap/parsers/ews_parser.rb} +20 -14
  24. data/lib/ews/soap/parsers/ews_sax_document.rb +66 -0
  25. data/lib/ews/soap/response_message.rb +78 -0
  26. data/lib/ews/soap/responses/create_attachment_response_message.rb +46 -0
  27. data/lib/{model/meeting_message.rb → ews/soap/responses/create_item_response_message.rb} +7 -10
  28. data/lib/ews/soap/responses/find_item_response_message.rb +80 -0
  29. data/lib/ews/soap/responses/get_events_response_message.rb +53 -0
  30. data/lib/ews/soap/responses/send_notification_response_message.rb +58 -0
  31. data/lib/{model/attachment.rb → ews/soap/responses/subscribe_response_message.rb} +17 -13
  32. data/lib/ews/templates/forward_item.rb +24 -0
  33. data/lib/ews/templates/message.rb +66 -0
  34. data/lib/ews/templates/reply_to_item.rb +25 -0
  35. data/lib/ews/types.rb +146 -0
  36. data/lib/ews/types/attachment.rb +77 -0
  37. data/lib/{model/meeting_cancellation.rb → ews/types/attendee.rb} +9 -8
  38. data/lib/ews/types/calendar_folder.rb +8 -0
  39. data/lib/ews/types/calendar_item.rb +37 -0
  40. data/lib/ews/types/contact.rb +7 -0
  41. data/lib/ews/types/contacts_folder.rb +8 -0
  42. data/lib/ews/types/copied_event.rb +51 -0
  43. data/lib/{soap/handsoap/builder.rb → ews/types/created_event.rb} +5 -2
  44. data/lib/{model/meeting_response.rb → ews/types/deleted_event.rb} +6 -6
  45. data/lib/ews/types/distribution_list.rb +7 -0
  46. data/lib/ews/types/event.rb +62 -0
  47. data/lib/ews/types/file_attachment.rb +65 -0
  48. data/lib/ews/types/folder.rb +60 -0
  49. data/lib/{model/distribution_list.rb → ews/types/free_busy_changed_event.rb} +6 -6
  50. data/lib/ews/types/generic_folder.rb +352 -0
  51. data/lib/ews/types/item.rb +381 -0
  52. data/lib/ews/types/item_attachment.rb +46 -0
  53. data/lib/{model → ews/types}/item_field_uri_map.rb +2 -2
  54. data/lib/ews/types/mailbox_user.rb +156 -0
  55. data/lib/ews/types/meeting_cancellation.rb +7 -0
  56. data/lib/ews/types/meeting_message.rb +7 -0
  57. data/lib/ews/types/meeting_request.rb +7 -0
  58. data/lib/ews/types/meeting_response.rb +7 -0
  59. data/lib/ews/types/message.rb +7 -0
  60. data/lib/ews/types/modified_event.rb +48 -0
  61. data/lib/{model/item_attachment.rb → ews/types/moved_event.rb} +33 -15
  62. data/lib/ews/types/new_mail_event.rb +24 -0
  63. data/lib/ews/types/out_of_office.rb +147 -0
  64. data/lib/ews/types/search_folder.rb +8 -0
  65. data/lib/ews/types/status_event.rb +39 -0
  66. data/lib/ews/types/task.rb +7 -0
  67. data/lib/ews/types/tasks_folder.rb +8 -0
  68. data/lib/viewpoint.rb +82 -106
  69. metadata +99 -67
  70. data/README +0 -114
  71. data/lib/exceptions/exceptions.rb +0 -46
  72. data/lib/model/calendar_folder.rb +0 -67
  73. data/lib/model/calendar_item.rb +0 -267
  74. data/lib/model/contact.rb +0 -238
  75. data/lib/model/contacts_folder.rb +0 -46
  76. data/lib/model/event.rb +0 -116
  77. data/lib/model/file_attachment.rb +0 -53
  78. data/lib/model/folder.rb +0 -47
  79. data/lib/model/generic_folder.rb +0 -471
  80. data/lib/model/item.rb +0 -313
  81. data/lib/model/mailbox_user.rb +0 -146
  82. data/lib/model/meeting_request.rb +0 -39
  83. data/lib/model/message.rb +0 -142
  84. data/lib/model/model.rb +0 -269
  85. data/lib/model/search_folder.rb +0 -48
  86. data/lib/model/task.rb +0 -121
  87. data/lib/model/tasks_folder.rb +0 -44
  88. data/lib/soap/handsoap/builders/ews_build_helpers.rb +0 -383
  89. data/lib/soap/handsoap/builders/ews_builder.rb +0 -146
  90. data/lib/soap/handsoap/ews_service.rb +0 -813
  91. data/lib/soap/handsoap/parser.rb +0 -104
  92. data/lib/soap/handsoap/parsers/ews_parser.rb +0 -246
  93. data/lib/soap/soap_provider.rb +0 -64
@@ -0,0 +1,146 @@
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::SOAP
20
+
21
+ # Exchange Notification operations as listed in the EWS Documentation.
22
+ # @see http://msdn.microsoft.com/en-us/library/bb409286.aspx
23
+ module ExchangeNotification
24
+ include Viewpoint::EWS::SOAP
25
+
26
+ # Used to subscribe client applications to either push, pull or stream notifications.
27
+ # @see http://msdn.microsoft.com/en-us/library/aa566188(v=EXCHG.140).aspx
28
+ # @param [Array<Hash>] subscriptions An array of Hash objects that describe each
29
+ # subscription.
30
+ # Ex: [ {:pull_subscription_request => {
31
+ # :subscribe_to_all_folders => false,
32
+ # :folder_ids => [ {:id => 'id', :change_key => 'ck'} ],
33
+ # :event_types=> %w{CopiedEvent CreatedEvent},
34
+ # :watermark => 'watermark id',
35
+ # :timeout => intval
36
+ # }},
37
+ # {:push_subscription_request => {
38
+ # :subscribe_to_all_folders => true,
39
+ # :event_types=> %w{CopiedEvent CreatedEvent},
40
+ # :status_frequency => 15,
41
+ # :uRL => 'http://my.endpoint.for.updates/',
42
+ # }},
43
+ # {:streaming_subscription_request => {
44
+ # :subscribe_to_all_folders => false,
45
+ # :folder_ids => [ {:id => 'id', :change_key => 'ck'} ],
46
+ # :event_types=> %w{NewMailEvent DeletedEvent},
47
+ # }},
48
+ # ]
49
+ def subscribe(subscriptions)
50
+ req = build_soap! do |type, builder|
51
+ if(type == :header)
52
+ else
53
+ builder.nbuild.Subscribe {
54
+ builder.nbuild.parent.default_namespace = @default_ns
55
+ subscriptions.each do |sub|
56
+ subtype = sub.keys.first
57
+ if(builder.respond_to?(subtype))
58
+ builder.send subtype, sub[subtype]
59
+ else
60
+ raise EwsBadArgumentError, "Bad subscription type. #{subtype}"
61
+ end
62
+ end
63
+ }
64
+ end
65
+ end
66
+ do_soap_request(req, response_class: EwsResponse)
67
+ end
68
+
69
+ # End a pull notification subscription.
70
+ # @see http://msdn.microsoft.com/en-us/library/aa564263.aspx
71
+ #
72
+ # @param [String] subscription_id The Id of the subscription
73
+ def unsubscribe(subscription_id)
74
+ req = build_soap! do |type, builder|
75
+ if(type == :header)
76
+ else
77
+ builder.nbuild.Unsubscribe {
78
+ builder.nbuild.parent.default_namespace = @default_ns
79
+ builder.subscription_id!(subscription_id)
80
+ }
81
+ end
82
+ end
83
+ do_soap_request(req, response_class: EwsResponse)
84
+ end
85
+
86
+ # Used by pull subscription clients to request notifications from the Client Access server
87
+ # @see http://msdn.microsoft.com/en-us/library/aa566199.aspx GetEvents on MSDN
88
+ #
89
+ # @param [String] subscription_id Subscription identifier
90
+ # @param [String] watermark Event bookmark in the events queue
91
+ def get_events(subscription_id, watermark)
92
+ req = build_soap! do |type, builder|
93
+ if(type == :header)
94
+ else
95
+ builder.nbuild.GetEvents {
96
+ builder.nbuild.parent.default_namespace = @default_ns
97
+ builder.subscription_id!(subscription_id)
98
+ builder.watermark!(watermark, NS_EWS_MESSAGES)
99
+ }
100
+ end
101
+ end
102
+ do_soap_request(req, response_class: EwsResponse)
103
+ end
104
+
105
+
106
+ # ------- convenience methods ------- #
107
+
108
+ # Create a pull subscription to a single folder
109
+ # @param folder [Hash] a hash with the folder :id and :change_key
110
+ # @param evtypes [Array] the events you would like to subscribe to.
111
+ # @param timeout [Fixnum] http://msdn.microsoft.com/en-us/library/aa565201.aspx
112
+ # @param watermark [String] http://msdn.microsoft.com/en-us/library/aa565886.aspx
113
+ def pull_subscribe_folder(folder, evtypes, timeout = nil, watermark = nil)
114
+ timeout ||= 240 # 4 hour default timeout
115
+ psr = {
116
+ :subscribe_to_all_folders => false,
117
+ :folder_ids => [ {:id => folder[:id], :change_key => folder[:change_key]} ],
118
+ :event_types=> evtypes,
119
+ :timeout => timeout
120
+ }
121
+ psr[:watermark] = watermark if watermark
122
+ subscribe([{pull_subscription_request: psr}])
123
+ end
124
+
125
+ # Create a push subscription to a single folder
126
+ # @param folder [Hash] a hash with the folder :id and :change_key
127
+ # @param evtypes [Array] the events you would like to subscribe to.
128
+ # @param url [String,URI] http://msdn.microsoft.com/en-us/library/aa566309.aspx
129
+ # @param watermark [String] http://msdn.microsoft.com/en-us/library/aa565886.aspx
130
+ # @param status_frequency [Fixnum] http://msdn.microsoft.com/en-us/library/aa564048.aspx
131
+ def push_subscribe_folder(folder, evtypes, url, status_frequency = nil, watermark = nil)
132
+ status_frequency ||= 30
133
+ psr = {
134
+ :subscribe_to_all_folders => false,
135
+ :folder_ids => [ {:id => folder[:id], :change_key => folder[:change_key]} ],
136
+ :event_types=> evtypes,
137
+ :status_frequency => status_frequency,
138
+ :uRL => url.to_s
139
+ }
140
+ psr[:watermark] = watermark if watermark
141
+ subscribe([{push_subscription_request: psr}])
142
+ end
143
+
144
+
145
+ end #ExchangeNotification
146
+ end
@@ -0,0 +1,33 @@
1
+ module Viewpoint::EWS::SOAP
2
+
3
+ # Exchange User Configuration operations as listed in the EWS Documentation.
4
+ # @see http://msdn.microsoft.com/en-us/library/bb409286.aspx
5
+ module ExchangeUserConfiguration
6
+ include Viewpoint::EWS::SOAP
7
+
8
+ # The GetUserConfiguration operation gets a user configuration object from
9
+ # a folder.
10
+ # @see http://msdn.microsoft.com/en-us/library/aa563465.aspx
11
+ # @param [Hash] opts
12
+ # @option opts [Hash] :user_config_name
13
+ # @option opts [String] :user_config_props
14
+ def get_user_configuration(opts)
15
+ opts = opts.clone
16
+ [:user_config_name, :user_config_props].each do |k|
17
+ validate_param(opts, k, true)
18
+ end
19
+ req = build_soap! do |type, builder|
20
+ if(type == :header)
21
+ else
22
+ builder.nbuild.GetUserConfiguration {|x|
23
+ x.parent.default_namespace = @default_ns
24
+ builder.user_configuration_name!(opts[:user_config_name])
25
+ builder.user_configuration_properties!(opts[:user_config_props])
26
+ }
27
+ end
28
+ end
29
+ do_soap_request(req, response_class: EwsSoapAvailabilityResponse)
30
+ end
31
+
32
+ end #ExchangeUserConfiguration
33
+ end
@@ -0,0 +1,294 @@
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::SOAP
20
+ class ExchangeWebService
21
+ include Viewpoint::EWS
22
+ include Viewpoint::EWS::SOAP
23
+ include ExchangeDataServices
24
+ include ExchangeNotification
25
+ include ExchangeAvailability
26
+ include ExchangeUserConfiguration
27
+
28
+ attr_accessor :server_version, :auto_deepen, :connection
29
+
30
+ # @param [Viewpoint::EWS::Connection] connection the connection object
31
+ # @param [Hash] opts additional options to the web service
32
+ # @option opts [String] :server_version what version to target with the
33
+ # requests. Must be one of the contants VERSION_2007, VERSION_2007_SP1,
34
+ # VERSION_2010, VERSION_2010_SP1, VERSION_2010_SP2, or VERSION_NONE. The
35
+ # default is VERSION_2010.
36
+ def initialize(connection, opts = {})
37
+ super()
38
+ @connection = connection
39
+ @server_version = opts[:server_version] ? opts[:server_version] : VERSION_2010
40
+ @auto_deepen = true
41
+ end
42
+
43
+ # Defines a request to synchronize a folder hierarchy on a client
44
+ # @see http://msdn.microsoft.com/en-us/library/aa580990.aspx
45
+ # @param [Hash] opts
46
+ # @option opts [Hash] :folder_shape The folder shape properties
47
+ # Ex: {:base_shape => 'Default', :additional_properties => 'bla bla bla'}
48
+ # @option opts [Hash] :sync_folder_id An optional Hash that represents a FolderId or
49
+ # DistinguishedFolderId.
50
+ # Ex: {:id => :inbox}
51
+ # @option opts [Hash] :sync_state The Base64 sync state id. If this is the
52
+ # first time syncing this does not need to be passed.
53
+ def sync_folder_hierarchy(opts)
54
+ req = build_soap! do |type, builder|
55
+ if(type == :header)
56
+ else
57
+ builder.nbuild.SyncFolderHierarchy {
58
+ builder.nbuild.parent.default_namespace = @default_ns
59
+ builder.folder_shape!(opts[:folder_shape])
60
+ builder.sync_folder_id!(opts[:sync_folder_id]) if opts[:sync_folder_id]
61
+ builder.sync_state!(opts[:sync_state]) if opts[:sync_state]
62
+ }
63
+ end
64
+ end
65
+ do_soap_request(req)
66
+ end
67
+
68
+ # Synchronizes items between the Exchange server and the client
69
+ # @see http://msdn.microsoft.com/en-us/library/aa563967(v=EXCHG.140).aspx
70
+ # @param [Hash] opts
71
+ # @option opts [Hash] :item_shape The item shape properties
72
+ # Ex: {:base_shape => 'Default', :additional_properties => 'bla bla bla'}
73
+ # @option opts [Hash] :sync_folder_id A Hash that represents a FolderId or
74
+ # DistinguishedFolderId. [ Ex: {:id => :inbox} ] OPTIONAL
75
+ # @option opts [String] :sync_state The Base64 sync state id. If this is the
76
+ # first time syncing this does not need to be passed. OPTIONAL on first call
77
+ # @option opts [Array <String>] :ignore An Array of ItemIds for items to ignore
78
+ # during the sync process. Ex: [{:id => 'id1', :change_key => 'ck'}, {:id => 'id2'}]
79
+ # OPTIONAL
80
+ # @option opts [Integer] :max_changes_returned ('required') The amount of items to sync per call.
81
+ # @option opts [String] :sync_scope specifies whether just items or items and folder associated
82
+ # information are returned. OPTIONAL
83
+ # options: 'NormalItems' or 'NormalAndAssociatedItems'
84
+ # @example
85
+ # { :item_shape => {:base_shape => 'Default'},
86
+ # :sync_folder_id => {:id => :inbox},
87
+ # :sync_state => myBase64id,
88
+ # :max_changes_returned => 256 }
89
+ def sync_folder_items(opts)
90
+ req = build_soap! do |type, builder|
91
+ if(type == :header)
92
+ else
93
+ builder.nbuild.SyncFolderItems {
94
+ builder.nbuild.parent.default_namespace = @default_ns
95
+ builder.item_shape!(opts[:item_shape])
96
+ builder.sync_folder_id!(opts[:sync_folder_id]) if opts[:sync_folder_id]
97
+ builder.sync_state!(opts[:sync_state]) if opts[:sync_state]
98
+ builder.ignore!(opts[:ignore]) if opts[:ignore]
99
+ builder.max_changes_returned!(opts[:max_changes_returned])
100
+ builder.sync_scope!(opts[:sync_scope]) if opts[:sync_scope]
101
+ }
102
+ end
103
+ end
104
+ do_soap_request(req)
105
+ end
106
+
107
+ def delete_attachment
108
+ action = "#{SOAP_ACTION_PREFIX}/DeleteAttachment"
109
+ resp = invoke("#{NS_EWS_MESSAGES}:DeleteAttachment", action) do |delete_attachment|
110
+ build_delete_attachment!(delete_attachment)
111
+ end
112
+ parse_delete_attachment(resp)
113
+ end
114
+
115
+ def create_managed_folder
116
+ action = "#{SOAP_ACTION_PREFIX}/CreateManagedFolder"
117
+ resp = invoke("#{NS_EWS_MESSAGES}:CreateManagedFolder", action) do |create_managed_folder|
118
+ build_create_managed_folder!(create_managed_folder)
119
+ end
120
+ parse_create_managed_folder(resp)
121
+ end
122
+
123
+ # Retrieves the delegate settings for a specific mailbox.
124
+ # @see http://msdn.microsoft.com/en-us/library/bb799735.aspx
125
+ #
126
+ # @param [String] owner The user that is delegating permissions
127
+ def get_delegate(owner)
128
+ action = "#{SOAP_ACTION_PREFIX}/GetDelegate"
129
+ resp = invoke("#{NS_EWS_MESSAGES}:GetDelegate", action) do |root|
130
+ root.set_attr('IncludePermissions', 'true')
131
+ build!(root) do
132
+ mailbox!(root, {:email_address => {:text => owner}})
133
+ end
134
+ end
135
+ parse_soap_response(resp)
136
+ end
137
+
138
+ # Adds one or more delegates to a principal's mailbox and sets specific access permissions.
139
+ # @see http://msdn.microsoft.com/en-us/library/bb856527.aspx
140
+ #
141
+ # @param [String] owner The user that is delegating permissions
142
+ # @param [String] delegate The user that is being given delegate permission
143
+ # @param [Hash] permissions A hash of permissions that will be delegated.
144
+ # This Hash will eventually be passed to add_hierarchy! in the builder so it is in that format.
145
+ def add_delegate(owner, delegate, permissions)
146
+ action = "#{SOAP_ACTION_PREFIX}/AddDelegate"
147
+ resp = invoke("#{NS_EWS_MESSAGES}:AddDelegate", action) do |root|
148
+ build!(root) do
149
+ add_delegate!(owner, delegate, permissions)
150
+ end
151
+ end
152
+ parse_soap_response(resp)
153
+ end
154
+
155
+ # Removes one or more delegates from a user's mailbox.
156
+ # @see http://msdn.microsoft.com/en-us/library/bb856564.aspx
157
+ #
158
+ # @param [String] owner The user that is delegating permissions
159
+ # @param [String] delegate The user that is being given delegate permission
160
+ def remove_delegate(owner, delegate)
161
+ action = "#{SOAP_ACTION_PREFIX}/RemoveDelegate"
162
+ resp = invoke("#{NS_EWS_MESSAGES}:RemoveDelegate", action) do |root|
163
+ build!(root) do
164
+ remove_delegate!(owner, delegate)
165
+ end
166
+ end
167
+ parse_soap_response(resp)
168
+ end
169
+
170
+ # Updates delegate permissions on a principal's mailbox
171
+ # @see http://msdn.microsoft.com/en-us/library/bb856529.aspx
172
+ #
173
+ # @param [String] owner The user that is delegating permissions
174
+ # @param [String] delegate The user that is being given delegate permission
175
+ # @param [Hash] permissions A hash of permissions that will be delegated.
176
+ # This Hash will eventually be passed to add_hierarchy! in the builder so it is in that format.
177
+ def update_delegate(owner, delegate, permissions)
178
+ action = "#{SOAP_ACTION_PREFIX}/UpdateDelegate"
179
+ resp = invoke("#{NS_EWS_MESSAGES}:UpdateDelegate", action) do |root|
180
+ build!(root) do
181
+ add_delegate!(owner, delegate, permissions)
182
+ end
183
+ end
184
+ parse_soap_response(resp)
185
+ end
186
+
187
+ # Provides detailed information about the availability of a set of users, rooms, and resources
188
+ # within a specified time window.
189
+ # @see http://msdn.microsoft.com/en-us/library/aa564001.aspx
190
+ # @param [Hash] opts
191
+ # @option opts [Hash] :time_zone The TimeZone data
192
+ # Example: {:bias => 'UTC offset in minutes',
193
+ # :standard_time => {:bias => 480, :time => '02:00:00',
194
+ # :day_order => 5, :month => 10, :day_of_week => 'Sunday'},
195
+ # :daylight_time => {same options as :standard_time}}
196
+ # @option opts [Array<Hash>] :mailbox_data Data for the mailbox to query
197
+ # Example: [{:attendee_type => 'Organizer|Required|Optional|Room|Resource',
198
+ # :email =>{:name => 'name', :address => 'email', :routing_type => 'SMTP'},
199
+ # :exclude_conflicts => true|false }]
200
+ # @option opts [Hash] :free_busy_view_options
201
+ # Example: {:time_window => {:start_time => DateTime,:end_time => DateTime},
202
+ # :merged_free_busy_interval_in_minutes => minute_int,
203
+ # :requested_view => None|MergedOnly|FreeBusy|FreeBusyMerged|Detailed
204
+ # |DetailedMerged} (optional)
205
+ # @option opts [Hash] :suggestions_view_options (optional)
206
+ # @todo Finish out :suggestions_view_options
207
+ def get_user_availability(opts)
208
+ opts = opts.clone
209
+ req = build_soap! do |type, builder|
210
+ if(type == :header)
211
+ else
212
+ builder.nbuild.GetUserAvailabilityRequest {|x|
213
+ x.parent.default_namespace = @default_ns
214
+ builder.time_zone!(opts[:time_zone])
215
+ builder.nbuild.MailboxDataArray {
216
+ opts[:mailbox_data].each do |mbd|
217
+ builder.mailbox_data!(mbd)
218
+ end
219
+ }
220
+ builder.free_busy_view_options!(opts[:free_busy_view_options])
221
+ builder.suggestions_view_options!(opts[:suggestions_view_options])
222
+ }
223
+ end
224
+ end
225
+
226
+ do_soap_request(req, response_class: EwsSoapFreeBusyResponse)
227
+ end
228
+
229
+
230
+ # Send the SOAP request to the endpoint and parse it.
231
+ # @param [String] soapmsg an XML formatted string
232
+ # @todo make this work for Viewpoint (imported from SPWS)
233
+ # @param [Hash] opts misc options
234
+ # @option opts [Boolean] :raw_response if true do not parse and return
235
+ # the raw response string.
236
+ def do_soap_request(soapmsg, opts = {})
237
+ @log.debug <<-EOF.gsub(/^ {8}/, '')
238
+ Sending SOAP Request:
239
+ ----------------
240
+ #{soapmsg}
241
+ ----------------
242
+ EOF
243
+ connection.dispatch(self, soapmsg, opts)
244
+ end
245
+
246
+ # @param [String] response the SOAP response string
247
+ # @param [Hash] opts misc options to send to the parser
248
+ # @option opts [Class] :response_class the response class
249
+ def parse_soap_response(soapmsg, opts = {})
250
+ raise EwsError, "Can't parse an empty response. Please check your endpoint." if(soapmsg.nil?)
251
+ opts[:response_class] ||= EwsSoapResponse
252
+ EwsParser.new(soapmsg).parse(opts)
253
+ end
254
+
255
+
256
+ private
257
+ # Private Methods (Builders and Parsers)
258
+
259
+ # Validate or set default values for options parameters.
260
+ # @param [Hash] opts The options parameter passed to an EWS operation
261
+ # @param [Symbol] key The key in the Hash we are validating
262
+ # @param [Boolean] required Whether or not this key is required
263
+ # @param [Object] default_val If the key is not required use this as a
264
+ # default value for the operation.
265
+ def validate_param(opts, key, required, default_val = nil)
266
+ if required
267
+ raise EwsBadArgumentError, "Required parameter(#{key}) not passed." unless opts.has_key?(key)
268
+ opts[key]
269
+ else
270
+ raise EwsBadArgumentError, "Default value not supplied." unless default_val
271
+ opts.has_key?(key) ? opts[key] : default_val
272
+ end
273
+ end
274
+
275
+ # Some operations only exist for certain versions of Exchange Server.
276
+ # This method should be called with the required version and we'll throw
277
+ # an exception of the currently set @server_version does not comply.
278
+ def validate_version(exchange_version)
279
+ if server_version < exchange_version
280
+ msg = 'The operation you are attempting to use is not compatible with'
281
+ msg << " your configured Exchange Server version(#{server_version})."
282
+ msg << " You must be running at least version (#{exchange_version})."
283
+ raise EwsServerVersionError, msg
284
+ end
285
+ end
286
+
287
+ # Build the common elements in the SOAP message and yield to any custom elements.
288
+ def build_soap!(&block)
289
+ opts = { :server_version => server_version }
290
+ EwsBuilder.new.build!(opts, &block)
291
+ end
292
+
293
+ end # class ExchangeWebService
294
+ end # Viewpoint