viewpoint 0.0.5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/README +84 -45
  2. data/Rakefile +7 -5
  3. data/TODO +6 -0
  4. data/VERSION +1 -1
  5. data/lib/exceptions/exceptions.rb +34 -0
  6. data/lib/extensions/string.rb +37 -0
  7. data/lib/model/calendar_folder.rb +45 -0
  8. data/lib/model/calendar_item.rb +145 -0
  9. data/lib/model/contact.rb +58 -0
  10. data/lib/model/contacts_folder.rb +35 -0
  11. data/lib/model/distribution_list.rb +26 -0
  12. data/lib/model/event.rb +118 -0
  13. data/lib/model/folder.rb +36 -0
  14. data/lib/model/generic_folder.rb +302 -0
  15. data/lib/model/item.rb +126 -0
  16. data/lib/model/mailbox_user.rb +107 -0
  17. data/lib/model/meeting_cancellation.rb +28 -0
  18. data/lib/{viewpoint/errors.rb → model/meeting_message.rb} +10 -14
  19. data/lib/model/meeting_request.rb +26 -0
  20. data/lib/model/meeting_response.rb +26 -0
  21. data/lib/model/message.rb +73 -0
  22. data/lib/model/model.rb +161 -0
  23. data/lib/model/search_folder.rb +36 -0
  24. data/lib/model/task.rb +62 -0
  25. data/lib/model/task_list.rb +19 -0
  26. data/lib/model/tasks_folder.rb +33 -0
  27. data/lib/soap/handsoap/builder.rb +22 -0
  28. data/lib/soap/handsoap/builders/ews_build_helpers.rb +317 -0
  29. data/lib/soap/handsoap/builders/ews_builder.rb +86 -0
  30. data/lib/soap/handsoap/ews_service.rb +646 -0
  31. data/lib/soap/handsoap/parser.rb +106 -0
  32. data/lib/soap/handsoap/parsers/ews_parser.rb +165 -0
  33. data/lib/soap/soap_provider.rb +75 -0
  34. data/lib/viewpoint.rb +98 -3
  35. data/preamble +1 -1
  36. data/test/spec/basic_functions.spec +51 -0
  37. data/test/spec/folder_subscriptions.spec +35 -0
  38. data/test/spec/folder_synchronization.spec +28 -0
  39. data/utils/ewsWSDL2rb.rb +29 -0
  40. metadata +101 -43
  41. data/lib/exchwebserv.rb +0 -6
  42. data/lib/soap/viewpoint.conf +0 -3
  43. data/lib/viewpoint/calendar.rb +0 -128
  44. data/lib/viewpoint/calendar_item.rb +0 -118
  45. data/lib/viewpoint/event.rb +0 -0
  46. data/lib/viewpoint/exchange_headers.rb +0 -49
  47. data/lib/viewpoint/exchwebserv.rb +0 -236
  48. data/lib/viewpoint/folder.rb +0 -358
  49. data/lib/viewpoint/item.rb +0 -101
  50. data/lib/viewpoint/mail.rb +0 -117
  51. data/lib/viewpoint/message.rb +0 -132
  52. data/lib/viewpoint/task.rb +0 -0
  53. data/lib/viewpoint/tasks.rb +0 -0
  54. data/lib/wsdl/defaultMappingRegistry.rb +0 -10680
  55. data/lib/wsdl/exchangeServiceBinding.rb +0 -349
  56. data/lib/wsdl/exchangeServiceTypes.rb +0 -11013
  57. data/test/spec/basic_features_spec.rb +0 -37
  58. data/test/test_client.rb +0 -13
  59. data/test/testrestrict.rb +0 -75
