viewpoint 0.1.26 → 1.1.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 (112) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +203 -0
  3. data/lib/ews/calendar_accessors.rb +34 -0
  4. data/lib/ews/connection.rb +140 -0
  5. data/lib/ews/connection_helper.rb +35 -0
  6. data/lib/ews/convert_accessors.rb +56 -0
  7. data/lib/{exceptions/exceptions.rb → ews/errors.rb} +29 -19
  8. data/lib/ews/ews_client.rb +105 -0
  9. data/lib/ews/exceptions/exceptions.rb +61 -0
  10. data/lib/ews/folder_accessors.rb +264 -0
  11. data/lib/ews/impersonation.rb +30 -0
  12. data/lib/ews/item_accessors.rb +242 -0
  13. data/lib/ews/mailbox_accessors.rb +92 -0
  14. data/lib/ews/meeting_accessors.rb +39 -0
  15. data/lib/ews/message_accessors.rb +93 -0
  16. data/lib/ews/push_subscription_accessors.rb +33 -0
  17. data/lib/ews/room_accessors.rb +48 -0
  18. data/lib/ews/roomlist_accessors.rb +47 -0
  19. data/lib/ews/soap.rb +64 -0
  20. data/lib/ews/soap/builders/ews_builder.rb +1384 -0
  21. data/lib/ews/soap/ews_response.rb +84 -0
  22. data/lib/ews/soap/ews_soap_availability_response.rb +58 -0
  23. data/lib/ews/soap/ews_soap_free_busy_response.rb +119 -0
  24. data/lib/ews/soap/ews_soap_response.rb +103 -0
  25. data/lib/ews/soap/ews_soap_room_response.rb +53 -0
  26. data/lib/ews/soap/ews_soap_roomlist_response.rb +54 -0
  27. data/lib/ews/soap/exchange_availability.rb +61 -0
  28. data/lib/ews/soap/exchange_data_services.rb +780 -0
  29. data/lib/ews/soap/exchange_notification.rb +146 -0
  30. data/lib/ews/soap/exchange_synchronization.rb +93 -0
  31. data/lib/ews/soap/exchange_time_zones.rb +56 -0
  32. data/lib/ews/soap/exchange_user_configuration.rb +33 -0
  33. data/lib/ews/soap/exchange_web_service.rb +264 -0
  34. data/lib/{model/item_attachment.rb → ews/soap/parsers/ews_parser.rb} +24 -14
  35. data/lib/ews/soap/parsers/ews_sax_document.rb +70 -0
  36. data/lib/ews/soap/response_message.rb +80 -0
  37. data/lib/ews/soap/responses/create_attachment_response_message.rb +47 -0
  38. data/lib/{model/meeting_message.rb → ews/soap/responses/create_item_response_message.rb} +7 -10
  39. data/lib/ews/soap/responses/find_item_response_message.rb +80 -0
  40. data/lib/ews/soap/responses/get_events_response_message.rb +53 -0
  41. data/lib/ews/soap/responses/send_notification_response_message.rb +59 -0
  42. data/lib/{model/attachment.rb → ews/soap/responses/subscribe_response_message.rb} +17 -13
  43. data/lib/{model/attendee.rb → ews/soap/responses/sync_folder_hierarchy_response_message.rb} +14 -15
  44. data/lib/ews/soap/responses/sync_folder_items_response_message.rb +36 -0
  45. data/lib/ews/templates/calendar_item.rb +79 -0
  46. data/lib/ews/templates/forward_item.rb +24 -0
  47. data/lib/ews/templates/message.rb +85 -0
  48. data/lib/ews/templates/reply_to_item.rb +25 -0
  49. data/lib/ews/templates/task.rb +74 -0
  50. data/lib/ews/types.rb +194 -0
  51. data/lib/ews/types/attachment.rb +77 -0
  52. data/lib/{model/meeting_cancellation.rb → ews/types/attendee.rb} +9 -8
  53. data/lib/ews/types/calendar_folder.rb +50 -0
  54. data/lib/ews/types/calendar_item.rb +130 -0
  55. data/lib/ews/types/contact.rb +7 -0
  56. data/lib/ews/types/contacts_folder.rb +8 -0
  57. data/lib/ews/types/copied_event.rb +51 -0
  58. data/lib/{soap/handsoap/builder.rb → ews/types/created_event.rb} +5 -2
  59. data/lib/ews/types/deleted_event.rb +24 -0
  60. data/lib/ews/types/distribution_list.rb +7 -0
  61. data/lib/ews/types/event.rb +62 -0
  62. data/lib/ews/types/export_items_response_message.rb +52 -0
  63. data/lib/ews/types/file_attachment.rb +65 -0
  64. data/lib/ews/types/folder.rb +60 -0
  65. data/lib/ews/types/free_busy_changed_event.rb +24 -0
  66. data/lib/ews/types/generic_folder.rb +418 -0
  67. data/lib/ews/types/item.rb +447 -0
  68. data/lib/ews/types/item_attachment.rb +84 -0
  69. data/lib/{model → ews/types}/item_field_uri_map.rb +2 -18
  70. data/lib/ews/types/mailbox_user.rb +156 -0
  71. data/lib/ews/types/meeting_cancellation.rb +7 -0
  72. data/lib/ews/types/meeting_message.rb +7 -0
  73. data/lib/ews/types/meeting_request.rb +7 -0
  74. data/lib/ews/types/meeting_response.rb +7 -0
  75. data/lib/ews/types/message.rb +7 -0
  76. data/lib/ews/types/modified_event.rb +48 -0
  77. data/lib/{extensions/string.rb → ews/types/moved_event.rb} +31 -15
  78. data/lib/ews/types/new_mail_event.rb +24 -0
  79. data/lib/ews/types/out_of_office.rb +147 -0
  80. data/lib/ews/types/post_item.rb +7 -0
  81. data/lib/ews/types/search_folder.rb +8 -0
  82. data/lib/ews/types/status_event.rb +39 -0
  83. data/lib/ews/types/task.rb +41 -0
  84. data/lib/ews/types/tasks_folder.rb +27 -0
  85. data/lib/viewpoint.rb +85 -108
  86. data/lib/{model/distribution_list.rb → viewpoint/logging.rb} +6 -3
  87. data/lib/{model/meeting_response.rb → viewpoint/logging/config.rb} +3 -3
  88. data/lib/viewpoint/string_utils.rb +76 -0
  89. metadata +156 -123
  90. data/README +0 -114
  91. data/lib/model/calendar_folder.rb +0 -67
  92. data/lib/model/calendar_item.rb +0 -267
  93. data/lib/model/contact.rb +0 -238
  94. data/lib/model/contacts_folder.rb +0 -46
  95. data/lib/model/event.rb +0 -116
  96. data/lib/model/file_attachment.rb +0 -53
  97. data/lib/model/folder.rb +0 -47
  98. data/lib/model/generic_folder.rb +0 -461
  99. data/lib/model/item.rb +0 -312
  100. data/lib/model/mailbox_user.rb +0 -146
  101. data/lib/model/meeting_request.rb +0 -39
  102. data/lib/model/message.rb +0 -142
  103. data/lib/model/model.rb +0 -269
  104. data/lib/model/search_folder.rb +0 -48
  105. data/lib/model/task.rb +0 -121
  106. data/lib/model/tasks_folder.rb +0 -44
  107. data/lib/soap/handsoap/builders/ews_build_helpers.rb +0 -383
  108. data/lib/soap/handsoap/builders/ews_builder.rb +0 -146
  109. data/lib/soap/handsoap/ews_service.rb +0 -790
  110. data/lib/soap/handsoap/parser.rb +0 -104
  111. data/lib/soap/handsoap/parsers/ews_parser.rb +0 -245
  112. data/lib/soap/soap_provider.rb +0 -64
