viewpoint 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 +2 -0
- data/Rakefile +9 -0
- data/TODO +2 -0
- data/VERSION +1 -1
- data/lib/exceptions/exceptions.rb +4 -0
- data/lib/model/attachment.rb +33 -0
- data/lib/model/calendar_folder.rb +24 -0
- data/lib/model/calendar_item.rb +0 -1
- data/lib/model/file_attachment.rb +54 -0
- data/lib/model/folder.rb +24 -0
- data/lib/model/generic_folder.rb +5 -5
- data/lib/model/item.rb +27 -1
- data/lib/model/item_attachment.rb +34 -0
- data/lib/model/mailbox_user.rb +13 -0
- data/lib/model/task.rb +31 -0
- data/lib/model/tasks_folder.rb +25 -0
- data/lib/soap/handsoap/builders/ews_build_helpers.rb +12 -0
- data/lib/soap/handsoap/builders/ews_builder.rb +11 -0
- data/lib/soap/handsoap/ews_service.rb +62 -14
- data/lib/soap/handsoap/parser.rb +1 -2
- data/lib/soap/handsoap/parsers/ews_parser.rb +17 -0
- data/lib/soap/soap_provider.rb +0 -7
- data/lib/viewpoint.rb +3 -0
- data/test/{spec/spec.opts → .rspec} +0 -0
- metadata +7 -4
data/README
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
--------------------------------------------------------------------------
|
2
2
|
Viewpoint for Exchange Web Services
|
3
|
+
http://github.com/zenchild/Viewpoint/wiki
|
3
4
|
--------------------------------------------------------------------------
|
4
5
|
This program attempts to create a client access library for Exchange Web
|
5
6
|
Services (EWS) in Ruby.
|
@@ -14,6 +15,7 @@ them or they are asked for.
|
|
14
15
|
|
15
16
|
BLOG: http://distributed-frostbite.blogspot.com/
|
16
17
|
Add me in LinkedIn: http://www.linkedin.com/in/danwanek
|
18
|
+
Find me on irc.freenode.net in #ruby-lang (zenChild)
|
17
19
|
|
18
20
|
--------------------------------------------------------------------------
|
19
21
|
MAJOR CHANGES TO THE FIRST VERSION:
|
data/Rakefile
CHANGED
@@ -2,6 +2,7 @@ require 'rubygems'
|
|
2
2
|
require 'rake/clean'
|
3
3
|
require 'rake/gempackagetask'
|
4
4
|
require 'date'
|
5
|
+
require 'metric_fu'
|
5
6
|
|
6
7
|
CLEAN.include("pkg")
|
7
8
|
CLEAN.include("doc")
|
@@ -67,3 +68,11 @@ def up_min_version
|
|
67
68
|
f.write(ver)
|
68
69
|
ver
|
69
70
|
end
|
71
|
+
|
72
|
+
MetricFu::Configuration.run do |config|
|
73
|
+
#define which metrics you want to use
|
74
|
+
# config.metrics = [:churn, :saikuro, :stats, :flog, :flay]
|
75
|
+
config.metrics = [:flog, :flay]
|
76
|
+
config.graphs = [:flog, :flay]
|
77
|
+
end
|
78
|
+
|
data/TODO
CHANGED
@@ -6,3 +6,5 @@
|
|
6
6
|
raise the NoMethod error
|
7
7
|
|
8
8
|
- Clean-up exceptions. There is exception raising in the Model that will never ocurr because it is already being checked for in the Parser
|
9
|
+
|
10
|
+
- Refactor #find_folders methods. There is a lot of duplicate code right now and it could be simplified quite a bit.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.3
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#############################################################################
|
2
|
+
# Copyright © 2010 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
|
+
|
21
|
+
module Viewpoint
|
22
|
+
module EWS
|
23
|
+
# A generic Attachment. This class should not be instantiated directly. You
|
24
|
+
# should use one of the subclasses like FileAttachment or ItemAttachment.
|
25
|
+
class Attachment
|
26
|
+
include Model
|
27
|
+
|
28
|
+
# All Attachment types will have an id.
|
29
|
+
attr_reader :id
|
30
|
+
|
31
|
+
end # Attachment
|
32
|
+
end # EWS
|
33
|
+
end # Viewpoint
|
@@ -22,6 +22,30 @@ module Viewpoint
|
|
22
22
|
module EWS
|
23
23
|
class CalendarFolder < GenericFolder
|
24
24
|
|
25
|
+
# Find Calendar subfolders of the passed root folder. If no parameters are passed
|
26
|
+
# this method will search from the Root folder.
|
27
|
+
# @param [Str] root An folder id, either a DistinguishedFolderId (must me a Symbol)
|
28
|
+
# or a FolderId (String)
|
29
|
+
# @param [String] traversal Shallow/Deep/SoftDeleted
|
30
|
+
# @return [Array] Returns an Array of Folder or subclasses of Folder
|
31
|
+
def self.find_folders(root = :msgfolderroot, traversal = 'Deep', shape = 'Default')
|
32
|
+
restr = {:restriction =>
|
33
|
+
{:is_equal_to => {:field_uRI => {:field_uRI=>'folder:FolderClass'},:field_uRI_or_constant=>{:constant => {:value => 'IPF.Appointment'}}}}
|
34
|
+
}
|
35
|
+
resp = (Viewpoint::EWS::EWS.instance).ews.find_folder( [normalize_id(root)], traversal, {:base_shape => shape}, restr)
|
36
|
+
if(resp.status == 'Success')
|
37
|
+
folders = []
|
38
|
+
resp.items.each do |f|
|
39
|
+
f_type = f.keys.first.to_s.camel_case
|
40
|
+
folders << (eval "#{f_type}.new(f[f.keys.first])")
|
41
|
+
end
|
42
|
+
return folders
|
43
|
+
else
|
44
|
+
raise EwsError, "Could not retrieve folders. #{resp.code}: #{resp.message}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
25
49
|
# initialize with an item of CalendarFolderType
|
26
50
|
def initialize(folder)
|
27
51
|
super(folder)
|
data/lib/model/calendar_item.rb
CHANGED
@@ -0,0 +1,54 @@
|
|
1
|
+
#############################################################################
|
2
|
+
# Copyright © 2010 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
|
+
|
21
|
+
module Viewpoint
|
22
|
+
module EWS
|
23
|
+
# This class represents a file attachment item. You can save this object
|
24
|
+
# to a file withthe #save_to_file method.
|
25
|
+
class FileAttachment < Attachment
|
26
|
+
|
27
|
+
# @param [String] attachment_id The unique ID for the attachment.
|
28
|
+
def initialize(attachment_id)
|
29
|
+
@id = attachment_id
|
30
|
+
conn = Viewpoint::EWS::EWS.instance
|
31
|
+
resp = conn.ews.get_attachment([attachment_id])
|
32
|
+
@file_name = resp.items.first[:file_attachment][:name][:text]
|
33
|
+
|
34
|
+
# content in Base64
|
35
|
+
@content = resp.items.first[:file_attachment][:content][:text]
|
36
|
+
end
|
37
|
+
|
38
|
+
# Save this FileAttachment object to a file. By default it saves
|
39
|
+
# it to the original file's name in the current working directory.
|
40
|
+
# @param [String,nil] base_dir the directory to save the file to. Pass nil if you
|
41
|
+
# do not want to specify a directory or you are passing a full path name to file_name
|
42
|
+
# @param [String] file_name The name of the file to save the content to.
|
43
|
+
# Leave this blank to use the default attachment name.
|
44
|
+
def save_to_file(base_dir = nil, file_name = @file_name)
|
45
|
+
base_dir << '/' unless(base_dir.nil? or base_dir.end_with?('/'))
|
46
|
+
File.open("#{base_dir}#{file_name}", 'w+') do |f|
|
47
|
+
f.write(Base64.decode64(@content))
|
48
|
+
end
|
49
|
+
true
|
50
|
+
end
|
51
|
+
|
52
|
+
end # FileAttachment
|
53
|
+
end # EWS
|
54
|
+
end # Viewpoint
|
data/lib/model/folder.rb
CHANGED
@@ -24,6 +24,30 @@ module Viewpoint
|
|
24
24
|
# This is the type of folder that mail messages will be found in.
|
25
25
|
class Folder < GenericFolder
|
26
26
|
|
27
|
+
# Find Message subfolders of the passed root folder. If no parameters are passed
|
28
|
+
# this method will search from the Root folder.
|
29
|
+
# @param [Str] root An folder id, either a DistinguishedFolderId (must me a Symbol)
|
30
|
+
# or a FolderId (String)
|
31
|
+
# @param [String] traversal Shallow/Deep/SoftDeleted
|
32
|
+
# @return [Array] Returns an Array of Folder or subclasses of Folder
|
33
|
+
def self.find_folders(root = :msgfolderroot, traversal = 'Deep', shape = 'Default')
|
34
|
+
restr = {:restriction =>
|
35
|
+
{:is_equal_to => {:field_uRI => {:field_uRI=>'folder:FolderClass'},:field_uRI_or_constant=>{:constant => {:value => 'IPF.Note'}}}}
|
36
|
+
}
|
37
|
+
resp = (Viewpoint::EWS::EWS.instance).ews.find_folder( [normalize_id(root)], traversal, {:base_shape => shape}, restr)
|
38
|
+
if(resp.status == 'Success')
|
39
|
+
folders = []
|
40
|
+
resp.items.each do |f|
|
41
|
+
f_type = f.keys.first.to_s.camel_case
|
42
|
+
folders << (eval "#{f_type}.new(f[f.keys.first])")
|
43
|
+
end
|
44
|
+
return folders
|
45
|
+
else
|
46
|
+
raise EwsError, "Could not retrieve folders. #{resp.code}: #{resp.message}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
27
51
|
# Initialize with an item of FolderType. This is typically the folder
|
28
52
|
# used to house mail messages.
|
29
53
|
def initialize(folder)
|
data/lib/model/generic_folder.rb
CHANGED
@@ -53,12 +53,12 @@ module Viewpoint
|
|
53
53
|
|
54
54
|
# Find subfolders of the passed root folder. If no parameters are passed
|
55
55
|
# this method will search from the Root folder.
|
56
|
-
# @param [
|
56
|
+
# @param [String,Symbol] root An folder id, either a DistinguishedFolderId (must me a Symbol)
|
57
57
|
# or a FolderId (String)
|
58
58
|
# @param [String] traversal Shallow/Deep/SoftDeleted
|
59
59
|
# @return [Array] Returns an Array of Folder or subclasses of Folder
|
60
|
-
def self.find_folders(root = :msgfolderroot, traversal = 'Shallow')
|
61
|
-
resp = (Viewpoint::EWS::EWS.instance).ews.find_folder( [normalize_id(root)], traversal )
|
60
|
+
def self.find_folders(root = :msgfolderroot, traversal = 'Shallow', shape = 'Default')
|
61
|
+
resp = (Viewpoint::EWS::EWS.instance).ews.find_folder( [normalize_id(root)], traversal, {:base_shape => shape} )
|
62
62
|
if(resp.status == 'Success')
|
63
63
|
folders = []
|
64
64
|
resp.items.each do |f|
|
@@ -88,13 +88,13 @@ module Viewpoint
|
|
88
88
|
|
89
89
|
# Gets a folder by name. This name must match the folder name exactly.
|
90
90
|
# @param [String] name The name of the folder to fetch.
|
91
|
-
def self.get_folder_by_name(name)
|
91
|
+
def self.get_folder_by_name(name, shape = 'Default')
|
92
92
|
# For now the :field_uRI and :field_uRI_or_constant must be in an Array for Ruby 1.8.7 because Hashes
|
93
93
|
# are not positional at insertion until 1.9
|
94
94
|
restr = {:restriction =>
|
95
95
|
{:is_equal_to =>
|
96
96
|
[{:field_uRI => {:field_uRI=>'folder:DisplayName'}}, {:field_uRI_or_constant =>{:constant => {:value=>name}}}]}}
|
97
|
-
resp = (Viewpoint::EWS::EWS.instance).ews.find_folder([:msgfolderroot], '
|
97
|
+
resp = (Viewpoint::EWS::EWS.instance).ews.find_folder([:msgfolderroot], 'Deep', {:base_shape => shape}, restr)
|
98
98
|
if(resp.status == 'Success')
|
99
99
|
f = resp.items.first
|
100
100
|
f_type = f.keys.first.to_s.camel_case
|
data/lib/model/item.rb
CHANGED
@@ -72,6 +72,7 @@ module Viewpoint
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def deepen!
|
75
|
+
return true unless @shallow
|
75
76
|
conn = Viewpoint::EWS::EWS.instance
|
76
77
|
resp = conn.ews.get_item([@item_id], {:base_shape => 'AllProperties'})
|
77
78
|
resp = resp.items.shift
|
@@ -80,6 +81,7 @@ module Viewpoint
|
|
80
81
|
@ews_methods = []
|
81
82
|
@ews_methods_undef = []
|
82
83
|
init_methods
|
84
|
+
true
|
83
85
|
end
|
84
86
|
|
85
87
|
# Move this item to a new folder
|
@@ -113,6 +115,25 @@ module Viewpoint
|
|
113
115
|
end
|
114
116
|
end
|
115
117
|
|
118
|
+
# Return the attachments for this Item
|
119
|
+
# @return [Array,Attachment] An array of Attachments for this Item
|
120
|
+
def attachments
|
121
|
+
return [] unless has_attachments?
|
122
|
+
deepen!
|
123
|
+
attmts = []
|
124
|
+
@ews_item[:attachments].each_pair do |k,v|
|
125
|
+
# k should be file_attachment or item_attachment
|
126
|
+
if(v.is_a?(Hash))
|
127
|
+
attmts << (eval "#{k.to_s.camel_case}.new(v[:attachment_id][:id])")
|
128
|
+
else
|
129
|
+
v.each do |att|
|
130
|
+
attmts << (eval "#{k.to_s.camel_case}.new(att[:attachment_id][:id])")
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
attmts
|
135
|
+
end
|
136
|
+
|
116
137
|
# Delete this item
|
117
138
|
# @param [Boolean] soft Whether or not to do a soft delete. By default EWS will do a
|
118
139
|
# hard delete of this item. See the MSDN docs for more info:
|
@@ -166,7 +187,12 @@ module Viewpoint
|
|
166
187
|
end
|
167
188
|
|
168
189
|
def method_missing(m, *args, &block)
|
169
|
-
|
190
|
+
if(@shallow)
|
191
|
+
deepen!
|
192
|
+
send(m, *args, &block)
|
193
|
+
else
|
194
|
+
warn "!!! No such method: #{m}"
|
195
|
+
end
|
170
196
|
end
|
171
197
|
|
172
198
|
end # Item
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#############################################################################
|
2
|
+
# Copyright © 2010 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
|
+
|
21
|
+
module Viewpoint
|
22
|
+
module EWS
|
23
|
+
# An attachment that represents an attachment to another Exchange Item.
|
24
|
+
# This is not yet implemented.
|
25
|
+
class ItemAttachment < Attachment
|
26
|
+
|
27
|
+
# @param [String] attachment_id The unique ID for the attachment.
|
28
|
+
def initialize(attachment_id)
|
29
|
+
raise EwsNotImplemented, "ItemAttachments are not yet implemented in Viewpoint"
|
30
|
+
end
|
31
|
+
|
32
|
+
end # ItemAttachment
|
33
|
+
end # EWS
|
34
|
+
end # Viewpoint
|
data/lib/model/mailbox_user.rb
CHANGED
@@ -52,6 +52,19 @@ module Viewpoint
|
|
52
52
|
@ews_item = mbox_user
|
53
53
|
define_str_var :name, :email_address, :routing_type, :mailbox_type, :item_id
|
54
54
|
end
|
55
|
+
|
56
|
+
def get_oof
|
57
|
+
mailbox = {:mailbox => {:address => {:text => email_address}}}
|
58
|
+
resp = (Viewpoint::EWS::EWS.instance).ews.get_user_oof_settings(mailbox)
|
59
|
+
s = resp[:oof_settings]
|
60
|
+
@oof_state = s[:oof_state][:text]
|
61
|
+
@oof_ext_audience = s[:external_audience][:text]
|
62
|
+
@oof_start = DateTime.parse(s[:duration][:start_time][:text])
|
63
|
+
@oof_end = DateTime.parse(s[:duration][:end_time][:text])
|
64
|
+
@oof_internal_reply = s[:internal_reply][:message][:text]
|
65
|
+
@oof_external_reply = s[:internal_reply][:message][:text]
|
66
|
+
true
|
67
|
+
end
|
55
68
|
|
56
69
|
# Adds one or more delegates to a principal's mailbox and sets specific access permissions
|
57
70
|
# @see http://msdn.microsoft.com/en-us/library/bb856527.aspx
|
data/lib/model/task.rb
CHANGED
@@ -51,6 +51,37 @@ module Viewpoint
|
|
51
51
|
super(ews_item)
|
52
52
|
end
|
53
53
|
|
54
|
+
# Delete this item
|
55
|
+
# @param [Boolean] soft Whether or not to do a soft delete. By default EWS will do a
|
56
|
+
# hard delete of this item. See the MSDN docs for more info:
|
57
|
+
# http://msdn.microsoft.com/en-us/library/aa562961.aspx
|
58
|
+
# @param [String, nil] affected_task_occurrences "AllOccurrences/SpecifiedOccurrenceOnly"
|
59
|
+
# Default is AllOccurrences
|
60
|
+
# If you use 'SpecifiedOccurrenceOnly' on a non-reocurring task you will receive and error.
|
61
|
+
# @return [Boolean] Whether or not the item was deleted
|
62
|
+
# @todo Add exception handling for failed deletes
|
63
|
+
#
|
64
|
+
def delete!(soft=false, affected_task_occurrences='AllOccurrences')
|
65
|
+
deltype = soft ? 'SoftDelete' : 'HardDelete'
|
66
|
+
resp = (Viewpoint::EWS::EWS.instance).ews.delete_item([@item_id], deltype, nil, affected_task_occurrences)
|
67
|
+
self.clear_object!
|
68
|
+
resp.status == 'Success'
|
69
|
+
end
|
70
|
+
|
71
|
+
# Delete this item by moving it to the Deleted Items folder
|
72
|
+
# @see http://msdn.microsoft.com/en-us/library/aa562961.aspx
|
73
|
+
# @param [String, nil] affected_task_occurrences "AllOccurrences/SpecifiedOccurrenceOnly"
|
74
|
+
# Default is AllOccurrences
|
75
|
+
# If you use 'SpecifiedOccurrenceOnly' on a non-reocurring task you will receive and error.
|
76
|
+
# @return [Boolean] Whether or not the item was deleted
|
77
|
+
# @todo Add exception handling for failed deletes
|
78
|
+
def recycle!(affected_task_occurrences='AllOccurrences')
|
79
|
+
resp = (Viewpoint::EWS::EWS.instance).ews.delete_item([@item_id], 'MoveToDeletedItems', nil, affected_task_occurrences)
|
80
|
+
self.clear_object!
|
81
|
+
resp.status == 'Success'
|
82
|
+
end
|
83
|
+
|
84
|
+
|
54
85
|
private
|
55
86
|
|
56
87
|
def init_methods
|
data/lib/model/tasks_folder.rb
CHANGED
@@ -22,6 +22,31 @@ module Viewpoint
|
|
22
22
|
module EWS
|
23
23
|
# This class represents a TaskFolderType object in the Exchange Data store.
|
24
24
|
class TasksFolder < GenericFolder
|
25
|
+
|
26
|
+
# Find Task subfolders of the passed root folder. If no parameters are passed
|
27
|
+
# this method will search from the Root folder.
|
28
|
+
# @param [Str] root An folder id, either a DistinguishedFolderId (must me a Symbol)
|
29
|
+
# or a FolderId (String)
|
30
|
+
# @param [String] traversal Shallow/Deep/SoftDeleted
|
31
|
+
# @return [Array] Returns an Array of Folder or subclasses of Folder
|
32
|
+
def self.find_folders(root = :msgfolderroot, traversal = 'Deep', shape = 'Default')
|
33
|
+
restr = {:restriction =>
|
34
|
+
{:is_equal_to => {:field_uRI => {:field_uRI=>'folder:FolderClass'},:field_uRI_or_constant=>{:constant => {:value => 'IPF.Task'}}}}
|
35
|
+
}
|
36
|
+
resp = (Viewpoint::EWS::EWS.instance).ews.find_folder( [normalize_id(root)], traversal, {:base_shape => shape}, restr)
|
37
|
+
if(resp.status == 'Success')
|
38
|
+
folders = []
|
39
|
+
resp.items.each do |f|
|
40
|
+
f_type = f.keys.first.to_s.camel_case
|
41
|
+
folders << (eval "#{f_type}.new(f[f.keys.first])")
|
42
|
+
end
|
43
|
+
return folders
|
44
|
+
else
|
45
|
+
raise EwsError, "Could not retrieve folders. #{resp.code}: #{resp.message}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
25
50
|
|
26
51
|
def initialize(folder)
|
27
52
|
super(folder)
|
@@ -308,6 +308,18 @@ module Viewpoint
|
|
308
308
|
end
|
309
309
|
end
|
310
310
|
end
|
311
|
+
|
312
|
+
def attachment_ids!(node, attachment_ids)
|
313
|
+
node.add("#{NS_EWS_MESSAGES}:AttachmentIds") do |att|
|
314
|
+
attachment_ids.each do |id|
|
315
|
+
add_hierarchy!(att, {:attachment_id => {:id => id}})
|
316
|
+
end
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
def attachment_shape!(node)
|
321
|
+
node.add("#{NS_EWS_MESSAGES}:AttachmentShape")
|
322
|
+
end
|
311
323
|
|
312
324
|
# Add a hierarchy of elements from hash data
|
313
325
|
# @example Hash to XML
|
@@ -43,6 +43,17 @@ module Viewpoint
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
+
# @see ExchangeWebService#subscribe
|
47
|
+
def push_subscription_request!(folder_ids, event_types, url, watermark=nil, status_frequency=5)
|
48
|
+
@node.add("#{NS_EWS_MESSAGES}:PushSubscriptionRequest") do |ps|
|
49
|
+
folder_ids!(ps, folder_ids, nil, "#{NS_EWS_TYPES}:FolderIds")
|
50
|
+
event_types!(ps, event_types)
|
51
|
+
ps.add("#{NS_EWS_TYPES}:Watermark", watermark) unless watermark.nil?
|
52
|
+
ps.add("#{NS_EWS_TYPES}:StatusFrequency", status_frequency)
|
53
|
+
ps.add("#{NS_EWS_TYPES}:URL", url)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
46
57
|
# @param [String] type The type of items in the items array message/calendar
|
47
58
|
# @todo Fix max_changes_returned to be more flexible
|
48
59
|
def create_item!(folder_id, items, message_disposition, send_invites, type)
|
@@ -51,6 +51,8 @@ module Viewpoint
|
|
51
51
|
end
|
52
52
|
|
53
53
|
# ********* Begin Hooks *********
|
54
|
+
|
55
|
+
|
54
56
|
def on_create_document(doc)
|
55
57
|
doc.alias NS_EWS_TYPES, 'http://schemas.microsoft.com/exchange/services/2006/types'
|
56
58
|
doc.alias NS_EWS_MESSAGES, 'http://schemas.microsoft.com/exchange/services/2006/messages'
|
@@ -73,6 +75,8 @@ module Viewpoint
|
|
73
75
|
def on_after_create_http_request(req)
|
74
76
|
req.set_auth @@user, @@pass
|
75
77
|
end
|
78
|
+
|
79
|
+
|
76
80
|
# ********** End Hooks **********
|
77
81
|
|
78
82
|
|
@@ -303,6 +307,19 @@ module Viewpoint
|
|
303
307
|
parse!(resp)
|
304
308
|
end
|
305
309
|
|
310
|
+
# Used to subscribe client applications to either push or pull notifications.
|
311
|
+
# @see http://msdn.microsoft.com/en-us/library/aa566188.aspx Subscribe on MSDN
|
312
|
+
def push_subscribe(folder_ids, event_types, url, watermark=nil, status_frequency=5)
|
313
|
+
action = "#{SOAP_ACTION_PREFIX}/Subscribe"
|
314
|
+
resp = invoke("#{NS_EWS_MESSAGES}:Subscribe", :soap_action => action) do |root|
|
315
|
+
build!(root) do
|
316
|
+
push_subscription_request!(folder_ids, event_types, url, watermark, status_frequency)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
parse!(resp)
|
320
|
+
|
321
|
+
end
|
322
|
+
|
306
323
|
# End a pull notification subscription.
|
307
324
|
# @see http://msdn.microsoft.com/en-us/library/aa564263.aspx
|
308
325
|
#
|
@@ -449,7 +466,27 @@ module Viewpoint
|
|
449
466
|
action = "#{SOAP_ACTION_PREFIX}/CreateItem"
|
450
467
|
resp = invoke("#{NS_EWS_MESSAGES}:CreateItem", :soap_action => action) do |node|
|
451
468
|
build!(node) do
|
452
|
-
create_item!(folder_id, items, message_disposition,
|
469
|
+
create_item!(folder_id, items, message_disposition, false, 'task')
|
470
|
+
end
|
471
|
+
end
|
472
|
+
parse!(resp)
|
473
|
+
end
|
474
|
+
|
475
|
+
# Operation is used to create contact items
|
476
|
+
# This is actually a CreateItem operation but they differ for different types
|
477
|
+
# of Exchange objects so it is named appropriately here.
|
478
|
+
# @see # http://msdn.microsoft.com/en-us/library/aa580529.aspx
|
479
|
+
#
|
480
|
+
# @param [String, Symbol] folder_id The folder to save this task in. Either a
|
481
|
+
# DistinguishedFolderId (must me a Symbol) or a FolderId (String)
|
482
|
+
# @param [Hash, Array] items An array of item Hashes or a single item Hash. Hash
|
483
|
+
# values should be based on values found here: http://msdn.microsoft.com/en-us/library/aa581315.aspx
|
484
|
+
# This Hash will eventually be passed to add_hierarchy! in the builder so it is in that format.
|
485
|
+
def create_contact_item(folder_id, items)
|
486
|
+
action = "#{SOAP_ACTION_PREFIX}/CreateItem"
|
487
|
+
resp = invoke("#{NS_EWS_MESSAGES}:CreateItem", :soap_action => action) do |node|
|
488
|
+
build!(node) do
|
489
|
+
create_item!(folder_id, items, nil, false, 'contact')
|
453
490
|
end
|
454
491
|
end
|
455
492
|
parse!(resp)
|
@@ -565,12 +602,18 @@ module Viewpoint
|
|
565
602
|
parse_delete_attachment(resp)
|
566
603
|
end
|
567
604
|
|
568
|
-
|
605
|
+
# Used to retrieve existing attachments on items in the Exchange store
|
606
|
+
# @see http://msdn.microsoft.com/en-us/library/aa494316.aspx
|
607
|
+
# @param [Array] attachment_ids Attachment Ids to fetch
|
608
|
+
def get_attachment(attachment_ids)
|
569
609
|
action = "#{SOAP_ACTION_PREFIX}/GetAttachment"
|
570
|
-
resp = invoke("#{NS_EWS_MESSAGES}:GetAttachment", :soap_action => action) do |
|
571
|
-
|
610
|
+
resp = invoke("#{NS_EWS_MESSAGES}:GetAttachment", :soap_action => action) do |root|
|
611
|
+
build!(root) do
|
612
|
+
attachment_shape!(root)
|
613
|
+
attachment_ids!(root, attachment_ids)
|
614
|
+
end
|
572
615
|
end
|
573
|
-
|
616
|
+
parse!(resp)
|
574
617
|
end
|
575
618
|
|
576
619
|
def create_managed_folder
|
@@ -656,24 +699,29 @@ module Viewpoint
|
|
656
699
|
parse_get_user_availability(resp)
|
657
700
|
end
|
658
701
|
|
659
|
-
|
702
|
+
# Gets a mailbox user's Out of Office (OOF) settings and messages.
|
703
|
+
# @see http://msdn.microsoft.com/en-us/library/aa563465.aspx
|
704
|
+
def get_user_oof_settings(mailbox)
|
660
705
|
action = "#{SOAP_ACTION_PREFIX}/GetUserOofSettings"
|
661
|
-
resp = invoke("#{NS_EWS_MESSAGES}:
|
662
|
-
|
706
|
+
resp = invoke("#{NS_EWS_MESSAGES}:GetUserOofSettingsRequest", :soap_action => action) do |root|
|
707
|
+
build!(root) do
|
708
|
+
mailbox!(root,mailbox[:mailbox],NS_EWS_TYPES)
|
709
|
+
end
|
663
710
|
end
|
664
|
-
|
711
|
+
parse!(resp)
|
665
712
|
end
|
666
713
|
|
667
|
-
|
714
|
+
# Sets a mailbox user's Out of Office (OOF) settings and message.
|
715
|
+
# @see http://msdn.microsoft.com/en-us/library/aa580294.aspx
|
716
|
+
def set_user_oof_settings(mailbox, oof_state, ext_audience, dt_start, dt_end, int_msg, ext_mg)
|
668
717
|
action = "#{SOAP_ACTION_PREFIX}/SetUserOofSettings"
|
669
|
-
resp = invoke("#{NS_EWS_MESSAGES}:SetUserOofSettings", :soap_action => action) do |
|
670
|
-
|
718
|
+
resp = invoke("#{NS_EWS_MESSAGES}:SetUserOofSettings", :soap_action => action) do |root|
|
719
|
+
build!(root)
|
671
720
|
end
|
672
|
-
|
721
|
+
parse!(resp)
|
673
722
|
end
|
674
723
|
|
675
724
|
|
676
|
-
|
677
725
|
# Private Methods (Builders and Parsers)
|
678
726
|
private
|
679
727
|
|
data/lib/soap/handsoap/parser.rb
CHANGED
@@ -27,13 +27,12 @@ module Viewpoint
|
|
27
27
|
@response = response
|
28
28
|
@response_type = (response/"//#{NS_SOAP}:Body/*").first.node_name
|
29
29
|
|
30
|
-
rmsg = (response/'
|
30
|
+
rmsg = (response/'//*[@ResponseClass]').first
|
31
31
|
@response_message = EwsSoapResponse.new(rmsg['ResponseClass'],
|
32
32
|
(rmsg/'m:ResponseCode/text()').first.to_s,
|
33
33
|
(rmsg/'m:MessageText/text()').first.to_s)
|
34
34
|
|
35
35
|
@response_message.set_soap_resp(response)
|
36
|
-
|
37
36
|
end
|
38
37
|
|
39
38
|
# This is the main parser method. It takes the response type and tries to
|
@@ -139,6 +139,20 @@ module Viewpoint
|
|
139
139
|
raise EwsError, "#{@response_message.code}: #{@response_message.message}"
|
140
140
|
end
|
141
141
|
end
|
142
|
+
|
143
|
+
def get_attachment_response(opts)
|
144
|
+
atts = []
|
145
|
+
if(@response_message.status == 'Success')
|
146
|
+
att_id = (@response/"//#{NS_EWS_MESSAGES}:Attachments/*").each do |a|
|
147
|
+
atts << xml_to_hash!(a.native_element)
|
148
|
+
end
|
149
|
+
@response_message.items = atts
|
150
|
+
#@response_message.items = @response
|
151
|
+
else
|
152
|
+
raise EwsError, "#{@response_message.code}: #{@response_message.message}"
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
142
156
|
|
143
157
|
def create_attachment_response(opts)
|
144
158
|
if(@response_message.status == 'Success')
|
@@ -163,7 +177,10 @@ module Viewpoint
|
|
163
177
|
else
|
164
178
|
raise EwsError, "#{@response_message.code}: #{@response_message.message}"
|
165
179
|
end
|
180
|
+
end
|
166
181
|
|
182
|
+
def get_user_oof_settings_response(opts)
|
183
|
+
@response_message.items = xml_to_hash!((@response/"//#{NS_EWS_TYPES}:OofSettings").first.native_element)
|
167
184
|
end
|
168
185
|
|
169
186
|
# Parse out a Mailbox element
|
data/lib/soap/soap_provider.rb
CHANGED
data/lib/viewpoint.rb
CHANGED
@@ -52,6 +52,9 @@ require 'model/meeting_request'
|
|
52
52
|
require 'model/meeting_response'
|
53
53
|
require 'model/meeting_cancellation'
|
54
54
|
require 'model/task'
|
55
|
+
require 'model/attachment'
|
56
|
+
require 'model/file_attachment'
|
57
|
+
require 'model/item_attachment'
|
55
58
|
|
56
59
|
# Load the Exception classes
|
57
60
|
require 'exceptions/exceptions'
|
File without changes
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
8
|
+
- 3
|
9
|
+
version: 0.1.3
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Dan Wanek
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-10-29 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -99,15 +99,18 @@ files:
|
|
99
99
|
- VERSION
|
100
100
|
- lib/exceptions/exceptions.rb
|
101
101
|
- lib/extensions/string.rb
|
102
|
+
- lib/model/attachment.rb
|
102
103
|
- lib/model/calendar_folder.rb
|
103
104
|
- lib/model/calendar_item.rb
|
104
105
|
- lib/model/contact.rb
|
105
106
|
- lib/model/contacts_folder.rb
|
106
107
|
- lib/model/distribution_list.rb
|
107
108
|
- lib/model/event.rb
|
109
|
+
- lib/model/file_attachment.rb
|
108
110
|
- lib/model/folder.rb
|
109
111
|
- lib/model/generic_folder.rb
|
110
112
|
- lib/model/item.rb
|
113
|
+
- lib/model/item_attachment.rb
|
111
114
|
- lib/model/mailbox_user.rb
|
112
115
|
- lib/model/meeting_cancellation.rb
|
113
116
|
- lib/model/meeting_message.rb
|
@@ -127,11 +130,11 @@ files:
|
|
127
130
|
- lib/soap/soap_provider.rb
|
128
131
|
- lib/viewpoint.rb
|
129
132
|
- preamble
|
133
|
+
- test/.rspec
|
130
134
|
- test/spec/basic_functions.spec
|
131
135
|
- test/spec/folder_subscriptions.spec
|
132
136
|
- test/spec/folder_synchronization.spec
|
133
137
|
- test/spec/item_tests.spec
|
134
|
-
- test/spec/spec.opts
|
135
138
|
- utils/ewsWSDL2rb.rb
|
136
139
|
has_rdoc: true
|
137
140
|
homepage: http://github.com/zenchild/Viewpoint
|