viewpoint 0.0.5 → 0.1.0

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.
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