viewpoint 0.1.27 → 1.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
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