@@ -0,0 +1,106 @@
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
+ module Viewpoint
21
+ module EWS
22
+ module SOAP
23
+ module Parser
24
+
25
+ def initialize(response)
26
+ # Unwrap SOAP Envelope
27
+ @response = response
28
+ @response_type = (response/"//#{NS_SOAP}:Body/*").first.node_name
29
+
30
+ rmsg = (response/'//m:ResponseMessages/*[@ResponseClass]').first
31
+ @response_message = EwsSoapResponse.new(rmsg['ResponseClass'],
32
+ (rmsg/'m:ResponseCode/text()').first.to_s,
33
+ (rmsg/'m:MessageText/text()').first.to_s)
34
+
35
+ @response_message.set_soap_resp(response)
36
+
37
+ end
38
+
39
+ # This is the main parser method. It takes the response type and tries to
40
+ # call a Ruby method of the same name.
41
+ # @todo Decide on an appropriate response if a method does not exist.
42
+ def parse(opts)
43
+ resp_method = @response_type.ruby_case
44
+ if(respond_to?(resp_method))
45
+ puts "Method Exists: #{resp_method}" if $DEBUG
46
+ method(resp_method).call(opts)
47
+ else
48
+ puts "No Method: #{resp_method}" if $DEBUG
49
+ end
50
+ @response_message
51
+ end
52
+
53
+ private
54
+
55
+ def method_exists?(method_name)
56
+ return self.methods.include?(method_name)
57
+ end
58
+
59
+ # Create a Hash from a Nokogiri element tree
60
+ # @param [Nokogiri::XML::Element, Nokogiri::XML::Text] nokoelem The Nokogiri element passed to this method
61
+ # @example XML
62
+ # <tiptop>
63
+ # <top Id="32fss">TestText</top>
64
+ # <middle Id='TestTestMiddle' />
65
+ # <bottom />
66
+ # </tiptop>
67
+ # becomes...
68
+ # {:tiptop=>{:top=>{:id=>"32fss", :text=>"TestText"}, :middle=>{:id=>"TestTestMiddle"}}}
69
+ def xml_to_hash!(nokoelem)
70
+ e_hash = {}
71
+ node_name = nokoelem.name.ruby_case.to_sym
72
+
73
+ if nokoelem.is_a? Nokogiri::XML::Element
74
+ nokoelem.attributes.each_pair do |k, v|
75
+ e_hash[k.ruby_case.to_sym] = v.value
76
+ end
77
+ nokoelem.children.each do |c|
78
+ new_hash = xml_to_hash!(c)
79
+ unless new_hash.nil?
80
+ e_hash.merge!(new_hash) do |k,v1,v2|
81
+ if(v1.is_a?(Array))
82
+ v1 << v2
83
+ else
84
+ [v1, v2]
85
+ end
86
+ end
87
+ end
88
+ end
89
+ return e_hash.empty? ? nil : {node_name => e_hash}
90
+ elsif nokoelem.is_a? Nokogiri::XML::Text
91
+ # Return a :text to value hash or nil if the text is empty
92
+ return {node_name => nokoelem.text} if nokoelem.text != "\n"
93
+ nil
94
+ else
95
+ # If something strange gets passed just return nil
96
+ return nil
97
+ end
98
+ end
99
+
100
+
101
+ end # Parser
102
+ end # SOAP
103
+ end # SPWS
104
+ end # Viewpoint
105
+
106
+ require 'parsers/ews_parser'
@@ -0,0 +1,165 @@
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
+ module SOAP
24
+ class EwsParser
25
+ include Parser
26
+
27
+ # Parsing Methods
28
+ # ---------------
29
+
30
+ def resolve_names_response(opts)
31
+ @response_message.items = resolution_set
32
+ end
33
+
34
+ def get_folder_response(opts)
35
+ @response_message.items = folders
36
+ end
37
+
38
+ def find_folder_response(opts)
39
+ folders = []
40
+ (@response/"//#{NS_EWS_MESSAGES}:FindFolderResponseMessage//#{NS_EWS_TYPES}:Folders/*").each do |f|
41
+ folders << xml_to_hash!(f.native_element)
42
+ end
43
+ @response_message.items = folders
44
+ end
45
+
46
+ def get_events_response(opts)
47
+ if @response_message.status == 'Success'
48
+ events = []
49
+ events << {}
50
+ events.first[:subscription_id] = (@response/"//#{NS_EWS_MESSAGES}:Notification/#{NS_EWS_TYPES}:SubscriptionId").first.to_s
51
+ events.first[:more_events] = (@response/"//#{NS_EWS_MESSAGES}:Notification/#{NS_EWS_TYPES}:SubscriptionId").first.to_boolean
52
+
53
+ (@response/"//#{NS_EWS_MESSAGES}:Notification/*[position()>3]").each do |e|
54
+ events << xml_to_hash!(e.native_element)
55
+ events.first[:watermark] = events.last[events.last.keys.first][:watermark][:text]
56
+ end
57
+
58
+ @response_message.items = events
59
+ else
60
+ raise EwsSubscriptionTimeout.new("#{@response_message.code}: #{@response_message.message}")
61
+ end
62
+ end
63
+
64
+ def find_item_response(opts)
65
+ items = []
66
+ items << {}
67
+ items.first[:total_items_in_view] = (@response/"//#{NS_EWS_MESSAGES}:FindItemResponseMessage/#{NS_EWS_MESSAGES}:RootFolder/@TotalItemsInView").first.to_i
68
+
69
+ (@response/"//#{NS_EWS_MESSAGES}:FindItemResponseMessage//#{NS_EWS_TYPES}:Items/*").each do |i|
70
+ items << xml_to_hash!(i.native_element)
71
+ end
72
+
73
+ @response_message.items = items
74
+ end
75
+
76
+ # Parsers the response from the SOAP Subscribe operation
77
+ # @see http://msdn.microsoft.com/en-us/library/aa566188.aspx
78
+ #
79
+ # @return [Hash] A hash with the keys :watermark and :subscription_id
80
+ # @raise [EwsError] Raise an error if the ResponseClass is not Success
81
+ def subscribe_response(opts)
82
+ subscription = []
83
+ sid = xml_to_hash!((@response/"//#{NS_EWS_MESSAGES}:SubscriptionId").first.native_element)
84
+ wmk = xml_to_hash!((@response/"//#{NS_EWS_MESSAGES}:Watermark").first.native_element)
85
+ subscription << sid.merge(wmk)
86
+ @response_message.items = subscription
87
+ end
88
+
89
+ # @todo Better handle error messages
90
+ def unsubscribe_response(opts)
91
+ @response_message
92
+ end
93
+
94
+ def get_item_response(opts)
95
+ if(@response_message.status == 'Success')
96
+ @response_message.items << xml_to_hash!((@response/"//#{NS_EWS_MESSAGES}:Items/*").first.native_element)
97
+ else
98
+ raise EwsError, "#{@response_message.code}: #{@response_message.message}"
99
+ end
100
+ end
101
+
102
+ # @todo need to find out out to us XPath to get ItemId. It doesn't seem to work now.
103
+ def create_item_response(opts)
104
+ if(@response_message.status == 'Success')
105
+ items = []
106
+ (@response/"//#{NS_EWS_MESSAGES}:Items/*").each do |i|
107
+ items << xml_to_hash!(i.native_element)
108
+ end
109
+ @response_message.items = items
110
+ else
111
+ raise EwsError, "#{@response_message.code}: #{@response_message.message}"
112
+ end
113
+ end
114
+
115
+ def sync_folder_items_response(opts)
116
+ if(@response_message.status == 'Success')
117
+ sync = []
118
+ sync << {}
119
+ sync.first[:sync_state] = (@response/"//#{NS_EWS_MESSAGES}:SyncState").first.to_s
120
+ sync.first[:includes_last_item_in_range] = (@response/"//#{NS_EWS_MESSAGES}:IncludesLastItemInRange").first.to_boolean
121
+ (@response/"//m:Changes/*").each do |c|
122
+ sync << xml_to_hash!(c.native_element)
123
+ end
124
+ @response_message.items = sync
125
+ else
126
+ raise EwsError, "#{@response_message.code}: #{@response_message.message}"
127
+ end
128
+
129
+ end
130
+
131
+ # Parse out a Mailbox element
132
+ # @param [XML] mbox The <t:Mailbox> element
133
+ # @return [Hash] Values of EWS Mailbox type :name, :email_address, :routing_type, :mailbox_type, :item_id
134
+ def mailbox(mbox_xml)
135
+ xml_to_hash!(mbox_xml.native_element)
136
+ end
137
+
138
+ def contact(contact_xml)
139
+ xml_to_hash!(contact_xml.native_element)
140
+ end
141
+
142
+ # Parse out Resolutions from a ResolutionSet from the ResolveNames operation
143
+ # @return [Array] An array of :mailbox,:contact Hashes that resolved.
144
+ def resolution_set
145
+ resolution_set = []
146
+ (@response/"//#{NS_EWS_MESSAGES}:ResolutionSet/*").each do |r|
147
+ mbox_hash = mailbox((r/"#{NS_EWS_TYPES}:Mailbox").first)
148
+ contact_hash = contact((r/"#{NS_EWS_TYPES}:Contact").first)
149
+ resolution_set << mbox_hash.merge(contact_hash)
150
+ end
151
+ resolution_set
152
+ end
153
+
154
+ def folders
155
+ folders = []
156
+ (@response/"//#{NS_EWS_MESSAGES}:Folders/*").each do |f|
157
+ folders << xml_to_hash!(f.native_element)
158
+ end
159
+ folders
160
+ end
161
+
162
+ end # EwsParser
163
+ end # SOAP
164
+ end # EWS
165
+ end # Viewpoint
@@ -0,0 +1,75 @@
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
+ # This file requires the appropriate SOAP Library (Handsoap today) and also
22
+ # defines certain contants that SOAP methods may use.
23
+ module Viewpoint
24
+ module EWS
25
+ module SOAP
26
+
27
+ # CONSTANTS
28
+
29
+ NS_SOAP = 'soap' # http://schemas.xmlsoap.org/soap/envelope/
30
+ NS_EWS_TYPES = 't' # http://schemas.microsoft.com/exchange/services/2006/types
31
+ NS_EWS_MESSAGES = 'm' # http://schemas.microsoft.com/exchange/services/2006/messages
32
+
33
+ # used in ResolveNames to determine where names are resolved
34
+ ActiveDirectory = 'ActiveDirectory'
35
+ ActiveDirectoryContacts = 'ActiveDirectoryContacts'
36
+ Contacts = 'Contacts'
37
+ ContactsActiveDirectory = 'ContactsActiveDirectory'
38
+
39
+
40
+
41
+ # A Generic Class for SOAP returns.
42
+ # @attr_reader [String] :message The text from the EWS element <m:ResponseCode>
43
+ class EwsSoapResponse
44
+
45
+ attr_reader :status, :code, :message, :soap_response
46
+ attr_accessor :items
47
+
48
+ def initialize(status, code, message)
49
+ @status, @code, @message = status, code, message
50
+
51
+ # Items is an array where hash types get stored for return
52
+ @items = []
53
+ end
54
+
55
+ def set_soap_resp(response)
56
+ @soap_response = response
57
+ end
58
+
59
+ end # EwsSoapResponse
60
+
61
+
62
+ end # SOAP
63
+ end # EWS
64
+ end # Viewpoint
65
+
66
+ require 'soap/handsoap/ews_service'
67
+
68
+ module Viewpoint
69
+ module EWS
70
+ module SOAP
71
+ end
72
+ end
73
+ end
74
+
75
+
@@ -1,5 +1,100 @@
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
+ # We only what one instance of this class so include Singleton
22
+ require 'singleton'
23
+ require 'date'
24
+
25
+ # Class Extensions
26
+ require 'extensions/string'
27
+
28
+ # Load the backend SOAP infrastructure. Today this is Handsoap.
29
+ require 'soap/soap_provider'
30
+
31
+ # Load the model classes
32
+ # Base Models
33
+ require 'model/model'
34
+ require 'model/mailbox_user'
35
+ require 'model/generic_folder'
36
+ require 'model/item'
37
+ # Specific Models
38
+ # Folders
39
+ require 'model/folder'
40
+ require 'model/calendar_folder'
41
+ require 'model/contacts_folder'
42
+ require 'model/search_folder'
43
+ require 'model/tasks_folder'
44
+ # Items
45
+ require 'model/message'
46
+ require 'model/calendar_item'
47
+ require 'model/contact'
48
+ require 'model/distribution_list'
49
+ require 'model/meeting_message'
50
+ require 'model/meeting_request'
51
+ require 'model/meeting_response'
52
+ require 'model/meeting_cancellation'
53
+ require 'model/task'
54
+
55
+ # Load the Exception classes
56
+ require 'exceptions/exceptions'
57
+
58
+
59
+ # This is the Singlenton class that controls access and presentation to Exchange
60
+ # Web Services. It is possible to just use the SOAP classes themselves but this
61
+ # is what ties all the pieces together.
62
+ # @attr_reader [SOAP::ExchangeWebService] :ews The SOAP object used to make calls
63
+ # to the Exchange Web Service.
1
64
  module Viewpoint
