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.
- data/README.md +196 -0
- data/lib/ews/calendar_accessors.rb +34 -0
- data/lib/ews/connection.rb +117 -0
- data/lib/ews/connection_helper.rb +35 -0
- data/lib/ews/ews_client.rb +71 -0
- data/lib/ews/exceptions/exceptions.rb +59 -0
- data/lib/ews/folder_accessors.rb +199 -0
- data/lib/ews/item_accessors.rb +157 -0
- data/lib/ews/mailbox_accessors.rb +87 -0
- data/lib/ews/message_accessors.rb +86 -0
- data/lib/ews/push_subscription_accessors.rb +33 -0
- data/lib/ews/soap.rb +63 -0
- data/lib/ews/soap/builders/ews_builder.rb +1011 -0
- data/lib/ews/soap/ews_response.rb +83 -0
- data/lib/ews/soap/ews_soap_availability_response.rb +58 -0
- data/lib/ews/soap/ews_soap_free_busy_response.rb +109 -0
- data/lib/ews/soap/ews_soap_response.rb +103 -0
- data/lib/ews/soap/exchange_availability.rb +61 -0
- data/lib/ews/soap/exchange_data_services.rb +742 -0
- data/lib/ews/soap/exchange_notification.rb +146 -0
- data/lib/ews/soap/exchange_user_configuration.rb +33 -0
- data/lib/ews/soap/exchange_web_service.rb +294 -0
- data/lib/{model/attendee.rb → ews/soap/parsers/ews_parser.rb} +20 -14
- data/lib/ews/soap/parsers/ews_sax_document.rb +66 -0
- data/lib/ews/soap/response_message.rb +78 -0
- data/lib/ews/soap/responses/create_attachment_response_message.rb +46 -0
- data/lib/{model/meeting_message.rb → ews/soap/responses/create_item_response_message.rb} +7 -10
- data/lib/ews/soap/responses/find_item_response_message.rb +80 -0
- data/lib/ews/soap/responses/get_events_response_message.rb +53 -0
- data/lib/ews/soap/responses/send_notification_response_message.rb +58 -0
- data/lib/{model/attachment.rb → ews/soap/responses/subscribe_response_message.rb} +17 -13
- data/lib/ews/templates/forward_item.rb +24 -0
- data/lib/ews/templates/message.rb +66 -0
- data/lib/ews/templates/reply_to_item.rb +25 -0
- data/lib/ews/types.rb +146 -0
- data/lib/ews/types/attachment.rb +77 -0
- data/lib/{model/meeting_cancellation.rb → ews/types/attendee.rb} +9 -8
- data/lib/ews/types/calendar_folder.rb +8 -0
- data/lib/ews/types/calendar_item.rb +37 -0
- data/lib/ews/types/contact.rb +7 -0
- data/lib/ews/types/contacts_folder.rb +8 -0
- data/lib/ews/types/copied_event.rb +51 -0
- data/lib/{soap/handsoap/builder.rb → ews/types/created_event.rb} +5 -2
- data/lib/{model/meeting_response.rb → ews/types/deleted_event.rb} +6 -6
- data/lib/ews/types/distribution_list.rb +7 -0
- data/lib/ews/types/event.rb +62 -0
- data/lib/ews/types/file_attachment.rb +65 -0
- data/lib/ews/types/folder.rb +60 -0
- data/lib/{model/distribution_list.rb → ews/types/free_busy_changed_event.rb} +6 -6
- data/lib/ews/types/generic_folder.rb +352 -0
- data/lib/ews/types/item.rb +381 -0
- data/lib/ews/types/item_attachment.rb +46 -0
- data/lib/{model → ews/types}/item_field_uri_map.rb +2 -2
- data/lib/ews/types/mailbox_user.rb +156 -0
- data/lib/ews/types/meeting_cancellation.rb +7 -0
- data/lib/ews/types/meeting_message.rb +7 -0
- data/lib/ews/types/meeting_request.rb +7 -0
- data/lib/ews/types/meeting_response.rb +7 -0
- data/lib/ews/types/message.rb +7 -0
- data/lib/ews/types/modified_event.rb +48 -0
- data/lib/{model/item_attachment.rb → ews/types/moved_event.rb} +33 -15
- data/lib/ews/types/new_mail_event.rb +24 -0
- data/lib/ews/types/out_of_office.rb +147 -0
- data/lib/ews/types/search_folder.rb +8 -0
- data/lib/ews/types/status_event.rb +39 -0
- data/lib/ews/types/task.rb +7 -0
- data/lib/ews/types/tasks_folder.rb +8 -0
- data/lib/viewpoint.rb +82 -106
- metadata +99 -67
- data/README +0 -114
- data/lib/exceptions/exceptions.rb +0 -46
- data/lib/model/calendar_folder.rb +0 -67
- data/lib/model/calendar_item.rb +0 -267
- data/lib/model/contact.rb +0 -238
- data/lib/model/contacts_folder.rb +0 -46
- data/lib/model/event.rb +0 -116
- data/lib/model/file_attachment.rb +0 -53
- data/lib/model/folder.rb +0 -47
- data/lib/model/generic_folder.rb +0 -471
- data/lib/model/item.rb +0 -313
- data/lib/model/mailbox_user.rb +0 -146
- data/lib/model/meeting_request.rb +0 -39
- data/lib/model/message.rb +0 -142
- data/lib/model/model.rb +0 -269
- data/lib/model/search_folder.rb +0 -48
- data/lib/model/task.rb +0 -121
- data/lib/model/tasks_folder.rb +0 -44
- data/lib/soap/handsoap/builders/ews_build_helpers.rb +0 -383
- data/lib/soap/handsoap/builders/ews_builder.rb +0 -146
- data/lib/soap/handsoap/ews_service.rb +0 -813
- data/lib/soap/handsoap/parser.rb +0 -104
- data/lib/soap/handsoap/parsers/ews_parser.rb +0 -246
- data/lib/soap/soap_provider.rb +0 -64
data/lib/model/calendar_item.rb
DELETED
|
@@ -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
|
data/lib/model/contact.rb
DELETED
|
@@ -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
|