viewpoint 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README +7 -1
- data/Rakefile +30 -3
- data/VERSION +1 -0
- data/examples/ews_fusefs.rb +2 -2
- data/lib/exchwebserv.rb +4 -226
- data/lib/viewpoint.rb +2 -0
- data/lib/{calendar.rb → viewpoint/calendar.rb} +0 -1
- data/lib/{calendar_item.rb → viewpoint/calendar_item.rb} +0 -1
- data/lib/{event.rb → viewpoint/event.rb} +0 -0
- data/lib/{exchange_headers.rb → viewpoint/exchange_headers.rb} +0 -1
- data/lib/viewpoint/exchwebserv.rb +233 -0
- data/lib/{folder.rb → viewpoint/folder.rb} +0 -1
- data/lib/{item.rb → viewpoint/item.rb} +0 -1
- data/lib/{mail.rb → viewpoint/mail.rb} +2 -7
- data/lib/{message.rb → viewpoint/message.rb} +0 -1
- data/lib/{task.rb → viewpoint/task.rb} +0 -0
- data/lib/{tasks.rb → viewpoint/tasks.rb} +0 -0
- data/test/spec/basic_features_spec.rb +37 -0
- data/test/test_client.rb +2 -1
- metadata +35 -15
- data/test/spec/authtest_spec.rb +0 -12
- data/test/spec/findfolders_spec.rb +0 -14
data/README
CHANGED
@@ -4,6 +4,11 @@
|
|
4
4
|
This program attempts to create a client access library for Exchange Web
|
5
5
|
Services (EWS) in Ruby.
|
6
6
|
--------------------------------------------------------------------------
|
7
|
+
TO USE:
|
8
|
+
require 'rubygems'
|
9
|
+
require 'viewpoint'
|
10
|
+
# See REQUIRED GEMS below
|
11
|
+
|
7
12
|
REQUIRED GEMS:
|
8
13
|
|
9
14
|
# Current SOAP4R ( http://dev.ctor.org/soap4r )
|
@@ -30,7 +35,8 @@ To run the FuseFS example you need the 'fusefs' gem
|
|
30
35
|
# "new_folder" is a type of Viewpoint::Folder
|
31
36
|
|
32
37
|
# === Convert your Exchange Calendar to a Icalendar::Calendar object ===
|
33
|
-
require '
|
38
|
+
require 'rubygems'
|
39
|
+
require 'viewpoint'
|
34
40
|
vp = Viewpoint::ExchWebServ.instance
|
35
41
|
vp.authenticate
|
36
42
|
vp.find_folders
|
data/Rakefile
CHANGED
@@ -27,8 +27,8 @@ GEMSPEC = Gem::Specification.new do |gem|
|
|
27
27
|
gem.extra_rdoc_files = %w(README COPYING.txt)
|
28
28
|
|
29
29
|
gem.required_ruby_version = '>= 1.8.7'
|
30
|
-
gem.
|
31
|
-
|
30
|
+
gem.add_runtime_dependency 'soap4r', '>=1.5.8'
|
31
|
+
gem.add_runtime_dependency 'icalendar'
|
32
32
|
gem.post_install_message = "Don't forget to create .viewpointrc. See README"
|
33
33
|
end
|
34
34
|
|
@@ -36,4 +36,31 @@ Rake::GemPackageTask.new(GEMSPEC) do |pkg|
|
|
36
36
|
pkg.need_tar = true
|
37
37
|
end
|
38
38
|
|
39
|
-
task :default => [:
|
39
|
+
task :default => [:buildgem]
|
40
|
+
|
41
|
+
desc "Build the gem without a version change"
|
42
|
+
task :buildgem => [:clean, :repackage]
|
43
|
+
|
44
|
+
desc "Build the gem, but increment the version first"
|
45
|
+
task :newrelease => [:versionup, :clean, :repackage]
|
46
|
+
|
47
|
+
|
48
|
+
desc "Increment the version by 1 minor release"
|
49
|
+
task :versionup do
|
50
|
+
ver = up_min_version
|
51
|
+
puts "New version: #{ver}"
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
def up_min_version
|
56
|
+
f = File.open('VERSION', 'r+')
|
57
|
+
ver = f.readline.chomp
|
58
|
+
v_arr = ver.split(/\./).map do |v|
|
59
|
+
v.to_i
|
60
|
+
end
|
61
|
+
v_arr[2] += 1
|
62
|
+
ver = v_arr.join('.')
|
63
|
+
f.rewind
|
64
|
+
f.write(ver)
|
65
|
+
ver
|
66
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.2
|
data/examples/ews_fusefs.rb
CHANGED
@@ -17,11 +17,11 @@
|
|
17
17
|
# You should have received a copy of the GNU General Public License along
|
18
18
|
# with Viewpoint. If not, see <http://www.gnu.org/licenses/>.
|
19
19
|
#############################################################################
|
20
|
+
$: << File.dirname(__FILE__) + '/../lib/'
|
20
21
|
require 'fusefs'
|
21
22
|
require 'time'
|
22
23
|
include FuseFS
|
23
|
-
require
|
24
|
-
require File.dirname(__FILE__) + '/../lib/folder'
|
24
|
+
require 'viewpoint'
|
25
25
|
include Viewpoint
|
26
26
|
|
27
27
|
|
data/lib/exchwebserv.rb
CHANGED
@@ -1,228 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
# This file is part of Viewpoint.
|
6
|
-
#
|
7
|
-
# Viewpoint is free software: you can redistribute it and/or
|
8
|
-
# modify it under the terms of the GNU General Public License as published
|
9
|
-
# by the Free Software Foundation, either version 3 of the License, or (at
|
10
|
-
# your option) any later version.
|
11
|
-
#
|
12
|
-
# Viewpoint is distributed in the hope that it will be useful,
|
13
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
15
|
-
# Public License for more details.
|
16
|
-
#
|
17
|
-
# You should have received a copy of the GNU General Public License along
|
18
|
-
# with Viewpoint. If not, see <http://www.gnu.org/licenses/>.
|
19
|
-
#############################################################################
|
20
|
-
$:.unshift(File.dirname(__FILE__))
|
21
|
-
require 'rubygems'
|
22
|
-
#require 'highline/import'
|
23
|
-
require 'singleton'
|
24
|
-
require 'wsdl/exchangeServiceBinding'
|
25
|
-
# --- Custom libs ---
|
26
|
-
require 'exchange_headers'
|
27
|
-
# --- Folder Types ---
|
28
|
-
require 'folder'
|
29
|
-
require 'calendar'
|
30
|
-
require 'mail'
|
1
|
+
# This exists for legacy reasons and will be depreciated soon
|
2
|
+
warn "*******************************************"
|
3
|
+
warn "Requiring exchwebserv is depreciated and will be removed soon.\nPlease require 'viewpoint'"
|
4
|
+
warn "*******************************************"
|
31
5
|
|
32
6
|
require 'viewpoint'
|
33
|
-
|
34
|
-
# This class will act as the controller for a client connection to the
|
35
|
-
# Exchange web service.
|
36
|
-
class Viewpoint::ExchWebServ
|
37
|
-
include Viewpoint
|
38
|
-
include Singleton
|
39
|
-
|
40
|
-
attr_reader :ews, :user, :authenticated
|
41
|
-
|
42
|
-
def initialize
|
43
|
-
@authenticated = false
|
44
|
-
@user = nil
|
45
|
-
@pass = nil
|
46
|
-
@ews_endpoint = nil
|
47
|
-
|
48
|
-
# Connection to Exchange web services.
|
49
|
-
# You can get fetch this from an accessor later.
|
50
|
-
@ews = nil
|
51
|
-
|
52
|
-
# Stores folders returned from 'find_folders'
|
53
|
-
@folders = {}
|
54
|
-
|
55
|
-
# Do initial authentication
|
56
|
-
#do_auth
|
57
|
-
end
|
58
|
-
|
59
|
-
|
60
|
-
# Finds all folders and returns a hash of FolderTypes
|
61
|
-
def find_folders
|
62
|
-
ff = FindFolderType.new()
|
63
|
-
ff.xmlattr_Traversal = FolderQueryTraversalType::Deep
|
64
|
-
ff.folderShape = FolderResponseShapeType.new( DefaultShapeNamesType::AllProperties )
|
65
|
-
fid = NonEmptyArrayOfBaseFolderIdsType.new()
|
66
|
-
fidt = DistinguishedFolderIdType.new
|
67
|
-
fidt.xmlattr_Id = DistinguishedFolderIdNameType::Root
|
68
|
-
fid.distinguishedFolderId = fidt
|
69
|
-
ff.parentFolderIds = fid
|
70
|
-
|
71
|
-
# FindFolderResponseType
|
72
|
-
resp = @ews.findFolder(ff)
|
73
|
-
|
74
|
-
# ArrayOfResponseMessagesType
|
75
|
-
msgs = resp.responseMessages
|
76
|
-
|
77
|
-
# Array of FindFolderResponseMessageType
|
78
|
-
msgs.findFolderResponseMessage.each do |elem|
|
79
|
-
# Mail Folders
|
80
|
-
mail_folders = {}
|
81
|
-
elem.rootFolder.folders.folder.each do |folder|
|
82
|
-
if( folder.folderClass != nil)
|
83
|
-
mail_folders[folder.displayName] = MailFolder.new(folder)
|
84
|
-
end
|
85
|
-
end
|
86
|
-
@folders['MailFolder'] = mail_folders
|
87
|
-
|
88
|
-
# CalendarFolderType
|
89
|
-
cal_folders = {}
|
90
|
-
elem.rootFolder.folders.calendarFolder.each do |folder|
|
91
|
-
cal_folders[folder.displayName] = CalendarFolder.new(folder)
|
92
|
-
end
|
93
|
-
@folders['CalendarFolder'] = cal_folders
|
94
|
-
|
95
|
-
#elem.rootFolder.folders.contactsFolder.each do |folder|
|
96
|
-
#end
|
97
|
-
#elem.rootFolder.folders.searchFolder.each do |folder|
|
98
|
-
#end
|
99
|
-
#elem.rootFolder.folders.tasksFolder.each do |folder|
|
100
|
-
#end
|
101
|
-
end
|
102
|
-
return @folders
|
103
|
-
end
|
104
|
-
|
105
|
-
# Return folder
|
106
|
-
# The default is to return a folder that is a subclass of Folder from the
|
107
|
-
# SqliteDB, but if fetch_from_ews is set to true it will go out and return
|
108
|
-
# the FolderType object from EWS.
|
109
|
-
# Parameters:
|
110
|
-
# folder_ids: NonEmptyArrayOfBaseFolderIdsType or String if fetch_from_ews is not set
|
111
|
-
# fetch_from_ews: boolean
|
112
|
-
# folder_shape: DefaultShapeNamesType
|
113
|
-
def get_folder(folder_ids, fetch_from_ews = false, folder_shape = DefaultShapeNamesType::AllProperties)
|
114
|
-
unless fetch_from_ews
|
115
|
-
return @folders['MailFolder'][folder_ids] ||
|
116
|
-
@folders['CalendarFolder'][folder_ids]
|
117
|
-
end
|
118
|
-
|
119
|
-
folder_shape = FolderResponseShapeType.new( folder_shape )
|
120
|
-
get_folder = GetFolderType.new(folder_shape, folder_ids)
|
121
|
-
|
122
|
-
resp = @ews.getFolder(get_folder).responseMessages.getFolderResponseMessage[0].folders.folder[0]
|
123
|
-
end
|
124
|
-
|
125
|
-
# Parameters:
|
126
|
-
# display_name: String
|
127
|
-
# fetch_from_ews: boolean
|
128
|
-
# folder_shape: DefaultShapeNamesType
|
129
|
-
def get_folder_by_name(display_name, fetch_from_ews = true, folder_shape = DefaultShapeNamesType::AllProperties)
|
130
|
-
#folder_ids = NonEmptyArrayOfBaseFolderIdsType.new()
|
131
|
-
dist_name = DistinguishedFolderIdType.new
|
132
|
-
dist_name.xmlattr_Id = DistinguishedFolderIdNameType.new(display_name.downcase)
|
133
|
-
#folder_ids.distinguishedFolderId = dist_name
|
134
|
-
folder_ids = NonEmptyArrayOfBaseFolderIdsType.new(nil, [dist_name])
|
135
|
-
|
136
|
-
get_folder(folder_ids, true, folder_shape)
|
137
|
-
end
|
138
|
-
|
139
|
-
# Parameters:
|
140
|
-
# folder_id: String
|
141
|
-
# change_key: String
|
142
|
-
# folder_shape: DefaultShapeNamesType
|
143
|
-
def get_folder_by_id(folder_id, change_key = nil, fetch_from_ews = true, folder_shape = DefaultShapeNamesType::AllProperties)
|
144
|
-
folder_ids = NonEmptyArrayOfBaseFolderIdsType.new()
|
145
|
-
folder_id_t = FolderIdType.new
|
146
|
-
folder_id_t.xmlattr_Id = folder_id
|
147
|
-
folder_id_t.xmlattr_ChangeKey = change_key unless change_key == nil
|
148
|
-
folder_ids.folderId = folder_id
|
149
|
-
folder_ids = NonEmptyArrayOfBaseFolderIdsType.new([folder_id_t], nil)
|
150
|
-
|
151
|
-
get_folder(folder_ids, true, folder_shape)
|
152
|
-
end
|
153
|
-
|
154
|
-
def get_mail_folders
|
155
|
-
return @folders['MailFolder']
|
156
|
-
end
|
157
|
-
|
158
|
-
def get_calendar_folders
|
159
|
-
return @folders['CalendarFolder']
|
160
|
-
end
|
161
|
-
|
162
|
-
def authenticate(user = nil, pass = nil, endpoint = nil)
|
163
|
-
unless @authenticated
|
164
|
-
@user = user
|
165
|
-
@pass = pass
|
166
|
-
@ews_endpoint = endpoint
|
167
|
-
do_auth unless @authenticated
|
168
|
-
end
|
169
|
-
@authenticated
|
170
|
-
end
|
171
|
-
|
172
|
-
private
|
173
|
-
def do_auth
|
174
|
-
retry_count = 0
|
175
|
-
begin
|
176
|
-
if( File.exists?("#{ENV['HOME']}/.viewpointrc") )
|
177
|
-
props = SOAP::Property.load(File.new("#{ENV['HOME']}/.viewpointrc"))
|
178
|
-
@user = props['exchange.ews.user'] if @user == nil
|
179
|
-
@pass = props['exchange.ews.pass'] if @pass == nil
|
180
|
-
@ews_endpoint = props['exchange.ews.endpoint'] if @ews_endpoint == nil
|
181
|
-
elsif( File.exists?("#{File.dirname(__FILE__)}/soap/viewpoint.conf") )
|
182
|
-
props = SOAP::Property.load(File.new("#{File.dirname(__FILE__)}/soap/viewpoint.conf"))
|
183
|
-
@user = props['exchange.ews.user'] if @user == nil
|
184
|
-
@pass = props['exchange.ews.pass'] if @pass == nil
|
185
|
-
@ews_endpoint = props['exchange.ews.endpoint'] if @ews_endpoint == nil
|
186
|
-
elsif(@ews_endpoint == nil && @user == nil && @pass == nil)
|
187
|
-
@ews_endpoint = ask("Exchange EWS Endpoint: ") { |q| q.echo = true }
|
188
|
-
@user = ask("User: ") { |q| q.echo = true }
|
189
|
-
@pass = ask("Pass: ") { |q| q.echo = "*"}
|
190
|
-
else
|
191
|
-
# Nothing to do
|
192
|
-
end
|
193
|
-
|
194
|
-
@ews = ExchangeServiceBinding.new(@ews_endpoint)
|
195
|
-
@ews.options["protocol.http.auth.ntlm"] = [@ews_endpoint.sub(/\/[^\/]+$/,'/'),@user,@pass]
|
196
|
-
@ews.headerhandler << ExchangeHeaders.new
|
197
|
-
|
198
|
-
# Log SOAP request and response for debugging. Run ruby with the '-d' option.
|
199
|
-
if($DEBUG) then
|
200
|
-
@ews.wiredump_file_base = "viewpoint-soaplog"
|
201
|
-
end
|
202
|
-
|
203
|
-
# Do a ResolveNames operation to make sure that authentication works.
|
204
|
-
# If you don't do an operation, you won't find out that bad credentials
|
205
|
-
# were entered until later. The ResolveNames operation is completely
|
206
|
-
# arbitrary and could be any EWS call.
|
207
|
-
# http://msdn.microsoft.com/en-us/library/bb409286.aspx
|
208
|
-
rnt = ResolveNamesType.new(nil,@user)
|
209
|
-
rnt.xmlattr_ReturnFullContactData = false
|
210
|
-
ews.resolveNames(rnt)
|
211
|
-
|
212
|
-
rescue SOAP::HTTPStreamError
|
213
|
-
puts "Bad Login! Try Again."
|
214
|
-
if( retry_count < 2)
|
215
|
-
retry_count += 1
|
216
|
-
retry
|
217
|
-
else
|
218
|
-
puts "-----------------------------------------------------------"
|
219
|
-
puts "Could not log into Exchange Web Services. Make sure your information is correct"
|
220
|
-
puts "End Point: #{@ews_endpoint}"
|
221
|
-
puts "User: #{@user}"
|
222
|
-
puts "-----------------------------------------------------------"
|
223
|
-
return
|
224
|
-
end
|
225
|
-
end
|
226
|
-
@authenticated = true
|
227
|
-
end
|
228
|
-
end
|
data/lib/viewpoint.rb
CHANGED
File without changes
|
@@ -0,0 +1,233 @@
|
|
1
|
+
#############################################################################
|
2
|
+
# Copyright © 2009 Dan Wanek <dan.wanek@gmail.com>
|
3
|
+
#
|
4
|
+
#
|
5
|
+
# This file is part of Viewpoint.
|
6
|
+
#
|
7
|
+
# Viewpoint is free software: you can redistribute it and/or
|
8
|
+
# modify it under the terms of the GNU General Public License as published
|
9
|
+
# by the Free Software Foundation, either version 3 of the License, or (at
|
10
|
+
# your option) any later version.
|
11
|
+
#
|
12
|
+
# Viewpoint is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
15
|
+
# Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License along
|
18
|
+
# with Viewpoint. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#############################################################################
|
20
|
+
$:.unshift(File.dirname(__FILE__))
|
21
|
+
require 'rubygems'
|
22
|
+
#require 'highline/import'
|
23
|
+
require 'singleton'
|
24
|
+
require 'wsdl/exchangeServiceBinding'
|
25
|
+
# --- Custom libs ---
|
26
|
+
require 'exchange_headers'
|
27
|
+
# --- Folder Types ---
|
28
|
+
require 'folder'
|
29
|
+
require 'calendar'
|
30
|
+
require 'mail'
|
31
|
+
|
32
|
+
# This class will act as the controller for a client connection to the
|
33
|
+
# Exchange web service.
|
34
|
+
class Viewpoint::ExchWebServ
|
35
|
+
include Viewpoint
|
36
|
+
include Singleton
|
37
|
+
|
38
|
+
attr_reader :ews, :user, :authenticated
|
39
|
+
|
40
|
+
def initialize
|
41
|
+
@authenticated = false
|
42
|
+
@user = nil
|
43
|
+
@pass = nil
|
44
|
+
@ews_endpoint = nil
|
45
|
+
|
46
|
+
# Connection to Exchange web services.
|
47
|
+
# You can get fetch this from an accessor later.
|
48
|
+
@ews = nil
|
49
|
+
|
50
|
+
# Stores folders returned from 'find_folders'
|
51
|
+
@folders = {}
|
52
|
+
|
53
|
+
# Do initial authentication
|
54
|
+
#do_auth
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
# Finds all folders and returns a hash of FolderTypes
|
59
|
+
def find_folders
|
60
|
+
ff = FindFolderType.new()
|
61
|
+
ff.xmlattr_Traversal = FolderQueryTraversalType::Deep
|
62
|
+
ff.folderShape = FolderResponseShapeType.new( DefaultShapeNamesType::AllProperties )
|
63
|
+
fid = NonEmptyArrayOfBaseFolderIdsType.new()
|
64
|
+
fidt = DistinguishedFolderIdType.new
|
65
|
+
fidt.xmlattr_Id = DistinguishedFolderIdNameType::Root
|
66
|
+
fid.distinguishedFolderId = fidt
|
67
|
+
ff.parentFolderIds = fid
|
68
|
+
|
69
|
+
# FindFolderResponseType
|
70
|
+
resp = @ews.findFolder(ff)
|
71
|
+
|
72
|
+
# ArrayOfResponseMessagesType
|
73
|
+
msgs = resp.responseMessages
|
74
|
+
|
75
|
+
# Array of FindFolderResponseMessageType
|
76
|
+
msgs.findFolderResponseMessage.each do |elem|
|
77
|
+
# Mail Folders
|
78
|
+
mail_folders = {}
|
79
|
+
elem.rootFolder.folders.folder.each do |folder|
|
80
|
+
if( folder.folderClass != nil)
|
81
|
+
mail_folders[folder.displayName] = MailFolder.new(folder)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
@folders['MailFolder'] = mail_folders
|
85
|
+
|
86
|
+
# CalendarFolderType
|
87
|
+
cal_folders = {}
|
88
|
+
elem.rootFolder.folders.calendarFolder.each do |folder|
|
89
|
+
cal_folders[folder.displayName] = CalendarFolder.new(folder)
|
90
|
+
end
|
91
|
+
@folders['CalendarFolder'] = cal_folders
|
92
|
+
|
93
|
+
#elem.rootFolder.folders.contactsFolder.each do |folder|
|
94
|
+
#end
|
95
|
+
#elem.rootFolder.folders.searchFolder.each do |folder|
|
96
|
+
#end
|
97
|
+
#elem.rootFolder.folders.tasksFolder.each do |folder|
|
98
|
+
#end
|
99
|
+
end
|
100
|
+
return @folders
|
101
|
+
end
|
102
|
+
|
103
|
+
# Return folder
|
104
|
+
# The default is to return a folder that is a subclass of Folder from the
|
105
|
+
# SqliteDB, but if fetch_from_ews is set to true it will go out and return
|
106
|
+
# the FolderType object from EWS.
|
107
|
+
# Parameters:
|
108
|
+
# folder_ids: NonEmptyArrayOfBaseFolderIdsType or String if fetch_from_ews is not set
|
109
|
+
# fetch_from_ews: boolean
|
110
|
+
# folder_shape: DefaultShapeNamesType
|
111
|
+
def get_folder(folder_ids, fetch_from_ews = false, folder_shape = DefaultShapeNamesType::AllProperties)
|
112
|
+
unless fetch_from_ews
|
113
|
+
return @folders['MailFolder'][folder_ids] ||
|
114
|
+
@folders['CalendarFolder'][folder_ids]
|
115
|
+
end
|
116
|
+
|
117
|
+
folder_shape = FolderResponseShapeType.new( folder_shape )
|
118
|
+
get_folder = GetFolderType.new(folder_shape, folder_ids)
|
119
|
+
|
120
|
+
resp = @ews.getFolder(get_folder).responseMessages.getFolderResponseMessage[0].folders.folder[0]
|
121
|
+
end
|
122
|
+
|
123
|
+
# Parameters:
|
124
|
+
# display_name: String
|
125
|
+
# fetch_from_ews: boolean
|
126
|
+
# folder_shape: DefaultShapeNamesType
|
127
|
+
def get_folder_by_name(display_name, fetch_from_ews = true, folder_shape = DefaultShapeNamesType::AllProperties)
|
128
|
+
#folder_ids = NonEmptyArrayOfBaseFolderIdsType.new()
|
129
|
+
dist_name = DistinguishedFolderIdType.new
|
130
|
+
dist_name.xmlattr_Id = DistinguishedFolderIdNameType.new(display_name.downcase)
|
131
|
+
#folder_ids.distinguishedFolderId = dist_name
|
132
|
+
folder_ids = NonEmptyArrayOfBaseFolderIdsType.new(nil, [dist_name])
|
133
|
+
|
134
|
+
get_folder(folder_ids, true, folder_shape)
|
135
|
+
end
|
136
|
+
|
137
|
+
# Parameters:
|
138
|
+
# folder_id: String
|
139
|
+
# change_key: String
|
140
|
+
# folder_shape: DefaultShapeNamesType
|
141
|
+
def get_folder_by_id(folder_id, change_key = nil, fetch_from_ews = true, folder_shape = DefaultShapeNamesType::AllProperties)
|
142
|
+
folder_ids = NonEmptyArrayOfBaseFolderIdsType.new()
|
143
|
+
folder_id_t = FolderIdType.new
|
144
|
+
folder_id_t.xmlattr_Id = folder_id
|
145
|
+
folder_id_t.xmlattr_ChangeKey = change_key unless change_key == nil
|
146
|
+
folder_ids.folderId = folder_id
|
147
|
+
folder_ids = NonEmptyArrayOfBaseFolderIdsType.new([folder_id_t], nil)
|
148
|
+
|
149
|
+
get_folder(folder_ids, true, folder_shape)
|
150
|
+
end
|
151
|
+
|
152
|
+
def get_mail_folders
|
153
|
+
return @folders['MailFolder']
|
154
|
+
end
|
155
|
+
|
156
|
+
def get_calendar_folders
|
157
|
+
return @folders['CalendarFolder']
|
158
|
+
end
|
159
|
+
|
160
|
+
def authenticate(user = nil, pass = nil, endpoint = nil)
|
161
|
+
unless @authenticated
|
162
|
+
@user = user
|
163
|
+
@pass = pass
|
164
|
+
@ews_endpoint = endpoint
|
165
|
+
do_auth unless @authenticated
|
166
|
+
end
|
167
|
+
@authenticated
|
168
|
+
end
|
169
|
+
|
170
|
+
|
171
|
+
# Resolve a Contact name.
|
172
|
+
# More info: http://msdn.microsoft.com/en-us/library/aa563518.aspx
|
173
|
+
def resolve_name(unresolved_entry, full_contact_data = false)
|
174
|
+
rn_t = ResolveNamesType.new(nil,unresolved_entry)
|
175
|
+
rn_t.xmlattr_ReturnFullContactData = full_contact_data
|
176
|
+
ews.resolveNames(rn_t).responseMessages.resolveNamesResponseMessage.first
|
177
|
+
end
|
178
|
+
|
179
|
+
private
|
180
|
+
def do_auth
|
181
|
+
retry_count = 0
|
182
|
+
begin
|
183
|
+
if( File.exists?("#{ENV['HOME']}/.viewpointrc") )
|
184
|
+
props = SOAP::Property.load(File.new("#{ENV['HOME']}/.viewpointrc"))
|
185
|
+
@user = props['exchange.ews.user'] if @user == nil
|
186
|
+
@pass = props['exchange.ews.pass'] if @pass == nil
|
187
|
+
@ews_endpoint = props['exchange.ews.endpoint'] if @ews_endpoint == nil
|
188
|
+
elsif( File.exists?("#{File.dirname(__FILE__)}/soap/viewpoint.conf") )
|
189
|
+
props = SOAP::Property.load(File.new("#{File.dirname(__FILE__)}/soap/viewpoint.conf"))
|
190
|
+
@user = props['exchange.ews.user'] if @user == nil
|
191
|
+
@pass = props['exchange.ews.pass'] if @pass == nil
|
192
|
+
@ews_endpoint = props['exchange.ews.endpoint'] if @ews_endpoint == nil
|
193
|
+
elsif(@ews_endpoint == nil && @user == nil && @pass == nil)
|
194
|
+
@ews_endpoint = ask("Exchange EWS Endpoint: ") { |q| q.echo = true }
|
195
|
+
@user = ask("User: ") { |q| q.echo = true }
|
196
|
+
@pass = ask("Pass: ") { |q| q.echo = "*"}
|
197
|
+
else
|
198
|
+
# Nothing to do
|
199
|
+
end
|
200
|
+
|
201
|
+
@ews = ExchangeServiceBinding.new(@ews_endpoint)
|
202
|
+
@ews.options["protocol.http.auth.ntlm"] = [@ews_endpoint.sub(/\/[^\/]+$/,'/'),@user,@pass]
|
203
|
+
@ews.headerhandler << ExchangeHeaders.new
|
204
|
+
|
205
|
+
# Log SOAP request and response for debugging. Run ruby with the '-d' option.
|
206
|
+
if($DEBUG) then
|
207
|
+
@ews.wiredump_file_base = "viewpoint-soaplog"
|
208
|
+
end
|
209
|
+
|
210
|
+
# Do a ResolveNames operation to make sure that authentication works.
|
211
|
+
# If you don't do an operation, you won't find out that bad credentials
|
212
|
+
# were entered until later. The ResolveNames operation is completely
|
213
|
+
# arbitrary and could be any EWS call.
|
214
|
+
# http://msdn.microsoft.com/en-us/library/bb409286.aspx
|
215
|
+
resolve_name(@user)
|
216
|
+
|
217
|
+
rescue SOAP::HTTPStreamError
|
218
|
+
puts "Bad Login! Try Again."
|
219
|
+
if( retry_count < 2)
|
220
|
+
retry_count += 1
|
221
|
+
retry
|
222
|
+
else
|
223
|
+
puts "-----------------------------------------------------------"
|
224
|
+
puts "Could not log into Exchange Web Services. Make sure your information is correct"
|
225
|
+
puts "End Point: #{@ews_endpoint}"
|
226
|
+
puts "User: #{@user}"
|
227
|
+
puts "-----------------------------------------------------------"
|
228
|
+
return
|
229
|
+
end
|
230
|
+
end
|
231
|
+
@authenticated = true
|
232
|
+
end
|
233
|
+
end
|
@@ -18,7 +18,6 @@
|
|
18
18
|
# with Viewpoint. If not, see <http://www.gnu.org/licenses/>.
|
19
19
|
#############################################################################
|
20
20
|
require 'rubygems'
|
21
|
-
require 'viewpoint'
|
22
21
|
|
23
22
|
# This class is inherited by all folder subtypes such as Mail, Calendar,
|
24
23
|
# Tasks and Search. It will serve as the brain for all of the methods that
|
@@ -17,7 +17,6 @@
|
|
17
17
|
# You should have received a copy of the GNU General Public License along
|
18
18
|
# with Viewpoint. If not, see <http://www.gnu.org/licenses/>.
|
19
19
|
#############################################################################
|
20
|
-
require 'viewpoint'
|
21
20
|
|
22
21
|
|
23
22
|
# This class is inherited by all Item subtypes such as Message, Event,
|
@@ -25,8 +25,6 @@ require 'folder'
|
|
25
25
|
# --- Item Types ---
|
26
26
|
require 'message'
|
27
27
|
|
28
|
-
require 'viewpoint'
|
29
|
-
|
30
28
|
|
31
29
|
class Viewpoint::MailFolder < Viewpoint::Folder
|
32
30
|
include Viewpoint
|
@@ -97,16 +95,13 @@ class Viewpoint::MailFolder < Viewpoint::Folder
|
|
97
95
|
|
98
96
|
resp = find_items(find_item_t)
|
99
97
|
|
98
|
+
messages = []
|
100
99
|
if resp != nil
|
101
|
-
messages = []
|
102
100
|
resp.rootFolder.items.message.each do |msg|
|
103
101
|
messages << Message.new(msg, self)
|
104
102
|
end
|
105
|
-
|
106
|
-
return messages
|
107
|
-
else
|
108
|
-
return resp
|
109
103
|
end
|
104
|
+
return messages
|
110
105
|
|
111
106
|
end
|
112
107
|
|
File without changes
|
File without changes
|
@@ -0,0 +1,37 @@
|
|
1
|
+
$: << File.dirname(__FILE__) + '/../../lib/'
|
2
|
+
require 'viewpoint'
|
3
|
+
|
4
|
+
describe "Test the basic features of Viewpoint" do
|
5
|
+
before(:all) do
|
6
|
+
@vp = Viewpoint::ExchWebServ.instance
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should have set authenticated to true" do
|
10
|
+
@vp.authenticate.should be_true
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should find all the EWS folders" do
|
14
|
+
@vp.find_folders.should be_an_instance_of(Hash)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should resolve the name" do
|
18
|
+
# Most systems have some sort of admin user defined.
|
19
|
+
# Change this to suit your needs.
|
20
|
+
name = "admin"
|
21
|
+
@vp.resolve_name(name).should be_an_instance_of(ResolveNamesResponseMessageType)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should retrieve all of todays messages" do
|
25
|
+
inbox = @vp.get_folder("Inbox")
|
26
|
+
messages = inbox.get_todays_messages
|
27
|
+
messages.should be_an_instance_of(Array)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should take the last message of the day and output it in rfc822" do
|
31
|
+
inbox = @vp.get_folder("Inbox")
|
32
|
+
messages = inbox.get_todays_messages
|
33
|
+
messages.should be_an_instance_of(Array)
|
34
|
+
messages.last.to_rfc822.should be_an_instance_of(String)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
data/test/test_client.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: viewpoint
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Wanek
|
@@ -11,8 +11,27 @@ cert_chain: []
|
|
11
11
|
|
12
12
|
date: 2009-11-09 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: soap4r
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.5.8
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: icalendar
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
16
35
|
description: " \tA Ruby client access library for Microsoft Exchange Web Services (EWS). It is a work in progress. Methods are still being added from the EWS API docs. Please see them for further information: http://msdn.microsoft.com/en-us/library/bb204119.aspx\n"
|
17
36
|
email: dan.wanek@gmail.com
|
18
37
|
executables: []
|
@@ -26,6 +45,7 @@ files:
|
|
26
45
|
- COPYING.txt
|
27
46
|
- README
|
28
47
|
- Rakefile
|
48
|
+
- VERSION
|
29
49
|
- examples/cal2ical.rb
|
30
50
|
- examples/ews_fusefs.rb
|
31
51
|
- examples/webclient/.gems
|
@@ -72,25 +92,25 @@ files:
|
|
72
92
|
- examples/webclient/views/layout.haml
|
73
93
|
- examples/webclient/views/mail.haml
|
74
94
|
- examples/webclient/views/welcome.haml
|
75
|
-
- lib/calendar.rb
|
76
|
-
- lib/calendar_item.rb
|
77
|
-
- lib/event.rb
|
78
|
-
- lib/exchange_headers.rb
|
79
95
|
- lib/exchwebserv.rb
|
80
|
-
- lib/folder.rb
|
81
|
-
- lib/item.rb
|
82
|
-
- lib/mail.rb
|
83
|
-
- lib/message.rb
|
84
96
|
- lib/soap/viewpoint.conf
|
85
|
-
- lib/task.rb
|
86
|
-
- lib/tasks.rb
|
87
97
|
- lib/viewpoint.rb
|
98
|
+
- lib/viewpoint/calendar.rb
|
99
|
+
- lib/viewpoint/calendar_item.rb
|
100
|
+
- lib/viewpoint/event.rb
|
101
|
+
- lib/viewpoint/exchange_headers.rb
|
102
|
+
- lib/viewpoint/exchwebserv.rb
|
103
|
+
- lib/viewpoint/folder.rb
|
104
|
+
- lib/viewpoint/item.rb
|
105
|
+
- lib/viewpoint/mail.rb
|
106
|
+
- lib/viewpoint/message.rb
|
107
|
+
- lib/viewpoint/task.rb
|
108
|
+
- lib/viewpoint/tasks.rb
|
88
109
|
- lib/wsdl/defaultMappingRegistry.rb
|
89
110
|
- lib/wsdl/exchangeServiceBinding.rb
|
90
111
|
- lib/wsdl/exchangeServiceTypes.rb
|
91
112
|
- preamble
|
92
|
-
- test/spec/
|
93
|
-
- test/spec/findfolders_spec.rb
|
113
|
+
- test/spec/basic_features_spec.rb
|
94
114
|
- test/test_client.rb
|
95
115
|
- test/testrestrict.rb
|
96
116
|
has_rdoc: true
|
data/test/spec/authtest_spec.rb
DELETED