viewpoint 0.0.1 → 0.0.2
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 +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