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.
- checksums.yaml +7 -0
- data/README.md +203 -0
- data/lib/ews/calendar_accessors.rb +34 -0
- data/lib/ews/connection.rb +140 -0
- data/lib/ews/connection_helper.rb +35 -0
- data/lib/ews/convert_accessors.rb +56 -0
- data/lib/{exceptions/exceptions.rb → ews/errors.rb} +29 -19
- data/lib/ews/ews_client.rb +105 -0
- data/lib/ews/exceptions/exceptions.rb +61 -0
- data/lib/ews/folder_accessors.rb +264 -0
- data/lib/ews/impersonation.rb +30 -0
- data/lib/ews/item_accessors.rb +242 -0
- data/lib/ews/mailbox_accessors.rb +92 -0
- data/lib/ews/meeting_accessors.rb +39 -0
- data/lib/ews/message_accessors.rb +93 -0
- data/lib/ews/push_subscription_accessors.rb +33 -0
- data/lib/ews/room_accessors.rb +48 -0
- data/lib/ews/roomlist_accessors.rb +47 -0
- data/lib/ews/soap.rb +64 -0
- data/lib/ews/soap/builders/ews_builder.rb +1384 -0
- data/lib/ews/soap/ews_response.rb +84 -0
- data/lib/ews/soap/ews_soap_availability_response.rb +58 -0
- data/lib/ews/soap/ews_soap_free_busy_response.rb +119 -0
- data/lib/ews/soap/ews_soap_response.rb +103 -0
- data/lib/ews/soap/ews_soap_room_response.rb +53 -0
- data/lib/ews/soap/ews_soap_roomlist_response.rb +54 -0
- data/lib/ews/soap/exchange_availability.rb +61 -0
- data/lib/ews/soap/exchange_data_services.rb +780 -0
- data/lib/ews/soap/exchange_notification.rb +146 -0
- data/lib/ews/soap/exchange_synchronization.rb +93 -0
- data/lib/ews/soap/exchange_time_zones.rb +56 -0
- data/lib/ews/soap/exchange_user_configuration.rb +33 -0
- data/lib/ews/soap/exchange_web_service.rb +264 -0
- data/lib/{model/item_attachment.rb → ews/soap/parsers/ews_parser.rb} +24 -14
- data/lib/ews/soap/parsers/ews_sax_document.rb +70 -0
- data/lib/ews/soap/response_message.rb +80 -0
- data/lib/ews/soap/responses/create_attachment_response_message.rb +47 -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 +59 -0
- data/lib/{model/attachment.rb → ews/soap/responses/subscribe_response_message.rb} +17 -13
- data/lib/{model/attendee.rb → ews/soap/responses/sync_folder_hierarchy_response_message.rb} +14 -15
- data/lib/ews/soap/responses/sync_folder_items_response_message.rb +36 -0
- data/lib/ews/templates/calendar_item.rb +79 -0
- data/lib/ews/templates/forward_item.rb +24 -0
- data/lib/ews/templates/message.rb +85 -0
- data/lib/ews/templates/reply_to_item.rb +25 -0
- data/lib/ews/templates/task.rb +74 -0
- data/lib/ews/types.rb +194 -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 +50 -0
- data/lib/ews/types/calendar_item.rb +130 -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/ews/types/deleted_event.rb +24 -0
- data/lib/ews/types/distribution_list.rb +7 -0
- data/lib/ews/types/event.rb +62 -0
- data/lib/ews/types/export_items_response_message.rb +52 -0
- data/lib/ews/types/file_attachment.rb +65 -0
- data/lib/ews/types/folder.rb +60 -0
- data/lib/ews/types/free_busy_changed_event.rb +24 -0
- data/lib/ews/types/generic_folder.rb +418 -0
- data/lib/ews/types/item.rb +447 -0
- data/lib/ews/types/item_attachment.rb +84 -0
- data/lib/{model → ews/types}/item_field_uri_map.rb +2 -18
- 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/{extensions/string.rb → ews/types/moved_event.rb} +31 -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/post_item.rb +7 -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 +41 -0
- data/lib/ews/types/tasks_folder.rb +27 -0
- data/lib/viewpoint.rb +85 -108
- data/lib/{model/distribution_list.rb → viewpoint/logging.rb} +6 -3
- data/lib/{model/meeting_response.rb → viewpoint/logging/config.rb} +3 -3
- data/lib/viewpoint/string_utils.rb +76 -0
- metadata +156 -123
- data/README +0 -114
- 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 -461
- data/lib/model/item.rb +0 -312
- 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 -790
- data/lib/soap/handsoap/parser.rb +0 -104
- data/lib/soap/handsoap/parsers/ews_parser.rb +0 -245
- data/lib/soap/soap_provider.rb +0 -64
data/README
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
--------------------------------------------------------------------------
|
|
2
|
-
Viewpoint for Exchange Web Services
|
|
3
|
-
http://github.com/zenchild/Viewpoint/wiki
|
|
4
|
-
--------------------------------------------------------------------------
|
|
5
|
-
This program attempts to create a client access library for Exchange Web
|
|
6
|
-
Services (EWS) in Ruby.
|
|
7
|
-
|
|
8
|
-
!!!CAUTION!!! This is currently BETA code and has changed dramatically from
|
|
9
|
-
the original version of Viewpoint which was based on Soap4r. This version
|
|
10
|
-
has essentially been gutted and written on top of Handsoap. Development
|
|
11
|
-
has been much more flexible, but the interface to Viewpoint has changed
|
|
12
|
-
quite a bit. I have tried to write good code comments and I will keep
|
|
13
|
-
enhancing this. I will also try and post examples on my blog as I write
|
|
14
|
-
them or they are asked for.
|
|
15
|
-
|
|
16
|
-
BLOG: http://distributed-frostbite.blogspot.com/
|
|
17
|
-
Add me in LinkedIn: http://www.linkedin.com/in/danwanek
|
|
18
|
-
Find me on irc.freenode.net in #ruby-lang (zenChild)
|
|
19
|
-
|
|
20
|
-
--------------------------------------------------------------------------
|
|
21
|
-
MAJOR CHANGES TO THE FIRST VERSION:
|
|
22
|
-
|
|
23
|
-
New SOAP backend
|
|
24
|
-
Viewpoint now uses Handsoap as its back-end instead of soap4r. While
|
|
25
|
-
soap4r does some very nice things for you automatically, it ends up
|
|
26
|
-
making your code base fairly large and it complicates any customizations
|
|
27
|
-
that you might want to make. One example is adding custom headers. Soap4r
|
|
28
|
-
required you to create a subclass to use as a sort of hook. I can do the
|
|
29
|
-
same thing in Handsoap with a one-liner in the services #on_create_document
|
|
30
|
-
method.
|
|
31
|
-
|
|
32
|
-
Models are completely rewritten
|
|
33
|
-
The models are completely new and not backward compatible with the old
|
|
34
|
-
version of Viewpoint. Some of the methods still exist, but don't count
|
|
35
|
-
on them. I've tried to make this version much more extensible than the
|
|
36
|
-
last.
|
|
37
|
-
|
|
38
|
-
Delegate access is supported
|
|
39
|
-
One thing that was often asked for, but missing from the previous version
|
|
40
|
-
was delegate access to mailboxes and calendars. This is now supported via
|
|
41
|
-
the 'act_as' parameter to the GenericFolder::get_folder method. For example:
|
|
42
|
-
ofolder = Folder.get_folder(:inbox,'otheruser@test.com')
|
|
43
|
-
If your user has delegate access to the Inbox for otheruser@test.com this
|
|
44
|
-
operation will retrieve their inbox and allow you to manipulate it as you
|
|
45
|
-
would with your own Inbox.
|
|
46
|
-
|
|
47
|
-
There is also some support for manipulation of delegate access itself via
|
|
48
|
-
the methods MailboxUser#add_delegate!, MailboxUser#update_delegate!, and
|
|
49
|
-
MailboxUser#get_delegate_info.
|
|
50
|
-
|
|
51
|
-
Misc other changes
|
|
52
|
-
Since it's a complete rewrite there are tons of other changes that you'll
|
|
53
|
-
notice. I've tried to keep the code comments coming so stay tuned to the
|
|
54
|
-
API docs for library information. I'll also be posting more examples to
|
|
55
|
-
my blog.
|
|
56
|
-
|
|
57
|
-
--------------------------------------------------------------------------
|
|
58
|
-
TO USE:
|
|
59
|
-
require 'rubygems'
|
|
60
|
-
require 'viewpoint'
|
|
61
|
-
# See REQUIRED GEMS below
|
|
62
|
-
|
|
63
|
-
REQUIRED GEMS:
|
|
64
|
-
|
|
65
|
-
# Handsoap (Thanks jrun for pointing me this way!)
|
|
66
|
-
gem install -r handsoap
|
|
67
|
-
# Nokogiri XML Parser
|
|
68
|
-
gem install -r nokogiri
|
|
69
|
-
# HttpClient
|
|
70
|
-
gem install -r httpclient
|
|
71
|
-
# NTLM Library
|
|
72
|
-
gem install -r rubyntlm
|
|
73
|
-
|
|
74
|
-
# iCalendar (still forthcoming in this release)
|
|
75
|
-
gem install -r icalendar
|
|
76
|
-
|
|
77
|
-
--------------------------------------------------------------------------
|
|
78
|
-
DESIGN GOALS/GUIDELINES:
|
|
79
|
-
|
|
80
|
-
1. The SOAP back-end should not know about the Model.
|
|
81
|
-
I went around and around on this one for awhile. There are some
|
|
82
|
-
simplicity advantages to creating Model objects within the SOAP
|
|
83
|
-
responses, but I ultimately decided against it so that one could use
|
|
84
|
-
the SOAP back-end without the Model. Essentially the SOAP classes
|
|
85
|
-
pass back a Hash that the Model uses to create its own objects.
|
|
86
|
-
|
|
87
|
-
2. The use of Hashes is not a crime.
|
|
88
|
-
While some people decidedly do not like Hashes and believe complex
|
|
89
|
-
hashing should be in the form of objects, there are some instances
|
|
90
|
-
where hashing is just plain simpler and flexible. To that end, I use
|
|
91
|
-
hashes pretty extensively in Viewpoint, both for objects being passed
|
|
92
|
-
to the SOAP back-end and returned from it.
|
|
93
|
-
|
|
94
|
-
3. Follow EWS naming conventions where it makes sense.
|
|
95
|
-
I try and follow the naming conventions of the Exchange Web Service
|
|
96
|
-
operations as much as it makes sense. There are some things howerver
|
|
97
|
-
where they do not and I have deviated somewhat. For example,
|
|
98
|
-
an instance method named delete_folder doesn't make much sense, but
|
|
99
|
-
an instance method named delete! is pretty clear what it deletes.
|
|
100
|
-
--------------------------------------------------------------------------
|
|
101
|
-
!!!SHOUTS OUT!!!
|
|
102
|
-
--------------------------------------------------------------------------
|
|
103
|
-
* Thanks to Harold Lee (https://github.com/haroldl) for working on the
|
|
104
|
-
get_user_availability code.
|
|
105
|
-
--------------------------------------------------------------------------
|
|
106
|
-
DISCLAIMER: If you see something that could be done better or would like
|
|
107
|
-
to help out in the development of this code please feel free to clone the
|
|
108
|
-
'git' repository and send me patches:
|
|
109
|
-
git clone git://github.com/zenchild/Viewpoint.git
|
|
110
|
-
or add an issue on GitHub:
|
|
111
|
-
http://github.com/zenchild/Viewpoint/issues
|
|
112
|
-
|
|
113
|
-
Cheers!
|
|
114
|
-
--------------------------------------------------------------------------
|
|
@@ -1,67 +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 CalendarFolder < GenericFolder
|
|
22
|
-
|
|
23
|
-
# Find folders of type Task
|
|
24
|
-
# @see GenericFolder.find_folders
|
|
25
|
-
# @param [String,Symbol] root An folder id, either a DistinguishedFolderId (must me a Symbol)
|
|
26
|
-
# or a FolderId (String)
|
|
27
|
-
# @param [String] traversal Shallow/Deep/SoftDeleted
|
|
28
|
-
# @param [String] shape the shape to return IdOnly/Default/AllProperties
|
|
29
|
-
# @param [optional, String] folder_type an optional folder type to limit the search to like 'IPF.Task'
|
|
30
|
-
# @return [Array] Returns an Array of Folder or subclasses of Folder
|
|
31
|
-
def self.find_folders(root = :msgfolderroot, traversal = 'Deep', shape = 'Default', folder_type = 'IPF.Appointment')
|
|
32
|
-
super(root, traversal, shape, folder_type)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
# initialize with an item of CalendarFolderType
|
|
37
|
-
def initialize(folder)
|
|
38
|
-
super(folder)
|
|
39
|
-
|
|
40
|
-
# @todo Handle:
|
|
41
|
-
# <SharingEffectiveRights/>
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
# Fetch only items from today (since midnight)
|
|
45
|
-
def todays_items(opts = {})
|
|
46
|
-
#This is a bit convoluted for pre-1.9.x ruby versions that don't support to_datetime
|
|
47
|
-
items_between(DateTime.parse(Date.today.to_s), DateTime.parse((Date.today + 1).to_s), opts)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
# Fetch items since a give DateTime
|
|
51
|
-
# @param [DateTime] start_date_time the time to fetch Items since.
|
|
52
|
-
def items_since(start_date_time, opts = {})
|
|
53
|
-
items_between(start_date_time, DateTime.now, opts)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
# Find Calendar Items between two dates
|
|
57
|
-
# @param [DateTime] start_date the date to start the search from
|
|
58
|
-
# @param [DateTime] end_date the date to end the search at
|
|
59
|
-
# @param [Hash] opts misc opts like restrictions, etc
|
|
60
|
-
def items_between(start_date, end_date, opts = {})
|
|
61
|
-
opts[:calendar_view] = {:max_entries_returned => 256, :start_date => start_date, :end_date => end_date}
|
|
62
|
-
find_items(opts)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
end # CalendarFolder
|
|
66
|
-
end # EWS
|
|
67
|
-
end # Viewpoint
|
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
|