@@ -15,32 +15,42 @@
15
15
  See the License for the specific language governing permissions and
16
16
  limitations under the License.
17
17
  =end
18
- module Viewpoint
19
- module EWS
20
18
 
21
- # Generic Ews Error
22
- class EwsError < StandardError
23
- end
19
+ module Viewpoint::EWS::Errors
20
+ class ResponseError < RuntimeError
21
+ attr_reader :response
24
22
 
25
- # Raise when authentication/authorization issues occur.
26
- class EwsLoginError < StandardError
23
+ def initialize(message, response)
24
+ super(message)
25
+ @response = response
27
26
  end
28
27
 
29
- # Raised when a user tries to query a folder subscription after the
30
- # subscription has timed out.
31
- class EwsSubscriptionTimeout < StandardError
28
+ def status
29
+ response.status
32
30
  end
33
31
 
34
- # Represents a function in EWS that is not yet implemented in Viewpoint
35
- class EwsNotImplemented < StandardError
32
+ def body
33
+ response.body
36
34
  end
35
+ end
36
+
37
+ class UnhandledResponseError < ResponseError
38
+ end
37
39
 
38
- # Raised when an method is called in the wrong way
39
- class EwsBadArgumentError < StandardError; end
40
+ class ServerError < ResponseError
41
+ end
40
42
 
