├── .devcontainer
└── devcontainer.json
├── .github
├── dependabot.yml
└── workflows
│ └── ruby.yml
├── .gitignore
├── Changelog.txt
├── Gemfile
├── Guardfile
├── LICENSE
├── README.md
├── Rakefile
├── TODO
├── VERSION
├── lib
├── ews
│ ├── calendar_accessors.rb
│ ├── connection.rb
│ ├── connection_helper.rb
│ ├── convert_accessors.rb
│ ├── errors.rb
│ ├── ews_client.rb
│ ├── exceptions
│ │ └── exceptions.rb
│ ├── folder_accessors.rb
│ ├── impersonation.rb
│ ├── item_accessors.rb
│ ├── mailbox_accessors.rb
│ ├── meeting_accessors.rb
│ ├── message_accessors.rb
│ ├── push_subscription_accessors.rb
│ ├── room_accessors.rb
│ ├── roomlist_accessors.rb
│ ├── soap.rb
│ ├── soap
│ │ ├── builders
│ │ │ └── ews_builder.rb
│ │ ├── ews_response.rb
│ │ ├── ews_soap_availability_response.rb
│ │ ├── ews_soap_free_busy_response.rb
│ │ ├── ews_soap_response.rb
│ │ ├── ews_soap_room_response.rb
│ │ ├── ews_soap_roomlist_response.rb
│ │ ├── exchange_availability.rb
│ │ ├── exchange_data_services.rb
│ │ ├── exchange_notification.rb
│ │ ├── exchange_synchronization.rb
│ │ ├── exchange_time_zones.rb
│ │ ├── exchange_user_configuration.rb
│ │ ├── exchange_web_service.rb
│ │ ├── parsers
│ │ │ ├── ews_parser.rb
│ │ │ └── ews_sax_document.rb
│ │ ├── response_message.rb
│ │ └── responses
│ │ │ ├── create_attachment_response_message.rb
│ │ │ ├── create_item_response_message.rb
│ │ │ ├── find_item_response_message.rb
│ │ │ ├── get_events_response_message.rb
│ │ │ ├── send_notification_response_message.rb
│ │ │ ├── subscribe_response_message.rb
│ │ │ ├── sync_folder_hierarchy_response_message.rb
│ │ │ └── sync_folder_items_response_message.rb
│ ├── templates
│ │ ├── calendar_item.rb
│ │ ├── forward_item.rb
│ │ ├── message.rb
│ │ ├── reply_to_item.rb
│ │ └── task.rb
│ ├── types.rb
│ └── types
│ │ ├── attachment.rb
│ │ ├── attendee.rb
│ │ ├── calendar_folder.rb
│ │ ├── calendar_item.rb
│ │ ├── contact.rb
│ │ ├── contacts_folder.rb
│ │ ├── copied_event.rb
│ │ ├── created_event.rb
│ │ ├── deleted_event.rb
│ │ ├── distribution_list.rb
│ │ ├── event.rb
│ │ ├── export_items_response_message.rb
│ │ ├── file_attachment.rb
│ │ ├── folder.rb
│ │ ├── free_busy_changed_event.rb
│ │ ├── generic_folder.rb
│ │ ├── item.rb
│ │ ├── item_attachment.rb
│ │ ├── item_field_uri_map.rb
│ │ ├── mailbox_user.rb
│ │ ├── meeting_cancellation.rb
│ │ ├── meeting_message.rb
│ │ ├── meeting_request.rb
│ │ ├── meeting_response.rb
│ │ ├── message.rb
│ │ ├── modified_event.rb
│ │ ├── moved_event.rb
│ │ ├── new_mail_event.rb
│ │ ├── out_of_office.rb
│ │ ├── post_item.rb
│ │ ├── search_folder.rb
│ │ ├── status_event.rb
│ │ ├── task.rb
│ │ └── tasks_folder.rb
├── viewpoint.rb
└── viewpoint
│ ├── logging.rb
│ ├── logging
│ └── config.rb
│ └── string_utils.rb
├── preamble
├── spec
├── .rspec
├── ews
│ ├── ews_client_spec.rb
│ └── types
│ │ └── calendar_item_spec.rb
├── soap_data
│ ├── basic_request.xml
│ ├── copy_folder_request.xml
│ ├── create_folder_request.xml
│ ├── delete_folder_request.xml
│ ├── dodgy_ews_response.xml
│ ├── empty_folder_request.xml
│ ├── find_folder_error_response.xml
│ ├── find_folder_request.xml
│ ├── find_folder_response.xml
│ ├── get_folder_request.xml
│ ├── get_room_lists_request.xml
│ ├── get_rooms_request.xml
│ └── move_folder_request.xml
├── spec_helper.rb
├── unit
│ ├── dodgy_file_spec.rb
│ ├── ews_folder_operations_spec.rb
│ ├── ews_parser_spec.rb
│ ├── ews_rooms_operations_spec.rb
│ ├── ews_soap_free_busy_response_spec.rb
│ ├── folder_accessors_spec.rb
│ ├── item_accessors_spec.rb
│ ├── mailbox_accessors_spec.rb
│ ├── meeting_accessors_spec.rb
│ └── soap
│ │ └── builders
│ │ └── ews_builder_spec.rb
├── viewpoint
│ └── string_utils_spec.rb
└── xml_matcher.rb
└── viewpoint.gemspec
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the
2 | // README at: https://github.com/devcontainers/templates/tree/main/src/ruby
3 | {
4 | "name": "Ruby",
5 | // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
6 | "image": "mcr.microsoft.com/devcontainers/ruby:1-3.3-bullseye"
7 |
8 | // Features to add to the dev container. More info: https://containers.dev/features.
9 | // "features": {},
10 |
11 | // Use 'forwardPorts' to make a list of ports inside the container available locally.
12 | // "forwardPorts": [],
13 |
14 | // Use 'postCreateCommand' to run commands after the container is created.
15 | // "postCreateCommand": "ruby --version",
16 |
17 | // Configure tool-specific properties.
18 | // "customizations": {},
19 |
20 | // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
21 | // "remoteUser": "root"
22 | }
23 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for more information:
4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5 | # https://containers.dev/guide/dependabot
6 |
7 | version: 2
8 | updates:
9 | - package-ecosystem: "devcontainers"
10 | directory: "/"
11 | schedule:
12 | interval: weekly
13 |
--------------------------------------------------------------------------------
/.github/workflows/ruby.yml:
--------------------------------------------------------------------------------
1 | # This workflow uses actions that are not certified by GitHub.
2 | # They are provided by a third-party and are governed by
3 | # separate terms of service, privacy policy, and support
4 | # documentation.
5 | # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6 | # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7 |
8 | name: Ruby
9 |
10 | on:
11 | - push
12 | - pull_request
13 |
14 | permissions:
15 | contents: read
16 |
17 | jobs:
18 | test:
19 |
20 | runs-on: ubuntu-latest
21 | strategy:
22 | matrix:
23 | ruby-version: ['2.7', '3.0', '3.1', '3.2', '3.3']
24 |
25 | steps:
26 | - uses: actions/checkout@v4
27 | - name: Set up Ruby
28 | uses: ruby/setup-ruby@v1
29 | with:
30 | ruby-version: ${{ matrix.ruby-version }}
31 | bundler-cache: true # runs 'bundle install' and caches installed gems automatically
32 | - name: Run tests
33 | run: bundle exec rspec
34 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | Gemfile.lock
2 | .DS_Store
3 | .rvmrc
4 | *.swp
5 | /test*.rb
6 | /\.test*
7 | .idea
8 | tmp
9 | vendor
10 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org/'
2 |
3 | gemspec
4 |
5 | group :development do
6 | gem 'rspec'
7 | gem 'rb-inotify', :require => false
8 | gem 'turn'
9 | gem "pry-nav"
10 | end
11 |
--------------------------------------------------------------------------------
/Guardfile:
--------------------------------------------------------------------------------
1 | # A sample Guardfile
2 | # More info at https://github.com/guard/guard#readme
3 |
4 | guard 'rspec' do
5 | watch(%r{^spec/.+_spec\.rb$})
6 | watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7 | watch('spec/spec_helper.rb') { "spec" }
8 | end
9 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 | require 'bundler'
3 |
4 | require 'bundler/gem_tasks'
5 | require 'date'
6 |
7 | task :default => [:gem]
8 |
9 | desc "Build the gem without a version change"
10 | task :gem do
11 | system "gem build viewpoint.gemspec"
12 | end
13 |
14 | desc "Clean the build environment"
15 | task :clean do
16 | system "rm -f viewpoint*.gem"
17 | end
18 |
19 | desc "Build the gem, but increment the version first"
20 | task :newrelease => [:versionup, :clean, :gem]
21 |
22 |
23 | desc "Increment the version by 1 minor release"
24 | task :versionup do
25 | ver = up_min_version
26 | puts "New version: #{ver}"
27 | end
28 |
29 |
30 | def up_min_version
31 | f = File.open('VERSION', 'r+')
32 | ver = f.readline.chomp
33 | v_arr = ver.split(/\./).map do |v|
34 | v.to_i
35 | end
36 | v_arr[2] += 1
37 | ver = v_arr.join('.')
38 | f.rewind
39 | f.write(ver)
40 | f.close
41 | ver
42 | end
43 |
--------------------------------------------------------------------------------
/TODO:
--------------------------------------------------------------------------------
1 | h2. TODOS
2 |
3 | * Automate "deepening" of Model objects by over-riding method_missing
4 |
5 |
6 | if object.is_shallow? && all_methods.index(method)
7 | deepen!
8 | else
9 | raise the NoMethod error
10 |
11 |
12 | * Clean-up exceptions. There is exception raising in the Model that will never ocurr because it is already being checked for in the Parser
13 |
14 | * Refactor #find_folders methods. There is a lot of duplicate code right now and it could be simplified quite a bit.
15 |
16 | * Test TODO
17 | ** Test for undefined methods and make sure the method_missing method isn't causing problems
18 |
--------------------------------------------------------------------------------
/VERSION:
--------------------------------------------------------------------------------
1 | 1.1.0
2 |
--------------------------------------------------------------------------------
/lib/ews/calendar_accessors.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is a cotribution to Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2013 Mark McCahill
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::CalendarAccessors
20 | include Viewpoint::EWS
21 |
22 | def event_busy_type( the_event )
23 | the_event[:calendar_event][:elems][2][:busy_type][:text]
24 | end
25 |
26 | def event_start_time( the_event )
27 | the_event[:calendar_event][:elems][0][:start_time][:text]
28 | end
29 |
30 | def event_end_time( the_event )
31 | the_event[:calendar_event][:elems][1][:end_time][:text]
32 | end
33 |
34 | end # Viewpoint::EWS::CalendarAccessors
35 |
--------------------------------------------------------------------------------
/lib/ews/connection.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 | require 'httpclient'
19 |
20 | class Viewpoint::EWS::Connection
21 | include Viewpoint::EWS::ConnectionHelper
22 | include Viewpoint::EWS
23 |
24 | attr_reader :endpoint
25 | # @param [String] endpoint the URL of the web service.
26 | # @example https:///ews/Exchange.asmx
27 | # @param [Hash] opts Misc config options (mostly for developement)
28 | # @option opts [Fixnum] :ssl_verify_mode
29 | # @option opts [Fixnum] :receive_timeout override the default receive timeout
30 | # seconds
31 | # @option opts [Fixnum] :connect_timeout override the default connect timeout
32 | # seconds
33 | # @option opts [Array] :trust_ca an array of hashed dir paths or a file
34 | # @option opts [String] :user_agent the http user agent to use in all requests
35 | def initialize(endpoint, opts = {})
36 | @log = Logging.logger[self.class.name.to_s.to_sym]
37 | if opts[:user_agent]
38 | @httpcli = HTTPClient.new(agent_name: opts[:user_agent])
39 | else
40 | @httpcli = HTTPClient.new
41 | end
42 |
43 | if opts[:trust_ca]
44 | @httpcli.ssl_config.clear_cert_store
45 | opts[:trust_ca].each do |ca|
46 | @httpcli.ssl_config.add_trust_ca ca
47 | end
48 | end
49 |
50 | @httpcli.ssl_config.verify_mode = opts[:ssl_verify_mode] if opts[:ssl_verify_mode]
51 | @httpcli.ssl_config.ssl_version = opts[:ssl_version] if opts[:ssl_version]
52 | # Up the keep-alive so we don't have to do the NTLM dance as often.
53 | @httpcli.keep_alive_timeout = 60
54 | @httpcli.receive_timeout = opts[:receive_timeout] if opts[:receive_timeout]
55 | @httpcli.connect_timeout = opts[:connect_timeout] if opts[:connect_timeout]
56 | @endpoint = endpoint
57 | end
58 |
59 | def set_auth(user,pass)
60 | @httpcli.set_auth(@endpoint.to_s, user, pass)
61 | end
62 |
63 | # Authenticate to the web service. You don't have to do this because
64 | # authentication will happen on the first request if you don't do it here.
65 | # @return [Boolean] true if authentication is successful, false otherwise
66 | def authenticate
67 | self.get && true
68 | end
69 |
70 | # Every Connection class must have the dispatch method. It is what sends the
71 | # SOAP request to the server and calls the parser method on the EWS instance.
72 | #
73 | # This was originally in the ExchangeWebService class but it was added here
74 | # to make the processing chain easier to modify. For example, it allows the
75 | # reactor pattern to handle the request with a callback.
76 | # @param ews [Viewpoint::EWS::SOAP::ExchangeWebService] used to call
77 | # #parse_soap_response
78 | # @param soapmsg [String]
79 | # @param opts [Hash] misc opts for handling the Response
80 | def dispatch(ews, soapmsg, opts)
81 | respmsg = post(soapmsg)
82 | @log.debug <<-EOF.gsub(/^ {6}/, '')
83 | Received SOAP Response:
84 | ----------------
85 | #{Nokogiri::XML(respmsg).to_xml}
86 | ----------------
87 | EOF
88 | opts[:raw_response] ? respmsg : ews.parse_soap_response(respmsg, opts)
89 | end
90 |
91 | # Send a GET to the web service
92 | # @return [String] If the request is successful (200) it returns the body of
93 | # the response.
94 | def get
95 | check_response( @httpcli.get(@endpoint) )
96 | end
97 |
98 | # Send a POST to the web service
99 | # @return [String] If the request is successful (200) it returns the body of
100 | # the response.
101 | def post(xmldoc)
102 | headers = {'Content-Type' => 'text/xml'}
103 | check_response( @httpcli.post(@endpoint, xmldoc, headers) )
104 | end
105 |
106 |
107 | private
108 |
109 | def check_response(resp)
110 | case resp.status
111 | when 200
112 | resp.body
113 | when 302
114 | # @todo redirect
115 | raise Errors::UnhandledResponseError.new("Unhandled HTTP Redirect", resp)
116 | when 401
117 | raise Errors::UnauthorizedResponseError.new("Unauthorized request", resp)
118 | when 500
119 | if resp.headers['Content-Type'] =~ /xml/
120 | err_string, err_code = parse_soap_error(resp.body)
121 | raise Errors::SoapResponseError.new("SOAP Error: Message: #{err_string} Code: #{err_code}", resp, err_code, err_string)
122 | else
123 | raise Errors::ServerError.new("Internal Server Error. Message: #{resp.body}", resp)
124 | end
125 | else
126 | raise Errors::ResponseError.new("HTTP Error Code: #{resp.status}, Msg: #{resp.body}", resp)
127 | end
128 | end
129 |
130 | # @param [String] xml to parse the errors from.
131 | def parse_soap_error(xml)
132 | ndoc = Nokogiri::XML(xml)
133 | ns = ndoc.collect_namespaces
134 | err_string = ndoc.xpath("//faultstring",ns).text
135 | err_code = ndoc.xpath("//faultcode",ns).text
136 | @log.debug "Internal SOAP error. Message: #{err_string}, Code: #{err_code}"
137 | [err_string, err_code]
138 | end
139 |
140 | end
141 |
--------------------------------------------------------------------------------
/lib/ews/connection_helper.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::ConnectionHelper
20 |
21 | def init_logging!
22 | @log = Logging.logger[self.class.name.to_s.to_sym]
23 | end
24 |
25 | # @param [String] xml to parse the errors from.
26 | def parse_soap_error(xml)
27 | ndoc = Nokogiri::XML(xml)
28 | ns = ndoc.collect_namespaces
29 | err_string = ndoc.xpath("//faultstring",ns).text
30 | err_code = ndoc.xpath("//faultcode",ns).text
31 | @log.debug "Internal SOAP error. Message: #{err_string}, Code: #{err_code}"
32 | [err_string, err_code]
33 | end
34 |
35 | end
36 |
--------------------------------------------------------------------------------
/lib/ews/convert_accessors.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2013 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 | module Viewpoint::EWS::ConvertAccessors
19 | include Viewpoint::EWS
20 |
21 | # This is a class method that converts identifiers between formats.
22 | # @param [String] id The id to be converted
23 | # @param [Hash] opts Misc options to control request
24 | # @option opts [Symbol] :format :ews_legacy_id/:ews_id/:entry_id/:hex_entry_id/:store_id/:owa_id
25 | # @option opts [Symbol] :destination_format :ews_legacy_id/:ews_id/:entry_id/:hex_entry_id/:store_id/:owa_id
26 | # @option opts [String] :mailbox Mailbox, if required
27 | # @return [EwsResponse] Returns an EwsResponse containing the convert response message
28 |
29 | def convert_id(id, opts = {})
30 | args = convert_id_args(id, opts.clone)
31 | obj = OpenStruct.new(opts: args)
32 | yield obj if block_given?
33 | resp = ews.convert_id(args)
34 | convert_id_parser(resp)
35 | end
36 |
37 | private
38 |
39 | def convert_id_args(id, opts)
40 | { id: id }.merge opts
41 | end
42 |
43 | def convert_id_parser(resp)
44 | rm = resp.response_messages[0]
45 |
46 | if(rm && rm.status == 'Success')
47 | # @todo create custom response class
48 | rm
49 | else
50 | code = rm.respond_to?(:code) ? rm.code : "Unknown"
51 | text = rm.respond_to?(:message_text) ? rm.message_text : "Unknown"
52 | raise EwsError, "Could not convert id. #{rm.code}: #{rm.message_text}"
53 | end
54 | end
55 |
56 | end # Viewpoint::EWS::ItemAccessors
57 |
--------------------------------------------------------------------------------
/lib/ews/errors.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::Errors
20 | class ResponseError < RuntimeError
21 | attr_reader :response
22 |
23 | def initialize(message, response)
24 | super(message)
25 | @response = response
26 | end
27 |
28 | def status
29 | response.status
30 | end
31 |
32 | def body
33 | response.body
34 | end
35 | end
36 |
37 | class UnhandledResponseError < ResponseError
38 | end
39 |
40 | class ServerError < ResponseError
41 | end
42 |
43 | class UnauthorizedResponseError < ResponseError
44 | end
45 |
46 | class SoapResponseError < ResponseError
47 | attr_reader :faultcode,
48 | :faultstring
49 |
50 | def initialize(message, response, faultcode, faultstring)
51 | super(message, response)
52 | @faultcode = faultcode
53 | @faultstring = faultstring
54 | end
55 | end
56 | end
57 |
--------------------------------------------------------------------------------
/lib/ews/ews_client.rb:
--------------------------------------------------------------------------------
1 | require 'ews/folder_accessors'
2 | require 'ews/item_accessors'
3 | require 'ews/message_accessors'
4 | require 'ews/mailbox_accessors'
5 | require 'ews/push_subscription_accessors'
6 | require 'ews/calendar_accessors'
7 | require 'ews/room_accessors'
8 | require 'ews/roomlist_accessors'
9 | require 'ews/convert_accessors'
10 | require 'ews/meeting_accessors'
11 |
12 | # This class is the glue between the Models and the Web Service.
13 | class Viewpoint::EWSClient
14 | include Viewpoint::EWS
15 | include Viewpoint::EWS::FolderAccessors
16 | include Viewpoint::EWS::ItemAccessors
17 | include Viewpoint::EWS::MessageAccessors
18 | include Viewpoint::EWS::MailboxAccessors
19 | include Viewpoint::EWS::PushSubscriptionAccessors
20 | include Viewpoint::EWS::CalendarAccessors
21 | include Viewpoint::EWS::RoomAccessors
22 | include Viewpoint::EWS::RoomlistAccessors
23 | include Viewpoint::EWS::ConvertAccessors
24 | include Viewpoint::EWS::MeetingAccessors
25 | include Viewpoint::StringUtils
26 |
27 | # The instance of Viewpoint::EWS::SOAP::ExchangeWebService
28 | attr_reader :ews, :endpoint, :username
29 |
30 | # Initialize the EWSClient instance.
31 | # @param [String] endpoint The EWS endpoint we will be connecting to
32 | # @param [String] user The user to authenticate as. If you are using
33 | # NTLM or Negotiate authentication you do not need to pass this parameter.
34 | # @param [String] pass The user password. If you are using NTLM or
35 | # Negotiate authentication you do not need to pass this parameter.
36 | # @param [Hash] opts Various options to pass to the backends
37 | # @option opts [String] :server_version The Exchange server version to
38 | # target. See the VERSION_* constants in
39 | # Viewpoint::EWS::SOAP::ExchangeWebService.
40 | # @option opts [Object] :http_class specify an alternate HTTP connection class.
41 | # @option opts [Hash] :http_opts options to pass to the connection
42 | def initialize(endpoint, username, password, opts = {})
43 | # dup all. @see ticket https://github.com/zenchild/Viewpoint/issues/68
44 | @endpoint = endpoint.dup
45 | @username = username.dup
46 | password = password.dup
47 | opts = opts.dup
48 | http_klass = opts[:http_class] || Viewpoint::EWS::Connection
49 | con = http_klass.new(endpoint, opts[:http_opts] || {})
50 | con.set_auth @username, password
51 | @ews = SOAP::ExchangeWebService.new(con, opts)
52 | end
53 |
54 | # @param deepen [Boolean] true to autodeepen, false otherwise
55 | # @param behavior [Symbol] :raise, :nil When setting autodeepen to false you
56 | # can choose what the behavior is when an attribute does not exist. The
57 | # default is to raise a EwsMinimalObjectError.
58 | def set_auto_deepen(deepen, behavior = :raise)
59 | if deepen
60 | ews.auto_deepen = true
61 | else
62 | behavior = [:raise, :nil].include?(behavior) ? behavior : :raise
63 | ews.no_auto_deepen_behavior = behavior
64 | ews.auto_deepen = false
65 | end
66 | end
67 |
68 | def auto_deepen=(deepen)
69 | set_auto_deepen deepen
70 | end
71 |
72 | # Specify a default time zone context for all time attributes
73 | # @param id [String] Identifier of a Microsoft well known time zone (e.g: 'UTC', 'W. Europe Standard Time')
74 | # @note A list of time zones known by the server can be requested via {EWS::SOAP::ExchangeTimeZones#get_time_zones}
75 | def set_time_zone(microsoft_time_zone_id)
76 | ews.set_time_zone_context microsoft_time_zone_id
77 | end
78 |
79 | private
80 |
81 |
82 | # This method also exists in EWS::Types, but there is a lot of other stuff
83 | # in there that I didn't want to include directly in this class.
84 | def class_by_name(cname)
85 | if(cname.instance_of? Symbol)
86 | cname = camel_case(cname)
87 | end
88 | Viewpoint::EWS::Types.const_get(cname)
89 | end
90 |
91 | # Used for multiple accessors
92 | def merge_restrictions!(obj, merge_type = :and)
93 | if obj.opts[:restriction] && !obj.opts[:restriction].empty? && !obj.restriction.empty?
94 | obj.opts[:restriction] = {
95 | merge_type => [
96 | obj.opts.delete(:restriction),
97 | obj.restriction
98 | ]
99 | }
100 | elsif !obj.restriction.empty?
101 | obj.opts[:restriction] = obj.restriction
102 | end
103 | end
104 |
105 | end
106 |
--------------------------------------------------------------------------------
/lib/ews/exceptions/exceptions.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 | module Viewpoint::EWS
19 |
20 | # Generic Ews Error
21 | class EwsError < StandardError; end
22 |
23 | # Raise when authentication/authorization issues occur.
24 | class EwsLoginError < EwsError; end
25 |
26 | class EwsSubscriptionError < EwsError; end
27 |
28 | # Raised when a user tries to query a folder subscription after the
29 | # subscription has timed out.
30 | class EwsSubscriptionTimeout < EwsSubscriptionError; end
31 |
32 | # Represents a function in EWS that is not yet implemented in Viewpoint
33 | class EwsNotImplemented < EwsError; end
34 |
35 | # Raised when an method is called in the wrong way
36 | class EwsBadArgumentError < EwsError; end
37 |
38 | # Raised when an item that is asked for is not found
39 | class EwsItemNotFound < EwsError; end
40 |
41 | # Raised when a folder that is asked for is not found
42 | class EwsFolderNotFound < EwsError; end
43 |
44 | # Raise an Exchange Server version error. This is in case some functionality
45 | # does not exist in a particular Server version but is called.
46 | class EwsServerVersionError < EwsError; end
47 |
48 | # Raised when #auto_deepen == false and a method is called for attributes
49 | # that have not yet been fetched.
50 | class EwsMinimalObjectError < EwsError; end
51 |
52 | class EwsFrozenObjectError < EwsError; end
53 |
54 | # Failed to save an object back to the EWS store.
55 | class SaveFailed < EwsError; end
56 |
57 | class EwsCreateItemError < EwsError; end
58 |
59 | class EwsSendItemError < EwsError; end
60 |
61 | end # Viewpoint::EWS
62 |
--------------------------------------------------------------------------------
/lib/ews/impersonation.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS
2 |
3 | ConnectingSID = {
4 | :UPN => 'PrincipalName',
5 | :SID => 'SID',
6 | :PSMTP => 'PrimarySmtpAddress',
7 | :SMTP => 'SmtpAddress'
8 | }
9 |
10 | # @param connecting_type [String] should be one of the ConnectingSID variables
11 | # ConnectingSID[:UPN] - use User Principal Name method
12 | # ConnectingSID[:SID] - use Security Identifier method
13 | # ConnectingSID[:PSMTP] - use primary Simple Mail Transfer Protocol method
14 | # ConnectingSID[:SMTP] - use Simple Mail Transfer Protocol method
15 | # you can add any other string, it will be converted into xml tag on soap request
16 | # @param address [String] an address to include to requests for impersonation
17 | def set_impersonation(connecting_type, address)
18 | if ConnectingSID.has_value? connecting_type or connecting_type.is_a? String then
19 | ews.impersonation_type = connecting_type
20 | ews.impersonation_address = address
21 | else
22 | raise EwsBadArgumentError, "Not a proper connecting method: #{connecting_type.class}"
23 | end
24 | end
25 |
26 | def remove_impersonation
27 | ews.impersonation_type = ""
28 | ews.impersonation_address = ""
29 | end
30 | end
--------------------------------------------------------------------------------
/lib/ews/mailbox_accessors.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::MailboxAccessors
20 | include Viewpoint::EWS
21 |
22 | # Resolve contacts in the Exchange Data Store
23 | # @param [String] ustring A string to resolve contacts to.
24 | # @return [Array] It returns an Array of MailboxUsers.
25 | def search_contacts(ustring)
26 | resp = ews.resolve_names(:name => ustring)
27 |
28 | users = []
29 | if(resp.status == 'Success')
30 | mb = resp.response_message[:elems][:resolution_set][:elems][0][:resolution][:elems][0]
31 | users << Types::MailboxUser.new(ews, mb[:mailbox][:elems])
32 | elsif(resp.code == 'ErrorNameResolutionMultipleResults')
33 | resp.response_message[:elems][:resolution_set][:elems].each do |u|
34 | if u[:resolution][:elems][0][:mailbox]
35 | users << Types::MailboxUser.new(ews, u[:resolution][:elems][0][:mailbox][:elems])
36 | end
37 | end
38 | else
39 | raise EwsError, "Find User produced an error: #{resp.code}: #{resp.message}"
40 | end
41 | users
42 | end
43 |
44 | # GetUserAvailability request
45 | # @see http://msdn.microsoft.com/en-us/library/aa563800.aspx
46 | # @param [Array] emails A list of emails you want to retrieve free-busy info for.
47 | # @param [Hash] opts
48 | # @option opts [DateTime] :start_time
49 | # @option opts [DateTime] :end_time
50 | # @option opts [Symbol] :requested_view :merged_only/:free_busy/
51 | # :free_busy_merged/:detailed/:detailed_merged
52 | # @option opts [Hash] :time_zone The TimeZone data
53 | # Example: {:bias => 'UTC offset in minutes',
54 | # :standard_time => {:bias => 480, :time => '02:00:00',
55 | # :day_order => 5, :month => 10, :day_of_week => 'Sunday'},
56 | # :daylight_time => {same options as :standard_time}}
57 | def get_user_availability(emails, opts)
58 | opts = opts.clone
59 | args = get_user_availability_args(emails, opts)
60 | resp = ews.get_user_availability(args.merge(opts))
61 | get_user_availability_parser(resp)
62 | end
63 |
64 |
65 | private
66 |
67 | def get_user_availability_args(emails, opts)
68 | unless opts.has_key?(:start_time) && opts.has_key?(:end_time) && opts.has_key?(:requested_view)
69 | raise EwsBadArgumentError, "You must specify a start_time, end_time and requested_view."
70 | end
71 |
72 | default_args = {
73 | mailbox_data: (emails.collect{|e| [email: {address: e}]}.flatten),
74 | free_busy_view_options: {
75 | time_window: {
76 | start_time: opts[:start_time],
77 | end_time: opts[:end_time]
78 | },
79 | requested_view: { :requested_free_busy_view => opts[:requested_view] },
80 | }
81 | }
82 | end
83 |
84 | def get_user_availability_parser(resp)
85 | if(resp.status == 'Success')
86 | resp
87 | else
88 | raise EwsError, "GetUserAvailability produced an error: #{resp.code}: #{resp.message}"
89 | end
90 | end
91 |
92 | end # Viewpoint::EWS::MailboxAccessors
93 |
--------------------------------------------------------------------------------
/lib/ews/meeting_accessors.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS::MeetingAccessors
2 | include Viewpoint::EWS
3 |
4 | def accept_meeting(opts)
5 | ews.create_item({
6 | message_disposition: 'SendOnly',
7 | items: [ { accept_item: opts_to_item(opts) } ]
8 | })
9 | end
10 |
11 | def decline_meeting(opts)
12 | ews.create_item({
13 | message_disposition: 'SendOnly',
14 | items: [ { decline_item: opts_to_item(opts) } ]
15 | })
16 | end
17 |
18 | def tentatively_accept_meeting(opts)
19 | ews.create_item({
20 | message_disposition: 'SendOnly',
21 | items: [ { tentatively_accept_item: opts_to_item(opts) } ]
22 | })
23 | end
24 |
25 | private
26 |
27 | def opts_to_item(opts)
28 | hash = {
29 | id: opts[:id],
30 | change_key: opts[:change_key],
31 | sensitivity: opts[:sensitivity]
32 | }
33 |
34 | hash[:text] = opts[:text] if opts[:text]
35 | hash[:body_type] = (opts[:body_type] || 'Text') if opts[:text]
36 |
37 | hash
38 | end
39 | end
40 |
--------------------------------------------------------------------------------
/lib/ews/message_accessors.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 | module Viewpoint::EWS::MessageAccessors
19 | include Viewpoint::EWS
20 |
21 | # Send an E-mail message
22 | #
23 | # @param [Hash] opts A Hash with message params
24 | # @option opts [String] :subject The message subject
25 | # @option opts [String] :body The message body
26 | # @option opts [Array] :to_recipients An array of e-mail addresses to send to
27 | # @option opts [Array] :cc_recipients An array of e-mail addresses to send to
28 | # @option opts [Array] :bcc_recipients An array of e-mail addresses to send to
29 | # @option opts [Array] :extended_properties An array of extended properties
30 | # [{extended_field_uri: {epros}, value: }] or values: [, ]
31 | # @option opts [Boolean] :draft if true it will save to the draft folder
32 | # without sending the message.
33 | # @option opts [String,Symbol,Hash] saved_item_folder_id Either a
34 | # FolderId(String) or a DistinguishedFolderId(Symbol). You can also pass a
35 | # Hash in the form: {id: , change_key: }
36 | # @option opts [Array] :file_attachments an Array of File or Tempfile objects
37 | # @option opts [Array] :inline_attachments an Array of Inline File or Tempfile objects
38 | # @return [Message,Boolean] Returns true if the message is sent, false if
39 | # nothing is returned from EWS or if draft is true it will return the
40 | # Message object. Finally, if something goes wrong, it raises an error
41 | # with a message stating why the e-mail could not be sent.
42 | # @todo Finish ItemAttachments
43 | def send_message(opts = {}, &block)
44 | msg = Template::Message.new opts.clone
45 | yield msg if block_given?
46 | if msg.has_attachments?
47 | draft = msg.draft
48 | resp = parse_create_item(ews.create_item(msg.to_ews))
49 | msg.draft = true
50 | msg.file_attachments.each do |f|
51 | next unless f.kind_of?(File) or f.kind_of?(Tempfile)
52 | resp.add_file_attachment(f)
53 | end
54 | msg.inline_attachments.each do |f|
55 | next unless f.kind_of?(File) or f.kind_of?(Tempfile)
56 | resp.add_inline_attachment(f)
57 | end
58 | if draft
59 | resp.submit_attachments!
60 | resp
61 | else
62 | resp.submit!
63 | end
64 | else
65 | resp = ews.create_item(msg.to_ews)
66 | resp.response_messages ? parse_create_item(resp) : false
67 | end
68 | end
69 |
70 | # See #send_message for options
71 | def draft_message(opts = {}, &block)
72 | send_message opts.merge(draft: true), &block
73 | end
74 |
75 |
76 | private
77 |
78 |
79 | def parse_create_item(resp)
80 | rm = resp.response_messages[0]
81 | if(rm.status == 'Success')
82 | rm.items.empty? ? true : parse_message(rm.items.first)
83 | else
84 | raise EwsError, "Could not send message. #{rm.code}: #{rm.message_text}"
85 | end
86 | end
87 |
88 | def parse_message(msg)
89 | mtype = msg.keys.first
90 | message = class_by_name(mtype).new(ews, msg[mtype])
91 | end
92 |
93 | end # Viewpoint::EWS::MessageAccessors
94 |
--------------------------------------------------------------------------------
/lib/ews/push_subscription_accessors.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::PushSubscriptionAccessors
20 | include Viewpoint::EWS
21 |
22 | def parse_send_notification(msg)
23 | parser = Viewpoint::EWS::SOAP::EwsParser.new(msg)
24 | resp = parser.parse response_class: Viewpoint::EWS::SOAP::EwsResponse
25 | rmsg = resp.response_messages[0]
26 | if rmsg.success?
27 | rmsg
28 | else
29 | raise EwsSubscriptionError, "#{rmsg.code}: #{rmsg.message_text}"
30 | end
31 | end
32 |
33 | end # Viewpoint::EWS::PushSubscriptionAccessors
34 |
--------------------------------------------------------------------------------
/lib/ews/room_accessors.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2013 Camille Baldock
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::RoomAccessors
20 | include Viewpoint::EWS
21 |
22 | # Gets the rooms that are available within the specified room distribution list
23 | # @see http://msdn.microsoft.com/en-us/library/dd899415.aspx
24 | # @param [String] roomDistributionList
25 | def get_rooms(roomDistributionList)
26 | resp = ews.get_rooms(roomDistributionList)
27 | get_rooms_parser(resp)
28 | end
29 |
30 | def room_name( room )
31 | room[:room][:elems][:id][:elems][0][:name][:text]
32 | end
33 |
34 | def room_email( room )
35 | room[:room][:elems][:id][:elems][1][:email_address][:text]
36 | end
37 |
38 | private
39 |
40 | def get_rooms_parser(resp)
41 | if resp.success?
42 | resp
43 | else
44 | raise EwsError, "GetRooms produced an error: #{resp.code}: #{resp.message}"
45 | end
46 | end
47 |
48 | end # Viewpoint::EWS::RoomAccessors
--------------------------------------------------------------------------------
/lib/ews/roomlist_accessors.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2013 Camille Baldock
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::RoomlistAccessors
20 | include Viewpoint::EWS
21 |
22 | # Gets the room lists that are available within the Exchange organization.
23 | # @see http://msdn.microsoft.com/en-us/library/dd899416.aspx
24 | def get_room_lists
25 | resp = ews.get_room_lists
26 | get_room_lists_parser(resp)
27 | end
28 |
29 | def roomlist_name( roomlist )
30 | roomlist[:address][:elems][:name][:text]
31 | end
32 |
33 | def roomlist_email( roomlist )
34 | roomlist[:address][:elems][:email_address][:text]
35 | end
36 |
37 | private
38 |
39 | def get_room_lists_parser(resp)
40 | if resp.success?
41 | resp
42 | else
43 | raise EwsError, "GetRoomLists produced an error: #{resp.code}: #{resp.message}"
44 | end
45 | end
46 |
47 | end # Viewpoint::EWS::RoomlistAccessors
--------------------------------------------------------------------------------
/lib/ews/soap.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | # This module defines some constants and other niceties to make available to
20 | # the underlying SOAP classes and modules that do the actual work.
21 | module Viewpoint
22 | module EWS
23 | module SOAP
24 |
25 | # CONSTANTS
26 |
27 | NS_SOAP = 'soap'.freeze
28 | NS_EWS_TYPES = 't'.freeze
29 | NS_EWS_MESSAGES = 'm'.freeze
30 | NAMESPACES = {
31 | "xmlns:#{NS_SOAP}" => 'http://schemas.xmlsoap.org/soap/envelope/',
32 | "xmlns:#{NS_EWS_TYPES}" => 'http://schemas.microsoft.com/exchange/services/2006/types',
33 | "xmlns:#{NS_EWS_MESSAGES}" => 'http://schemas.microsoft.com/exchange/services/2006/messages',
34 | }.freeze
35 |
36 | # used in ResolveNames to determine where names are resolved
37 | ActiveDirectory = 'ActiveDirectory'
38 | ActiveDirectoryContacts = 'ActiveDirectoryContacts'
39 | Contacts = 'Contacts'
40 | ContactsActiveDirectory = 'ContactsActiveDirectory'
41 |
42 | # Target specific Exchange Server versions
43 | # @see http://msdn.microsoft.com/en-us/library/bb891876(v=exchg.140).aspx
44 | VERSION_2007 = 'Exchange2007'
45 | VERSION_2007_SP1 = 'Exchange2007_SP1'
46 | VERSION_2010 = 'Exchange2010'
47 | VERSION_2010_SP1 = 'Exchange2010_SP1'
48 | VERSION_2010_SP2 = 'Exchange2010_SP2'
49 | VERSION_2013 = 'Exchange2013'
50 | VERSION_2013_SP1 = 'Exchange2013_SP1'
51 | VERSION_NONE = 'none'
52 |
53 | HARD_DELETE = 'HardDelete'
54 | SOFT_DELETE = 'SoftDelete'
55 | MOVE_TO_DELETED_ITEMS = 'MoveToDeletedItems'
56 |
57 | def initialize
58 | @log = Logging.logger[self.class.name.to_s.to_sym]
59 | @default_ns = NAMESPACES["xmlns:#{NS_EWS_MESSAGES}"]
60 | end
61 |
62 | end # SOAP
63 | end # EWS
64 | end # Viewpoint
65 |
--------------------------------------------------------------------------------
/lib/ews/soap/ews_response.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::SOAP
20 |
21 | # A Generic Class for SOAP returns.
22 | class EwsResponse
23 | include Viewpoint::StringUtils
24 |
25 | def initialize(sax_hash)
26 | @resp = sax_hash
27 | simplify!
28 | end
29 |
30 | def envelope
31 | @resp[:envelope][:elems]
32 | end
33 |
34 | def header
35 | envelope[0][:header][:elems]
36 | end
37 |
38 | def body
39 | envelope[1][:body][:elems]
40 | end
41 |
42 | def response
43 | body[0]
44 | end
45 |
46 | def response_messages
47 | return @response_messages if @response_messages
48 |
49 | @response_messages = []
50 | response_type = response.keys.first
51 | response[response_type][:elems][0][:response_messages][:elems].each do |rm|
52 | response_message_type = rm.keys[0]
53 | rm_klass = class_by_name(response_message_type)
54 | @response_messages << rm_klass.new(rm)
55 | end
56 | @response_messages
57 | end
58 |
59 |
60 | private
61 |
62 |
63 | def simplify!
64 | response_type = response.keys.first
65 | response[response_type][:elems][0][:response_messages][:elems].each do |rm|
66 | key = rm.keys.first
67 | rm[key][:elems] = rm[key][:elems].inject(&:merge)
68 | end
69 | end
70 |
71 | def class_by_name(cname)
72 | begin
73 | if(cname.instance_of? Symbol)
74 | cname = camel_case(cname)
75 | end
76 | Viewpoint::EWS::SOAP.const_get(cname)
77 | rescue NameError => e
78 | ResponseMessage
79 | end
80 | end
81 |
82 | end # EwsSoapResponse
83 |
84 | end # Viewpoint::EWS::SOAP
85 |
--------------------------------------------------------------------------------
/lib/ews/soap/ews_soap_availability_response.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::SOAP
20 |
21 | # This is a speciality response class to handle the idiosynracies of
22 | # Availability responses.
23 | # @attr_reader [String] :message The text from the EWS element
24 | class EwsSoapAvailabilityResponse < EwsSoapResponse
25 |
26 | def response_messages
27 | nil
28 | end
29 |
30 | def response
31 | body[0][response_key]
32 | end
33 |
34 | def response_message
35 | key = response.keys.first
36 | response[key]
37 | end
38 |
39 | def response_code
40 | response_message[:elems][:response_code][:text]
41 | end
42 | alias :code :response_code
43 |
44 | def response_key
45 | key = body[0].keys.first
46 | end
47 |
48 | private
49 |
50 | def simplify!
51 | key = response_key
52 | body[0][key] = body[0][key][:elems].inject(:merge)
53 | response_message[:elems] = response_message[:elems].inject(:merge)
54 | end
55 |
56 | end # EwsSoapAvailabilityResponse
57 |
58 | end # Viewpoint::EWS::SOAP
59 |
--------------------------------------------------------------------------------
/lib/ews/soap/ews_soap_free_busy_response.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is a cotribution to Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2013 Mark McCahill
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::SOAP
20 |
21 | class EwsSoapFreeBusyResponse < EwsSoapResponse
22 |
23 | def initialize(sax_hash)
24 | @resp = sax_hash
25 | simplify!
26 | end
27 |
28 | def envelope
29 | @resp[:envelope][:elems]
30 | end
31 |
32 | def header
33 | envelope[0][:header][:elems]
34 | end
35 |
36 | def body
37 | envelope[1][:body][:elems]
38 | end
39 |
40 | def get_user_availability_response
41 | body.first[:get_user_availability_response][:elems].first[:free_busy_response_array][:elems].first[:free_busy_response][:elems]
42 | end
43 |
44 | def response
45 | body
46 | end
47 |
48 | def calendar_event_array
49 | result = find_in_hash_list(get_user_availability_response[1][:free_busy_view][:elems], :calendar_event_array)
50 | result ? result[:elems] : []
51 | end
52 |
53 | def working_hours
54 | get_user_availability_response[1][:free_busy_view][:elems][2][:working_hours][:elems]
55 | end
56 |
57 | def response_message
58 | find_in_hash_list(get_user_availability_response, :response_message)
59 | end
60 |
61 | def response_class
62 | response_message[:attribs][:response_class]
63 | end
64 | alias :status :response_class
65 |
66 | def response_code
67 | result = find_in_hash_list(response_message[:elems], :response_code)
68 | result ? result[:text] : nil
69 | end
70 | alias :code :response_code
71 |
72 | def response_message_text
73 | guard_hash response_message[:elems], [:message_text, :text]
74 | end
75 | alias :message :response_message_text
76 |
77 | def response_key
78 | response_message[:elems]
79 | end
80 |
81 | def success?
82 | response_class == "Success"
83 | end
84 |
85 | private
86 |
87 | def simplify!
88 | # key = response_key
89 | # body[0][key] = body[0][key][:elems].inject(:merge)
90 | # response_message[:elems] = response_message[:elems].inject(:merge)
91 | end
92 |
93 | # If the keys don't exist in the Hash return nil
94 | # @param[Hash] hsh
95 | # @param[Array] keys keys to follow in the array
96 | # @return [Object, nil]
97 | def guard_hash(hsh, keys)
98 | key = keys.shift
99 | return nil unless hsh.is_a?(Hash) && hsh.has_key?(key)
100 |
101 | if keys.empty?
102 | hsh[key]
103 | else
104 | guard_hash hsh[key], keys
105 | end
106 | end
107 |
108 | # Find the first element in a list of hashes or return nil
109 | # Example:
110 | # find_in_hash_list([{:foo => :bar}, {:bar => :baz}], :foo)
111 | # => :bar
112 | def find_in_hash_list(collection, key)
113 | result = collection.find { |hsh| hsh.keys.include?(key) }
114 | result ? result[key] : nil
115 | end
116 |
117 | end # EwsSoapFreeBusyResponse
118 |
119 | end # Viewpoint::EWS::SOAP
120 |
--------------------------------------------------------------------------------
/lib/ews/soap/ews_soap_response.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::SOAP
20 |
21 | # A Generic Class for SOAP returns.
22 | # @attr_reader [String] :message The text from the EWS element
23 | class EwsSoapResponse
24 |
25 | def initialize(sax_hash)
26 | @resp = sax_hash
27 | simplify!
28 | end
29 |
30 | def envelope
31 | @resp[:envelope][:elems]
32 | end
33 |
34 | def header
35 | envelope[0][:header][:elems]
36 | end
37 |
38 | def body
39 | envelope[1][:body][:elems]
40 | end
41 |
42 | def response
43 | body[0]
44 | end
45 |
46 | def response_messages
47 | key = response.keys.first
48 | response[key][:elems].find{|e| e.keys.include? :response_messages }[:response_messages][:elems]
49 | end
50 |
51 | def response_message
52 | key = response_messages[0].keys.first
53 | response_messages[0][key]
54 | end
55 |
56 | def response_class
57 | response_message[:attribs][:response_class]
58 | end
59 | alias :status :response_class
60 |
61 | def response_code
62 | response_message[:elems][:response_code][:text]
63 | end
64 | alias :code :response_code
65 |
66 | def response_message_text
67 | guard_hash response_message[:elems], [:message_text, :text]
68 | end
69 | alias :message :response_message_text
70 |
71 | def success?
72 | response_class == "Success"
73 | end
74 |
75 |
76 | private
77 |
78 |
79 | def simplify!
80 | response_messages.each do |rm|
81 | key = rm.keys.first
82 | rm[key][:elems] = rm[key][:elems].inject(&:merge)
83 | end
84 | end
85 |
86 | # If the keys don't exist in the Hash return nil
87 | # @param[Hash] hsh
88 | # @param[Array] keys keys to follow in the array
89 | # @return [Object, nil]
90 | def guard_hash(hsh, keys)
91 | key = keys.shift
92 | return nil unless hsh.is_a?(Hash) && hsh.has_key?(key)
93 |
94 | if keys.empty?
95 | hsh[key]
96 | else
97 | guard_hash hsh[key], keys
98 | end
99 | end
100 |
101 | end # EwsSoapResponse
102 |
103 | end # Viewpoint::EWS::SOAP
104 |
--------------------------------------------------------------------------------
/lib/ews/soap/ews_soap_room_response.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is a contribution to Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2013 Camille Baldock
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::SOAP
20 |
21 | # A class for roomlists SOAP returns.
22 | # @attr_reader [String] :message The text from the EWS element
23 | class EwsSoapRoomResponse < EwsSoapResponse
24 |
25 | def response_messages
26 | key = response.keys.first
27 | subresponse = response[key][:elems][1]
28 | response_class = subresponse.keys.first
29 | subresponse[response_class][:elems]
30 | end
31 |
32 | def roomsArray
33 | response[:get_rooms_response][:elems][1][:rooms][:elems]
34 | end
35 |
36 | def success?
37 | response.first[1][:attribs][:response_class] == "Success"
38 | end
39 |
40 | private
41 |
42 | def simplify!
43 | if response_messages
44 | response_messages.each do |rm|
45 | key = rm.keys.first
46 | rm[key][:elems] = rm[key][:elems].inject(&:merge)
47 | end
48 | end
49 | end
50 |
51 | end # EwsSoapRoomResponse
52 |
53 | end # Viewpoint::EWS::SOAP
54 |
--------------------------------------------------------------------------------
/lib/ews/soap/ews_soap_roomlist_response.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is a contribution to Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2013 Camille Baldock
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::SOAP
20 |
21 | # A class for roomlists SOAP returns.
22 | # @attr_reader [String] :message The text from the EWS element
23 | class EwsSoapRoomlistResponse < EwsSoapResponse
24 |
25 | def response_messages
26 | key = response.keys.first
27 | subresponse = response[key][:elems][1]
28 | response_class = subresponse.keys.first
29 | subresponse[response_class][:elems]
30 | end
31 |
32 | def roomListsArray
33 | response[:get_room_lists_response][:elems][1][:room_lists][:elems]
34 | end
35 |
36 | def success?
37 | response.first[1][:attribs][:response_class] == "Success"
38 | end
39 |
40 | private
41 |
42 |
43 | def simplify!
44 | if response_messages
45 | response_messages.each do |rm|
46 | key = rm.keys.first
47 | rm[key][:elems] = rm[key][:elems].inject(&:merge)
48 | end
49 | end
50 | end
51 |
52 | end # EwsSoapRoomlistResponse
53 |
54 | end # Viewpoint::EWS::SOAP
55 |
--------------------------------------------------------------------------------
/lib/ews/soap/exchange_availability.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS::SOAP
2 |
3 | # Exchange Availability operations as listed in the EWS Documentation.
4 | # @see http://msdn.microsoft.com/en-us/library/bb409286.aspx
5 | module ExchangeAvailability
6 | include Viewpoint::EWS::SOAP
7 |
8 | # -------------- Availability Operations -------------
9 |
10 | # Gets a mailbox user's Out of Office (OOF) settings and messages.
11 | # @see http://msdn.microsoft.com/en-us/library/aa563465.aspx
12 | # @param [Hash] opts
13 | # @option opts [String] :address the email address of the user
14 | # @option opts [String] :name the user display name (optional)
15 | # @option opts [String] :routing_type the routing protocol (optional and stupid)
16 | def get_user_oof_settings(opts)
17 | opts = opts.clone
18 | [:address].each do |k|
19 | validate_param(opts, k, true)
20 | end
21 | req = build_soap! do |type, builder|
22 | if(type == :header)
23 | else
24 | builder.nbuild.GetUserOofSettingsRequest {|x|
25 | x.parent.default_namespace = @default_ns
26 | builder.mailbox!(opts)
27 | }
28 | end
29 | end
30 | do_soap_request(req, response_class: EwsSoapAvailabilityResponse)
31 | end
32 |
33 | # Sets a mailbox user's Out of Office (OOF) settings and message.
34 | # @see http://msdn.microsoft.com/en-us/library/aa580294.aspx
35 | # @param [Hash] opts
36 | # @option opts [Hash] :mailbox the mailbox hash for the use
37 | # @option opts [String,Symbol] :oof_state :enabled, :disabled, :scheduled
38 | # @option opts [Hash] :duration {start_time: DateTime, end_time: DateTime}
39 | # @option opts [String] :internal_reply
40 | # @option opts [String] :external_reply
41 | # @option opts [String,Symbol] :external_audience :none, :known, :all
42 | def set_user_oof_settings(opts)
43 | opts = opts.clone
44 | [:mailbox, :oof_state].each do |k|
45 | validate_param(opts, k, true)
46 | end
47 | req = build_soap! do |type, builder|
48 | if(type == :header)
49 | else
50 | builder.nbuild.SetUserOofSettingsRequest {|x|
51 | x.parent.default_namespace = @default_ns
52 | builder.mailbox! opts.delete(:mailbox)
53 | builder.user_oof_settings!(opts)
54 | }
55 | end
56 | end
57 | do_soap_request(req, response_class: EwsSoapAvailabilityResponse)
58 | end
59 |
60 | end #ExchangeAvailability
61 | end
62 |
--------------------------------------------------------------------------------
/lib/ews/soap/exchange_notification.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::SOAP
20 |
21 | # Exchange Notification operations as listed in the EWS Documentation.
22 | # @see http://msdn.microsoft.com/en-us/library/bb409286.aspx
23 | module ExchangeNotification
24 | include Viewpoint::EWS::SOAP
25 |
26 | # Used to subscribe client applications to either push, pull or stream notifications.
27 | # @see http://msdn.microsoft.com/en-us/library/aa566188(v=EXCHG.140).aspx
28 | # @param [Array] subscriptions An array of Hash objects that describe each
29 | # subscription.
30 | # Ex: [ {:pull_subscription_request => {
31 | # :subscribe_to_all_folders => false,
32 | # :folder_ids => [ {:id => 'id', :change_key => 'ck'} ],
33 | # :event_types=> %w{CopiedEvent CreatedEvent},
34 | # :watermark => 'watermark id',
35 | # :timeout => intval
36 | # }},
37 | # {:push_subscription_request => {
38 | # :subscribe_to_all_folders => true,
39 | # :event_types=> %w{CopiedEvent CreatedEvent},
40 | # :status_frequency => 15,
41 | # :uRL => 'http://my.endpoint.for.updates/',
42 | # }},
43 | # {:streaming_subscription_request => {
44 | # :subscribe_to_all_folders => false,
45 | # :folder_ids => [ {:id => 'id', :change_key => 'ck'} ],
46 | # :event_types=> %w{NewMailEvent DeletedEvent},
47 | # }},
48 | # ]
49 | def subscribe(subscriptions)
50 | req = build_soap! do |type, builder|
51 | if(type == :header)
52 | else
53 | builder.nbuild.Subscribe {
54 | builder.nbuild.parent.default_namespace = @default_ns
55 | subscriptions.each do |sub|
56 | subtype = sub.keys.first
57 | if(builder.respond_to?(subtype))
58 | builder.send subtype, sub[subtype]
59 | else
60 | raise EwsBadArgumentError, "Bad subscription type. #{subtype}"
61 | end
62 | end
63 | }
64 | end
65 | end
66 | do_soap_request(req, response_class: EwsResponse)
67 | end
68 |
69 | # End a pull notification subscription.
70 | # @see http://msdn.microsoft.com/en-us/library/aa564263.aspx
71 | #
72 | # @param [String] subscription_id The Id of the subscription
73 | def unsubscribe(subscription_id)
74 | req = build_soap! do |type, builder|
75 | if(type == :header)
76 | else
77 | builder.nbuild.Unsubscribe {
78 | builder.nbuild.parent.default_namespace = @default_ns
79 | builder.subscription_id!(subscription_id)
80 | }
81 | end
82 | end
83 | do_soap_request(req, response_class: EwsResponse)
84 | end
85 |
86 | # Used by pull subscription clients to request notifications from the Client Access server
87 | # @see http://msdn.microsoft.com/en-us/library/aa566199.aspx GetEvents on MSDN
88 | #
89 | # @param [String] subscription_id Subscription identifier
90 | # @param [String] watermark Event bookmark in the events queue
91 | def get_events(subscription_id, watermark)
92 | req = build_soap! do |type, builder|
93 | if(type == :header)
94 | else
95 | builder.nbuild.GetEvents {
96 | builder.nbuild.parent.default_namespace = @default_ns
97 | builder.subscription_id!(subscription_id)
98 | builder.watermark!(watermark, NS_EWS_MESSAGES)
99 | }
100 | end
101 | end
102 | do_soap_request(req, response_class: EwsResponse)
103 | end
104 |
105 |
106 | # ------- convenience methods ------- #
107 |
108 | # Create a pull subscription to a single folder
109 | # @param folder [Hash] a hash with the folder :id and :change_key
110 | # @param evtypes [Array] the events you would like to subscribe to.
111 | # @param timeout [Fixnum] http://msdn.microsoft.com/en-us/library/aa565201.aspx
112 | # @param watermark [String] http://msdn.microsoft.com/en-us/library/aa565886.aspx
113 | def pull_subscribe_folder(folder, evtypes, timeout = nil, watermark = nil)
114 | timeout ||= 240 # 4 hour default timeout
115 | psr = {
116 | :subscribe_to_all_folders => false,
117 | :folder_ids => [ {:id => folder[:id], :change_key => folder[:change_key]} ],
118 | :event_types=> evtypes,
119 | :timeout => timeout
120 | }
121 | psr[:watermark] = watermark if watermark
122 | subscribe([{pull_subscription_request: psr}])
123 | end
124 |
125 | # Create a push subscription to a single folder
126 | # @param folder [Hash] a hash with the folder :id and :change_key
127 | # @param evtypes [Array] the events you would like to subscribe to.
128 | # @param url [String,URI] http://msdn.microsoft.com/en-us/library/aa566309.aspx
129 | # @param watermark [String] http://msdn.microsoft.com/en-us/library/aa565886.aspx
130 | # @param status_frequency [Fixnum] http://msdn.microsoft.com/en-us/library/aa564048.aspx
131 | def push_subscribe_folder(folder, evtypes, url, status_frequency = nil, watermark = nil)
132 | status_frequency ||= 30
133 | psr = {
134 | :subscribe_to_all_folders => false,
135 | :folder_ids => [ {:id => folder[:id], :change_key => folder[:change_key]} ],
136 | :event_types=> evtypes,
137 | :status_frequency => status_frequency,
138 | :uRL => url.to_s
139 | }
140 | psr[:watermark] = watermark if watermark
141 | subscribe([{push_subscription_request: psr}])
142 | end
143 |
144 |
145 | end #ExchangeNotification
146 | end
147 |
--------------------------------------------------------------------------------
/lib/ews/soap/exchange_synchronization.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::SOAP
20 |
21 | # Exchange Synchronization operations as listed in the EWS Documentation.
22 | # @see http://msdn.microsoft.com/en-us/library/bb409286.aspx
23 | module ExchangeSynchronization
24 | include Viewpoint::EWS::SOAP
25 |
26 | # Defines a request to synchronize a folder hierarchy on a client
27 | # @see http://msdn.microsoft.com/en-us/library/aa580990.aspx
28 | # @param [Hash] opts
29 | # @option opts [Hash] :folder_shape The folder shape properties
30 | # Ex: {:base_shape => 'Default', :additional_properties => 'bla bla bla'}
31 | # @option opts [Hash] :sync_folder_id An optional Hash that represents a FolderId or
32 | # DistinguishedFolderId.
33 | # Ex: {:id => :inbox}
34 | # @option opts [Hash] :sync_state The Base64 sync state id. If this is the
35 | # first time syncing this does not need to be passed.
36 | def sync_folder_hierarchy(opts)
37 | opts = opts.clone
38 | req = build_soap! do |type, builder|
39 | if(type == :header)
40 | else
41 | builder.nbuild.SyncFolderHierarchy {
42 | builder.nbuild.parent.default_namespace = @default_ns
43 | builder.folder_shape!(opts[:folder_shape])
44 | builder.sync_folder_id!(opts[:sync_folder_id]) if opts[:sync_folder_id]
45 | builder.sync_state!(opts[:sync_state]) if opts[:sync_state]
46 | }
47 | end
48 | end
49 | do_soap_request(req, response_class: EwsResponse)
50 | end
51 |
52 | # Synchronizes items between the Exchange server and the client
53 | # @see http://msdn.microsoft.com/en-us/library/aa563967(v=EXCHG.140).aspx
54 | # @param [Hash] opts
55 | # @option opts [Hash] :item_shape The item shape properties
56 | # Ex: {:base_shape => 'Default', :additional_properties => 'bla bla bla'}
57 | # @option opts [Hash] :sync_folder_id A Hash that represents a FolderId or
58 | # DistinguishedFolderId. [ Ex: {:id => :inbox} ] OPTIONAL
59 | # @option opts [String] :sync_state The Base64 sync state id. If this is the
60 | # first time syncing this does not need to be passed. OPTIONAL on first call
61 | # @option opts [Array ] :ignore An Array of ItemIds for items to ignore
62 | # during the sync process. Ex: [{:id => 'id1', :change_key => 'ck'}, {:id => 'id2'}]
63 | # OPTIONAL
64 | # @option opts [Integer] :max_changes_returned ('required') The amount of items to sync per call.
65 | # @option opts [String] :sync_scope specifies whether just items or items and folder associated
66 | # information are returned. OPTIONAL
67 | # options: 'NormalItems' or 'NormalAndAssociatedItems'
68 | # @example
69 | # { :item_shape => {:base_shape => 'Default'},
70 | # :sync_folder_id => {:id => :inbox},
71 | # :sync_state => myBase64id,
72 | # :max_changes_returned => 256 }
73 | def sync_folder_items(opts)
74 | opts = opts.clone
75 | req = build_soap! do |type, builder|
76 | if(type == :header)
77 | else
78 | builder.nbuild.SyncFolderItems {
79 | builder.nbuild.parent.default_namespace = @default_ns
80 | builder.item_shape!(opts[:item_shape])
81 | builder.sync_folder_id!(opts[:sync_folder_id]) if opts[:sync_folder_id]
82 | builder.sync_state!(opts[:sync_state]) if opts[:sync_state]
83 | builder.ignore!(opts[:ignore]) if opts[:ignore]
84 | builder.max_changes_returned!(opts[:max_changes_returned])
85 | builder.sync_scope!(opts[:sync_scope]) if opts[:sync_scope]
86 | }
87 | end
88 | end
89 | do_soap_request(req, response_class: EwsResponse)
90 | end
91 |
92 | end #ExchangeSynchronization
93 | end
94 |
--------------------------------------------------------------------------------
/lib/ews/soap/exchange_time_zones.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS::SOAP
2 |
3 | module ExchangeTimeZones
4 | include Viewpoint::EWS::SOAP
5 |
6 | # Request list of server known time zones
7 | # @param full [Boolean] Request full time zone definition? Returns only name and id if false.
8 | # @param ids [Array] Returns only the specified time zones instead of all if present
9 | # @return [Array] Array of Objects responding to #id() and #name()
10 | # @example Retrieving server time zones
11 | # ews_client = Viewpoint::EWSClient.new # ...
12 | # zones = ews_client.ews.get_time_zones
13 | # @todo Implement TimeZoneDefinition with sub elements Periods, TransitionsGroups and Transitions
14 | def get_time_zones(full = false, ids = nil)
15 | req = build_soap! do |type, builder|
16 | unless type == :header
17 | builder.get_server_time_zones!(full: full, ids: ids)
18 | end
19 | end
20 | result = do_soap_request req, response_class: EwsSoapResponse
21 |
22 | if result.success?
23 | zones = []
24 | result.response_messages.each do |message|
25 | elements = message[:get_server_time_zones_response_message][:elems][:time_zone_definitions][:elems]
26 | elements.each do |definition|
27 | data = {
28 | id: definition[:time_zone_definition][:attribs][:id],
29 | name: definition[:time_zone_definition][:attribs][:name]
30 | }
31 | zones << OpenStruct.new(data)
32 | end
33 | end
34 | zones
35 | else
36 | raise EwsError, "Could not get time zones"
37 | end
38 | end
39 |
40 | # Sets the time zone context header
41 | # @param id [String] Identifier of a Microsoft well known time zone
42 | # @example Set time zone context for connection
43 | # ews_client = Viewpoint::EWSClient.new # ...
44 | # ews_client.set_time_zone 'AUS Central Standard Time'
45 | # # subsequent request will send the TimeZoneContext header
46 | # @see EWSClient#set_time_zone
47 | def set_time_zone_context(id)
48 | if id
49 | @time_zone_context = {id: id}
50 | else
51 | @time_zone_context = nil
52 | end
53 | end
54 |
55 | end
56 | end
57 |
--------------------------------------------------------------------------------
/lib/ews/soap/exchange_user_configuration.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS::SOAP
2 |
3 | # Exchange User Configuration operations as listed in the EWS Documentation.
4 | # @see http://msdn.microsoft.com/en-us/library/bb409286.aspx
5 | module ExchangeUserConfiguration
6 | include Viewpoint::EWS::SOAP
7 |
8 | # The GetUserConfiguration operation gets a user configuration object from
9 | # a folder.
10 | # @see http://msdn.microsoft.com/en-us/library/aa563465.aspx
11 | # @param [Hash] opts
12 | # @option opts [Hash] :user_config_name
13 | # @option opts [String] :user_config_props
14 | def get_user_configuration(opts)
15 | opts = opts.clone
16 | [:user_config_name, :user_config_props].each do |k|
17 | validate_param(opts, k, true)
18 | end
19 | req = build_soap! do |type, builder|
20 | if(type == :header)
21 | else
22 | builder.nbuild.GetUserConfiguration {|x|
23 | x.parent.default_namespace = @default_ns
24 | builder.user_configuration_name!(opts[:user_config_name])
25 | builder.user_configuration_properties!(opts[:user_config_props])
26 | }
27 | end
28 | end
29 | do_soap_request(req, response_class: EwsSoapAvailabilityResponse)
30 | end
31 |
32 | end #ExchangeUserConfiguration
33 | end
34 |
--------------------------------------------------------------------------------
/lib/ews/soap/parsers/ews_parser.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::SOAP
20 | class EwsParser
21 | include Viewpoint::EWS
22 |
23 | # @param [String] soap_resp
24 | def initialize(soap_resp)
25 | @soap_resp = soap_resp
26 | @sax_doc = EwsSaxDocument.new
27 | end
28 |
29 | def parse(opts = {})
30 | opts[:response_class] ||= EwsSoapResponse
31 | @soap_resp.gsub!(/([0-8bcef]|1[0-9a-f]);/i, '')
32 | sax_parser.parse(@soap_resp)
33 | opts[:response_class].new @sax_doc.struct
34 | end
35 |
36 | private
37 |
38 | def sax_parser
39 | @parser ||= Nokogiri::XML::SAX::Parser.new(@sax_doc)
40 | end
41 |
42 | end # EwsParser
43 | end # Viewpoint
44 |
--------------------------------------------------------------------------------
/lib/ews/soap/parsers/ews_sax_document.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::SOAP
20 | # Parse the incoming response document via a SAX parser instead of the
21 | # traditional DOM parser. In early benchmarks this was performing about
22 | # 132% faster than the DOM-based parser for large documents.
23 | class EwsSaxDocument < Nokogiri::XML::SAX::Document
24 | include Viewpoint::EWS
25 | include Viewpoint::StringUtils
26 |
27 | attr_reader :struct
28 |
29 | def initialize
30 | @struct = {}
31 | @elems = []
32 | end
33 |
34 | def characters(string)
35 | # FIXME: Move white space removal to somewhere else.
36 | # This function can be called multiple times. In this case newlines in Text Bodies get stripped.
37 | # See: https://github.com/zenchild/Viewpoint/issues/90
38 | #string.strip!
39 | return if string.empty?
40 | if @elems.last[:text]
41 | @elems.last[:text] += string
42 | else
43 | @elems.last[:text] = string
44 | end
45 | end
46 |
47 | def start_element_namespace(name, attributes = [], prefix = nil, uri = nil, ns = [])
48 | name = ruby_case(name).to_sym
49 | elem = {}
50 | unless attributes.empty?
51 | elem[:attribs] = attributes.collect{|a|
52 | { ruby_case(a.localname).to_sym => a.value}
53 | }.inject(&:merge)
54 | end
55 | @elems << elem
56 | end
57 |
58 | def end_element_namespace name, prefix=nil, uri=nil
59 | name = ruby_case(name).to_sym
60 | elem = @elems.pop
61 | if @elems.empty?
62 | @struct[name] = elem
63 | else
64 | @elems.last[:elems] = [] unless @elems.last[:elems].is_a?(Array)
65 | @elems.last[:elems] << {name => elem}
66 | end
67 | end
68 |
69 | end
70 | end
71 |
--------------------------------------------------------------------------------
/lib/ews/soap/response_message.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::SOAP
20 | class ResponseMessage
21 |
22 | attr_reader :message, :type
23 |
24 | def initialize(message)
25 | @type = message.keys.first
26 | @message = message[@type]
27 | end
28 |
29 | def response_class
30 | message[:attribs][:response_class]
31 | end
32 | alias :status :response_class
33 |
34 | def success?
35 | response_class == 'Success'
36 | end
37 |
38 | def message_text
39 | safe_hash_access message, [:elems, :message_text, :text]
40 | end
41 |
42 | def response_code
43 | safe_hash_access message, [:elems, :response_code, :text]
44 | end
45 | alias :code :response_code
46 |
47 | def message_xml
48 | safe_hash_access message, [:elems, :message_xml, :text]
49 | end
50 |
51 | def items
52 | safe_hash_access(message, [:elems, :items, :elems]) || []
53 | end
54 |
55 |
56 | private
57 |
58 |
59 | def safe_hash_access(hsh, keys)
60 | key = keys.shift
61 | return nil unless hsh.is_a?(Hash) && hsh.has_key?(key)
62 |
63 | if keys.empty?
64 | hsh[key]
65 | else
66 | safe_hash_access hsh[key], keys
67 | end
68 | end
69 |
70 | end
71 | end # Viewpoint::EWS::SOAP
72 |
73 | require_relative './responses/create_item_response_message'
74 | require_relative './responses/create_attachment_response_message'
75 | require_relative './responses/find_item_response_message'
76 | require_relative './responses/subscribe_response_message'
77 | require_relative './responses/get_events_response_message'
78 | require_relative './responses/send_notification_response_message'
79 | require_relative './responses/sync_folder_items_response_message'
80 | require_relative './responses/sync_folder_hierarchy_response_message'
81 |
--------------------------------------------------------------------------------
/lib/ews/soap/responses/create_attachment_response_message.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::SOAP
20 |
21 | class CreateAttachmentResponseMessage < ResponseMessage
22 | include Viewpoint::StringUtils
23 |
24 | def attachments
25 | return @attachments if @attachments
26 |
27 | a = safe_hash_access message, [:elems, :attachments, :elems]
28 | @attachments = a.nil? ? nil : parse_attachments(a)
29 | end
30 |
31 |
32 | private
33 |
34 |
35 | def parse_attachments(att)
36 | att.collect do |a|
37 | type = a.keys.first
38 | klass = Viewpoint::EWS::Types.const_get(camel_case(type))
39 | item = OpenStruct.new
40 | item.ews = nil
41 | klass.new(item, a[type])
42 | end
43 | end
44 |
45 | end # CreateAttachmentResponseMessage
46 |
47 | end # Viewpoint::EWS::SOAP
48 |
--------------------------------------------------------------------------------
/lib/ews/soap/responses/create_item_response_message.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::SOAP
20 |
21 | class CreateItemResponseMessage < ResponseMessage
22 |
23 | end # CreateItemResponseMessage
24 |
25 | end # Viewpoint::EWS::SOAP
26 |
--------------------------------------------------------------------------------
/lib/ews/soap/responses/find_item_response_message.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::SOAP
20 |
21 | class RootFolder
22 |
23 | attr_reader :root
24 |
25 | def initialize(root)
26 | @root = root
27 | end
28 |
29 | def indexed_paging_offset
30 | attrib :index_paging_offset
31 | end
32 |
33 | def numerator_offset
34 | attrib :numerator_offset
35 | end
36 |
37 | def absolute_denominator
38 | attrib :absolute_denominator
39 | end
40 |
41 | def includes_last_item_in_range
42 | attrib :includes_last_item_in_range
43 | end
44 |
45 | def total_items_in_view
46 | attrib :total_items_in_view
47 | end
48 |
49 | def items
50 | root[:elems][0][:items][:elems] || []
51 | end
52 |
53 | def groups
54 | root[:elems][0][:groups][:elems]
55 | end
56 |
57 |
58 | private
59 |
60 |
61 | def attrib(key)
62 | return nil unless root.has_key?(:attribs)
63 | root[:attribs][key]
64 | end
65 |
66 | end
67 |
68 |
69 | class FindItemResponseMessage < ResponseMessage
70 |
71 | def root_folder
72 | return @root_folder if @root_folder
73 |
74 | rf = safe_hash_access message, [:elems, :root_folder]
75 | @root_folder = rf.nil? ? nil : RootFolder.new(rf)
76 | end
77 |
78 | end # FindItemResponseMessage
79 |
80 | end # Viewpoint::EWS::SOAP
81 |
--------------------------------------------------------------------------------
/lib/ews/soap/responses/get_events_response_message.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::SOAP
20 | class GetEventsResponseMessage < ResponseMessage
21 |
22 | def notification
23 | safe_hash_access message, [:elems, :notification, :elems]
24 | end
25 |
26 | def subscription_id
27 | safe_hash_access notification[0], [:subscription_id, :text]
28 | end
29 |
30 | def previous_watermark
31 | safe_hash_access notification[1], [:previous_watermark, :text]
32 | end
33 |
34 | def new_watermark
35 | ev = notification.last
36 | if ev
37 | type = ev.keys.first
38 | ev[type][:elems][0][:watermark][:text]
39 | else
40 | nil
41 | end
42 | end
43 |
44 | def more_events?
45 | safe_hash_access(notification[2], [:more_events, :text]) == 'true'
46 | end
47 |
48 | def events
49 | notification[3..-1]
50 | end
51 |
52 | end # GetEventsResponseMessage
53 | end # Viewpoint::EWS::SOAP
54 |
--------------------------------------------------------------------------------
/lib/ews/soap/responses/send_notification_response_message.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::SOAP
20 | class SendNotificationResponseMessage < ResponseMessage
21 | include Viewpoint::StringUtils
22 |
23 | def notification
24 | safe_hash_access message, [:elems, :notification, :elems]
25 | end
26 |
27 | def subscription_id
28 | safe_hash_access notification[0], [:subscription_id, :text]
29 | end
30 |
31 | def previous_watermark
32 | safe_hash_access notification[1], [:previous_watermark, :text]
33 | end
34 |
35 | def new_watermark
36 | ev = notification.last
37 | if ev
38 | type = ev.keys.first
39 | ev[type][:elems][0][:watermark][:text]
40 | else
41 | nil
42 | end
43 | end
44 |
45 | def more_events?
46 | safe_hash_access(notification[2], [:more_events, :text]) == 'true'
47 | end
48 |
49 | def events
50 | @events ||=
51 | notification[3..-1].collect do |ev|
52 | type = ev.keys.first
53 | klass = Viewpoint::EWS::Types.const_get(camel_case(type))
54 | klass.new(nil, ev[type])
55 | end
56 | end
57 |
58 | end # SendNotificationResponseMessage
59 | end # Viewpoint::EWS::SOAP
60 |
--------------------------------------------------------------------------------
/lib/ews/soap/responses/subscribe_response_message.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::SOAP
20 | class SubscribeResponseMessage < ResponseMessage
21 |
22 | def subscription
23 | safe_hash_access message, [:elems]
24 | end
25 |
26 | def subscription_id
27 | safe_hash_access subscription, [:subscription_id, :text]
28 | end
29 |
30 | def watermark
31 | safe_hash_access subscription, [:watermark, :text]
32 | end
33 |
34 | end # SubscribeResponseMessage
35 | end # Viewpoint::EWS::SOAP
36 |
--------------------------------------------------------------------------------
/lib/ews/soap/responses/sync_folder_hierarchy_response_message.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::SOAP
20 | class SyncFolderHierarchyResponseMessage < ResponseMessage
21 |
22 | def sync_state
23 | safe_hash_access message, [:elems, :sync_state, :text]
24 | end
25 |
26 | def includes_last_folder_in_range?
27 | ans = safe_hash_access message, [:elems, :includes_last_folder_in_range, :text]
28 | ans.downcase == 'true'
29 | end
30 |
31 | def changes
32 | safe_hash_access(message, [:elems, :changes, :elems]) || []
33 | end
34 |
35 | end # SyncFolderHierarchyResponseMessage
36 | end # Viewpoint::EWS::SOAP
37 |
--------------------------------------------------------------------------------
/lib/ews/soap/responses/sync_folder_items_response_message.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::SOAP
20 | class SyncFolderItemsResponseMessage < ResponseMessage
21 |
22 | def sync_state
23 | safe_hash_access message, [:elems, :sync_state, :text]
24 | end
25 |
26 | def includes_last_item_in_range?
27 | ans = safe_hash_access message, [:elems, :includes_last_item_in_range, :text]
28 | ans.downcase == 'true'
29 | end
30 |
31 | def changes
32 | safe_hash_access(message, [:elems, :changes, :elems]) || []
33 | end
34 |
35 | end # SyncFolderItemsResponseMessage
36 | end # Viewpoint::EWS::SOAP
37 |
--------------------------------------------------------------------------------
/lib/ews/templates/calendar_item.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS
2 | module Template
3 | # Template for creating CalendarItems
4 | # @see http://msdn.microsoft.com/en-us/library/exchange/aa564765.aspx
5 | class CalendarItem < OpenStruct
6 |
7 | # Available parameters with the required ordering
8 | PARAMETERS = %w{mime_content item_id parent_folder_id item_class subject sensitivity body attachments
9 | date_time_received size categories in_reply_to is_submitted is_draft is_from_me is_resend is_unmodified
10 | internet_message_headers date_time_sent date_time_created response_objects reminder_due_by reminder_is_set
11 | reminder_minutes_before_start display_cc display_to has_attachments extended_property culture start end
12 | original_start is_all_day_event legacy_free_busy_status location when is_meeting is_cancelled is_recurring
13 | meeting_request_was_sent is_response_requested calendar_item_type my_response_type organizer
14 | required_attendees optional_attendees resources conflicting_meeting_count adjacent_meeting_count
15 | conflicting_meetings adjacent_meetings duration time_zone appointment_reply_time appointment_sequence_number
16 | appointment_state recurrence first_occurrence last_occurrence modified_occurrences deleted_occurrences
17 | meeting_time_zone start_time_zone end_time_zone conference_type allow_new_time_proposal is_online_meeting
18 | meeting_workspace_url net_show_url effective_rights last_modified_name last_modified_time is_associated
19 | web_client_read_form_query_string web_client_edit_form_query_string conversation_id unique_body
20 | }.map(&:to_sym).freeze
21 |
22 | # Returns a new CalendarItem template
23 | def initialize(opts = {})
24 | super opts.dup
25 | end
26 |
27 | # EWS CreateItem container
28 | # @return [Hash]
29 | def to_ews_create(opts = {})
30 | structure = {}
31 | structure[:message_disposition] = (draft ? 'SaveOnly' : 'SendAndSaveCopy')
32 | # options
33 | structure[:send_meeting_invitations] = (opts.has_key?(:send_meeting_invitations) ? opts[:send_meeting_invitations] : 'SendToNone')
34 |
35 | if self.saved_item_folder_id
36 | if self.saved_item_folder_id.kind_of?(Hash)
37 | structure[:saved_item_folder_id] = saved_item_folder_id
38 | else
39 | structure[:saved_item_folder_id] = {id: saved_item_folder_id}
40 | end
41 | end
42 |
43 | structure[:items] = [{calendar_item: to_ews_item}]
44 | structure
45 | end
46 |
47 | # EWS Item hash
48 | #
49 | # Puts all known parameters in the required ordering and structure
50 | # @return [Hash]
51 | def to_ews_item
52 | item_parameters = {}
53 | PARAMETERS.each do |key|
54 | if !(value = self.send(key)).nil?
55 |
56 | # Convert non duplicable values to String
57 | case value
58 | when NilClass, FalseClass, TrueClass, Symbol, Numeric
59 | value = value.to_s
60 | end
61 |
62 | # Convert attributes
63 | case key
64 | when :start, :end
65 | item_parameters[key] = {text: value.respond_to?(:iso8601) ? value.iso8601 : value}
66 | when :body
67 | item_parameters[key] = {body_type: self.body_type || 'Text', text: value.to_s}
68 | else
69 | item_parameters[key] = value
70 | end
71 | end
72 | end
73 |
74 | item_parameters
75 | end
76 |
77 | end
78 | end
79 | end
80 |
--------------------------------------------------------------------------------
/lib/ews/templates/forward_item.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS
2 | module Template
3 | class ForwardItem < Message
4 |
5 | # Format this object for EWS backend consumption.
6 | def to_ews
7 | ews_opts, msg = to_ews_basic
8 | msg[:reference_item_id] = reference_item_id
9 | msg[:new_body_content] = {text: new_body_content, body_type: new_body_type}
10 | ews_opts.merge({items: [{forward_item: msg}]})
11 | end
12 |
13 | private
14 |
15 |
16 | def init_defaults!
17 | super
18 | self.new_body_content ||= ''
19 | self.new_body_type ||= 'Text'
20 | end
21 |
22 | end
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/lib/ews/templates/message.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS
2 | module Template
3 | class Message < OpenStruct
4 |
5 | def initialize(opts = {})
6 | super opts.clone
7 | init_defaults!
8 | end
9 |
10 | # Format this object for EWS backend consumption.
11 | def to_ews
12 | ews_opts, msg = to_ews_basic
13 | ews_opts.merge({items: [{message: msg}]})
14 | end
15 |
16 | def has_attachments?
17 | !(file_attachments.empty? && item_attachments.empty? && inline_attachments.empty?)
18 | end
19 |
20 |
21 | private
22 |
23 |
24 | def init_defaults!
25 | self.subject ||= nil
26 | self.body ||= nil
27 | self.body_type ||= 'Text'
28 | self.importance ||= 'Normal'
29 | self.draft ||= false
30 | self.is_read = true if is_read.nil?
31 | self.to_recipients ||= []
32 | self.cc_recipients ||= []
33 | self.bcc_recipients ||= []
34 | self.file_attachments ||= []
35 | self.item_attachments ||= []
36 | self.inline_attachments ||= []
37 | self.extended_properties ||= []
38 | end
39 |
40 | def to_ews_basic
41 | ews_opts = {}
42 | ews_opts[:message_disposition] = (draft ? 'SaveOnly' : 'SendAndSaveCopy')
43 |
44 | if saved_item_folder_id
45 | if saved_item_folder_id.kind_of?(Hash)
46 | ews_opts[:saved_item_folder_id] = saved_item_folder_id
47 | else
48 | ews_opts[:saved_item_folder_id] = {id: saved_item_folder_id}
49 | end
50 | end
51 |
52 | msg = {}
53 | msg[:subject] = subject if subject
54 | msg[:body] = {text: body, body_type: body_type} if body
55 |
56 | msg[:importance] = importance if importance
57 |
58 | to_r = to_recipients.collect{|r| {mailbox: {email_address: r}}}
59 | msg[:to_recipients] = to_r unless to_r.empty?
60 |
61 | cc_r = cc_recipients.collect{|r| {mailbox: {email_address: r}}}
62 | msg[:cc_recipients] = cc_r unless cc_r.empty?
63 |
64 | bcc_r = bcc_recipients.collect{|r| {mailbox: {email_address: r}}}
65 | msg[:bcc_recipients] = bcc_r unless bcc_r.empty?
66 |
67 | msg[:is_read] = is_read
68 |
69 | msg[:extended_properties] = extended_properties unless extended_properties.empty?
70 |
71 | [ews_opts, msg]
72 | end
73 |
74 | end
75 | end
76 | end
77 |
--------------------------------------------------------------------------------
/lib/ews/templates/reply_to_item.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS
2 | module Template
3 | class ReplyToItem < Message
4 |
5 | # Format this object for EWS backend consumption.
6 | def to_ews
7 | ews_opts, msg = to_ews_basic
8 | msg[:reference_item_id] = reference_item_id
9 | msg[:new_body_content] = {text: new_body_content, body_type: new_body_type}
10 | ews_opts.merge({items: [{ews_type => msg}]})
11 | end
12 |
13 | private
14 |
15 |
16 | def init_defaults!
17 | super
18 | self.new_body_content ||= ''
19 | self.new_body_type ||= 'Text'
20 | self.ews_type = :reply_to_item
21 | end
22 |
23 | end
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/lib/ews/templates/task.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS
2 | module Template
3 | # Template for creating Tasks
4 | # @see http://msdn.microsoft.com/en-us/library/exchange/aa564765.aspx
5 | class Task < OpenStruct
6 |
7 | # Available parameters with the required ordering
8 | PARAMETERS = %w{mime_content item_id parent_folder_id item_class subject sensitivity body attachments
9 | date_time_received size categories in_reply_to is_submitted is_draft is_from_me is_resend
10 | is_unmodified internet_message_headers date_time_sent date_time_created response_objects
11 | reminder_due_by reminder_is_set reminder_minutes_before_start display_cc display_to
12 | has_attachments extended_property culture actual_work assigned_time billing_information
13 | change_count companies complete_date contacts delegation_state delegator due_date
14 | is_assignment_editable is_complete is_recurring is_team_task mileage owner percent_complete
15 | recurrence start_date status status_description total_work effective_rights last_modified_name
16 | last_modified_time is_associated web_client_read_form_query_string
17 | web_client_edit_form_query_string conversation_id unique_body
18 | }.map(&:to_sym).freeze
19 |
20 | # Returns a new Task template
21 | def initialize(opts = {})
22 | super opts.dup
23 | end
24 |
25 | # EWS CreateItem container
26 | # @return [Hash]
27 | def to_ews_create
28 | structure = {}
29 |
30 | if self.saved_item_folder_id
31 | if self.saved_item_folder_id.kind_of?(Hash)
32 | structure[:saved_item_folder_id] = saved_item_folder_id
33 | else
34 | structure[:saved_item_folder_id] = {id: saved_item_folder_id}
35 | end
36 | end
37 |
38 | structure[:items] = [{task: to_ews_item}]
39 | structure
40 | end
41 |
42 | # EWS Item hash
43 | #
44 | # Puts all known parameters in the required ordering and structure
45 | # @return [Hash]
46 | def to_ews_item
47 | item_parameters = {}
48 | PARAMETERS.each do |key|
49 | if !(value = self.send(key)).nil?
50 |
51 | # Convert non duplicable values to String
52 | case value
53 | when NilClass, FalseClass, TrueClass, Symbol, Numeric
54 | value = value.to_s
55 | end
56 |
57 | # Convert attributes
58 | case key
59 | when :start_date, :due_date
60 | item_parameters[key] = {text: value.respond_to?(:iso8601) ? value.iso8601 : value}
61 | when :body
62 | item_parameters[key] = {body_type: self.body_type || 'Text', text: value.to_s}
63 | else
64 | item_parameters[key] = value
65 | end
66 | end
67 | end
68 |
69 | item_parameters
70 | end
71 |
72 | end
73 | end
74 | end
75 |
--------------------------------------------------------------------------------
/lib/ews/types.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS
2 | module Types
3 | include Viewpoint::StringUtils
4 |
5 | KEY_PATHS = {
6 | extended_properties: [:extended_property],
7 | }
8 | KEY_TYPES = {
9 | extended_properties: :build_extended_properties,
10 | }
11 | KEY_ALIAS = {}
12 |
13 | attr_reader :ews_item
14 |
15 | # @param [SOAP::ExchangeWebService] ews the EWS reference
16 | # @param [Hash] ews_item the EWS parsed response document
17 | def initialize(ews, ews_item)
18 | @ews = ews
19 | @ews_item = ews_item
20 | @shallow = true
21 | @frozen = false
22 | end
23 |
24 | def method_missing(method_sym, *arguments, &block)
25 | if method_keys.include?(method_sym)
26 | type_convert( method_sym, resolve_method(method_sym) )
27 | else
28 | super
29 | end
30 | end
31 |
32 | def to_s
33 | "#{self.class.name}: EWS METHODS: #{self.ews_methods.sort.join(', ')}"
34 | end
35 |
36 | def frozen?
37 | @frozen
38 | end
39 |
40 | # @param ronly [Boolean] true to freeze
41 | def freeze!
42 | @frozen = true
43 | end
44 |
45 | def unfreeze!
46 | @frozen = false
47 | end
48 |
49 | def shallow?
50 | @shallow
51 | end
52 |
53 | def mark_deep!
54 | @shallow = false
55 | end
56 |
57 | def auto_deepen?
58 | ews.auto_deepen
59 | end
60 |
61 | def deepen!
62 | if shallow?
63 | self.get_all_properties!
64 | @shallow = false
65 | true
66 | end
67 | end
68 | alias_method :enlighten!, :deepen!
69 |
70 | # @see http://www.ruby-doc.org/core/classes/Object.html#M000333
71 | def respond_to?(method_sym, include_private = false)
72 | if method_keys.include?(method_sym)
73 | true
74 | else
75 | super
76 | end
77 | end
78 |
79 | def methods(include_super = true)
80 | super + ews_methods
81 | end
82 |
83 | def ews_methods
84 | key_paths.keys + key_alias.keys
85 | end
86 |
87 | protected # things like OutOfOffice need protected level access
88 |
89 | def ews
90 | @ews
91 | end
92 |
93 | private
94 |
95 | def key_paths
96 | KEY_PATHS
97 | end
98 |
99 | def key_types
100 | KEY_TYPES
101 | end
102 |
103 | def key_alias
104 | KEY_ALIAS
105 | end
106 |
107 | def class_by_name(cname)
108 | if(cname.instance_of? Symbol)
109 | cname = camel_case(cname)
110 | end
111 | Viewpoint::EWS::Types.const_get(cname)
112 | end
113 |
114 | def type_convert(key,str)
115 | begin
116 | key = key_alias[key] || key
117 | if key_types[key]
118 | key_types[key].is_a?(Symbol) ? method(key_types[key]).call(str) : key_types[key].call(str)
119 | else
120 | str
121 | end
122 | rescue
123 | nil
124 | end
125 | end
126 |
127 | def resolve_method(method_sym)
128 | begin
129 | resolve_key_path(@ews_item, method_path(method_sym))
130 | rescue
131 | if shallow?
132 | if frozen?
133 | raise EwsFrozenObjectError, "Could not resolve :#{method_sym} on frozen object."
134 | elsif auto_deepen?
135 | enlighten!
136 | retry
137 | else
138 | if !auto_deepen?
139 | if ews.no_auto_deepen_behavior == :raise
140 | raise EwsMinimalObjectError, "Could not resolve :#{method_sym}. #auto_deepen set to false"
141 | else
142 | nil
143 | end
144 | else
145 | end
146 | end
147 | else
148 | nil
149 | end
150 | end
151 | end
152 |
153 | def resolve_key_path(hsh, path)
154 | k = path.first
155 | return hsh[k] if path.length == 1
156 | resolve_key_path(hsh[k],path[1..-1])
157 | end
158 |
159 | def method_keys
160 | key_paths.keys + key_alias.keys
161 | end
162 |
163 | # Resolve the method path with or without an alias
164 | def method_path(sym)
165 | key_paths[key_alias[sym] || sym]
166 | end
167 |
168 | def build_extended_properties(eprops)
169 | h = {}
170 | # todo
171 | # the return pattern seems broken in some cases,
172 | # probably needs fixing via a dedicated response parser
173 | eprops.each do |e|
174 | if e.size == 1
175 | e[:elems].each_cons(2) do |k,v|
176 | key = k[:extended_field_u_r_i][:attribs][:property_name].downcase.to_sym
177 | val = v[:value][:text]
178 | h.store(key,val)
179 | end
180 | elsif e.size == 2
181 | e[1].each_cons(2) do |k,v|
182 | key = k[:extended_field_u_r_i][:attribs][:property_name].downcase.to_sym
183 | val = v[:value][:text]
184 | h.store(key,val)
185 | end
186 | else
187 | raise EwsMinimalObjectError, "Not prepared to deal with elements greater than 2"
188 | end
189 | end
190 | h
191 | end
192 |
193 | end
194 | end
195 |
--------------------------------------------------------------------------------
/lib/ews/types/attachment.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::Types
20 | # A generic Attachment. This class should not be instantiated directly. You
21 | # should use one of the subclasses like FileAttachment or ItemAttachment.
22 | class Attachment
23 | include Viewpoint::EWS
24 | include Viewpoint::EWS::Types
25 | include Viewpoint::EWS::Types::Item
26 |
27 | ATTACH_KEY_PATHS = {
28 | :id => [:attachment_id, :attribs, :id],
29 | :parent_item_id => [:attachment_id, :attribs, :root_item_id],
30 | :parent_change_key => [:attachment_id, :attribs, :root_item_change_key],
31 | :name => [:name, :text],
32 | :content_type => [:content_type, :text],
33 | :content_id => [:content_id],
34 | :size => [:size, :text],
35 | :last_modified_time => [:last_modified_time, :text],
36 | :is_inline? => [:is_inline, :text],
37 | }
38 |
39 | ATTACH_KEY_TYPES = {
40 | is_inline?: ->(str){str.downcase == 'true'},
41 | last_modified_type: ->(str){DateTime.parse(str)},
42 | size: ->(str){str.to_i},
43 | content_id: :fix_content_id,
44 | }
45 |
46 | ATTACH_KEY_ALIAS = { }
47 |
48 | # @param [Hash] attachment The attachment ews_item
49 | def initialize(item, attachment)
50 | @item = item
51 | super(item.ews, attachment)
52 | end
53 |
54 |
55 | private
56 |
57 |
58 | def key_paths
59 | @key_paths ||= ATTACH_KEY_PATHS
60 | end
61 |
62 | def key_types
63 | @key_types ||= ATTACH_KEY_TYPES
64 | end
65 |
66 | def key_alias
67 | @key_alias ||= ATTACH_KEY_ALIAS
68 | end
69 |
70 | # Sometimes the SOAP response comes back with two identical content_ids.
71 | # This method fishes them out no matter which way them come.
72 | def fix_content_id(content_id)
73 | content_id.is_a?(Array) ? content_id.last[:text] : content_id[:text]
74 | end
75 |
76 | end
77 | end
78 |
--------------------------------------------------------------------------------
/lib/ews/types/attendee.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::Types
20 |
21 | # This represents a Mailbox object in the Exchange data store
22 | # @see http://msdn.microsoft.com/en-us/library/aa565036.aspx MSDN docs
23 | # @todo Design a Class method that resolves to an Array of MailboxUsers
24 | class Attendee < MailboxUser
25 | end # Attendee
26 |
27 | end # Viewpoint::EWS::Types
28 |
--------------------------------------------------------------------------------
/lib/ews/types/calendar_folder.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS::Types
2 | class CalendarFolder
3 | include Viewpoint::EWS
4 | include Viewpoint::EWS::Types
5 | include Viewpoint::EWS::Types::GenericFolder
6 |
7 | # Fetch items between a given time period
8 | # @param [DateTime] start_date the time to start fetching Items from
9 | # @param [DateTime] end_date the time to stop fetching Items from
10 | def items_between(start_date, end_date, opts={})
11 | items do |obj|
12 | obj.restriction = { :and =>
13 | [
14 | {:is_greater_than_or_equal_to =>
15 | [
16 | {:field_uRI => {:field_uRI=>'calendar:Start'}},
17 | {:field_uRI_or_constant=>{:constant => {:value =>start_date}}}
18 | ]
19 | },
20 | {:is_less_than_or_equal_to =>
21 | [
22 | {:field_uRI => {:field_uRI=>'calendar:End'}},
23 | {:field_uRI_or_constant=>{:constant => {:value =>end_date}}}
24 | ]
25 | }
26 | ]
27 | }
28 | end
29 | end
30 |
31 | # Fetch items between a given time period using a calendar view.
32 | # The calendar view will include occurences of recurring calendar items
33 | # next to the regular single calendar items.
34 | # @param [DateTime] start_date the time to start fetching Items from
35 | # @param [DateTime] end_date the time to stop fetching Items from
36 | # @param opts [Hash]
37 | # @option opts :max_entries_returned [Integer] the maximum number of entries to return
38 | def items_between_calendar_view(start_date, end_date, opts={})
39 | view_opts = {:start_date => start_date, :end_date => end_date}
40 | view_opts[:max_entries_returned] = opts.delete(:max_entries_returned) if opts[:max_entries_returned]
41 | items(opts.merge(:calendar_view => view_opts))
42 | end
43 |
44 | # Creates a new appointment
45 | # @param attributes [Hash] Parameters of the calendar item. Some example attributes are listed below.
46 | # @option attributes :subject [String]
47 | # @option attributes :start [Time]
48 | # @option attributes :end [Time]
49 | # @return [CalendarItem]
50 | # @see Template::CalendarItem
51 | def create_item(attributes, to_ews_create_opts = {})
52 | template = Viewpoint::EWS::Template::CalendarItem.new attributes
53 | template.saved_item_folder_id = {id: self.id, change_key: self.change_key}
54 | rm = ews.create_item(template.to_ews_create(to_ews_create_opts)).response_messages.first
55 | if rm && rm.success?
56 | CalendarItem.new ews, rm.items.first[:calendar_item][:elems].first
57 | else
58 | if rm
59 | raise EwsCreateItemError, "Could not create item in folder. #{rm.code}: #{rm.message_text}"
60 | else
61 | raise EwsCreateItemError, "Could not create item in folder."
62 | end
63 | end
64 | end
65 |
66 | end
67 | end
68 |
--------------------------------------------------------------------------------
/lib/ews/types/calendar_item.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS::Types
2 | class CalendarItem
3 | include Viewpoint::EWS
4 | include Viewpoint::EWS::Types
5 | include Viewpoint::EWS::Types::Item
6 | include Viewpoint::StringUtils
7 |
8 | CALENDAR_ITEM_KEY_PATHS = {
9 | recurring?: [:is_recurring, :text],
10 | meeting?: [:is_meeting, :text],
11 | cancelled?: [:is_cancelled, :text],
12 | duration: [:duration, :text],
13 | time_zone: [:time_zone, :text],
14 | start: [:start, :text],
15 | end: [:end, :text],
16 | location: [:location, :text],
17 | all_day?: [:is_all_day_event, :text],
18 | legacy_free_busy_status: [:legacy_free_busy_status, :text],
19 | my_response_type: [:my_response_type, :text],
20 | organizer: [:organizer, :elems, 0, :mailbox, :elems],
21 | optional_attendees: [:optional_attendees, :elems ],
22 | required_attendees: [:required_attendees, :elems ],
23 | recurrence: [:recurrence, :elems ],
24 | deleted_occurrences: [:deleted_occurrences, :elems ],
25 | modified_occurrences: [:modified_occurrences, :elems ]
26 | }
27 |
28 | CALENDAR_ITEM_KEY_TYPES = {
29 | start: ->(str){DateTime.parse(str)},
30 | end: ->(str){DateTime.parse(str)},
31 | recurring?: ->(str){str.downcase == 'true'},
32 | meeting?: ->(str){str.downcase == 'true'},
33 | cancelled?: ->(str){str.downcase == 'true'},
34 | all_day?: ->(str){str.downcase == 'true'},
35 | organizer: :build_mailbox_user,
36 | optional_attendees: :build_attendees_users,
37 | required_attendees: :build_attendees_users,
38 | deleted_occurrences: :build_deleted_occurrences,
39 | modified_occurrences: :build_modified_occurrences
40 | }
41 | CALENDAR_ITEM_KEY_ALIAS = {}
42 |
43 | # Delete this calendar item
44 | # @param deltype [Symbol] The delete type; must be :hard, :soft, or :recycle.
45 | # By default EWS will do a hard delete of this calendar item. See the=
46 | # MSDN docs for more info: http://msdn.microsoft.com/en-us/library/aa562961.aspx
47 | # @param cancel_type [String] 'SendToNone'/'SendOnlyToAll'/'SendToAllAndSaveCopy'
48 | # Default is 'SendOnlyToAll'
49 | # @return [Boolean] Whether or not the calendar item was deleted
50 | def delete!(deltype = :hard, cancel_type = 'SendOnlyToAll', opts = {})
51 | opts = opts.merge(:send_meeting_cancellations => cancel_type)
52 | super(deltype, opts)
53 | end
54 |
55 | # Updates the specified item attributes
56 | #
57 | # Uses `SetItemField` if value is present and `DeleteItemField` if value is nil
58 | # @param updates [Hash] with (:attribute => value)
59 | # @param options [Hash]
60 | # @option options :conflict_resolution [String] one of 'NeverOverwrite', 'AutoResolve' (default) or 'AlwaysOverwrite'
61 | # @option options :send_meeting_invitations_or_cancellations [String] one of 'SendToNone' (default), 'SendOnlyToAll',
62 | # 'SendOnlyToChanged', 'SendToAllAndSaveCopy' or 'SendToChangedAndSaveCopy'
63 | # @return [CalendarItem, false]
64 | # @example Update Subject and Body
65 | # item = #...
66 | # item.update_item!(subject: 'New subject', body: 'New Body')
67 | # @see http://msdn.microsoft.com/en-us/library/exchange/aa580254.aspx
68 | # @todo AppendToItemField updates not implemented
69 | def update_item!(updates, options = {})
70 | item_updates = []
71 | updates.each do |attribute, value|
72 | item_field = FIELD_URIS[attribute][:text] if FIELD_URIS.include? attribute
73 | field = {field_uRI: {field_uRI: item_field}}
74 |
75 | if value.nil? && item_field
76 | # Build DeleteItemField Change
77 | item_updates << {delete_item_field: field}
78 | elsif item_field
79 | # Build SetItemField Change
80 | item = Viewpoint::EWS::Template::CalendarItem.new(attribute => value)
81 |
82 | # Remap attributes because ews_builder #dispatch_field_item! uses #build_xml!
83 | item_attributes = item.to_ews_item.map do |name, value|
84 | if value.is_a? String
85 | {name => {text: value}}
86 | elsif value.is_a? Hash
87 | node = {name => {}}
88 | value.each do |attrib_key, attrib_value|
89 | attrib_key = camel_case(attrib_key) unless attrib_key == :text
90 | node[name][attrib_key] = attrib_value
91 | end
92 | node
93 | else
94 | {name => value}
95 | end
96 | end
97 |
98 | item_updates << {set_item_field: field.merge(calendar_item: {sub_elements: item_attributes})}
99 | else
100 | # Ignore unknown attribute
101 | end
102 | end
103 |
104 | if item_updates.any?
105 | data = {}
106 | data[:conflict_resolution] = options[:conflict_resolution] || 'AutoResolve'
107 | data[:send_meeting_invitations_or_cancellations] = options[:send_meeting_invitations_or_cancellations] || 'SendToNone'
108 | data[:item_changes] = [{item_id: self.item_id, updates: item_updates}]
109 | rm = ews.update_item(data).response_messages.first
110 | if rm && rm.success?
111 | self.get_all_properties!
112 | self
113 | else
114 | if rm
115 | raise EwsCreateItemError, "Could not update calendar item. #{rm.code}: #{rm.message_text}"
116 | else
117 | raise EwsCreateItemError, "Could not update calendar item."
118 | end
119 | end
120 | end
121 |
122 | end
123 |
124 | def duration_in_seconds
125 | iso8601_duration_to_seconds(duration)
126 | end
127 |
128 |
129 | private
130 |
131 |
132 | def key_paths
133 | super.merge(CALENDAR_ITEM_KEY_PATHS)
134 | end
135 |
136 | def key_types
137 | super.merge(CALENDAR_ITEM_KEY_TYPES)
138 | end
139 |
140 | def key_alias
141 | super.merge(CALENDAR_ITEM_KEY_ALIAS)
142 | end
143 |
144 |
145 | end
146 | end
147 |
--------------------------------------------------------------------------------
/lib/ews/types/contact.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS::Types
2 | class Contact
3 | include Viewpoint::EWS
4 | include Viewpoint::EWS::Types
5 | include Viewpoint::EWS::Types::Item
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/lib/ews/types/contacts_folder.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS::Types
2 | class ContactsFolder
3 | include Viewpoint::EWS
4 | include Viewpoint::EWS::Types
5 | include Viewpoint::EWS::Types::GenericFolder
6 |
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/lib/ews/types/copied_event.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::Types
20 |
21 | class CopiedEvent < Event
22 |
23 | COPIED_EVENT_KEY_PATHS = {
24 | :old_item_id => [:old_item_id, :attribs],
25 | :old_folder_id => [:old_folder_id, :attribs],
26 | :old_parent_folder_id => [:old_parent_folder_id, :attribs],
27 | }
28 |
29 | COPIED_EVENT_KEY_TYPES = {
30 | }
31 |
32 | COPIED_EVENT_KEY_ALIAS = { }
33 |
34 |
35 | private
36 |
37 |
38 | def key_paths
39 | @key_paths ||= super.merge COPIED_EVENT_KEY_PATHS
40 | end
41 |
42 | def key_types
43 | @key_types ||= super.merge COPIED_EVENT_KEY_TYPES
44 | end
45 |
46 | def key_alias
47 | @key_alias ||= super.merge COPIED_EVENT_KEY_ALIAS
48 | end
49 |
50 | end
51 | end
52 |
--------------------------------------------------------------------------------
/lib/ews/types/created_event.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::Types
20 |
21 | class CreatedEvent < Event
22 |
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/lib/ews/types/deleted_event.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::Types
20 |
21 | class DeletedEvent < Event
22 |
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/lib/ews/types/distribution_list.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS::Types
2 | class DistributionList
3 | include Viewpoint::EWS
4 | include Viewpoint::EWS::Types
5 | include Viewpoint::EWS::Types::Item
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/lib/ews/types/event.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::Types
20 |
21 | class Event
22 | include Viewpoint::EWS
23 | include Viewpoint::EWS::Types
24 | include Viewpoint::EWS::Types::Item
25 |
26 | EVENT_KEY_PATHS = {
27 | :watermark => [:watermark, :text],
28 | :timestamp => [:time_stamp, :text],
29 | :item_id => [:item_id, :attribs],
30 | :folder_id => [:folder_id, :attribs],
31 | :parent_folder_id => [:parent_folder_id, :attribs],
32 | }
33 |
34 | EVENT_KEY_TYPES = {
35 | :timestamp => ->(ts){ DateTime.iso8601(ts) }
36 | }
37 |
38 | EVENT_KEY_ALIAS = { }
39 |
40 | def initialize(ews, event)
41 | @ews = ews
42 | super(ews, event)
43 | end
44 |
45 |
46 | private
47 |
48 |
49 | def key_paths
50 | @key_paths ||= EVENT_KEY_PATHS
51 | end
52 |
53 | def key_types
54 | @key_types ||= EVENT_KEY_TYPES
55 | end
56 |
57 | def key_alias
58 | @key_alias ||= EVENT_KEY_ALIAS
59 | end
60 |
61 | end
62 | end
63 |
--------------------------------------------------------------------------------
/lib/ews/types/export_items_response_message.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS::Types
2 |
3 | class ExportItemsResponseMessage
4 | include Viewpoint::EWS
5 | include Viewpoint::EWS::Types
6 | include Viewpoint::EWS::Types::Item
7 |
8 | BULK_KEY_PATHS = {
9 | :id => [:item_id, :attribs, :id],
10 | :change_key => [:item_id, :attribs, :change_key],
11 | :data => [:data, :text]
12 | }
13 |
14 | BULK_KEY_TYPES = { }
15 |
16 | BULK_KEY_ALIAS = { }
17 |
18 | def initialize(ews, bulk_item)
19 | super(ews, bulk_item)
20 | @item = bulk_item
21 | @ews = ews
22 | end
23 |
24 | def id
25 | @item[:item_id][:attribs][:id]
26 | end
27 |
28 | def change_key
29 | @item[:item_id][:attribs][:change_key]
30 | end
31 |
32 | def data
33 | @item[:data][:text]
34 | end
35 |
36 |
37 | private
38 |
39 | def key_paths
40 | @key_paths ||= BULK_KEY_PATHS
41 | end
42 |
43 | def key_types
44 | @key_types ||= BULK_KEY_TYPES
45 | end
46 |
47 | def key_alias
48 | @key_alias ||= BULK_KEY_ALIAS
49 | end
50 |
51 | end
52 | end
--------------------------------------------------------------------------------
/lib/ews/types/file_attachment.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::Types
20 | class FileAttachment < Attachment
21 |
22 | FILE_ATTACH_KEY_PATHS = {
23 | :is_contact_photo? => [:is_contact_photo, :text],
24 | :content => [:content, :text],
25 | }
26 |
27 | FILE_ATTACH_KEY_TYPES = {
28 | is_contact_photo?: ->(str){str.downcase == 'true'},
29 | }
30 |
31 | FILE_ATTACH_KEY_ALIAS = {
32 | :file_name => :name,
33 | }
34 |
35 | def get_all_properties!
36 | resp = ews.get_attachment attachment_ids: [self.id]
37 | @ews_item.merge!(parse_response(resp))
38 | end
39 |
40 | private
41 |
42 |
43 | def key_paths
44 | super.merge(FILE_ATTACH_KEY_PATHS)
45 | end
46 |
47 | def key_types
48 | super.merge(FILE_ATTACH_KEY_TYPES)
49 | end
50 |
51 | def key_alias
52 | super.merge(FILE_ATTACH_KEY_ALIAS)
53 | end
54 |
55 | def parse_response(resp)
56 | if(resp.status == 'Success')
57 | resp.response_message[:elems][:attachments][:elems][0][:file_attachment][:elems].inject(&:merge)
58 | else
59 | raise EwsError, "Could not retrieve #{self.class}. #{resp.code}: #{resp.message}"
60 | end
61 | end
62 |
63 | end
64 | end
65 |
66 |
--------------------------------------------------------------------------------
/lib/ews/types/folder.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS::Types
2 | class Folder
3 | include Viewpoint::EWS
4 | include Viewpoint::EWS::Types
5 | include Viewpoint::EWS::Types::GenericFolder
6 |
7 | FOLDER_KEY_PATHS = {
8 | :unread_count => [:unread_count, :text],
9 | }
10 | FOLDER_KEY_TYPES = {
11 | :unread_count => ->(str){str.to_i},
12 | }
13 | FOLDER_KEY_ALIAS = {}
14 |
15 | alias :messages :items
16 |
17 | def unread_messages
18 | self.items read_unread_restriction
19 | end
20 |
21 | def read_messages
22 | self.items read_unread_restriction(true)
23 | end
24 |
25 | def messages_with_attachments
26 | opts = {:restriction =>
27 | {:is_equal_to => [
28 | {:field_uRI => {:field_uRI=>'item:HasAttachments'}},
29 | {:field_uRI_or_constant => {:constant => {:value=> true}}}
30 | ]}
31 | }
32 | self.items opts
33 | end
34 |
35 | private
36 |
37 |
38 | def read_unread_restriction(read = false)
39 | {:restriction =>
40 | {:is_equal_to => [
41 | {:field_uRI => {:field_uRI=>'message:IsRead'}},
42 | {:field_uRI_or_constant => {:constant => {:value=> read}}}
43 | ]}
44 | }
45 | end
46 |
47 | def key_paths
48 | @key_paths ||= super.merge(FOLDER_KEY_PATHS)
49 | end
50 |
51 | def key_types
52 | @key_types ||= super.merge(FOLDER_KEY_TYPES)
53 | end
54 |
55 | def key_alias
56 | @key_alias ||= super.merge(FOLDER_KEY_ALIAS)
57 | end
58 |
59 | end
60 | end
61 |
--------------------------------------------------------------------------------
/lib/ews/types/free_busy_changed_event.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::Types
20 |
21 | class FreeBusyChangedEvent < Event
22 |
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/lib/ews/types/item_attachment.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::Types
20 | class ItemAttachment < Attachment
21 |
22 | ITEM_ATTACH_KEY_PATHS = {
23 | item: [:item],
24 | message: [:message],
25 | calendar_item: [:calendar_item],
26 | contact: [:contact],
27 | task: [:task],
28 | meeting_message: [:meeting_message],
29 | meeting_request: [:meeting_request],
30 | meeting_response: [:meeting_response],
31 | meeting_cancellation: [:meeting_cancellation]
32 | }
33 |
34 | ITEM_ATTACH_KEY_TYPES = {
35 | message: :build_message,
36 | calendar_item: :build_calendar_item,
37 | contact: :build_contact,
38 | task: :build_task,
39 | meeting_message: :build_meeting_message,
40 | meeting_request: :build_meeting_request,
41 | meeting_response: :build_meeting_response,
42 | meeting_cancellation: :build_meeting_cancellation
43 | }
44 |
45 | ITEM_ATTACH_KEY_ALIAS = { }
46 |
47 | def get_all_properties!
48 | resp = ews.get_attachment attachment_ids: [self.id]
49 | @ews_item.merge!(parse_response(resp))
50 | end
51 |
52 | private
53 |
54 | def self.method_missing(method, *args, &block)
55 | if method.to_s =~ /^build_(.+)$/
56 | class_by_name($1).new(ews, args[0])
57 | else
58 | super
59 | end
60 | end
61 |
62 | def key_paths
63 | super.merge(ITEM_ATTACH_KEY_PATHS)
64 | end
65 |
66 | def key_types
67 | super.merge(ITEM_ATTACH_KEY_TYPES)
68 | end
69 |
70 | def key_alias
71 | super.merge(ITEM_ATTACH_KEY_ALIAS)
72 | end
73 |
74 | def parse_response(resp)
75 | if(resp.status == 'Success')
76 | resp.response_message[:elems][:attachments][:elems][0][:item_attachment][:elems].inject(&:merge)
77 | else
78 | raise EwsError, "Could not retrieve #{self.class}. #{resp.code}: #{resp.message}"
79 | end
80 | end
81 |
82 | end
83 | end
84 |
85 |
--------------------------------------------------------------------------------
/lib/ews/types/mailbox_user.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::Types
20 |
21 | # This represents a Mailbox object in the Exchange data store
22 | # @see http://msdn.microsoft.com/en-us/library/aa565036.aspx MSDN docs
23 | # @todo Design a Class method that resolves to an Array of MailboxUsers
24 | class MailboxUser
25 | include Viewpoint::EWS
26 | include Viewpoint::EWS::Types
27 |
28 | MAILBOX_KEY_PATHS = {
29 | name: [:name],
30 | email_address: [:email_address],
31 | }
32 | MAILBOX_KEY_TYPES = {}
33 | MAILBOX_KEY_ALIAS = {
34 | email: :email_address,
35 | }
36 |
37 | def initialize(ews, mbox_user)
38 | @ews = ews
39 | @ews_item = mbox_user
40 | simplify!
41 | end
42 |
43 | def out_of_office_settings
44 | mailbox = {:address => self.email_address}
45 | resp = @ews.get_user_oof_settings(mailbox)
46 | ewsi = resp.response.clone
47 | ewsi.delete(:response_message)
48 | return OutOfOffice.new(self,ewsi)
49 | s = resp[:oof_settings]
50 | @oof_state = s[:oof_state][:text]
51 | @oof_ext_audience = s[:external_audience][:text]
52 | @oof_start = DateTime.parse(s[:duration][:start_time][:text])
53 | @oof_end = DateTime.parse(s[:duration][:end_time][:text])
54 | @oof_internal_reply = s[:internal_reply][:message][:text]
55 | @oof_external_reply = s[:internal_reply][:message][:text]
56 | true
57 | end
58 |
59 | # Get information about when the user with the given email address is available.
60 | # @param [String] email_address The email address of the person to find availability for.
61 | # @param [DateTime] start_time The start of the time range to check as an xs:dateTime.
62 | # @param [DateTime] end_time The end of the time range to check as an xs:dateTime.
63 | # @see http://msdn.microsoft.com/en-us/library/aa563800(v=exchg.140)
64 | def get_user_availability(email_address, start_time, end_time)
65 | opts = {
66 | mailbox_data: [ :email =>{:address => email_address} ],
67 | free_busy_view_options: {
68 | time_window: {start_time: start_time, end_time: end_time},
69 | }
70 | }
71 | resp = (Viewpoint::EWS::EWS.instance).ews.get_user_availability(opts)
72 | if(resp.status == 'Success')
73 | return resp.items
74 | else
75 | raise EwsError, "GetUserAvailability produced an error: #{resp.code}: #{resp.message}"
76 | end
77 | end
78 |
79 | # Adds one or more delegates to a principal's mailbox and sets specific access permissions
80 | # @see http://msdn.microsoft.com/en-us/library/bb856527.aspx
81 | #
82 | # @param [String,MailboxUser] delegate_email The user you would like to give delegate access to.
83 | # This can either be a simple String e-mail address or you can pass in a MailboxUser object.
84 | # @param [Hash] permissions A hash of folder type keys and permission type values. An example
85 | # would be {:calendar_folder_permission_level => 'Editor'}. Possible keys are:
86 | # :calendar_folder_permission_level, :tasks_folder_permission_level, :inbox_folder_permission_level
87 | # :contacts_folder_permission_level, :notes_folder_permission_level, :journal_folder_permission_level
88 | # and possible values are: None/Editor/Reviewer/Author/Custom
89 | # @return [true] This method either returns true or raises an error with the message
90 | # as to why this operation did not succeed.
91 | def add_delegate!(delegate_email, permissions)
92 | # Use a new hash so the passed hash is not modified in case we are in a loop.
93 | # Thanks to Markus Roberts for pointing this out.
94 | formatted_perms = {}
95 | # Modify permissions so we can pass it to the builders
96 | permissions.each_pair do |k,v|
97 | formatted_perms[k] = {:text => v}
98 | end
99 |
100 | resp = (Viewpoint::EWS::EWS.instance).ews.add_delegate(self.email_address, delegate_email, formatted_perms)
101 | if(resp.status == 'Success')
102 | return true
103 | else
104 | raise EwsError, "Could not add delegate access for user #{delegate_email}: #{resp.code}, #{resp.message}"
105 | end
106 | end
107 |
108 | def update_delegate!(delegate_email, permissions)
109 | # Modify permissions so we can pass it to the builders
110 | formatted_perms = {}
111 | permissions.each_pair do |k,v|
112 | formatted_perms[k] = {:text => v}
113 | end
114 |
115 | resp = (Viewpoint::EWS::EWS.instance).ews.update_delegate(self.email_address, delegate_email, formatted_perms)
116 | if(resp.status == 'Success')
117 | return true
118 | else
119 | raise EwsError, "Could not update delegate access for user #{delegate_email}: #{resp.code}, #{resp.message}"
120 | end
121 | end
122 |
123 | def get_delegate_info()
124 | resp = (Viewpoint::EWS::EWS.instance).ews.get_delegate(self.email_address)
125 | # if(resp.status == 'Success')
126 | # return true
127 | # else
128 | # raise EwsError, "Could not update delegate access for user #{delegate_email}: #{resp.code}, #{resp.message}"
129 | # end
130 | end
131 |
132 |
133 | private
134 |
135 |
136 | def simplify!
137 | @ews_item = @ews_item.inject({}){|m,o|
138 | m[o.keys.first] = o.values.first[:text];
139 | m
140 | }
141 | end
142 |
143 | def key_paths
144 | @key_paths ||= super.merge(MAILBOX_KEY_PATHS)
145 | end
146 |
147 | def key_types
148 | @key_types ||= super.merge(MAILBOX_KEY_TYPES)
149 | end
150 |
151 | def key_alias
152 | @key_alias ||= super.merge(MAILBOX_KEY_ALIAS)
153 | end
154 |
155 | end # MailboxUser
156 | end # Viewpoint::EWS::Types
157 |
--------------------------------------------------------------------------------
/lib/ews/types/meeting_cancellation.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS::Types
2 | class MeetingCancellation
3 | include Viewpoint::EWS
4 | include Viewpoint::EWS::Types
5 | include Viewpoint::EWS::Types::Item
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/lib/ews/types/meeting_message.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS::Types
2 | class MeetingMessage
3 | include Viewpoint::EWS
4 | include Viewpoint::EWS::Types
5 | include Viewpoint::EWS::Types::Item
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/lib/ews/types/meeting_request.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS::Types
2 | class MeetingRequest
3 | include Viewpoint::EWS
4 | include Viewpoint::EWS::Types
5 | include Viewpoint::EWS::Types::Item
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/lib/ews/types/meeting_response.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS::Types
2 | class MeetingResponse
3 | include Viewpoint::EWS
4 | include Viewpoint::EWS::Types
5 | include Viewpoint::EWS::Types::Item
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/lib/ews/types/message.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS::Types
2 | class Message
3 | include Viewpoint::EWS
4 | include Viewpoint::EWS::Types
5 | include Viewpoint::EWS::Types::Item
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/lib/ews/types/modified_event.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::Types
20 |
21 | class ModifiedEvent < Event
22 |
23 | MODIFIED_EVENT_KEY_PATHS = {
24 | }
25 |
26 | MODIFIED_EVENT_KEY_TYPES = {
27 | }
28 |
29 | MODIFIED_EVENT_KEY_ALIAS = { }
30 |
31 |
32 | private
33 |
34 |
35 | def key_paths
36 | @key_paths ||= super.merge MODIFIED_EVENT_KEY_PATHS
37 | end
38 |
39 | def key_types
40 | @key_types ||= super.merge MODIFIED_EVENT_KEY_TYPES
41 | end
42 |
43 | def key_alias
44 | @key_alias ||= super.merge MODIFIED_EVENT_KEY_ALIAS
45 | end
46 |
47 | end
48 | end
49 |
--------------------------------------------------------------------------------
/lib/ews/types/moved_event.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::Types
20 |
21 | class MovedEvent < Event
22 |
23 | MOVED_EVENT_KEY_PATHS = {
24 | :old_item_id => [:old_item_id, :attribs],
25 | :old_folder_id => [:old_folder_id, :attribs],
26 | :old_parent_folder_id => [:old_parent_folder_id, :attribs],
27 | }
28 |
29 | MOVED_EVENT_KEY_TYPES = {
30 | }
31 |
32 | MOVED_EVENT_KEY_ALIAS = { }
33 |
34 |
35 | private
36 |
37 |
38 | def key_paths
39 | @key_paths ||= super.merge MOVED_EVENT_KEY_PATHS
40 | end
41 |
42 | def key_types
43 | @key_types ||= super.merge MOVED_EVENT_KEY_TYPES
44 | end
45 |
46 | def key_alias
47 | @key_alias ||= super.merge MOVED_EVENT_KEY_ALIAS
48 | end
49 |
50 | end
51 | end
52 |
--------------------------------------------------------------------------------
/lib/ews/types/new_mail_event.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::Types
20 |
21 | class NewMailEvent < Event
22 |
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/lib/ews/types/out_of_office.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::Types
20 |
21 | OOF_KEY_PATHS = {
22 | :enabled? => [:oof_settings, :oof_state],
23 | :scheduled? => [:oof_settings, :oof_state],
24 | :duration => [:oof_settings, :duration],
25 | }
26 |
27 | OOF_KEY_TYPES = {
28 | :enabled? => ->(str){str == :enabled},
29 | :scheduled? => ->(str){str == :scheduled},
30 | :duration => ->(hsh){ hsh[:start_time]..hsh[:end_time] },
31 | }
32 |
33 | OOF_KEY_ALIAS = {}
34 |
35 | # This represents OutOfOffice settings
36 | # @see http://msdn.microsoft.com/en-us/library/aa563465.aspx
37 | class OutOfOffice
38 | include Viewpoint::EWS
39 | include Viewpoint::EWS::Types
40 |
41 | attr_reader :user
42 |
43 | # @param [MailboxUser] user
44 | # @param [Hash] ews_item
45 | def initialize(user, ews_item)
46 | @ews = user.ews
47 | @user = user
48 | @ews_item = ews_item
49 | @changed = false
50 | simplify!
51 | end
52 |
53 | def changed?
54 | @changed
55 | end
56 |
57 | def save!
58 | return true unless changed?
59 | opts = { mailbox: {address: user.email_address} }.merge(@ews_item[:oof_settings])
60 | resp = @ews.set_user_oof_settings(opts)
61 | if resp.success?
62 | @changed = false
63 | true
64 | else
65 | raise SaveFailed, "Could not save #{self.class}. #{resp.code}: #{resp.message}"
66 | end
67 | end
68 |
69 | def enable
70 | return true if enabled?
71 | @changed = true
72 | @ews_item[:oof_settings][:oof_state] = :enabled
73 | end
74 |
75 | def disable
76 | return true unless enabled? || scheduled?
77 | @changed = true
78 | @ews_item[:oof_settings][:oof_state] = :disabled
79 | end
80 |
81 | # Schedule an out of office.
82 | # @param [DateTime] start_time
83 | # @param [DateTime] end_time
84 | def schedule(start_time, end_time)
85 | @changed = true
86 | @ews_item[:oof_settings][:oof_state] = :scheduled
87 | set_duration start_time, end_time
88 | end
89 |
90 | # Specify a duration for this Out Of Office setting
91 | # @param [DateTime] start_time
92 | # @param [DateTime] end_time
93 | def set_duration(start_time, end_time)
94 | @changed = true
95 | @ews_item[:oof_settings][:duration][:start_time] = start_time
96 | @ews_item[:oof_settings][:duration][:end_time] = end_time
97 | end
98 |
99 | # A message to send to internal users
100 | # @param [String] message
101 | def internal_reply=(message)
102 | @changed = true
103 | @ews_item[:oof_settings][:internal_reply] = message
104 | end
105 |
106 | # A message to send to external users
107 | # @param [String] message
108 | def external_reply=(message)
109 | @changed = true
110 | @ews_item[:oof_settings][:external_reply] = message
111 | end
112 |
113 |
114 | private
115 |
116 | def key_paths
117 | @key_paths ||= super.merge(OOF_KEY_PATHS)
118 | end
119 |
120 | def key_types
121 | @key_types ||= super.merge(OOF_KEY_TYPES)
122 | end
123 |
124 | def key_alias
125 | @key_alias ||= super.merge(OOF_KEY_ALIAS)
126 | end
127 |
128 | def simplify!
129 | oof_settings = @ews_item[:oof_settings][:elems].inject(:merge)
130 | oof_settings[:oof_state] = oof_settings[:oof_state][:text].downcase.to_sym
131 | oof_settings[:external_audience] = oof_settings[:external_audience][:text]
132 | if oof_settings[:duration]
133 | dur = oof_settings[:duration][:elems].inject(:merge)
134 | oof_settings[:duration] = {
135 | start_time: DateTime.iso8601(dur[:start_time][:text]),
136 | end_time: DateTime.iso8601(dur[:end_time][:text])
137 | }
138 | end
139 | oof_settings[:internal_reply] = oof_settings[:internal_reply][:elems][0][:message][:text] || ""
140 | oof_settings[:external_reply] = oof_settings[:external_reply][:elems][0][:message][:text] || ""
141 | @ews_item[:oof_settings] = oof_settings
142 | @ews_item[:allow_external_oof] = @ews_item[:allow_external_oof][:text]
143 | end
144 |
145 | end #OutOfOffice
146 |
147 | end
148 |
--------------------------------------------------------------------------------
/lib/ews/types/post_item.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS::Types
2 | class PostItem
3 | include Viewpoint::EWS
4 | include Viewpoint::EWS::Types
5 | include Viewpoint::EWS::Types::Item
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/lib/ews/types/search_folder.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS::Types
2 | class SearchFolder
3 | include Viewpoint::EWS
4 | include Viewpoint::EWS::Types
5 | include Viewpoint::EWS::Types::GenericFolder
6 |
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/lib/ews/types/status_event.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint::EWS::Types
20 |
21 | class StatusEvent
22 | include Viewpoint::EWS
23 | include Viewpoint::EWS::Types
24 | include Viewpoint::EWS::Types::Item
25 |
26 | STATUS_EVENT_KEY_PATHS = {
27 | :watermark => [:watermark, :text],
28 | }
29 |
30 |
31 | private
32 |
33 |
34 | def key_paths
35 | @key_paths ||= STATUS_EVENT_KEY_PATHS
36 | end
37 |
38 | end
39 | end
40 |
--------------------------------------------------------------------------------
/lib/ews/types/task.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS::Types
2 | class Task
3 | include Viewpoint::EWS
4 | include Viewpoint::EWS::Types
5 | include Viewpoint::EWS::Types::Item
6 |
7 | TASK_KEY_PATHS = {
8 | complete?: [:is_complete, :text],
9 | recurring?: [:is_recurring, :text],
10 | start_date: [:start_date, :text],
11 | due_date: [:end_date, :text],
12 | reminder_due_by: [:reminder_due_by, :text],
13 | reminder?: [:reminder_is_set, :text],
14 | percent_complete: [:percent_complete, :text],
15 | status: [:status, :text],
16 | }
17 |
18 | TASK_KEY_TYPES = {
19 | recurring?: ->(str){str.downcase == 'true'},
20 | complete?: ->(str){str.downcase == 'true'},
21 | reminder?: ->(str){str.downcase == 'true'},
22 | percent_complete: ->(str){str.to_i},
23 | }
24 | TASK_KEY_ALIAS = {}
25 |
26 | private
27 |
28 | def key_paths
29 | super.merge(TASK_KEY_PATHS)
30 | end
31 |
32 | def key_types
33 | super.merge(TASK_KEY_TYPES)
34 | end
35 |
36 | def key_alias
37 | super.merge(TASK_KEY_ALIAS)
38 | end
39 |
40 | end
41 | end
42 |
--------------------------------------------------------------------------------
/lib/ews/types/tasks_folder.rb:
--------------------------------------------------------------------------------
1 | module Viewpoint::EWS::Types
2 | class TasksFolder
3 | include Viewpoint::EWS
4 | include Viewpoint::EWS::Types
5 | include Viewpoint::EWS::Types::GenericFolder
6 |
7 | # Creates a new task
8 | # @param attributes [Hash] Parameters of the task. Some example attributes are listed below.
9 | # @option attributes :subject [String]
10 | # @option attributes :start_date [Time]
11 | # @option attributes :due_date [Time]
12 | # @option attributes :reminder_due_by [Time]
13 | # @option attributes :reminder_is_set [Boolean]
14 | # @return [Task]
15 | # @see Template::Task
16 | def create_item(attributes)
17 | template = Viewpoint::EWS::Template::Task.new attributes
18 | template.saved_item_folder_id = {id: self.id, change_key: self.change_key}
19 | rm = ews.create_item(template.to_ews_create).response_messages.first
20 | if rm && rm.success?
21 | Task.new ews, rm.items.first[:task][:elems].first
22 | else
23 | if rm
24 | raise EwsCreateItemError, "Could not create item in folder. #{rm.code}: #{rm.message_text}"
25 | else
26 | raise EwsCreateItemError, "Could not create item in folder."
27 | end
28 | end
29 | end
30 | end
31 | end
32 |
--------------------------------------------------------------------------------
/lib/viewpoint.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | require 'kconv' if(RUBY_VERSION.start_with? '1.9') # bug in rubyntlm with ruby 1.9.x
20 | require 'date'
21 | require 'base64'
22 | require 'nokogiri'
23 | require 'ostruct'
24 | require 'logging'
25 |
26 | # String utilities
27 | require 'viewpoint/string_utils'
28 |
29 | # Load the logging setup
30 | require 'viewpoint/logging'
31 |
32 | # Load the Exception classes
33 | require 'ews/exceptions/exceptions'
34 |
35 | # Load the backend SOAP / EWS infrastructure.
36 | require 'ews/soap'
37 | require 'ews/soap/response_message'
38 | require 'ews/soap/ews_response'
39 | require 'ews/soap/ews_soap_response'
40 | require 'ews/soap/ews_soap_availability_response'
41 | require 'ews/soap/ews_soap_free_busy_response'
42 | require 'ews/soap/ews_soap_room_response'
43 | require 'ews/soap/ews_soap_roomlist_response'
44 | require 'ews/soap/builders/ews_builder'
45 | require 'ews/soap/parsers/ews_parser'
46 | require 'ews/soap/parsers/ews_sax_document'
47 | # Mix-ins for the ExchangeWebService
48 | require 'ews/soap/exchange_data_services'
49 | require 'ews/soap/exchange_notification'
50 | require 'ews/soap/exchange_synchronization'
51 | require 'ews/soap/exchange_availability'
52 | require 'ews/soap/exchange_user_configuration'
53 | require 'ews/soap/exchange_time_zones'
54 | require 'ews/soap/exchange_web_service'
55 |
56 | require 'ews/errors'
57 | require 'ews/connection_helper'
58 | require 'ews/connection'
59 |
60 | require 'ews/impersonation'
61 |
62 | # Base Types
63 | require 'ews/types'
64 | require 'ews/types/item_field_uri_map'
65 | require 'ews/types/generic_folder'
66 | require 'ews/types/item'
67 | # Folders
68 | require 'ews/types/folder'
69 | require 'ews/types/calendar_folder'
70 | require 'ews/types/contacts_folder'
71 | require 'ews/types/tasks_folder'
72 | require 'ews/types/search_folder'
73 | # Items
74 | require 'ews/types/message'
75 | require 'ews/types/calendar_item'
76 | require 'ews/types/contact'
77 | require 'ews/types/distribution_list'
78 | require 'ews/types/meeting_message'
79 | require 'ews/types/meeting_request'
80 | require 'ews/types/meeting_response'
81 | require 'ews/types/meeting_cancellation'
82 | require 'ews/types/task'
83 | require 'ews/types/attachment'
84 | require 'ews/types/file_attachment'
85 | require 'ews/types/item_attachment'
86 | require 'ews/types/mailbox_user'
87 | require 'ews/types/out_of_office'
88 | require 'ews/types/export_items_response_message'
89 | require 'ews/types/post_item'
90 |
91 | # Events
92 | require 'ews/types/event'
93 | require 'ews/types/copied_event'
94 | require 'ews/types/created_event'
95 | require 'ews/types/deleted_event'
96 | require 'ews/types/free_busy_changed_event'
97 | require 'ews/types/modified_event'
98 | require 'ews/types/moved_event'
99 | require 'ews/types/new_mail_event'
100 | require 'ews/types/status_event'
101 |
102 | # Template Objects
103 | require 'ews/templates/message'
104 | require 'ews/templates/forward_item'
105 | require 'ews/templates/reply_to_item'
106 | require 'ews/templates/calendar_item'
107 | require 'ews/templates/task'
108 |
109 | # The proxy between the models and the web service
110 | require 'ews/ews_client'
111 |
--------------------------------------------------------------------------------
/lib/viewpoint/logging.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint
20 | module EWS
21 | attr_reader :logger
22 |
23 | def self.root_logger
24 | Logging.logger.root
25 | end
26 | end # EWS
27 | end
28 |
--------------------------------------------------------------------------------
/lib/viewpoint/logging/config.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint
20 | module EWS
21 | Logging.logger.root.level = :debug
22 | Logging.logger.root.appenders = Logging.appenders.stdout
23 | end # EWS
24 | end
25 |
--------------------------------------------------------------------------------
/lib/viewpoint/string_utils.rb:
--------------------------------------------------------------------------------
1 | =begin
2 | This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3 |
4 | Copyright © 2011 Dan Wanek
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | =end
18 |
19 | module Viewpoint
20 |
21 | class StringFormatException < ::Exception; end
22 |
23 | # Collection of utility methods for working with Strings
24 | module StringUtils
25 |
26 | DURATION_RE = /
27 | (?P)
28 | ((?\d+)W)?
29 | ((?\d+)D)?
30 | (?