viewpoint 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +24 -22
- data/lib/ews/connection.rb +15 -1
- data/lib/ews/ews_client.rb +13 -9
- data/lib/ews/meeting_accessors.rb +39 -0
- data/lib/ews/soap/builders/ews_builder.rb +97 -2
- data/lib/ews/soap/exchange_time_zones.rb +1 -1
- data/lib/ews/soap/parsers/ews_parser.rb +1 -1
- data/lib/ews/templates/calendar_item.rb +3 -2
- data/lib/ews/templates/message.rb +3 -0
- data/lib/ews/types/calendar_folder.rb +2 -2
- data/lib/ews/types/calendar_item.rb +1 -0
- data/lib/ews/types/generic_folder.rb +0 -2
- data/lib/ews/types/item.rb +10 -4
- data/lib/ews/types/item_field_uri_map.rb +0 -16
- data/lib/ews/types/post_item.rb +7 -0
- data/lib/ews/types/task.rb +12 -8
- data/lib/viewpoint.rb +1 -0
- metadata +17 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c7f0f3182b5374e87a352b910d8a4437adeeb7e
|
4
|
+
data.tar.gz: 4f5418c72292865e2e041f8fdf2db2c3a975774d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e8650776addf7c9b89a3351150106596252bffa3363e6c625cb14143da2c0f4d818cc7db12fe0c4ce4f970fab70d3a0f25fc7014f099032daa53f2e0fb435d9e
|
7
|
+
data.tar.gz: bd58e56479fd14c718d02392444a018128efe60e147d97bc4e8ad7203db3d91a4ef87090667e55bcf8050dda5a5ea87fa37d2bed00e92f8337577e31131c9f31
|
data/README.md
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
# Viewpoint for Exchange Web Services
|
2
|
+
[![Build Status](https://img.shields.io/travis/WinRb/Viewpoint.svg?branch=master)](https://travis-ci.org/WinRb/Viewpoint)
|
3
|
+
[![Gem Version](https://img.shields.io/gem/v/viewpoint.svg)](https://rubygems.org/gems/viewpoint)
|
4
|
+
[![License](https://img.shields.io/github/license/WinRb/Viewpoint.svg)](https://github.com/WinRb/Viewpoint/blob/master/LICENSE)
|
5
|
+
[![Wiki](https://img.shields.io/badge/docs-wiki-lightgrey.svg)](http://github.com/WinRb/Viewpoint/wiki)
|
6
|
+
[![Documentation](https://img.shields.io/badge/docs-rdoc-lightgrey.svg)](http://www.rubydoc.info/github/WinRb/Viewpoint/frames)
|
5
7
|
|
6
8
|
Viewpoint for EWS provides a thin Ruby layer on top of Microsoft Exchange
|
7
9
|
Web Services(EWS). It also includes a bunch of model classes that add an
|
@@ -33,22 +35,22 @@ out of the picture this is no longer required. Go crazy ;)
|
|
33
35
|
## Enhanced in 1.0
|
34
36
|
|
35
37
|
* *Delegate access is supported*
|
36
|
-
One thing that was often asked for, but missing from the previous version was delegate access to mailboxes and calendars. This is now supported via the
|
38
|
+
One thing that was often asked for, but missing from the previous version was delegate access to mailboxes and calendars. This is now supported via the `act_as` parameter to the `GenericFolder::get_folder` method.
|
37
39
|
|
38
|
-
|
39
|
-
```
|
40
|
+
> Inbox example:
|
41
|
+
```inbox = Folder.get_folder(:inbox, opts = {act_as: "user@host.com"})```
|
40
42
|
|
41
|
-
|
43
|
+
> If your user has delegate access to the Inbox for user@host.com this operation will retrieve their inbox and allow you to manipulate it as you would with your own Inbox.
|
42
44
|
|
43
|
-
|
44
|
-
```
|
45
|
+
> Calendar example:
|
46
|
+
```calendar = cli.get_folder(:calendar, opts = {act_as: "user@host.com"})```
|
45
47
|
|
46
|
-
|
48
|
+
> If your user has delegate access to the Calendar for user@host.com this operation will retrieve their calendar and allow you to manipulate it as you would with your own Calendar, depending on the permissions the other user has granted you.
|
47
49
|
|
48
50
|
|
49
51
|
* There is also some support for manipulation of delegate access itself via
|
50
|
-
the methods MailboxUser#add_delegate
|
51
|
-
MailboxUser#get_delegate_info
|
52
|
+
the methods `MailboxUser#add_delegate!`, `MailboxUser#update_delegate!`, and
|
53
|
+
`MailboxUser#get_delegate_info`.
|
52
54
|
|
53
55
|
|
54
56
|
# Using Viewpoint
|
@@ -75,11 +77,11 @@ There are also various options you can pass to EWSClient.
|
|
75
77
|
|
76
78
|
If you are testing in an environment using a self-signed certificate you can pass a connection parameter to ignore SSL verification by passing `http_opts: {ssl_verify_mode: 0}`.
|
77
79
|
|
78
|
-
If you want to target a specific version of Exchange you can pass `server_version: SOAP::ExchangeWebService::VERSION_2010_SP1`. You really shouldn't have to use this unless you know why.
|
80
|
+
If you want to target a specific version of Exchange you can pass `server_version: SOAP::ExchangeWebService::VERSION_2010_SP1`. You really shouldn't have to use this unless you know why. If you are interacting with servers which you do not know the version(s) of, an incorrect version may manifest as a `SoapResponseError` or a HTTP 400 `ResponseError`. Note that different versions are particular; for example, `VERSION_2007` may not work against a `VERSION_2007_SP1` system.
|
79
81
|
|
80
82
|
## Accessors
|
81
83
|
|
82
|
-
There are some basic accessors available on the Viewpoint::EWSClient instance. In prior versions these were typically class methods off of the models themselves (ex: Folder.get_folder(id)). Now all accessors are available through EWSClient
|
84
|
+
There are some basic accessors available on the `Viewpoint::EWSClient` instance. In prior versions these were typically class methods off of the models themselves (ex: `Folder.get_folder(id)`). Now all accessors are available through `EWSClient`.
|
83
85
|
|
84
86
|
### Folder Accessors
|
85
87
|
|
@@ -164,8 +166,9 @@ busy_times.each { | event |
|
|
164
166
|
user_free_busy.working_hours
|
165
167
|
```
|
166
168
|
|
167
|
-
|
168
169
|
### Mailbox Accessors
|
170
|
+
- No examples yet
|
171
|
+
|
169
172
|
### Message Accessors
|
170
173
|
```ruby
|
171
174
|
cli.send_message subject: "Test", body: "Test", to_recipients: ['test@example.com']
|
@@ -184,18 +187,17 @@ end
|
|
184
187
|
## Thanks go out to...
|
185
188
|
|
186
189
|
* Handl.it for sponsoring a good portion of the development effort.
|
187
|
-
|
188
|
-
* The National Association of REALTORS
|
190
|
+
* https://www.handle.com/
|
191
|
+
* The National Association of REALTORS® for providing a testing account
|
189
192
|
and much appreciated input and support.
|
190
193
|
* The Holmes Group Limited for providing Exchange 2013 test accounts.
|
191
194
|
|
192
|
-
|
193
|
-
|
195
|
+
## DISCLAIMER:
|
196
|
+
If you see something that could be done better or would like
|
194
197
|
to help out in the development of this code please feel free to clone the
|
195
198
|
'git' repository and send me patches:
|
196
|
-
git clone git://github.com/zenchild/Viewpoint.git
|
199
|
+
`git clone git://github.com/zenchild/Viewpoint.git`
|
197
200
|
or add an issue on GitHub:
|
198
201
|
http://github.com/zenchild/Viewpoint/issues
|
199
202
|
|
200
203
|
Cheers!
|
201
|
-
---
|
data/lib/ews/connection.rb
CHANGED
@@ -26,19 +26,33 @@ class Viewpoint::EWS::Connection
|
|
26
26
|
# @example https://<site>/ews/Exchange.asmx
|
27
27
|
# @param [Hash] opts Misc config options (mostly for developement)
|
28
28
|
# @option opts [Fixnum] :ssl_verify_mode
|
29
|
+
# @option opts [Fixnum] :receive_timeout override the default receive timeout
|
30
|
+
# seconds
|
31
|
+
# @option opts [Fixnum] :connect_timeout override the default connect timeout
|
32
|
+
# seconds
|
29
33
|
# @option opts [Array] :trust_ca an array of hashed dir paths or a file
|
34
|
+
# @option opts [String] :user_agent the http user agent to use in all requests
|
30
35
|
def initialize(endpoint, opts = {})
|
31
36
|
@log = Logging.logger[self.class.name.to_s.to_sym]
|
32
|
-
|
37
|
+
if opts[:user_agent]
|
38
|
+
@httpcli = HTTPClient.new(agent_name: opts[:user_agent])
|
39
|
+
else
|
40
|
+
@httpcli = HTTPClient.new
|
41
|
+
end
|
42
|
+
|
33
43
|
if opts[:trust_ca]
|
34
44
|
@httpcli.ssl_config.clear_cert_store
|
35
45
|
opts[:trust_ca].each do |ca|
|
36
46
|
@httpcli.ssl_config.add_trust_ca ca
|
37
47
|
end
|
38
48
|
end
|
49
|
+
|
39
50
|
@httpcli.ssl_config.verify_mode = opts[:ssl_verify_mode] if opts[:ssl_verify_mode]
|
51
|
+
@httpcli.ssl_config.ssl_version = opts[:ssl_version] if opts[:ssl_version]
|
40
52
|
# Up the keep-alive so we don't have to do the NTLM dance as often.
|
41
53
|
@httpcli.keep_alive_timeout = 60
|
54
|
+
@httpcli.receive_timeout = opts[:receive_timeout] if opts[:receive_timeout]
|
55
|
+
@httpcli.connect_timeout = opts[:connect_timeout] if opts[:connect_timeout]
|
42
56
|
@endpoint = endpoint
|
43
57
|
end
|
44
58
|
|
data/lib/ews/ews_client.rb
CHANGED
@@ -7,6 +7,7 @@ require 'ews/calendar_accessors'
|
|
7
7
|
require 'ews/room_accessors'
|
8
8
|
require 'ews/roomlist_accessors'
|
9
9
|
require 'ews/convert_accessors'
|
10
|
+
require 'ews/meeting_accessors'
|
10
11
|
|
11
12
|
# This class is the glue between the Models and the Web Service.
|
12
13
|
class Viewpoint::EWSClient
|
@@ -20,10 +21,11 @@ class Viewpoint::EWSClient
|
|
20
21
|
include Viewpoint::EWS::RoomAccessors
|
21
22
|
include Viewpoint::EWS::RoomlistAccessors
|
22
23
|
include Viewpoint::EWS::ConvertAccessors
|
24
|
+
include Viewpoint::EWS::MeetingAccessors
|
23
25
|
include Viewpoint::StringUtils
|
24
26
|
|
25
27
|
# The instance of Viewpoint::EWS::SOAP::ExchangeWebService
|
26
|
-
attr_reader :ews
|
28
|
+
attr_reader :ews, :endpoint, :username
|
27
29
|
|
28
30
|
# Initialize the EWSClient instance.
|
29
31
|
# @param [String] endpoint The EWS endpoint we will be connecting to
|
@@ -37,13 +39,15 @@ class Viewpoint::EWSClient
|
|
37
39
|
# Viewpoint::EWS::SOAP::ExchangeWebService.
|
38
40
|
# @option opts [Object] :http_class specify an alternate HTTP connection class.
|
39
41
|
# @option opts [Hash] :http_opts options to pass to the connection
|
40
|
-
def initialize(endpoint,
|
42
|
+
def initialize(endpoint, username, password, opts = {})
|
41
43
|
# dup all. @see ticket https://github.com/zenchild/Viewpoint/issues/68
|
42
|
-
endpoint
|
43
|
-
|
44
|
+
@endpoint = endpoint.dup
|
45
|
+
@username = username.dup
|
46
|
+
password = password.dup
|
47
|
+
opts = opts.dup
|
44
48
|
http_klass = opts[:http_class] || Viewpoint::EWS::Connection
|
45
49
|
con = http_klass.new(endpoint, opts[:http_opts] || {})
|
46
|
-
con.set_auth
|
50
|
+
con.set_auth @username, password
|
47
51
|
@ews = SOAP::ExchangeWebService.new(con, opts)
|
48
52
|
end
|
49
53
|
|
@@ -53,11 +57,11 @@ class Viewpoint::EWSClient
|
|
53
57
|
# default is to raise a EwsMinimalObjectError.
|
54
58
|
def set_auto_deepen(deepen, behavior = :raise)
|
55
59
|
if deepen
|
56
|
-
|
60
|
+
ews.auto_deepen = true
|
57
61
|
else
|
58
62
|
behavior = [:raise, :nil].include?(behavior) ? behavior : :raise
|
59
|
-
|
60
|
-
|
63
|
+
ews.no_auto_deepen_behavior = behavior
|
64
|
+
ews.auto_deepen = false
|
61
65
|
end
|
62
66
|
end
|
63
67
|
|
@@ -69,7 +73,7 @@ class Viewpoint::EWSClient
|
|
69
73
|
# @param id [String] Identifier of a Microsoft well known time zone (e.g: 'UTC', 'W. Europe Standard Time')
|
70
74
|
# @note A list of time zones known by the server can be requested via {EWS::SOAP::ExchangeTimeZones#get_time_zones}
|
71
75
|
def set_time_zone(microsoft_time_zone_id)
|
72
|
-
|
76
|
+
ews.set_time_zone_context microsoft_time_zone_id
|
73
77
|
end
|
74
78
|
|
75
79
|
private
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Viewpoint::EWS::MeetingAccessors
|
2
|
+
include Viewpoint::EWS
|
3
|
+
|
4
|
+
def accept_meeting(opts)
|
5
|
+
ews.create_item({
|
6
|
+
message_disposition: 'SendOnly',
|
7
|
+
items: [ { accept_item: opts_to_item(opts) } ]
|
8
|
+
})
|
9
|
+
end
|
10
|
+
|
11
|
+
def decline_meeting(opts)
|
12
|
+
ews.create_item({
|
13
|
+
message_disposition: 'SendOnly',
|
14
|
+
items: [ { decline_item: opts_to_item(opts) } ]
|
15
|
+
})
|
16
|
+
end
|
17
|
+
|
18
|
+
def tentatively_accept_meeting(opts)
|
19
|
+
ews.create_item({
|
20
|
+
message_disposition: 'SendOnly',
|
21
|
+
items: [ { tentatively_accept_item: opts_to_item(opts) } ]
|
22
|
+
})
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def opts_to_item(opts)
|
28
|
+
hash = {
|
29
|
+
id: opts[:id],
|
30
|
+
change_key: opts[:change_key],
|
31
|
+
sensitivity: opts[:sensitivity]
|
32
|
+
}
|
33
|
+
|
34
|
+
hash[:text] = opts[:text] if opts[:text]
|
35
|
+
hash[:body_type] = (opts[:body_type] || 'Text') if opts[:text]
|
36
|
+
|
37
|
+
hash
|
38
|
+
end
|
39
|
+
end
|
@@ -822,6 +822,10 @@ module Viewpoint::EWS::SOAP
|
|
822
822
|
}
|
823
823
|
end
|
824
824
|
|
825
|
+
def is_read!(read)
|
826
|
+
nbuild[NS_EWS_TYPES].IsRead(read)
|
827
|
+
end
|
828
|
+
|
825
829
|
def calendar_item!(item)
|
826
830
|
nbuild[NS_EWS_TYPES].CalendarItem {
|
827
831
|
item.each_pair {|k,v|
|
@@ -830,9 +834,62 @@ module Viewpoint::EWS::SOAP
|
|
830
834
|
}
|
831
835
|
end
|
832
836
|
|
837
|
+
def calendar_item_type!(type)
|
838
|
+
nbuild[NS_EWS_TYPES].CalendarItemType(type)
|
839
|
+
end
|
840
|
+
|
841
|
+
def recurrence!(item)
|
842
|
+
nbuild[NS_EWS_TYPES].Recurrence {
|
843
|
+
item.each_pair { |k, v|
|
844
|
+
self.send("#{k}!", v)
|
845
|
+
}
|
846
|
+
}
|
847
|
+
end
|
848
|
+
|
849
|
+
def daily_recurrence!(item)
|
850
|
+
nbuild[NS_EWS_TYPES].DailyRecurrence {
|
851
|
+
item.each_pair { |k, v|
|
852
|
+
self.send("#{k}!", v)
|
853
|
+
}
|
854
|
+
}
|
855
|
+
end
|
856
|
+
|
857
|
+
def weekly_recurrence!(item)
|
858
|
+
nbuild[NS_EWS_TYPES].WeeklyRecurrence {
|
859
|
+
item.each_pair { |k, v|
|
860
|
+
self.send("#{k}!", v)
|
861
|
+
}
|
862
|
+
}
|
863
|
+
end
|
864
|
+
|
865
|
+
def interval!(num)
|
866
|
+
nbuild[NS_EWS_TYPES].Interval(num)
|
867
|
+
end
|
868
|
+
|
869
|
+
def no_end_recurrence!(item)
|
870
|
+
nbuild[NS_EWS_TYPES].NoEndRecurrence {
|
871
|
+
item.each_pair { |k, v|
|
872
|
+
self.send("#{k}!", v)
|
873
|
+
}
|
874
|
+
}
|
875
|
+
end
|
876
|
+
|
877
|
+
def numbered_recurrence!(item)
|
878
|
+
nbuild[NS_EWS_TYPES].NumberedRecurrence {
|
879
|
+
item.each_pair { |k, v|
|
880
|
+
self.send("#{k}!", v)
|
881
|
+
}
|
882
|
+
}
|
883
|
+
end
|
884
|
+
|
885
|
+
def number_of_occurrences!(count)
|
886
|
+
nbuild[NS_EWS_TYPES].NumberOfOccurrences(count)
|
887
|
+
end
|
888
|
+
|
889
|
+
|
833
890
|
def task!(item)
|
834
891
|
nbuild[NS_EWS_TYPES].Task {
|
835
|
-
item.each_pair {|k,v|
|
892
|
+
item.each_pair {|k, v|
|
836
893
|
self.send("#{k}!", v)
|
837
894
|
}
|
838
895
|
}
|
@@ -949,7 +1006,7 @@ module Viewpoint::EWS::SOAP
|
|
949
1006
|
end
|
950
1007
|
|
951
1008
|
def start_date!(sd)
|
952
|
-
nbuild[NS_EWS_TYPES].StartDate
|
1009
|
+
nbuild[NS_EWS_TYPES].StartDate sd[:text]
|
953
1010
|
end
|
954
1011
|
|
955
1012
|
def due_date!(dd)
|
@@ -964,6 +1021,10 @@ module Viewpoint::EWS::SOAP
|
|
964
1021
|
nbuild[NS_EWS_TYPES].IsAllDayEvent(all_day)
|
965
1022
|
end
|
966
1023
|
|
1024
|
+
def is_response_requested!(response_requested)
|
1025
|
+
nbuild[NS_EWS_TYPES].IsResponseRequested(response_requested)
|
1026
|
+
end
|
1027
|
+
|
967
1028
|
def reminder_is_set!(reminder)
|
968
1029
|
nbuild[NS_EWS_TYPES].ReminderIsSet reminder
|
969
1030
|
end
|
@@ -1202,6 +1263,33 @@ module Viewpoint::EWS::SOAP
|
|
1202
1263
|
@nbuild[NS_EWS_MESSAGES].GetRoomLists
|
1203
1264
|
end
|
1204
1265
|
|
1266
|
+
def accept_item!(opts)
|
1267
|
+
@nbuild[NS_EWS_TYPES].AcceptItem {
|
1268
|
+
sensitivity!(opts)
|
1269
|
+
body!(opts) if opts[:text]
|
1270
|
+
reference_item_id!(opts)
|
1271
|
+
}
|
1272
|
+
end
|
1273
|
+
|
1274
|
+
def tentatively_accept_item!(opts)
|
1275
|
+
@nbuild[NS_EWS_TYPES].TentativelyAcceptItem {
|
1276
|
+
sensitivity!(opts)
|
1277
|
+
body!(opts) if opts[:text]
|
1278
|
+
reference_item_id!(opts)
|
1279
|
+
}
|
1280
|
+
end
|
1281
|
+
|
1282
|
+
def decline_item!(opts)
|
1283
|
+
@nbuild[NS_EWS_TYPES].DeclineItem {
|
1284
|
+
sensitivity!(opts)
|
1285
|
+
body!(opts) if opts[:text]
|
1286
|
+
reference_item_id!(opts)
|
1287
|
+
}
|
1288
|
+
end
|
1289
|
+
|
1290
|
+
def sensitivity!(value)
|
1291
|
+
nbuild[NS_EWS_TYPES].Sensitivity(value[:sensitivity])
|
1292
|
+
end
|
1205
1293
|
|
1206
1294
|
private
|
1207
1295
|
|
@@ -1237,6 +1325,13 @@ private
|
|
1237
1325
|
end
|
1238
1326
|
end
|
1239
1327
|
|
1328
|
+
def meeting_time_zone!(mtz)
|
1329
|
+
nbuild[NS_EWS_TYPES].MeetingTimeZone do |x|
|
1330
|
+
x.parent['TimeZoneName'] = mtz[:time_zone_name] if mtz[:time_zone_name]
|
1331
|
+
nbuild[NS_EWS_TYPES].BaseOffset(mtz[:base_offset][:text]) if mtz[:base_offset]
|
1332
|
+
end
|
1333
|
+
end
|
1334
|
+
|
1240
1335
|
# some methods need special naming so they use the '_r' suffix like 'and'
|
1241
1336
|
def normalize_type(type)
|
1242
1337
|
case type
|
@@ -7,7 +7,7 @@ module Viewpoint::EWS::SOAP
|
|
7
7
|
# @param full [Boolean] Request full time zone definition? Returns only name and id if false.
|
8
8
|
# @param ids [Array] Returns only the specified time zones instead of all if present
|
9
9
|
# @return [Array] Array of Objects responding to #id() and #name()
|
10
|
-
# @example Retrieving server
|
10
|
+
# @example Retrieving server time zones
|
11
11
|
# ews_client = Viewpoint::EWSClient.new # ...
|
12
12
|
# zones = ews_client.ews.get_time_zones
|
13
13
|
# @todo Implement TimeZoneDefinition with sub elements Periods, TransitionsGroups and Transitions
|
@@ -28,11 +28,11 @@ module Viewpoint::EWS::SOAP
|
|
28
28
|
|
29
29
|
def parse(opts = {})
|
30
30
|
opts[:response_class] ||= EwsSoapResponse
|
31
|
+
@soap_resp.gsub!(/&#x([0-8bcef]|1[0-9a-f]);/i, '')
|
31
32
|
sax_parser.parse(@soap_resp)
|
32
33
|
opts[:response_class].new @sax_doc.struct
|
33
34
|
end
|
34
35
|
|
35
|
-
|
36
36
|
private
|
37
37
|
|
38
38
|
def sax_parser
|
@@ -26,10 +26,11 @@ module Viewpoint::EWS
|
|
26
26
|
|
27
27
|
# EWS CreateItem container
|
28
28
|
# @return [Hash]
|
29
|
-
def to_ews_create
|
29
|
+
def to_ews_create(opts = {})
|
30
30
|
structure = {}
|
31
31
|
structure[:message_disposition] = (draft ? 'SaveOnly' : 'SendAndSaveCopy')
|
32
|
-
|
32
|
+
# options
|
33
|
+
structure[:send_meeting_invitations] = (opts.has_key?(:send_meeting_invitations) ? opts[:send_meeting_invitations] : 'SendToNone')
|
33
34
|
|
34
35
|
if self.saved_item_folder_id
|
35
36
|
if self.saved_item_folder_id.kind_of?(Hash)
|
@@ -27,6 +27,7 @@ module Viewpoint::EWS
|
|
27
27
|
self.body_type ||= 'Text'
|
28
28
|
self.importance ||= 'Normal'
|
29
29
|
self.draft ||= false
|
30
|
+
self.is_read = true if is_read.nil?
|
30
31
|
self.to_recipients ||= []
|
31
32
|
self.cc_recipients ||= []
|
32
33
|
self.bcc_recipients ||= []
|
@@ -63,6 +64,8 @@ module Viewpoint::EWS
|
|
63
64
|
bcc_r = bcc_recipients.collect{|r| {mailbox: {email_address: r}}}
|
64
65
|
msg[:bcc_recipients] = bcc_r unless bcc_r.empty?
|
65
66
|
|
67
|
+
msg[:is_read] = is_read
|
68
|
+
|
66
69
|
msg[:extended_properties] = extended_properties unless extended_properties.empty?
|
67
70
|
|
68
71
|
[ews_opts, msg]
|
@@ -35,10 +35,10 @@ module Viewpoint::EWS::Types
|
|
35
35
|
# @option attributes :end [Time]
|
36
36
|
# @return [CalendarItem]
|
37
37
|
# @see Template::CalendarItem
|
38
|
-
def create_item(attributes)
|
38
|
+
def create_item(attributes, to_ews_create_opts = {})
|
39
39
|
template = Viewpoint::EWS::Template::CalendarItem.new attributes
|
40
40
|
template.saved_item_folder_id = {id: self.id, change_key: self.change_key}
|
41
|
-
rm = ews.create_item(template.to_ews_create).response_messages.first
|
41
|
+
rm = ews.create_item(template.to_ews_create(to_ews_create_opts)).response_messages.first
|
42
42
|
if rm && rm.success?
|
43
43
|
CalendarItem.new ews, rm.items.first[:calendar_item][:elems].first
|
44
44
|
else
|
@@ -15,6 +15,7 @@ module Viewpoint::EWS::Types
|
|
15
15
|
end: [:end, :text],
|
16
16
|
location: [:location, :text],
|
17
17
|
all_day?: [:is_all_day_event, :text],
|
18
|
+
legacy_free_busy_status: [:legacy_free_busy_status, :text],
|
18
19
|
my_response_type: [:my_response_type, :text],
|
19
20
|
organizer: [:organizer, :elems, 0, :mailbox, :elems],
|
20
21
|
optional_attendees: [:optional_attendees, :elems ],
|
@@ -245,8 +245,6 @@ module Viewpoint::EWS::Types
|
|
245
245
|
end
|
246
246
|
|
247
247
|
def push_subscribe(url, evtypes = [:all], watermark = nil, status_frequency = nil)
|
248
|
-
# Refresh the subscription if already subscribed
|
249
|
-
unsubscribe if subscribed?
|
250
248
|
|
251
249
|
event_types = normalize_event_names(evtypes)
|
252
250
|
folder = {id: self.id, change_key: self.change_key}
|
data/lib/ews/types/item.rb
CHANGED
@@ -24,6 +24,7 @@ module Viewpoint::EWS::Types
|
|
24
24
|
size: [:size, :text],
|
25
25
|
date_time_sent: [:date_time_sent, :text],
|
26
26
|
date_time_created: [:date_time_created, :text],
|
27
|
+
last_modified_time: [:last_modified_time, :text],
|
27
28
|
mime_content: [:mime_content, :text],
|
28
29
|
has_attachments?:[:has_attachments, :text],
|
29
30
|
is_associated?: [:is_associated, :text],
|
@@ -50,6 +51,7 @@ module Viewpoint::EWS::Types
|
|
50
51
|
size: ->(str){str.to_i},
|
51
52
|
date_time_sent: ->(str){DateTime.parse(str)},
|
52
53
|
date_time_created: ->(str){DateTime.parse(str)},
|
54
|
+
last_modified_time: ->(str){DateTime.parse(str)},
|
53
55
|
has_attachments?: ->(str){str.downcase == 'true'},
|
54
56
|
is_associated?: ->(str){str.downcase == 'true'},
|
55
57
|
is_read?: ->(str){str.downcase == 'true'},
|
@@ -118,10 +120,14 @@ module Viewpoint::EWS::Types
|
|
118
120
|
simplify!
|
119
121
|
end
|
120
122
|
|
121
|
-
# Mark an item as read
|
122
|
-
|
123
|
-
|
124
|
-
|
123
|
+
# Mark an item as read
|
124
|
+
def mark_read!
|
125
|
+
update_is_read_status true
|
126
|
+
end
|
127
|
+
|
128
|
+
# Mark an item as unread
|
129
|
+
def mark_unread!
|
130
|
+
update_is_read_status false
|
125
131
|
end
|
126
132
|
|
127
133
|
# Move this item to a new folder
|
@@ -22,16 +22,12 @@ module Viewpoint
|
|
22
22
|
|
23
23
|
FIELD_URIS= {
|
24
24
|
:folder_id => {:text => 'folder:FolderId', :writable => true},
|
25
|
-
:parent_folder_id => {:text => 'folder:ParentFolderId', :writable => true},
|
26
|
-
:display_name => {:text => 'folder:DisplayName', :writable => true},
|
27
|
-
:unread_count => {:text => 'folder:UnreadCount', :writable => true},
|
28
25
|
:total_count => {:text => 'folder:TotalCount', :writable => true},
|
29
26
|
:child_folder_count => {:text => 'folder:ChildFolderCount', :writable => true},
|
30
27
|
:folder_class => {:text => 'folder:FolderClass', :writable => true},
|
31
28
|
:search_parameters => {:text => 'folder:SearchParameters', :writable => true},
|
32
29
|
:managed_folder_information => {:text => 'folder:ManagedFolderInformation', :writable => true},
|
33
30
|
:permission_set => {:text => 'folder:PermissionSet', :writable => true},
|
34
|
-
:effective_rights => {:text => 'folder:EffectiveRights', :writable => true},
|
35
31
|
:sharing_effective_rights => {:text => 'folder:SharingEffectiveRights', :writable => true},
|
36
32
|
:item_id => {:text => 'item:ItemId', :writable => true},
|
37
33
|
:parent_folder_id => {:text => 'item:ParentFolderId', :writable => true},
|
@@ -40,10 +36,6 @@ module Viewpoint
|
|
40
36
|
:attachments => {:text => 'item:Attachments', :writable => true},
|
41
37
|
:subject => {:text => 'item:Subject', :writable => true},
|
42
38
|
:date_time_received => {:text => 'item:DateTimeReceived', :writable => true},
|
43
|
-
:size => {:text => 'item:Size', :writable => true},
|
44
|
-
:categories => {:text => 'item:Categories', :writable => true},
|
45
|
-
:has_attachments => {:text => 'item:HasAttachments', :writable => true},
|
46
|
-
:importance => {:text => 'item:Importance', :writable => true},
|
47
39
|
:in_reply_to => {:text => 'item:InReplyTo', :writable => true},
|
48
40
|
:internet_message_headers => {:text => 'item:InternetMessageHeaders', :writable => true},
|
49
41
|
:is_associated => {:text => 'item:IsAssociated', :writable => true},
|
@@ -62,19 +54,15 @@ module Viewpoint
|
|
62
54
|
:reminder_minutes_before_start => {:text => 'item:ReminderMinutesBeforeStart', :writable => true},
|
63
55
|
:display_to => {:text => 'item:DisplayTo', :writable => true},
|
64
56
|
:display_cc => {:text => 'item:DisplayCc', :writable => true},
|
65
|
-
:culture => {:text => 'item:Culture', :writable => true},
|
66
57
|
:effective_rights => {:text => 'item:EffectiveRights', :writable => true},
|
67
58
|
:last_modified_name => {:text => 'item:LastModifiedName', :writable => true},
|
68
59
|
:last_modified_time => {:text => 'item:LastModifiedTime', :writable => true},
|
69
|
-
:conversation_id => {:text => 'item:ConversationId', :writable => true},
|
70
60
|
:unique_body => {:text => 'item:UniqueBody', :writable => true},
|
71
61
|
:web_client_read_form_query_string => {:text => 'item:WebClientReadFormQueryString', :writable => true},
|
72
62
|
:web_client_edit_form_query_string => {:text => 'item:WebClientEditFormQueryString', :writable => true},
|
73
63
|
:conversation_index => {:text => 'message:ConversationIndex', :writable => true},
|
74
|
-
:conversation_topic => {:text => 'message:ConversationTopic', :writable => true},
|
75
64
|
:internet_message_id => {:text => 'message:InternetMessageId', :writable => true},
|
76
65
|
:is_read => {:text => 'message:IsRead', :writable => true},
|
77
|
-
:is_response_requested => {:text => 'message:IsResponseRequested', :writable => true},
|
78
66
|
:is_read_receipt_requested => {:text => 'message:IsReadReceiptRequested', :writable => true},
|
79
67
|
:is_delivery_receipt_requested => {:text => 'message:IsDeliveryReceiptRequested', :writable => true},
|
80
68
|
:references => {:text => 'message:References', :writable => true},
|
@@ -100,7 +88,6 @@ module Viewpoint
|
|
100
88
|
:when => {:text => 'calendar:When', :writable => true},
|
101
89
|
:is_meeting => {:text => 'calendar:IsMeeting', :writable => true},
|
102
90
|
:is_cancelled => {:text => 'calendar:IsCancelled', :writable => true},
|
103
|
-
:is_recurring => {:text => 'calendar:IsRecurring', :writable => true},
|
104
91
|
:meeting_request_was_sent => {:text => 'calendar:MeetingRequestWasSent', :writable => true},
|
105
92
|
:is_response_requested => {:text => 'calendar:IsResponseRequested', :writable => true},
|
106
93
|
:calendar_item_type => {:text => 'calendar:CalendarItemType', :writable => true},
|
@@ -118,7 +105,6 @@ module Viewpoint
|
|
118
105
|
:appointment_reply_time => {:text => 'calendar:AppointmentReplyTime', :writable => true},
|
119
106
|
:appointment_sequence_number => {:text => 'calendar:AppointmentSequenceNumber', :writable => true},
|
120
107
|
:appointment_state => {:text => 'calendar:AppointmentState', :writable => true},
|
121
|
-
:recurrence => {:text => 'calendar:Recurrence', :writable => true},
|
122
108
|
:first_occurrence => {:text => 'calendar:FirstOccurrence', :writable => true},
|
123
109
|
:last_occurrence => {:text => 'calendar:LastOccurrence', :writable => true},
|
124
110
|
:modified_occurrences => {:text => 'calendar:ModifiedOccurrences', :writable => true},
|
@@ -138,7 +124,6 @@ module Viewpoint
|
|
138
124
|
:assigned_time => {:text => 'task:AssignedTime', :writable => true},
|
139
125
|
:billing_information => {:text => 'task:BillingInformation', :writable => true},
|
140
126
|
:change_count => {:text => 'task:ChangeCount', :writable => true},
|
141
|
-
:companies => {:text => 'task:Companies', :writable => true},
|
142
127
|
:complete_date => {:text => 'task:CompleteDate', :writable => true},
|
143
128
|
:contacts => {:text => 'task:Contacts', :writable => true},
|
144
129
|
:delegation_state => {:text => 'task:DelegationState', :writable => true},
|
@@ -148,7 +133,6 @@ module Viewpoint
|
|
148
133
|
:is_complete => {:text => 'task:IsComplete', :writable => true},
|
149
134
|
:is_recurring => {:text => 'task:IsRecurring', :writable => true},
|
150
135
|
:is_team_task => {:text => 'task:IsTeamTask', :writable => true},
|
151
|
-
:mileage => {:text => 'task:Mileage', :writable => true},
|
152
136
|
:owner => {:text => 'task:Owner', :writable => true},
|
153
137
|
:percent_complete => {:text => 'task:PercentComplete', :writable => true},
|
154
138
|
:recurrence => {:text => 'task:Recurrence', :writable => true},
|
data/lib/ews/types/task.rb
CHANGED
@@ -5,18 +5,21 @@ module Viewpoint::EWS::Types
|
|
5
5
|
include Viewpoint::EWS::Types::Item
|
6
6
|
|
7
7
|
TASK_KEY_PATHS = {
|
8
|
-
complete?:
|
9
|
-
recurring?:
|
10
|
-
start_date:
|
11
|
-
due_date:
|
8
|
+
complete?: [:is_complete, :text],
|
9
|
+
recurring?: [:is_recurring, :text],
|
10
|
+
start_date: [:start_date, :text],
|
11
|
+
due_date: [:end_date, :text],
|
12
12
|
reminder_due_by: [:reminder_due_by, :text],
|
13
|
-
reminder?:
|
13
|
+
reminder?: [:reminder_is_set, :text],
|
14
|
+
percent_complete: [:percent_complete, :text],
|
15
|
+
status: [:status, :text],
|
14
16
|
}
|
15
17
|
|
16
18
|
TASK_KEY_TYPES = {
|
17
|
-
recurring?:
|
18
|
-
complete?:
|
19
|
-
reminder?:
|
19
|
+
recurring?: ->(str){str.downcase == 'true'},
|
20
|
+
complete?: ->(str){str.downcase == 'true'},
|
21
|
+
reminder?: ->(str){str.downcase == 'true'},
|
22
|
+
percent_complete: ->(str){str.to_i},
|
20
23
|
}
|
21
24
|
TASK_KEY_ALIAS = {}
|
22
25
|
|
@@ -33,5 +36,6 @@ module Viewpoint::EWS::Types
|
|
33
36
|
def key_alias
|
34
37
|
super.merge(TASK_KEY_ALIAS)
|
35
38
|
end
|
39
|
+
|
36
40
|
end
|
37
41
|
end
|
data/lib/viewpoint.rb
CHANGED
metadata
CHANGED
@@ -1,69 +1,69 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: viewpoint
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Wanek
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: httpclient
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rubyntlm
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: logging
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
description: 'A Ruby client access library for Microsoft Exchange Web Services (EWS). Examples
|
@@ -88,6 +88,7 @@ files:
|
|
88
88
|
- lib/ews/impersonation.rb
|
89
89
|
- lib/ews/item_accessors.rb
|
90
90
|
- lib/ews/mailbox_accessors.rb
|
91
|
+
- lib/ews/meeting_accessors.rb
|
91
92
|
- lib/ews/message_accessors.rb
|
92
93
|
- lib/ews/push_subscription_accessors.rb
|
93
94
|
- lib/ews/room_accessors.rb
|
@@ -153,6 +154,7 @@ files:
|
|
153
154
|
- lib/ews/types/moved_event.rb
|
154
155
|
- lib/ews/types/new_mail_event.rb
|
155
156
|
- lib/ews/types/out_of_office.rb
|
157
|
+
- lib/ews/types/post_item.rb
|
156
158
|
- lib/ews/types/search_folder.rb
|
157
159
|
- lib/ews/types/status_event.rb
|
158
160
|
- lib/ews/types/task.rb
|
@@ -166,25 +168,25 @@ licenses: []
|
|
166
168
|
metadata: {}
|
167
169
|
post_install_message:
|
168
170
|
rdoc_options:
|
169
|
-
- -x
|
171
|
+
- "-x"
|
170
172
|
- test/
|
171
|
-
- -x
|
173
|
+
- "-x"
|
172
174
|
- examples/
|
173
175
|
require_paths:
|
174
176
|
- lib
|
175
177
|
required_ruby_version: !ruby/object:Gem::Requirement
|
176
178
|
requirements:
|
177
|
-
- -
|
179
|
+
- - ">="
|
178
180
|
- !ruby/object:Gem::Version
|
179
181
|
version: 1.9.1
|
180
182
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
181
183
|
requirements:
|
182
|
-
- -
|
184
|
+
- - ">="
|
183
185
|
- !ruby/object:Gem::Version
|
184
186
|
version: '0'
|
185
187
|
requirements: []
|
186
188
|
rubyforge_project:
|
187
|
-
rubygems_version: 2.
|
189
|
+
rubygems_version: 2.6.6
|
188
190
|
signing_key:
|
189
191
|
specification_version: 4
|
190
192
|
summary: A Ruby client access library for Microsoft Exchange Web Services (EWS)
|