41
- # Raised when a folder that is asked for is not found
42
- class EwsFolderNotFound < StandardError; end
43
+ class UnauthorizedResponseError < ResponseError
44
+ end
43
45
 
44
- end # EWS
45
- end # Viewpoint
46
-
46
+ class SoapResponseError < ResponseError
47
+ attr_reader :faultcode,
48
+ :faultstring
49
+
50
+ def initialize(message, response, faultcode, faultstring)
51
+ super(message, response)
52
+ @faultcode = faultcode
53
+ @faultstring = faultstring
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,105 @@
1
+ require 'ews/folder_accessors'
2
+ require 'ews/item_accessors'
3
+ require 'ews/message_accessors'
4
+ require 'ews/mailbox_accessors'
5
+ require 'ews/push_subscription_accessors'
6
+ require 'ews/calendar_accessors'
7
+ require 'ews/room_accessors'
8
+ require 'ews/roomlist_accessors'
9
+ require 'ews/convert_accessors'
10
+ require 'ews/meeting_accessors'
11
+
12
+ # This class is the glue between the Models and the Web Service.
13
+ class Viewpoint::EWSClient
14
+ include Viewpoint::EWS
15
+ include Viewpoint::EWS::FolderAccessors
16
+ include Viewpoint::EWS::ItemAccessors
17
+ include Viewpoint::EWS::MessageAccessors
18
+ include Viewpoint::EWS::MailboxAccessors
19
+ include Viewpoint::EWS::PushSubscriptionAccessors
20
+ include Viewpoint::EWS::CalendarAccessors
21
+ include Viewpoint::EWS::RoomAccessors
22
+ include Viewpoint::EWS::RoomlistAccessors
23
+ include Viewpoint::EWS::ConvertAccessors
24
+ include Viewpoint::EWS::MeetingAccessors
25
+ include Viewpoint::StringUtils
26
+
27
+ # The instance of Viewpoint::EWS::SOAP::ExchangeWebService
28
+ attr_reader :ews, :endpoint, :username
29
+
30
+ # Initialize the EWSClient instance.
31
+ # @param [String] endpoint The EWS endpoint we will be connecting to
32
+ # @param [String] user The user to authenticate as. If you are using
33
+ # NTLM or Negotiate authentication you do not need to pass this parameter.
34
+ # @param [String] pass The user password. If you are using NTLM or
35
+ # Negotiate authentication you do not need to pass this parameter.
36
+ # @param [Hash] opts Various options to pass to the backends
37
+ # @option opts [String] :server_version The Exchange server version to
38
+ # target. See the VERSION_* constants in
39
+ # Viewpoint::EWS::SOAP::ExchangeWebService.
40
+ # @option opts [Object] :http_class specify an alternate HTTP connection class.
41
+ # @option opts [Hash] :http_opts options to pass to the connection
42
+ def initialize(endpoint, username, password, opts = {})
43
+ # dup all. @see ticket https://github.com/zenchild/Viewpoint/issues/68
44
+ @endpoint = endpoint.dup
45
+ @username = username.dup
46
+ password = password.dup
47
+ opts = opts.dup
48
+ http_klass = opts[:http_class] || Viewpoint::EWS::Connection
49
+ con = http_klass.new(endpoint, opts[:http_opts] || {})
50
+ con.set_auth @username, password
51
+ @ews = SOAP::ExchangeWebService.new(con, opts)
52
+ end
53
+
54
+ # @param deepen [Boolean] true to autodeepen, false otherwise
55
+ # @param behavior [Symbol] :raise, :nil When setting autodeepen to false you
56
+ # can choose what the behavior is when an attribute does not exist. The
57
+ # default is to raise a EwsMinimalObjectError.
58
+ def set_auto_deepen(deepen, behavior = :raise)
59
+ if deepen
60
+ ews.auto_deepen = true
61
+ else
62
+ behavior = [:raise, :nil].include?(behavior) ? behavior : :raise
63
+ ews.no_auto_deepen_behavior = behavior
64
+ ews.auto_deepen = false
65
+ end
66
+ end
67
+
68
+ def auto_deepen=(deepen)
69
+ set_auto_deepen deepen
70
+ end
71
+
72
+ # Specify a default time zone context for all time attributes
73
+ # @param id [String] Identifier of a Microsoft well known time zone (e.g: 'UTC', 'W. Europe Standard Time')
74
+ # @note A list of time zones known by the server can be requested via {EWS::SOAP::ExchangeTimeZones#get_time_zones}
75
+ def set_time_zone(microsoft_time_zone_id)
76
+ ews.set_time_zone_context microsoft_time_zone_id
77
+ end
78
+
79
+ private
80
+
81
+
82
+ # This method also exists in EWS::Types, but there is a lot of other stuff
83
+ # in there that I didn't want to include directly in this class.
84
+ def class_by_name(cname)
85
+ if(cname.instance_of? Symbol)
86
+ cname = camel_case(cname)
87
+ end
88
+ Viewpoint::EWS::Types.const_get(cname)
89
+ end
90
+
91
+ # Used for multiple accessors
92
+ def merge_restrictions!(obj, merge_type = :and)
93
+ if obj.opts[:restriction] && !obj.opts[:restriction].empty? && !obj.restriction.empty?
94
+ obj.opts[:restriction] = {
95
+ merge_type => [
96
+ obj.opts.delete(:restriction),
97
+ obj.restriction
98
+ ]
99
+ }
100
+ elsif !obj.restriction.empty?
101
+ obj.opts[:restriction] = obj.restriction
102
+ end
103
+ end
104
+
105
+ end
@@ -0,0 +1,61 @@
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
19
+
20
+ # Generic Ews Error
21
+ class EwsError < StandardError; end
22
+
23
+ # Raise when authentication/authorization issues occur.
24
+ class EwsLoginError < EwsError; end
25
+
26
+ class EwsSubscriptionError < EwsError; end
27
+
28
+ # Raised when a user tries to query a folder subscription after the
29
+ # subscription has timed out.
30
+ class EwsSubscriptionTimeout < EwsSubscriptionError; end
31
+
32
+ # Represents a function in EWS that is not yet implemented in Viewpoint
33
+ class EwsNotImplemented < EwsError; end
34
+
35
+ # Raised when an method is called in the wrong way
36
+ class EwsBadArgumentError < EwsError; end
37
+
38
+ # Raised when an item that is asked for is not found
39
+ class EwsItemNotFound < EwsError; end
40
+
41
+ # Raised when a folder that is asked for is not found
42
+ class EwsFolderNotFound < EwsError; end
43
+
44
+ # Raise an Exchange Server version error. This is in case some functionality
45
+ # does not exist in a particular Server version but is called.
46
+ class EwsServerVersionError < EwsError; end
47
+
48
+ # Raised when #auto_deepen == false and a method is called for attributes
49
+ # that have not yet been fetched.
50
+ class EwsMinimalObjectError < EwsError; end
51
+
52
+ class EwsFrozenObjectError < EwsError; end
53
+
54
+ # Failed to save an object back to the EWS store.
55
+ class SaveFailed < EwsError; end
56
+
57
+ class EwsCreateItemError < EwsError; end
58
+
59
+ class EwsSendItemError < EwsError; end
60
+
61
+ end # Viewpoint::EWS
@@ -0,0 +1,264 @@
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::FolderAccessors
19
+ include Viewpoint::EWS
20
+
21
+ FOLDER_TYPE_MAP = {
22
+ :mail => 'IPF.Note',
23
+ :calendar => 'IPF.Appointment',
24
+ :task => 'IPF.Task',
25
+ }
26
+
27
+ # Find subfolders of the passed root folder. If no parameters are passed this
28
+ # method will search from the Root folder.
29
+ # @param [Hash] opts Misc options to control request
30
+ # @option opts [String,Symbol] :root Either a FolderId(String) or a
31
+ # DistinguishedFolderId(Symbol) . This is where to start the search from.
32
+ # Usually :root,:msgfolderroot, or :publicfoldersroot
33
+ # @option opts [Symbol] :traversal :shallow/:deep/:soft_deleted
34
+ # @option opts [Symbol] :shape :id_only/:default/:all_properties
35
+ # @option opts [optional, String] :folder_type an optional folder type to
36
+ # limit the search to like 'IPF.Task'
37
+ # @return [Array] Returns an Array of Folder or subclasses of Folder
38
+ # @raise [EwsError] raised when the backend SOAP method returns an error.
39
+ def folders(opts={})
40
+ opts = opts.clone
41
+ args = find_folders_args(opts)
42
+ obj = OpenStruct.new(opts: args, restriction: {})
43
+ yield obj if block_given?
44
+ merge_restrictions! obj
45
+ resp = ews.find_folder( args )
46
+ find_folders_parser(resp)
47
+ end
48
+ alias :find_folders :folders
49
+
50
+ # Get a specific folder by id or symbol
51
+ # @param [String,Symbol,Hash] folder_id Either a FolderId(String) or a
52
+ # DistinguishedFolderId(Symbol). You can also pass a Hash in the form:
53
+ # {id: <fold_id>, change_key: <change_key>}
54
+ # @param [Hash] opts Misc options to control request
55
+ # @option opts [Symbol] :shape :id_only/:default/:all_properties
56
+ # @option opts [String,nil] :act_as User to act on behalf as. This user must
57
+ # have been given delegate access to the folder or this operation will fail.
58
+ # @raise [EwsError] raised when the backend SOAP method returns an error.
59
+ def get_folder(folder_id, opts = {})
60
+ opts = opts.clone
61
+ args = get_folder_args(folder_id, opts)
62
+ resp = ews.get_folder(args)
63
+ get_folder_parser(resp)
64
+ end
65
+
66
+ # Get a specific folder by its name
67
+ # @param [String] name The folder name
68
+ # @param [Hash] opts Misc options to control request
69
+ # @option opts [String,Symbol] :parent Either a FolderId(String) or a
70
+ # DistinguishedFolderId(Symbol) . This is the parent folder.
71
+ # @option opts [Symbol] :shape :id_only/:default/:all_properties
72
+ # @option opts [String,nil] :act_as User to act on behalf as. This user must
73
+ # have been given delegate access to the folder or this operation will fail.
74
+ # @raise [EwsError] raised when the backend SOAP method returns an error.
75
+ def get_folder_by_name(name, opts={})
76
+ opts = opts.clone
77
+ opts[:root] = opts.delete(:parent)
78
+ folders(opts) do |obj|
79
+ obj.restriction = {
80
+ :is_equal_to =>
81
+ [
82
+ {:field_uRI => {:field_uRI=>'folder:DisplayName'}},
83
+ {:field_uRI_or_constant => {:constant => {:value=>name}}}
84
+ ]
85
+ }
86
+ end.first
87
+ end
88
+
89
+ # @param [String] name The name of the new folder
90
+ # @param [Hash] opts
91
+ # @option opts [String,Symbol] :parent Either a FolderId(String) or a
92
+ # DistinguishedFolderId(Symbol) . This is the parent folder.
93
+ # @option opts [Symbol] :type the type of folder to create. must be one of
94
+ # :folder, :calendar, :contacts, :search, or :tasks
95
+ # @see http://msdn.microsoft.com/en-us/library/aa580808.aspx
96
+ def make_folder(name, opts={})
97
+ parent = opts[:parent] || :msgfolderroot
98
+ resp = ews.create_folder :parent_folder_id => {:id => parent},
99
+ :folders => [folder_type(opts[:type]) => {:display_name => name}]
100
+ create_folder_parser(resp).first
101
+ end
102
+ alias :mkfolder :make_folder
103
+
104
+ # Get a specific folder by id or symbol
105
+ # @param [Hash] opts Misc options to control request
106
+ # @option opts [Symbol] :shape :id_only/:default/:all_properties
107
+ # @option opts [String,Symbol,Hash] :folder_id You can optionally specify a
108
+ # folder_id to limit the hierarchy synchronization to it. It must be a
109
+ # FolderId(String), a DistinguishedFolderId(Symbol) or you can pass a Hash
110
+ # in the form: {id: <fold_id>, change_key: <change_key>}
111
+ # @option opts [String] :sync_state an optional Base64 encoded SyncState
112
+ # String from a previous sync call.
113
+ # @yield [Hash] yields the formatted argument Hash for last-minute
114
+ # modification before calling the backend EWS method.
115
+ # @return [Hash] A hash with the following keys
116
+ # :all_synced, whether or not additional calls are needed to get all folders
117
+ # :sync_state, the sync state to use for the next call
118
+ # and the following optional keys depending on the changes
119
+ # :create, :update, :delete
120
+ # @raise [EwsError] raised when the backend SOAP method returns an error.
121
+ def sync_folders(opts = {})
122
+ opts = opts.clone
123
+ args = sync_folders_args(opts)
124
+ yield args if block_given?
125
+ resp = ews.sync_folder_hierarchy( args )
126
+ sync_folders_parser(resp)
127
+ end
128
+
129
+
130
+ private
131
+
132
+ # Build up the arguements for #find_folders
133
+ def find_folders_args(opts)
134
+ opts[:root] = opts[:root] || :msgfolderroot
135
+ opts[:traversal] = opts[:traversal] || :shallow
136
+ opts[:shape] = opts[:shape] || :default
137
+ folder_id = {:id => opts[:root]}
138
+ folder_id[:act_as] = opts[:act_as] if opts[:act_as]
139
+ if( opts[:folder_type] )
140
+ restr = { :is_equal_to =>
141
+ [
142
+ {:field_uRI => {:field_uRI=>'folder:FolderClass'}},
143
+ {:field_uRI_or_constant=>{:constant =>
144
+ {:value => map_folder_type(opts[:folder_type])}}},
145
+ ]
146
+ }
147
+ end
148
+ args = {
149
+ :parent_folder_ids => [folder_id],
150
+ :traversal => opts[:traversal],
151
+ :folder_shape => {:base_shape => opts[:shape]}
152
+ }
153
+ args[:restriction] = restr if restr
154
+ args
155
+ end
156
+
157
+ # @param [Viewpoint::EWS::SOAP::EwsSoapResponse] resp
158
+ def find_folders_parser(resp)
159
+ if resp.status == 'Success'
160
+ folders = resp.response_message[:elems][:root_folder][:elems][0][:folders][:elems]
161
+ return [] if folders.nil?
162
+ folders.collect do |f|
163
+ ftype = f.keys.first
164
+ class_by_name(ftype).new(ews, f[ftype])
165
+ end
166
+ else
167
+ raise EwsFolderNotFound, "Could not retrieve folders. #{resp.code}: #{resp.message}"
168
+ end
169
+ end
170
+
171
+ def create_folder_parser(resp)
172
+ if resp.status == 'Success'
173
+ folders = resp.response_message[:elems][:folders][:elems]
174
+ folders.collect do |f|
175
+ ftype = f.keys.first
176
+ class_by_name(ftype).new(ews, f[ftype])
177
+ end
178
+ else
179
+ raise EwsError, "Could not create folder. #{resp.code}: #{resp.message}"
180
+ end
181
+ end
182
+
183
+ # Build up the arguements for #get_folder
184
+ def get_folder_args(folder_id, opts)
185
+ opts[:shape] ||= :default
186
+ default_args = {
187
+ :folder_shape => {:base_shape => opts[:shape]}
188
+ }
189
+ if folder_id.is_a?(Hash)
190
+ default_args[:folder_ids] = [folder_id]
191
+ else
192
+ default_args[:folder_ids] = [{:id => folder_id}]
193
+ end
194
+ default_args.merge opts
195
+ end
196
+
197
+ # @param [Viewpoint::EWS::SOAP::EwsSoapResponse] resp
198
+ def get_folder_parser(resp)
199
+ if(resp.status == 'Success')
200
+ f = resp.response_message[:elems][:folders][:elems][0]
201
+ ftype = f.keys.first
202
+ class_by_name(ftype).new(ews, f[ftype])
203
+ else
204
+ raise EwsFolderNotFound, "Could not retrieve folder. #{resp.code}: #{resp.message}"
205
+ end
206
+ end
207
+
208
+ def sync_folders_args(opts)
209
+ opts[:shape] = opts[:shape] || :default
210
+ args = { :folder_shape => {:base_shape => opts[:shape]} }
211
+ if opts[:folder_id]
212
+ folder_id = opts[:folder_id]
213
+ if folder_id.is_a?(Hash)
214
+ args[:sync_folder_id] = folder_id
215
+ else
216
+ args[:sync_folder_id] = {:id => folder_id}
217
+ end
218
+ end
219
+ args[:sync_state] = opts[:sync_state] if opts[:sync_state]
220
+ args
221
+ end
222
+
223
+ def sync_folders_parser(resp)
224
+ rmsg = resp.response_messages[0]
225
+ if rmsg.success?
226
+ rhash = {}
227
+ rhash[:all_synced] = rmsg.includes_last_folder_in_range?
228
+ rhash[:sync_state] = rmsg.sync_state
229
+ rmsg.changes.each do |c|
230
+ ctype = c.keys.first
231
+ rhash[ctype] = [] unless rhash.has_key?(ctype)
232
+ if ctype == :delete
233
+ rhash[ctype] << c[ctype][:elems][0][:folder_id][:attribs]
234
+ else
235
+ type = c[ctype][:elems][0].keys.first
236
+ item = class_by_name(type).new(ews, c[ctype][:elems][0][type])
237
+ rhash[ctype] << item
238
+ end
239
+ end
240
+ rhash
241
+ else
242
+ raise EwsError, "Could not synchronize folders. #{rmsg.response_code}: #{rmsg.message_text}"
243
+ end
244
+ end
245
+
246
+ # Map a passed parameter to a know folder type mapping. If no mapping
247
+ # exits simply allow the passed in type to be passed to the SOAP call.
248
+ # @param [Symbol] type a symbol in FOLDER_TYPE_MAP
249
+ def map_folder_type(type)
250
+ FOLDER_TYPE_MAP[type] || type
251
+ end
252
+
253
+ def folder_type(type)
254
+ case type
255
+ when nil, :folder
256
+ :folder
257
+ when :calendar, :contacts, :search, :tasks
258
+ "#{type}_folder".to_sym
259
+ else
260
+ raise EwsBadArgumentError, "Not a proper folder type: :#{type}"
261
+ end
262
+ end
263
+
264
+ end