2
- end
65
+ module EWS
66
+ # @attr_reader [Viewpoint::EWS::SOAP::ExchangeWebService] :ews The EWS object used
67
+ # to make SOAP calls. You typically don't need to use this, but if you want to
68
+ # play around with the SOAP back-end it's available.
69
+ class EWS
70
+ include Singleton
71
+ include Viewpoint
3
72
 
4
- require 'viewpoint/errors'
5
- require 'viewpoint/exchwebserv'
73
+ attr_reader :ews
74
+
75
+ def self.endpoint=(endpoint, version = 1)
76
+ @@endpoint = endpoint
77
+ SOAP::ExchangeWebService.endpoint(:uri => endpoint, :version => version)
78
+ end
79
+
80
+ def self.endpoint
81
+ @@endpoint
82
+ end
83
+
84
+ def self.set_auth(user,pass)
85
+ @@user = user
86
+ SOAP::ExchangeWebService.set_auth(user,pass)
87
+ end
88
+
89
+ def initialize
90
+ @ews = SOAP::ExchangeWebService.new
91
+ end
92
+
93
+ # The MailboxUser object that represents the user connected to EWS.
94
+ def me
95
+ @me ||= MailboxUser.find_user("#{@@user}@")
96
+ end
97
+
98
+ end # class EWS
99
+ end # EWS
100
+ end