viewpoint 0.1.26 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +203 -0
  3. data/lib/ews/calendar_accessors.rb +34 -0
  4. data/lib/ews/connection.rb +140 -0
  5. data/lib/ews/connection_helper.rb +35 -0
  6. data/lib/ews/convert_accessors.rb +56 -0
  7. data/lib/{exceptions/exceptions.rb → ews/errors.rb} +29 -19
  8. data/lib/ews/ews_client.rb +105 -0
  9. data/lib/ews/exceptions/exceptions.rb +61 -0
  10. data/lib/ews/folder_accessors.rb +264 -0
  11. data/lib/ews/impersonation.rb +30 -0
  12. data/lib/ews/item_accessors.rb +242 -0
  13. data/lib/ews/mailbox_accessors.rb +92 -0
  14. data/lib/ews/meeting_accessors.rb +39 -0
  15. data/lib/ews/message_accessors.rb +93 -0
  16. data/lib/ews/push_subscription_accessors.rb +33 -0
  17. data/lib/ews/room_accessors.rb +48 -0
  18. data/lib/ews/roomlist_accessors.rb +47 -0
  19. data/lib/ews/soap.rb +64 -0
  20. data/lib/ews/soap/builders/ews_builder.rb +1384 -0
  21. data/lib/ews/soap/ews_response.rb +84 -0
  22. data/lib/ews/soap/ews_soap_availability_response.rb +58 -0
  23. data/lib/ews/soap/ews_soap_free_busy_response.rb +119 -0
  24. data/lib/ews/soap/ews_soap_response.rb +103 -0
  25. data/lib/ews/soap/ews_soap_room_response.rb +53 -0
  26. data/lib/ews/soap/ews_soap_roomlist_response.rb +54 -0
  27. data/lib/ews/soap/exchange_availability.rb +61 -0
  28. data/lib/ews/soap/exchange_data_services.rb +780 -0
  29. data/lib/ews/soap/exchange_notification.rb +146 -0
  30. data/lib/ews/soap/exchange_synchronization.rb +93 -0
  31. data/lib/ews/soap/exchange_time_zones.rb +56 -0
  32. data/lib/ews/soap/exchange_user_configuration.rb +33 -0
  33. data/lib/ews/soap/exchange_web_service.rb +264 -0
  34. data/lib/{model/item_attachment.rb → ews/soap/parsers/ews_parser.rb} +24 -14
  35. data/lib/ews/soap/parsers/ews_sax_document.rb +70 -0
  36. data/lib/ews/soap/response_message.rb +80 -0
  37. data/lib/ews/soap/responses/create_attachment_response_message.rb +47 -0
  38. data/lib/{model/meeting_message.rb → ews/soap/responses/create_item_response_message.rb} +7 -10
  39. data/lib/ews/soap/responses/find_item_response_message.rb +80 -0
  40. data/lib/ews/soap/responses/get_events_response_message.rb +53 -0
  41. data/lib/ews/soap/responses/send_notification_response_message.rb +59 -0
  42. data/lib/{model/attachment.rb → ews/soap/responses/subscribe_response_message.rb} +17 -13
  43. data/lib/{model/attendee.rb → ews/soap/responses/sync_folder_hierarchy_response_message.rb} +14 -15
  44. data/lib/ews/soap/responses/sync_folder_items_response_message.rb +36 -0
  45. data/lib/ews/templates/calendar_item.rb +79 -0
  46. data/lib/ews/templates/forward_item.rb +24 -0
  47. data/lib/ews/templates/message.rb +85 -0
  48. data/lib/ews/templates/reply_to_item.rb +25 -0
  49. data/lib/ews/templates/task.rb +74 -0
  50. data/lib/ews/types.rb +194 -0
  51. data/lib/ews/types/attachment.rb +77 -0
  52. data/lib/{model/meeting_cancellation.rb → ews/types/attendee.rb} +9 -8
  53. data/lib/ews/types/calendar_folder.rb +50 -0
  54. data/lib/ews/types/calendar_item.rb +130 -0
  55. data/lib/ews/types/contact.rb +7 -0
  56. data/lib/ews/types/contacts_folder.rb +8 -0
  57. data/lib/ews/types/copied_event.rb +51 -0
  58. data/lib/{soap/handsoap/builder.rb → ews/types/created_event.rb} +5 -2
  59. data/lib/ews/types/deleted_event.rb +24 -0
  60. data/lib/ews/types/distribution_list.rb +7 -0
  61. data/lib/ews/types/event.rb +62 -0
  62. data/lib/ews/types/export_items_response_message.rb +52 -0
  63. data/lib/ews/types/file_attachment.rb +65 -0
  64. data/lib/ews/types/folder.rb +60 -0
  65. data/lib/ews/types/free_busy_changed_event.rb +24 -0
  66. data/lib/ews/types/generic_folder.rb +418 -0
  67. data/lib/ews/types/item.rb +447 -0
  68. data/lib/ews/types/item_attachment.rb +84 -0
  69. data/lib/{model → ews/types}/item_field_uri_map.rb +2 -18
  70. data/lib/ews/types/mailbox_user.rb +156 -0
  71. data/lib/ews/types/meeting_cancellation.rb +7 -0
  72. data/lib/ews/types/meeting_message.rb +7 -0
  73. data/lib/ews/types/meeting_request.rb +7 -0
  74. data/lib/ews/types/meeting_response.rb +7 -0
  75. data/lib/ews/types/message.rb +7 -0
  76. data/lib/ews/types/modified_event.rb +48 -0
  77. data/lib/{extensions/string.rb → ews/types/moved_event.rb} +31 -15
  78. data/lib/ews/types/new_mail_event.rb +24 -0
  79. data/lib/ews/types/out_of_office.rb +147 -0
  80. data/lib/ews/types/post_item.rb +7 -0
  81. data/lib/ews/types/search_folder.rb +8 -0
  82. data/lib/ews/types/status_event.rb +39 -0
  83. data/lib/ews/types/task.rb +41 -0
  84. data/lib/ews/types/tasks_folder.rb +27 -0
  85. data/lib/viewpoint.rb +85 -108
  86. data/lib/{model/distribution_list.rb → viewpoint/logging.rb} +6 -3
  87. data/lib/{model/meeting_response.rb → viewpoint/logging/config.rb} +3 -3
  88. data/lib/viewpoint/string_utils.rb +76 -0
  89. metadata +156 -123
  90. data/README +0 -114
  91. data/lib/model/calendar_folder.rb +0 -67
  92. data/lib/model/calendar_item.rb +0 -267
  93. data/lib/model/contact.rb +0 -238
  94. data/lib/model/contacts_folder.rb +0 -46
  95. data/lib/model/event.rb +0 -116
  96. data/lib/model/file_attachment.rb +0 -53
  97. data/lib/model/folder.rb +0 -47
  98. data/lib/model/generic_folder.rb +0 -461
  99. data/lib/model/item.rb +0 -312
  100. data/lib/model/mailbox_user.rb +0 -146
  101. data/lib/model/meeting_request.rb +0 -39
  102. data/lib/model/message.rb +0 -142
  103. data/lib/model/model.rb +0 -269
  104. data/lib/model/search_folder.rb +0 -48
  105. data/lib/model/task.rb +0 -121
  106. data/lib/model/tasks_folder.rb +0 -44
  107. data/lib/soap/handsoap/builders/ews_build_helpers.rb +0 -383
  108. data/lib/soap/handsoap/builders/ews_builder.rb +0 -146
  109. data/lib/soap/handsoap/ews_service.rb +0 -790
  110. data/lib/soap/handsoap/parser.rb +0 -104
  111. data/lib/soap/handsoap/parsers/ews_parser.rb +0 -245
  112. data/lib/soap/soap_provider.rb +0 -64
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
@@ -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