homeaway-api 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,67 @@
1
+ # Copyright (c) 2015 HomeAway.com, Inc.
2
+ # All rights reserved. http://www.homeaway.com
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'faraday'
17
+ require 'faraday-http-cache'
18
+ require 'faraday_middleware/response/follow_redirects'
19
+ require 'faraday_middleware/instrumentation'
20
+ require 'faraday_middleware/response/mashify'
21
+ require 'faraday_middleware/response/parse_json'
22
+
23
+ module HomeAway
24
+ module API
25
+ # @private
26
+ module Adapters
27
+ # @private
28
+ class FaradayAdapter
29
+ # @private
30
+ def self.call(site, opts, headers, method, uri, body, params)
31
+ agent = Faraday::Connection.new(site, opts) do |conn|
32
+ conn.headers = headers
33
+ conn.adapter Faraday.default_adapter
34
+ conn.options.params_encoder = Faraday::FlatParamsEncoder
35
+ conn.use Faraday::HttpCache
36
+ conn.use FaradayMiddleware::Mashify, :mash_class => HomeAway::API::Response
37
+ conn.use FaradayMiddleware::ParseJson
38
+ conn.use FaradayMiddleware::Instrumentation
39
+ conn.use FaradayMiddleware::FollowRedirects
40
+ end
41
+ response = agent.send(method, uri) do |req|
42
+ req.body = body.to_json unless body.empty?
43
+ req.params = params unless params.empty?
44
+ end
45
+ self.transform response
46
+ end
47
+
48
+ # @private
49
+ def self.transform(response)
50
+ mash = response.body
51
+ mash = HomeAway::API::Response.new unless mash
52
+ mash._metadata.headers = HomeAway::API::Response.new(response.headers.to_hash) if response.respond_to? :headers
53
+ if response.respond_to? :status
54
+ mash._metadata.status_code = response.status
55
+ if mash._metadata.status_code.to_i >= 400
56
+ raise (HomeAway::API::Errors.for_http_code mash._metadata.status_code).new(mash)
57
+ end
58
+ end
59
+ if response.respond_to? :env
60
+ mash._metadata.request_headers = HomeAway::API::Response.new(response.env.request_headers.to_hash) if response.env.respond_to? :request_headers
61
+ end
62
+ mash
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,83 @@
1
+ # Copyright (c) 2015 HomeAway.com, Inc.
2
+ # All rights reserved. http://www.homeaway.com
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'hurley'
17
+ require 'cgi'
18
+
19
+ # @private
20
+ module Hurley
21
+ # @private
22
+ class Query
23
+ # @private
24
+ def self.default
25
+ @default ||= Flat
26
+ end
27
+ end
28
+ end
29
+
30
+
31
+ module HomeAway
32
+ module API
33
+ # @private
34
+ module Adapters
35
+ # @private
36
+ class HurleyAdapter
37
+ # @private
38
+ def self.__update_opts(struct, opts)
39
+ opts.each_pair do |k, v|
40
+ method = "#{k}=".to_sym
41
+ if struct.respond_to?(method)
42
+ struct.send(method, v)
43
+ end
44
+ end
45
+ end
46
+
47
+ # @private
48
+ def self.call(site, opts, headers, method, uri, body, params)
49
+ begin
50
+ agent = Hurley::Client.new(site)
51
+ agent.header.update(headers)
52
+ self.__update_opts(agent.request_options, opts)
53
+ self.__update_opts(agent.ssl_options, opts)
54
+ request = agent.request(method, uri)
55
+ request.query.update(params) unless params.empty?
56
+ request.body = body.to_json unless (!body.respond_to?(:to_json) || body.empty?)
57
+ response = agent.call(request)
58
+ rescue => e
59
+ raise HomeAway::API::Errors::HomeAwayAPIError.new(e.message.to_s)
60
+ end
61
+ response_to_mash(response)
62
+ end
63
+
64
+ # @private
65
+ def self.response_to_mash(response)
66
+ body = response.body ||= {}
67
+ mash = HomeAway::API::Response.new
68
+ mash.update JSON.parse(body) unless body.empty?
69
+ mash._metadata = HomeAway::API::Response.new
70
+ mash._metadata.headers = response.header.to_hash if response.respond_to? :header
71
+ if response.respond_to? :status_code
72
+ mash._metadata.status_code = response.status_code
73
+ if mash._metadata.status_code.to_i >= 400
74
+ raise (HomeAway::API::Errors.for_http_code mash._metadata.status_code).new(mash)
75
+ end
76
+ end
77
+ mash.delete(:_metadata) if mash._metadata.empty?
78
+ mash
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,224 @@
1
+ # Copyright (c) 2015 HomeAway.com, Inc.
2
+ # All rights reserved. http://www.homeaway.com
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ module HomeAway
17
+ module API
18
+ class Client
19
+
20
+ # @return [Hash] the global default configuration
21
+ def self.default_configuration
22
+ @@default_configuration ||= HomeAway::API::Util::Defaults.instance.to_hash
23
+ end
24
+
25
+ # Pass a block expecting a single hash parameter and set any global configuration settings
26
+ # that will be inherited by all instances created in the future
27
+ # @return [Hash] the global default configuration
28
+ def self.configure
29
+ yield @@default_configuration if block_given?
30
+ @@default_configuration
31
+ end
32
+
33
+ include HomeAway::API::Util::OAuth
34
+
35
+ attr_accessor :configuration
36
+ attr_reader :mode, :token, :token_expires
37
+
38
+ # @!attribute [rw] configuration
39
+ # @return [Hash] the current client configuration
40
+
41
+ # @!attribute [r] token
42
+ # @return [String] the current encoded token this client has
43
+
44
+ # @!attribute [r] mode
45
+ # @return [Symbol] the current authentication state of this client. One of either :unauthorized, :two_legged, or :three_legged
46
+
47
+ # @!attribute [r] token_expires
48
+ # @return [Time] the time that the current token in use on this client will expire
49
+
50
+
51
+ # Instantiates a new HomeAway API client
52
+ #
53
+ # @option opts [String] :client_id Your HomeAway API OAuth client id. Required here if not set globally
54
+ # @option opts [String] :client_secret Your HomeAway API OAuth client secret. Required here if not set globally
55
+ # @option opts [String] :token An existing token if you already have one saved from a previous usage of the api
56
+ # @return [HomeAway::API::Client] a newly instantiated HomeAway API client
57
+ def initialize(opts={})
58
+ @configuration = Hashie::Mash.new(self.class.default_configuration.merge(opts))
59
+ if opts.has_key?(:token)
60
+ @configuration[:manual_token_supplied] = true
61
+ set_token(opts.delete(:token))
62
+ end
63
+ validate_configuration
64
+ logger.debug("client initialized with configuration: #{@configuration}")
65
+ attempt_auth if @token.nil?
66
+ end
67
+
68
+ # Update the configuration of this particular instance of the client.
69
+ # Pass a block expecting a single hash parameter to update the configuration settings.
70
+ # @return [Hash] This client's configuration
71
+ def configure
72
+ yield @configuration if block_given?
73
+ validate_configuration
74
+ @configuration
75
+ end
76
+
77
+ # @return [Object] The current logger that has been configured
78
+ def logger
79
+ @configuration.logger
80
+ end
81
+
82
+ # @return [String] The current bearer auth token
83
+ def token
84
+ raise HomeAway::API::Errors::HomeAwayAPIError.new('Ticket must be supplied') if @token.nil?
85
+ @token
86
+ end
87
+
88
+ # @private
89
+ def marshal_dump
90
+ # we lose our logger instance naively here, marshal dump doesn't like
91
+ # one of its fields
92
+ dump_config = configuration.dup.to_hash
93
+ dump_config.delete('logger')
94
+ [@token, token_expires, dump_config]
95
+ end
96
+
97
+ # @private
98
+ def marshal_load(array)
99
+ @token = array[0]
100
+ @token_expires = array[1]
101
+ @configuration = Hashie::Mash.new(array[2])
102
+ @configuration.logger = HomeAway::API::Util::Defaults.instance.logger
103
+ end
104
+
105
+ # @return [Boolean] Has the token that the client is currently using expired?
106
+ def token_expired?
107
+ return false if @configuration[:manual_token_supplied]
108
+ begin
109
+ Time.now >= token_expires
110
+ rescue
111
+ true
112
+ end
113
+ end
114
+
115
+ # @private
116
+ def get(url, params={})
117
+ method :get, url, {}, params
118
+ end
119
+
120
+ # @private
121
+ def put(url, body, params={})
122
+ method :put, url, body, params
123
+ end
124
+
125
+ # @private
126
+ def post(url, body, params={})
127
+ method :post, url, body, params
128
+ end
129
+
130
+ # @private
131
+ def delete(url, params={})
132
+ method :delete, url, {}, params
133
+ end
134
+
135
+ # @private
136
+ def options(url, params={})
137
+ method :options, url, {}, params
138
+ end
139
+
140
+ private
141
+
142
+ def validate_configuration
143
+ required_uuids = [:client_id, :client_secret]
144
+ [required_uuids].flatten.each do |required_configuration_directive|
145
+ raise ArgumentError.new("#{required_configuration_directive.to_s} is required but not supplied") if (@configuration[required_configuration_directive] == nil || @configuration[required_configuration_directive].nil? || !configuration.has_key?(required_configuration_directive))
146
+ end
147
+ required_uuids.each do |uuid|
148
+ HomeAway::API::Util::Validators.uuid(@configuration[uuid])
149
+ end
150
+ true
151
+ end
152
+
153
+
154
+ def adapter
155
+ registered_adapters = {
156
+ :faraday => HomeAway::API::Adapters::FaradayAdapter,
157
+ :hurley => HomeAway::API::Adapters::HurleyAdapter
158
+ }
159
+ raise ArgumentError.new("Invalid adapter #{@configuration[:adapter]}") unless registered_adapters.keys.include? @configuration[:adapter]
160
+ logger.debug("using adapter: #{@configuration[:adapter]}")
161
+ registered_adapters[@configuration[:adapter]]
162
+ end
163
+
164
+ def headers
165
+ headers = {}
166
+ headers['content-type'] = 'application/json'
167
+ headers['Cache-control'] = @configuration[:cache_control]
168
+ headers['Authorization'] = "Bearer #{token}"
169
+ headers['User-Agent'] = "HomeAway API ruby_sdk/#{HomeAway::API::VERSION}"
170
+ headers['X-HomeAway-RequestMarker'] = SecureRandom.uuid
171
+ headers['X-HomeAway-TestMode'] = 'true' if @configuration[:test_mode]
172
+ logger.debug("Sending headers: #{headers.to_json}")
173
+ headers
174
+ end
175
+
176
+ def method(method, url, body, params)
177
+ if token_expired?
178
+ if @configuration[:auto_reauth]
179
+ logger.info('Token expired and auth_reauth is enabled, attempting 2 legged oauth.')
180
+ attempt_auth
181
+ logger.info("Re-authentication attempt completed. Current client status: #{@mode}")
182
+ else
183
+ raise HomeAway::API::Errors::TokenExpiredError.new('token is expired, please login again via the oauth url')
184
+ end
185
+ end
186
+ logger.info("#{method.to_s.upcase} to #{url} with params #{params.to_json}")
187
+ site = @configuration[:api_site] ||= @configuration[:site]
188
+ response = adapter.call(site, @configuration[:connection_opts], headers, method, url, body, params)
189
+ logger.debug("returning payload: #{response.to_json}")
190
+ response
191
+ end
192
+
193
+ def attempt_auth
194
+ begin
195
+ two_legged!
196
+ @mode = :two_legged
197
+ rescue => e
198
+ logger.info("failed to perform automatic 2 legged oauth due to: #{e.to_s}")
199
+ @mode = :unauthorized
200
+ end
201
+ end
202
+
203
+ def set_token(token)
204
+ @token = token
205
+ begin
206
+ listing '100000'
207
+ begin
208
+ me
209
+ logger.info('token supplied on client initialization provided 3-legged oauth')
210
+ @mode = :three_legged
211
+ rescue => e
212
+ logger.info('token supplied on client initialization provided 2-legged oauth')
213
+ @mode = :two_legged
214
+ end
215
+ rescue => e
216
+ logger.error("token supplied on client initialization was not valid: #{e.to_s}")
217
+ @mode = :unauthorized
218
+ end
219
+ end
220
+ end
221
+ end
222
+ end
223
+
224
+ require 'homeaway/api/domain/client_includes'
@@ -0,0 +1,45 @@
1
+ # Copyright (c) 2015 HomeAway.com, Inc.
2
+ # All rights reserved. http://www.homeaway.com
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ module HomeAway
17
+ module API
18
+ module Domain
19
+ module AddMessage
20
+
21
+ # Add a Message to a Conversation
22
+ #
23
+ # analogous to calling a POST on API url /public/addMessage
24
+ #
25
+ # @note user must be logged in via 3 legged oauth to call this function without error
26
+ #
27
+ # Headers:
28
+ # * X-HomeAway-DisplayLocale: If a locale is not specified in a query param, it will be searched for in the X-HomeAway-DisplayLocale Header. If it is not supplied in either area the default locale of the user will be selected if it exists. Otherwise the Accept-Language Header will be used.
29
+ #
30
+ # @param conversation_id [String] The Conversation UUID to load.
31
+ # @param message [String] The body of the message to add to the given conversation.
32
+ # @return [HomeAway::API::Response] the result of the call to the API
33
+ def add_message(conversation_id, message, opts={})
34
+ body = {
35
+ 'message' => message.to_s,
36
+ }.merge(HomeAway::API::Util::Validators.query_keys(opts))
37
+ params = {
38
+ 'conversationId' => HomeAway::API::Util::Validators.uuid(conversation_id)
39
+ }
40
+ post '/public/addMessage', body, params
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,44 @@
1
+ # Copyright (c) 2015 HomeAway.com, Inc.
2
+ # All rights reserved. http://www.homeaway.com
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'homeaway/api/domain/listing'
17
+ require 'homeaway/api/domain/listing_reviews'
18
+ require 'homeaway/api/domain/search'
19
+ require 'homeaway/api/domain/quote'
20
+ require 'homeaway/api/domain/my_listings'
21
+ require 'homeaway/api/domain/my_inbox'
22
+ require 'homeaway/api/domain/submit_review'
23
+ require 'homeaway/api/domain/me'
24
+ require 'homeaway/api/domain/my_reservations'
25
+ require 'homeaway/api/domain/add_message'
26
+ require 'homeaway/api/domain/conversation'
27
+
28
+ module HomeAway
29
+ module API
30
+ class Client
31
+ include HomeAway::API::Domain::Listing
32
+ include HomeAway::API::Domain::ListingReviews
33
+ include HomeAway::API::Domain::Search
34
+ include HomeAway::API::Domain::Quote
35
+ include HomeAway::API::Domain::MyListings
36
+ include HomeAway::API::Domain::MyInbox
37
+ include HomeAway::API::Domain::SubmitReview
38
+ include HomeAway::API::Domain::Me
39
+ include HomeAway::API::Domain::MyReservations
40
+ include HomeAway::API::Domain::AddMessage
41
+ include HomeAway::API::Domain::Conversation
42
+ end
43
+ end
44
+ end