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
@@ -1,267 +0,0 @@
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
20
- module EWS
21
- class CalendarItem < Message
22
-
23
- # This is a class method that creates a new CalendarItem in the Exchange Data Store.
24
- # @param [Hash] item A Hash of values based on values found here:
25
- # http://msdn.microsoft.com/en-us/library/aa564765.aspx
26
- # @param [String, Symbol] folder_id The folder to create this item in. Either a
27
- # DistinguishedFolderId (must me a Symbol) or a FolderId (String)
28
- # @param [String] send_invites "SendToNone/SendOnlyToAll/SendToAllAndSaveCopy"
29
- # See: http://msdn.microsoft.com/en-us/library/aa565209.aspx
30
- # @example Typical Usage
31
- # item = { :subject => {:text => 'Planning'},
32
- # :body => {:body_type => 'Text', :text => 'This is a test'},
33
- # :start => {:text => '2010-07-29T14:00:00'},
34
- # :end => {:text => '2010-07-29T15:00:00'},
35
- # :is_all_day_event => {:text => 'false'},
36
- # :location => {:text => 'Room 234'},
37
- # :required_attendees => {:attendee => {:mailbox => {:email_address => {:text => 'test@test.com'}}}}
38
- # }
39
- # @example Minimal Usage
40
- # item = { :subject => {:text => 'Planning'},
41
- # :start => {:text => '2010-07-29T14:00:00'},
42
- # :end => {:text => '2010-07-29T15:00:00'}
43
- # }
44
- def self.create_item_from_hash(item, folder_id = :calendar, send_invites = 'SendToAllAndSaveCopy')
45
- conn = Viewpoint::EWS::EWS.instance
46
- resp = conn.ews.create_calendar_item(folder_id, item, send_invites)
47
- if(resp.status == 'Success')
48
- resp = resp.items.shift
49
- self.new(resp[resp.keys.first])
50
- else
51
- raise EwsError, "Could not create CalendarItem. #{resp.code}: #{resp.message}"
52
- end
53
- end
54
-
55
- # Format attendees (usually called from #add_attendees!
56
- # @param [Array,String,Hash,MailboxUser] attendees
57
- # @param [Symbol] type the type of the attendees :required_attendees/:optional_attendees/:resources
58
- def self.format_attendees(attendees, type=:required_attendees)
59
- case attendees.class.to_s
60
- when 'String'
61
- return {type => [{:attendee => {:mailbox => {:email_address => {:text => attendees}}}}]}
62
- when /Attendee|MailboxUser/
63
- return {type => [{:attendee => {:mailbox => [{:name => {:text => attendees.name}}, {:email_address => {:text => attendees.email_address}}]}}]}
64
- when 'Hash'
65
- return {type => [{:attendee => {:mailbox => [{:name => {:text => attendees[:name]}}, {:email_address => {:text => attendees[:email_address]}}]}}]}
66
- when 'Array'
67
- as = {type => []}
68
- attendees.each do |a|
69
- as.merge!(format_attendees(a, type)) {|k,v1,v2| v1 + v2}
70
- end
71
- return as
72
- end
73
- end
74
-
75
- # Create a new CalendarItem.
76
- # If a block is given it is passed an opts hash with the keys :folder_id and :send_invites.
77
- # See ::create_item_from_hash for details
78
- # @param [DateTime] v_start The date and time when the CalendarItem begins
79
- # @param [DateTime] v_end The date and time when the CalendarItem ends
80
- # @param [String] subject The subject of this Item
81
- # @param [String,optional] body The body of this object
82
- # @param [String,optional] location The location where this calendar item will ocurr
83
- # @param [Array<String,MailboxUser,Attendee>,optional] required_attendees An Array of e-mail addresses of required attendees
84
- # @param [Array<String,MailboxUser,Attendee>,optional] optional_attendees An Array of e-mail addresses of optional attendees
85
- # @param [Array<String,MailboxUser,Attendee>,optional] resources An Array of e-mail addresses of resources
86
- def self.create_item(v_start, v_end, subject, body = nil, location = nil, required_attendees=[], optional_attendees=[], resources=[])
87
- item = {}
88
- opts = {:folder_id => :calendar, :send_invites => 'SendToAllAndSaveCopy'}
89
- yield opts if block_given?
90
- item[:start] = {:text => v_start.to_s}
91
- item[:end] = {:text => v_end.to_s}
92
- item[:subject] = {:text => subject}
93
- item[:body] = {:text => body, :body_type => 'Text'} unless body.nil?
94
- item[:location] = {:text => location} unless location.nil?
95
- item.merge!(self.format_attendees(required_attendees)) unless required_attendees.empty?
96
- item.merge!(self.format_attendees(optional_attendees, :optional_attendees)) unless optional_attendees.empty?
97
- resources.each do |a|
98
- item[:resources] = [] unless item[:resources].is_a?(Array)
99
- item[:resources] << {:attendee => {:mailbox => {:email_address => {:text => a}}}}
100
- end
101
- self.create_item_from_hash(item, opts[:folder_id], opts[:send_invites])
102
- end
103
-
104
- # Initialize an Exchange Web Services item of type CalendarItem
105
- def initialize(ews_item, opts={})
106
- super(ews_item, opts)
107
- end
108
-
109
- # Add attendees to this CalendarItem. This does not commit the changes so you will have to use #save! to
110
- # commit them back. If you want to commit them at once look at the #add_attendees! method.
111
- # @param [Array] required Required attendees to add to this object
112
- # Array values of attendees may be simple email strings, MailboxUser items or Hashes in the form
113
- # {:email_address => 'email@test', :name => 'My Name'}.
114
- # @param [Array] optional Optional attendees to add to this object
115
- # see the notes for the 'required' parameter.
116
- # @example
117
- # ['user1@example.org', 'user2@example.org']
118
- # or
119
- # [{:name => 'User1', :email_address => 'user1@example.org'}, {:name => 'User2', :email_address => 'user2@example.org'}]
120
- # or
121
- # ['user1@example.org', 'user2@example.org'], ['user3@example.org', 'user4@example.org']
122
- # or
123
- # [{:name => 'User1', :email_address => 'user1@example.org'}, {:name => 'User2', :email_address => 'user2@example.org'}],
124
- # [{:name => 'User3', :email_address => 'user3@example.org'}, {:name => 'User4', :email_address => 'user4@example.org'}]
125
- # @return [Boolean] true on success, false otherwise
126
- # @todo add ability to add resources
127
- def add_attendees(required, optional = [], resources = [])
128
- update = {}
129
- update.merge!(self.class.format_attendees(required)) unless required.empty? || required.nil?
130
- update.merge!(self.class.format_attendees(optional, :optional_attendees)) unless optional.empty? || optional.nil?
131
-
132
- return false if update.empty?
133
-
134
- @required_attendees, @optional_attendees = nil, nil
135
- changes = update_attribs(update, :append)
136
- @updates.merge!({:preformatted => changes}) {|k,v1,v2| v1 + v2}
137
- true
138
- end
139
-
140
- # This is the same as the #add_attendees method, but it actually commits the change back to Exchange
141
- # @see #add_attendees
142
- def add_attendees!(required, optional = [], resources = [])
143
- add_attendees(required, optional, resources)
144
- save!
145
- end
146
-
147
- # Remove the attendees from the attendee list. This does not commit the changes so you will have to use
148
- # #save! to commit them back. If you want to commit them at once look at the #remove_attendees! method.
149
- # @param [Array] attendees the attendees to remove from this CalendarItem
150
- # [Viewpoint::EWS::Attendee<user1>, Viewpoint::EWS::Attendee<user2>] or
151
- # ['user1@example.org', 'user2@example.org']
152
- # @return [Boolean] false if the object is not updated, true otherwise
153
- def remove_attendees(attendees)
154
- return false if attendees.empty?
155
-
156
- emails = attendees.is_a?(Array) ? attendees : attendees.values
157
- emails = emails.collect do |v|
158
- case v.class.to_s
159
- when 'String'
160
- v
161
- when /MailboxUser|Attendee/
162
- v.email_address
163
- when 'Hash'
164
- v[:email_address]
165
- end
166
- end
167
-
168
- update = {}
169
- [:required_attendees, :optional_attendees].each do |type|
170
- ivar = self.send(type.to_s)
171
- next if ivar.nil?
172
-
173
- required_a = ivar.select {|v| !emails.include?(v.email_address) }
174
- formatted_a = self.class.format_attendees(required_a, type)
175
- if formatted_a[type].empty?
176
- update[:preformatted] ||= []
177
- update[:preformatted] << {:delete_item_field => [{:field_uRI => {:field_uRI=>FIELD_URIS[type][:text]}}]}
178
- self.instance_eval "undef #{type}"
179
- else
180
- update.merge!(formatted_a)
181
- end
182
- end
183
-
184
- return false if update.empty?
185
-
186
- @required_attendees, @optional_attendees = nil, nil
187
- @updates.merge!(update) {|k,v1,v2| v1 + v2}
188
- true
189
- end
190
-
191
- # This is the same as the #remove_attendees method, but it actually commits the change back to Exchange
192
- # @see #remove_attendees
193
- def remove_attendees!(attendees)
194
- remove_attendees(attendees)
195
- save!
196
- end
197
-
198
- # Call UpdateItem for this item with the passed updates
199
- # @param [Hash] updates a well-formed update hash
200
- # @example {:set_item_field=>{:field_u_r_i=>{:field_u_r_i=>"message:IsRead"}, :message=>{:is_read=>{:text=>"true"}}}}
201
- # TODO: This is a stand-in for the Item#update! method until I can firm it up a bit. It is neccessary for the SendMeetingInvitationsOrCancellations attrib
202
- def update!(updates)
203
- conn = Viewpoint::EWS::EWS.instance
204
- resp = conn.ews.update_item([{:id => @item_id, :change_key => @change_key}], {:updates => updates},
205
- {:message_disposition => 'SaveOnly', :conflict_resolution => 'AutoResolve', :send_meeting_invitations_or_cancellations => 'SendOnlyToChanged'})
206
- if resp.status == 'Success'
207
- @item_id = resp.items.first[resp.items.first.keys.first][:item_id][:id]
208
- @change_key = resp.items.first[resp.items.first.keys.first][:item_id][:change_key]
209
- @shallow = true
210
- deepen!
211
- else
212
- raise EwsError, "Trouble updating Item. #{resp.code}: #{resp.message}"
213
- end
214
-
215
- end
216
-
217
- # Delete this item
218
- # @param [Boolean] soft Whether or not to do a soft delete. By default EWS will do a
219
- # hard delete of this item. See the MSDN docs for more info:
220
- # http://msdn.microsoft.com/en-us/library/aa562961.aspx
221
- # @param [String] cancel_type "SendToNone/SendOnlyToAll/SendToAllAndSaveCopy"
222
- # Default is SendOnlyToAll
223
- # @return [Boolean] Whether or not the item was deleted
224
- # @todo Add exception handling for failed deletes
225
- #
226
- def delete!(soft=false, cancel_type='SendOnlyToAll')
227
- deltype = soft ? 'SoftDelete' : 'HardDelete'
228
- resp = (Viewpoint::EWS::EWS.instance).ews.delete_item([@item_id], deltype, cancel_type)
229
- self.clear_object!
230
- resp.status == 'Success'
231
- end
232
-
233
- # Delete this item by moving it to the Deleted Items folder
234
- # @see http://msdn.microsoft.com/en-us/library/aa562961.aspx
235
- # @return [Boolean] Whether or not the item was deleted
236
- # @todo Add exception handling for failed deletes
237
- def recycle!(cancel_type='SendOnlyToAll')
238
- resp = (Viewpoint::EWS::EWS.instance).ews.delete_item([@item_id], 'MoveToDeletedItems', cancel_type)
239
- self.clear_object!
240
- resp.status == 'Success'
241
- end
242
-
243
-
244
- private
245
-
246
- def init_methods
247
- super
248
- define_str_var :calendar_item_type, :duration, :time_zone, :when, :location, :u_i_d, {:u_i_d => :uid}
249
- define_str_var :legacy_free_busy_status, :my_response_type, :meeting_workspace_url, :net_show_url
250
- define_int_var :adjacent_meeting_count, :appointment_sequence_number, :appointment_state
251
- define_int_var :conference_type, :conflicting_meeting_count
252
- define_mbox_user :organizer
253
- define_bool_var :is_all_day_event, :is_cancelled, :is_meeting, :is_online_meeting, :is_recurring
254
- define_bool_var :allow_new_time_proposal, :meeting_request_was_sent
255
- define_datetime_var :appointment_reply_time, :start, :end, :original_start
256
- define_attendees :required_attendees, :optional_attendees, :resources
257
-
258
- # @todo Handle:
259
- # <AdjacentMeetings/> <ConflictingMeetings/> <DeletedOccurrences/>
260
- # <FirstOccurrence/> <LastOccurrence/> <ModifiedOccurrences/>
261
- # <StartTimeZone/> <EndTimeZone/> <MeetingTimeZone/>
262
- # <Recurrence/>
263
- end
264
-
265
- end # CalendarItem
266
- end # EWS
267
- end # Viewpoint
@@ -1,238 +0,0 @@
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
20
- module EWS
21
- # Represents a Contact Item in the Exchange datastore.
22
- class Contact < Item
23
-
24
- # This is a class method that creates a new Contact in the Exchange Data Store.
25
- # @param [Hash] item A Hash of values based on values found here:
26
- # http://msdn.microsoft.com/en-us/library/aa581315.aspx
27
- # @param [String, Symbol] folder_id The folder to create this item in. Either a
28
- # DistinguishedFolderId (must me a Symbol) or a FolderId (String)
29
- # @param [String] send_invites "SendToNone/SendOnlyToAll/SendToAllAndSaveCopy"
30
- # See: http://msdn.microsoft.com/en-us/library/aa565209.aspx
31
- # @example Typical Usage
32
- # item = {
33
- # :file_as => {:text => 'Dan Wanek'},
34
- # :given_name => {:text => 'Dan Wanek'},
35
- # :company_name => {:text => 'Test Company'},
36
- # :email_addresses => [
37
- # {:entry => {:key => 'EmailAddress1', :text => 'myemail@work.com'}},
38
- # {:entry => {:key => 'EmailAddress2', :text => 'myemail@home.com'}}
39
- # ],
40
- # :physical_addresses => [
41
- # {:entry => {:key => 'Business', :sub_elements => {:street => {:text => '6343 N Baltimore'}, :city => {:text => 'Bismarck'}, :state => {:text => 'ND'} }}}
42
- # ],
43
- # :phone_numbers => [
44
- # {:entry => {:key => 'BusinessPhone', :text => '7012220000'}}
45
- # ],
46
- # :job_title => {:text => 'Systems Architect'}
47
- # }
48
- # @example Minimal Usage
49
- def self.create_item_from_hash(item, folder_id = :contacts)
50
- conn = Viewpoint::EWS::EWS.instance
51
- resp = conn.ews.create_contact_item(folder_id, item)
52
- if(resp.status == 'Success')
53
- resp = resp.items.shift
54
- self.new(resp[resp.keys.first])
55
- else
56
- raise EwsError, "Could not create Contact. #{resp.code}: #{resp.message}"
57
- end
58
- end
59
-
60
- # Create a Contact in the Exchange Data Store
61
- def self.add_contact()
62
- item = {}
63
-
64
- conn = Viewpoint::EWS::EWS.instance
65
- resp = conn.ews.create_contact_item()
66
-
67
- if(resp.status == 'Success')
68
- resp = resp.items.shift
69
- self.new(resp[resp.keys.first])
70
- else
71
- raise EwsError, "Could not add contact. #{resp.code}: #{resp.message}"
72
- end
73
- end
74
-
75
- # Initialize an Exchange Web Services item of type Contact
76
- def initialize(ews_item, opts={})
77
- super(ews_item, opts)
78
- end
79
-
80
- def set_email_addresses(email1, email2=nil, email3=nil)
81
- changes = []
82
- type = self.class.name.split(/::/).last.ruby_case.to_sym
83
- k = :email_addresses
84
- v = 'EmailAddress1'
85
- changes << {:set_item_field =>
86
- [{:indexed_field_uRI => {:field_uRI => FIELD_URIS[k][:text], :field_index => v}}, {type=>{k => {:entry => {:key => v, :text => email1}}}}]} unless email1.nil?
87
- v = 'EmailAddress2'
88
- changes << {:set_item_field =>
89
- [{:indexed_field_uRI => {:field_uRI => FIELD_URIS[k][:text], :field_index => v}}, {type=>{k => {:entry => {:key => v, :text => email2}}}}]} unless email2.nil?
90
- v = 'EmailAddress3'
91
- changes << {:set_item_field =>
92
- [{:indexed_field_uRI => {:field_uRI => FIELD_URIS[k][:text], :field_index => v}}, {type=>{k => {:entry => {:key => v, :text => email3}}}}]} unless email3.nil?
93
- @updates.merge!({:preformatted => changes}) {|k,v1,v2| v1 + v2}
94
- end
95
-
96
- # Set the phone number. You must give a type based on the available Exchange phone number types
97
- # @param [Symbol] type the type of number to set. It must be one of these:
98
- # :assistant_phone, :business_fax, :business_phone, :business_phone2, :callback, :car_phone, :company_main_phone,
99
- # :home_fax, :home_phone, :home_phone2, :isdn, :mobile_phone, :other_fax, :other_telephone, :pager, :primary_phone,
100
- # :radio_phone, :telex, :tty_tdd_phone
101
- # @param [String] phone_number The phone number
102
- def set_phone_number(phone_type, phone_number)
103
- valid_types = [:assistant_phone, :business_fax, :business_phone, :business_phone2, :callback, :car_phone, :company_main_phone,
104
- :home_fax, :home_phone, :home_phone2, :isdn, :mobile_phone, :other_fax, :other_telephone, :pager, :primary_phone,
105
- :radio_phone, :telex, :tty_tdd_phone]
106
- raise EwsError, "Invalid phone type (#{phone_type}) passed to Contact#set_phone_number." unless valid_types.index phone_type
107
- type = self.class.name.split(/::/).last.ruby_case.to_sym
108
-
109
- changes = []
110
- k = :phone_numbers
111
- v = phone_type.to_s.camel_case
112
- changes << {:set_item_field =>
113
- [{:indexed_field_uRI => {:field_uRI => FIELD_URIS[k][:text], :field_index => v}}, {type=>{k => {:entry => {:key => v, :text => phone_number}}}}]}
114
- @updates.merge!({:preformatted => changes}) {|k,v1,v2| v1 + v2}
115
- end
116
-
117
- # Set an address for this contact
118
- # @param [Symbol] address_type the type of Exchange address to set. It must be one of the following:
119
- # :business, :home, :other
120
- # @param [Hash] address the address elements to set. It may include the following keys
121
- # :street, :city, :state, :country_or_region, :postal_code
122
- # @todo check for empty address hash
123
- def set_address(address_type, address)
124
- valid_types = [:business, :home, :other]
125
- raise EwsError, "Invalid address type (#{address_type}) passed to Contact#set_address." unless valid_types.index address_type
126
- valid_field_types = [:street, :city, :state, :country_or_region, :postal_code]
127
- type = self.class.name.split(/::/).last.ruby_case.to_sym
128
- v = address_type.to_s.camel_case
129
-
130
- changes = []
131
- field = 'PhysicalAddresses'
132
- address.keys.each do |addr_item|
133
- raise EwsError, "Invalid address element (#{addr_item}) passed to Contact#set_address." unless valid_field_types.index addr_item
134
- index_field = "contacts:PhysicalAddress:#{addr_item.to_s.camel_case}"
135
- changes << {:set_item_field =>
136
- [{:indexed_field_uRI => {
137
- :field_uRI => index_field, :field_index => v}}, {type => {field => {:entry => {:key => v, addr_item =>{ :text => address[addr_item]}}}}}
138
- ]}
139
- end
140
- @updates.merge!({:preformatted => changes}) {|k,v1,v2| v1 + v2}
141
- end
142
-
143
-
144
- private
145
-
146
- def init_methods
147
- super()
148
-
149
- define_str_var :file_as, :file_as_mapping, :display_name, :job_title, :given_name, :surname, :company_name
150
- define_attr_str_var :complete_name, :first_name, :middle_name, :last_name, :initials, :full_name
151
- define_inet_addresses :email_addresses, :im_addresses
152
- define_phone_numbers :phone_numbers
153
- define_physical_addresses :physical_addresses
154
- end
155
-
156
-
157
- # Define email_addresses or im_addresses for a Contact
158
- def define_inet_addresses(*inet_addresses)
159
- inet_addresses.each do |itype|
160
- eval "@#{itype} ||= {}"
161
- return unless self.instance_variable_get("@#{itype}").empty?
162
- if(@ews_item.has_key?(itype))
163
- @ews_methods << itype
164
- if(@ews_item[itype][:entry].is_a?(Array))
165
- @ews_item[itype][:entry].each do |entry|
166
- next if entry.keys.length == 1
167
- eval "@#{itype}[entry[:key].ruby_case.to_sym] = (entry.has_key?(:text) ? entry[:text] : '')"
168
- end
169
- else
170
- entry = @ews_item[itype][:entry]
171
- next if entry.keys.length == 1
172
- eval "@#{itype}[entry[:key].ruby_case.to_sym] = (entry.has_key?(:text) ? entry[:text] : '')"
173
- end
174
- self.instance_eval <<-EOF
175
- def #{itype}
176
- self.instance_variable_get "@#{itype}"
177
- end
178
- EOF
179
- else
180
- @ews_methods_undef << itype
181
- end
182
- end
183
- end
184
-
185
- def define_phone_numbers(phone_numbers)
186
- @phone_numbers ||= {}
187
- return unless @phone_numbers.empty?
188
- if(@ews_item.has_key?(phone_numbers))
189
- if(@ews_item[phone_numbers][:entry].is_a?(Array))
190
- @ews_item[phone_numbers][:entry].each do |entry|
191
- next if entry.keys.length == 1
192
- @phone_numbers[entry[:key].ruby_case.to_sym] = (entry.has_key?(:text) ? entry[:text] : "")
193
- end
194
- else # it is a Hash then
195
- entry = @ews_item[phone_numbers][:entry]
196
- return if entry.keys.length == 1
197
- @phone_numbers[entry[:key].ruby_case.to_sym] = (entry.has_key?(:text) ? entry[:text] : "")
198
- end
199
- self.instance_eval <<-EOF
200
- def #{phone_numbers}
201
- @phone_numbers
202
- end
203
- EOF
204
- @ews_methods << phone_numbers
205
- else
206
- @ews_methods_undef << itype
207
- end
208
- end
209
-
210
- # Define physical_addresses for a Contact
211
- def define_physical_addresses(physical_addresses)
212
- @physical_addresses ||= {}
213
- return unless @physical_addresses.empty?
214
- if(@ews_item.has_key?(physical_addresses))
215
- @ews_methods << physical_addresses
216
- entries = @ews_item[physical_addresses][:entry]
217
- entries = entries.is_a?(Array) ? entries : [entries]
218
- entries.each do |entry|
219
- next if entry.keys.length == 1
220
- key = entry.delete(:key)
221
- @physical_addresses[key.ruby_case.to_sym] = {}
222
- entry.each_pair do |ekey,ev|
223
- @physical_addresses[key.ruby_case.to_sym][ekey] = ev[:text]
224
- end
225
- end
226
- self.instance_eval <<-EOF
227
- def #{physical_addresses}
228
- @physical_addresses
229
- end
230
- EOF
231
- else
232
- @ews_methods_undef << itype
233
- end
234
- end
235
-
236
- end # Contact
237
- end # EWS
238
- end # Viewpoint