exchanger 0.1.2 → 0.1.3
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 +1 -0
- data/lib/exchanger.rb +5 -0
- data/lib/exchanger/client.rb +2 -2
- data/lib/exchanger/config.rb +2 -1
- data/lib/exchanger/elements/calendar_event.rb +11 -0
- data/lib/exchanger/elements/calendar_event_details.rb +8 -0
- data/lib/exchanger/operations/get_user_availability.rb +92 -0
- data/lib/exchanger/version.rb +1 -1
- data/spec/calendar_item_spec.rb +1 -1
- data/spec/client_spec.rb +1 -1
- data/spec/config.yml +5 -3
- data/spec/contact_spec.rb +1 -1
- data/spec/element_spec.rb +1 -1
- data/spec/field_spec.rb +1 -1
- data/spec/fixtures/get_user_availability.yml.example +4 -0
- data/spec/folder_spec.rb +1 -1
- data/spec/get_user_availability_spec.rb +44 -0
- metadata +94 -29
data/README.md
CHANGED
data/lib/exchanger.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require "singleton"
|
2
2
|
require "delegate"
|
3
3
|
require "base64"
|
4
|
+
require 'kconv' # Need for rubyntlm on Ruby 1.9
|
5
|
+
require 'tzinfo'
|
4
6
|
|
5
7
|
require "active_support/core_ext"
|
6
8
|
require "nokogiri"
|
@@ -47,6 +49,8 @@ require "exchanger/elements/meeting_response"
|
|
47
49
|
require "exchanger/elements/meeting_cancellation"
|
48
50
|
require "exchanger/elements/task"
|
49
51
|
require "exchanger/elements/distribution_list"
|
52
|
+
require "exchanger/elements/calendar_event_details"
|
53
|
+
require "exchanger/elements/calendar_event"
|
50
54
|
|
51
55
|
# Operations
|
52
56
|
require "exchanger/operation"
|
@@ -59,6 +63,7 @@ require "exchanger/operations/update_item"
|
|
59
63
|
require "exchanger/operations/delete_item"
|
60
64
|
require "exchanger/operations/resolve_names"
|
61
65
|
require "exchanger/operations/expand_dl"
|
66
|
+
require "exchanger/operations/get_user_availability"
|
62
67
|
|
63
68
|
module Exchanger
|
64
69
|
NS = {
|
data/lib/exchanger/client.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
module Exchanger
|
2
2
|
# SOAP Client for Exhange Web Services
|
3
3
|
class Client
|
4
|
-
delegate :endpoint, :timeout, :username, :password, :debug, :to => "Exchanger.config"
|
4
|
+
delegate :endpoint, :timeout, :username, :password, :debug, :insecure_ssl, :to => "Exchanger.config"
|
5
5
|
|
6
6
|
def initialize
|
7
7
|
@client = HTTPClient.new
|
8
8
|
@client.debug_dev = STDERR if debug
|
9
9
|
@client.set_auth nil, username, password if username
|
10
|
+
@client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE if insecure_ssl
|
10
11
|
end
|
11
12
|
|
12
13
|
# Does the actual HTTP level interaction.
|
13
14
|
def request(post_body, headers)
|
14
|
-
# @client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
15
15
|
response = @client.post(endpoint, post_body, headers)
|
16
16
|
return { :status => response.status, :body => response.content, :content_type => response.contenttype }
|
17
17
|
end
|
data/lib/exchanger/config.rb
CHANGED
@@ -2,7 +2,7 @@ module Exchanger
|
|
2
2
|
class Config
|
3
3
|
include Singleton
|
4
4
|
|
5
|
-
attr_accessor :endpoint, :timeout, :username, :password, :debug
|
5
|
+
attr_accessor :endpoint, :timeout, :username, :password, :debug, :insecure_ssl
|
6
6
|
|
7
7
|
def initialize
|
8
8
|
reset
|
@@ -15,6 +15,7 @@ module Exchanger
|
|
15
15
|
@username = nil
|
16
16
|
@password = nil
|
17
17
|
@debug = false
|
18
|
+
@insecure_ssl = false
|
18
19
|
end
|
19
20
|
|
20
21
|
# Configure Exchanger client from a hash. This is usually called after parsing a
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Exchanger
|
2
|
+
# The CalendarEvent element represents a unique calendar item occurrence.
|
3
|
+
#
|
4
|
+
# http://msdn.microsoft.com/en-us/library/aa564053(v=exchg.140)
|
5
|
+
class CalendarEvent < Item
|
6
|
+
element :start_time, :type => Time
|
7
|
+
element :end_time, :type => Time
|
8
|
+
element :busy_type
|
9
|
+
element :calendar_event_details, :type => CalendarEventDetails
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module Exchanger
|
2
|
+
# Getting User Availability
|
3
|
+
#
|
4
|
+
# http://msdn.microsoft.com/en-us/library/aa494212(v=exchg.80)
|
5
|
+
class GetUserAvailability < Operation
|
6
|
+
class Request < Operation::Request
|
7
|
+
attr_accessor :time_zone, :email_address, :start_time, :end_time
|
8
|
+
|
9
|
+
# Reset request options to defaults.
|
10
|
+
def reset
|
11
|
+
@time_zone = 'Europe/London'
|
12
|
+
@email_address = 'test.test@test.com'
|
13
|
+
@start_time = Date.today.to_time + 1
|
14
|
+
@end_time = (Date.today + 1).to_time - 1
|
15
|
+
end
|
16
|
+
|
17
|
+
def time_zone_period
|
18
|
+
begin
|
19
|
+
current_tz = TZInfo::Timezone.get(time_zone).current_period
|
20
|
+
rescue => e
|
21
|
+
raise Exchanger::Operation::ResponseError.new(e, 500)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_xml
|
26
|
+
current_tz = time_zone_period
|
27
|
+
minutes_of_utc_offset = current_tz.utc_offset/60 # Get the base offset of the timezone from UTC in minutes
|
28
|
+
minutes_of_std_offset = current_tz.std_offset/60 # Get the daylight savings offset from standard time in minutes
|
29
|
+
|
30
|
+
start_date_time = start_time.strftime("%Y-%m-%dT%H:%M:%S")
|
31
|
+
end_date_time = end_time.strftime("%Y-%m-%dT%H:%M:%S")
|
32
|
+
|
33
|
+
Nokogiri::XML::Builder.new do |xml|
|
34
|
+
xml.send("soap:Envelope", "xmlns:xsi" => NS["xsi"], "xmlns:xsd" => NS["xsd"], "xmlns:soap" => NS["soap"], "xmlns:t" => NS["t"], "xmlns:m" => NS["m"]) do
|
35
|
+
xml.send("soap:Body") do
|
36
|
+
xml.send("m:GetUserAvailabilityRequest") do
|
37
|
+
xml.send("t:TimeZone") do
|
38
|
+
xml.send("t:Bias", (minutes_of_utc_offset * -1))
|
39
|
+
# if daylight savings time is active for current time zone
|
40
|
+
# How to find correct standard time and daylight saving time configuration
|
41
|
+
if current_tz.dst?
|
42
|
+
xml.send("t:StandardTime") do
|
43
|
+
xml.send("t:Bias", 0)
|
44
|
+
xml.send("t:Time", "04:00:00")
|
45
|
+
xml.send("t:DayOrder", 5)
|
46
|
+
xml.send("t:Month", 10)
|
47
|
+
xml.send("t:DayOfWeek", "Sunday")
|
48
|
+
end
|
49
|
+
xml.send("t:DaylightTime") do
|
50
|
+
xml.send("t:Bias", (minutes_of_std_offset * -1))
|
51
|
+
xml.send("t:Time", "03:00:00")
|
52
|
+
xml.send("t:DayOrder", 5)
|
53
|
+
xml.send("t:Month", 3)
|
54
|
+
xml.send("t:DayOfWeek", "Sunday")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
xml.send("m:MailboxDataArray") do
|
59
|
+
xml.send("t:MailboxData") do
|
60
|
+
xml.send("t:Email") do
|
61
|
+
xml.send("t:Address", email_address)
|
62
|
+
end
|
63
|
+
xml.send("t:AttendeeType", "Required")
|
64
|
+
xml.send("t:ExcludeConflicts", "false")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
xml.send("t:FreeBusyViewOptions") do
|
68
|
+
xml.send("t:TimeWindow") do
|
69
|
+
xml.send("t:StartTime", start_date_time)
|
70
|
+
xml.send("t:EndTime", end_date_time)
|
71
|
+
end
|
72
|
+
xml.send("t:MergedFreeBusyIntervalInMinutes", 60)
|
73
|
+
xml.send("t:RequestedView", "DetailedMerged")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class Response < Operation::Response
|
83
|
+
def items
|
84
|
+
to_xml.xpath(".//t:CalendarEventArray", NS).children.map do |node|
|
85
|
+
item_klass = Exchanger.const_get(node.name)
|
86
|
+
item_klass.new_from_xml(node)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
data/lib/exchanger/version.rb
CHANGED
data/spec/calendar_item_spec.rb
CHANGED
data/spec/client_spec.rb
CHANGED
data/spec/config.yml
CHANGED
data/spec/contact_spec.rb
CHANGED
data/spec/element_spec.rb
CHANGED
data/spec/field_spec.rb
CHANGED
data/spec/folder_spec.rb
CHANGED
@@ -0,0 +1,44 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Exchanger::GetUserAvailability do
|
4
|
+
describe "Get user availability" do
|
5
|
+
before(:all) do
|
6
|
+
@valid_attributes = YAML.load_file("#{File.dirname(__FILE__)}/fixtures/get_user_availability.yml")
|
7
|
+
@valid_attributes["start_time"] = Time.parse(@valid_attributes["start_time"])
|
8
|
+
@valid_attributes["end_time"] = Time.parse(@valid_attributes["end_time"])
|
9
|
+
end
|
10
|
+
|
11
|
+
before do
|
12
|
+
@response = Exchanger::GetUserAvailability.run(@valid_attributes)
|
13
|
+
@items = @response.items
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should be sucessfull with default values" do
|
17
|
+
Exchanger::GetUserAvailability.run().status.should == 200
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should be sucessfull with valid data" do
|
21
|
+
@response.status.should == 200
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should response have calendar event items" do
|
25
|
+
@items.all?{ |i| i.class.name == "Exchanger::CalendarEvent" }.should be_true
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should calendar event item have valid attributes" do
|
29
|
+
["start_time", "end_time", "busy_type", "calendar_event_details"].each do |k|
|
30
|
+
@items[0].attributes.keys.include?(k).should be_true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should calendar event items have calendar event details" do
|
35
|
+
@items.all?{ |i| i.calendar_event_details.class.name == "Exchanger::CalendarEventDetails" }.should be_true
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should calendar event details item have valid attributes" do
|
39
|
+
["id","subject","location", "is_meeting", "is_recurring", "is_exception", "is_reminder_set", "is_private"].each do |k|
|
40
|
+
@items[0].calendar_event_details.attributes.keys.include?(k).should be_true
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: exchanger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-06-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: 2.2.2
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.2.2
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: nokogiri
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ! '>='
|
@@ -32,10 +37,15 @@ dependencies:
|
|
32
37
|
version: 1.3.0
|
33
38
|
type: :runtime
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.3.0
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: httpclient
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
51
|
- - ! '>='
|
@@ -43,10 +53,15 @@ dependencies:
|
|
43
53
|
version: 2.1.5.2
|
44
54
|
type: :runtime
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.1.5.2
|
47
62
|
- !ruby/object:Gem::Dependency
|
48
63
|
name: rubyntlm
|
49
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
50
65
|
none: false
|
51
66
|
requirements:
|
52
67
|
- - ! '>='
|
@@ -54,10 +69,15 @@ dependencies:
|
|
54
69
|
version: 0.1.1
|
55
70
|
type: :runtime
|
56
71
|
prerelease: false
|
57
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 0.1.1
|
58
78
|
- !ruby/object:Gem::Dependency
|
59
79
|
name: rake
|
60
|
-
requirement:
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
61
81
|
none: false
|
62
82
|
requirements:
|
63
83
|
- - ! '>='
|
@@ -65,10 +85,15 @@ dependencies:
|
|
65
85
|
version: '0'
|
66
86
|
type: :development
|
67
87
|
prerelease: false
|
68
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
69
94
|
- !ruby/object:Gem::Dependency
|
70
95
|
name: i18n
|
71
|
-
requirement:
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
72
97
|
none: false
|
73
98
|
requirements:
|
74
99
|
- - ! '>='
|
@@ -76,10 +101,15 @@ dependencies:
|
|
76
101
|
version: '0'
|
77
102
|
type: :development
|
78
103
|
prerelease: false
|
79
|
-
version_requirements:
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
80
110
|
- !ruby/object:Gem::Dependency
|
81
111
|
name: rspec
|
82
|
-
requirement:
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
83
113
|
none: false
|
84
114
|
requirements:
|
85
115
|
- - ~>
|
@@ -87,10 +117,15 @@ dependencies:
|
|
87
117
|
version: 2.6.0
|
88
118
|
type: :development
|
89
119
|
prerelease: false
|
90
|
-
version_requirements:
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ~>
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 2.6.0
|
91
126
|
- !ruby/object:Gem::Dependency
|
92
127
|
name: rcov
|
93
|
-
requirement:
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
94
129
|
none: false
|
95
130
|
requirements:
|
96
131
|
- - ! '>='
|
@@ -98,10 +133,15 @@ dependencies:
|
|
98
133
|
version: '0'
|
99
134
|
type: :development
|
100
135
|
prerelease: false
|
101
|
-
version_requirements:
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
102
142
|
- !ruby/object:Gem::Dependency
|
103
143
|
name: yard
|
104
|
-
requirement:
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
105
145
|
none: false
|
106
146
|
requirements:
|
107
147
|
- - ! '>='
|
@@ -109,10 +149,15 @@ dependencies:
|
|
109
149
|
version: '0'
|
110
150
|
type: :development
|
111
151
|
prerelease: false
|
112
|
-
version_requirements:
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
113
158
|
- !ruby/object:Gem::Dependency
|
114
159
|
name: BlueCloth
|
115
|
-
requirement:
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
116
161
|
none: false
|
117
162
|
requirements:
|
118
163
|
- - ! '>='
|
@@ -120,7 +165,28 @@ dependencies:
|
|
120
165
|
version: '0'
|
121
166
|
type: :development
|
122
167
|
prerelease: false
|
123
|
-
version_requirements:
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
- !ruby/object:Gem::Dependency
|
175
|
+
name: tzinfo
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
177
|
+
none: false
|
178
|
+
requirements:
|
179
|
+
- - ! '>='
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
182
|
+
type: :development
|
183
|
+
prerelease: false
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ! '>='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
124
190
|
description: Ruby library for accessing Microsoft Exchange using Exchange Web Services
|
125
191
|
email: 1@wb4.lv
|
126
192
|
executables: []
|
@@ -135,6 +201,8 @@ files:
|
|
135
201
|
- lib/exchanger/element.rb
|
136
202
|
- lib/exchanger/elements/attendee.rb
|
137
203
|
- lib/exchanger/elements/base_folder.rb
|
204
|
+
- lib/exchanger/elements/calendar_event.rb
|
205
|
+
- lib/exchanger/elements/calendar_event_details.rb
|
138
206
|
- lib/exchanger/elements/calendar_folder.rb
|
139
207
|
- lib/exchanger/elements/calendar_item.rb
|
140
208
|
- lib/exchanger/elements/complete_name.rb
|
@@ -168,6 +236,7 @@ files:
|
|
168
236
|
- lib/exchanger/operations/find_item.rb
|
169
237
|
- lib/exchanger/operations/get_folder.rb
|
170
238
|
- lib/exchanger/operations/get_item.rb
|
239
|
+
- lib/exchanger/operations/get_user_availability.rb
|
171
240
|
- lib/exchanger/operations/resolve_names.rb
|
172
241
|
- lib/exchanger/operations/update_item.rb
|
173
242
|
- lib/exchanger/persistence.rb
|
@@ -180,7 +249,9 @@ files:
|
|
180
249
|
- spec/contact_spec.rb
|
181
250
|
- spec/element_spec.rb
|
182
251
|
- spec/field_spec.rb
|
252
|
+
- spec/fixtures/get_user_availability.yml.example
|
183
253
|
- spec/folder_spec.rb
|
254
|
+
- spec/get_user_availability_spec.rb
|
184
255
|
- spec/mailbox_spec.rb
|
185
256
|
- spec/spec_helper.rb
|
186
257
|
- README.md
|
@@ -197,21 +268,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
197
268
|
- - ! '>='
|
198
269
|
- !ruby/object:Gem::Version
|
199
270
|
version: '0'
|
200
|
-
segments:
|
201
|
-
- 0
|
202
|
-
hash: -2432050375325580757
|
203
271
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
204
272
|
none: false
|
205
273
|
requirements:
|
206
274
|
- - ! '>='
|
207
275
|
- !ruby/object:Gem::Version
|
208
276
|
version: '0'
|
209
|
-
segments:
|
210
|
-
- 0
|
211
|
-
hash: -2432050375325580757
|
212
277
|
requirements: []
|
213
278
|
rubyforge_project:
|
214
|
-
rubygems_version: 1.8.
|
279
|
+
rubygems_version: 1.8.24
|
215
280
|
signing_key:
|
216
281
|
specification_version: 3
|
217
282
|
summary: Ruby library for accessing Microsoft Exchange using Exchange Web Services
|