spark_api 1.3.16 → 1.3.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -21,6 +21,7 @@ Usage Examples
21
21
  ------------------------
22
22
 
23
23
  ```ruby
24
+ require 'spark_api'
24
25
  SparkApi.configure do |config|
25
26
  config.endpoint = 'https://sparkapi.com'
26
27
  # Using Spark API Authentication, refer to the Authentication documentation for OAuth2
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.3.16
1
+ 1.3.17
@@ -29,6 +29,10 @@ module SparkApi
29
29
  end
30
30
  @logger
31
31
  end
32
+
33
+ def self.logger= logger
34
+ @logger = logger
35
+ end
32
36
  #:nocov:
33
37
 
34
38
  def self.client(opts={})
@@ -22,8 +22,8 @@ module SparkApi
22
22
  start_time = Time.now
23
23
  request_time = Time.now - start_time
24
24
  new_session = @authenticator.authenticate
25
- SparkApi.logger.info("[#{(request_time * 1000).to_i}ms]")
26
- SparkApi.logger.debug("Session: #{new_session.inspect}")
25
+ SparkApi.logger.info { "[#{(request_time * 1000).to_i}ms]" }
26
+ SparkApi.logger.debug { "Session: #{new_session.inspect}" }
27
27
  new_session
28
28
  end
29
29
 
@@ -34,7 +34,7 @@ module SparkApi
34
34
 
35
35
  # Delete the current session
36
36
  def logout
37
- SparkApi.logger.info("Logging out.")
37
+ SparkApi.logger.info { "Logging out." }
38
38
  @authenticator.logout
39
39
  end
40
40
 
@@ -17,15 +17,15 @@ module SparkApi
17
17
 
18
18
  def authenticate
19
19
  sig = sign("#{@client.api_secret}ApiKey#{@client.api_key}")
20
- SparkApi.logger.debug("Authenticating to #{@client.endpoint}")
20
+ SparkApi.logger.debug { "Authenticating to #{@client.endpoint}" }
21
21
  start_time = Time.now
22
22
  request_path = "/#{@client.version}/session?ApiKey=#{@client.api_key}&ApiSig=#{sig}"
23
23
  resp = @client.connection(true).post request_path, ""
24
24
  request_time = Time.now - start_time
25
- SparkApi.logger.info("[#{(request_time * 1000).to_i}ms] Api: POST #{request_path}")
26
- SparkApi.logger.debug("Authentication Response: #{resp.inspect}")
25
+ SparkApi.logger.info { "[#{(request_time * 1000).to_i}ms] Api: POST #{request_path}" }
26
+ SparkApi.logger.debug { "Authentication Response: #{resp.inspect}" }
27
27
  @session = Session.new(resp.body.results.first)
28
- SparkApi.logger.debug("Authentication: #{@session.inspect}")
28
+ SparkApi.logger.debug { "Authentication: #{@session.inspect}" }
29
29
  @session
30
30
  end
31
31
 
@@ -74,11 +74,11 @@ module SparkApi
74
74
  request_opts.merge!(options)
75
75
  sig = sign_token(escaped_path, request_opts, body)
76
76
  request_path = "#{escaped_path}?#{build_url_parameters({"ApiSig"=>sig}.merge(request_opts))}"
77
- SparkApi.logger.debug("Request: #{request_path}")
77
+ SparkApi.logger.debug { "Request: #{request_path}" }
78
78
  if body.nil?
79
79
  response = @client.connection.send(method, request_path)
80
80
  else
81
- SparkApi.logger.debug("Data: #{body}")
81
+ SparkApi.logger.debug { "Data: #{body}" }
82
82
  response = @client.connection.send(method, request_path, body)
83
83
  end
84
84
  response
@@ -50,11 +50,11 @@ module SparkApi
50
50
 
51
51
  parameter_string = options.size > 0 ? "?#{build_url_parameters(options)}" : ""
52
52
  request_path = "#{escaped_path}#{parameter_string}"
53
- SparkApi.logger.debug("Request: #{request_path}")
53
+ SparkApi.logger.debug { "Request: #{request_path}" }
54
54
  if body.nil?
55
55
  response = connection.send(method, request_path)
56
56
  else
57
- SparkApi.logger.debug("Data: #{body}")
57
+ SparkApi.logger.debug { "Data: #{body}" }
58
58
  response = connection.send(method, request_path, body)
59
59
  end
60
60
  response
@@ -76,14 +76,14 @@ module SparkApi
76
76
  # Create a sparkbar token based on the current user's access token
77
77
  def sparkbar_token()
78
78
  raise ClientError, "OAuth2Provider must configure the sparkbar_uri to use sparkbar tokens" if provider.sparkbar_uri.nil?
79
- SparkApi.logger.debug("[sparkbar] create token to #{provider.sparkbar_uri}")
79
+ SparkApi.logger.debug { "[sparkbar] create token to #{provider.sparkbar_uri}" }
80
80
  uri = URI.parse(provider.sparkbar_uri)
81
81
  request_path = "#{uri.path}"
82
82
 
83
- SparkApi.logger.info("[sparkbar] create token to #{request_path}, #{session.access_token.inspect}")
83
+ SparkApi.logger.info { "[sparkbar] create token to #{request_path}, #{session.access_token.inspect}" }
84
84
  response = sparkbar_connection("#{uri.scheme}://#{uri.host}").post(request_path, "access_token=#{session.access_token}").body
85
85
  token = response["token"]
86
- SparkApi.logger.debug("[sparkbar] New token created #{token}")
86
+ SparkApi.logger.debug { "[sparkbar] New token created #{token}" }
87
87
  token
88
88
  end
89
89
 
@@ -14,22 +14,22 @@ module SparkApi
14
14
 
15
15
  def on_complete(env)
16
16
  body = MultiJson.decode(env[:body])
17
- SparkApi.logger.debug("[oauth2] Response Body: #{body.inspect}")
17
+ SparkApi.logger.debug { "[oauth2] Response Body: #{body.inspect}" }
18
18
  unless body.is_a?(Hash)
19
19
  raise InvalidResponse, "The server response could not be understood"
20
20
  end
21
21
  case env[:status]
22
22
  when 200..299
23
- SparkApi.logger.debug("[oauth2] Success!")
23
+ SparkApi.logger.debug{ "[oauth2] Success!" }
24
24
  session = OAuthSession.new(body)
25
25
  else
26
26
  # Handle the WWW-Authenticate Response Header Field if present. This can be returned by
27
27
  # OAuth2 implementations and wouldn't hurt to log.
28
28
  auth_header_error = env[:request_headers]["WWW-Authenticate"]
29
- SparkApi.logger.warn("Authentication error #{auth_header_error}") unless auth_header_error.nil?
29
+ SparkApi.logger.warn { "Authentication error #{auth_header_error}" } unless auth_header_error.nil?
30
30
  raise ClientError, {:message => body["error"], :code =>0, :status => env[:status]}
31
31
  end
32
- SparkApi.logger.debug("[oauth2] Session=#{session.inspect}")
32
+ SparkApi.logger.debug { "[oauth2] Session=#{session.inspect}" }
33
33
  env[:body] = session
34
34
  end
35
35
 
@@ -46,13 +46,13 @@ module SparkApi
46
46
 
47
47
  def on_complete(env)
48
48
  body = MultiJson.decode(env[:body])
49
- SparkApi.logger.debug("[sparkbar] Response Body: #{body.inspect}")
49
+ SparkApi.logger.debug{ "[sparkbar] Response Body: #{body.inspect}" }
50
50
  unless body.is_a?(Hash)
51
51
  raise InvalidResponse, "The server response could not be understood"
52
52
  end
53
53
  case env[:status]
54
54
  when 200..299
55
- SparkApi.logger.debug("[sparkbar] Success!")
55
+ SparkApi.logger.debug{ "[sparkbar] Success!" }
56
56
  if body.include?("token")
57
57
  env[:body] = body
58
58
  return
@@ -17,7 +17,7 @@ module SparkApi
17
17
  else
18
18
  raise ClientError, "Unsupported grant type [#{provider.grant_type}]"
19
19
  end
20
- SparkApi.logger.debug("[oauth2] setup #{granter.class.name}")
20
+ SparkApi.logger.debug { "[oauth2] setup #{granter.class.name}" }
21
21
  granter
22
22
  end
23
23
 
@@ -38,16 +38,16 @@ module SparkApi
38
38
  protected
39
39
 
40
40
  def create_session(token_params)
41
- SparkApi.logger.debug("[oauth2] create_session to #{provider.access_uri} params #{token_params}")
41
+ SparkApi.logger.debug { "[oauth2] create_session to #{provider.access_uri} params #{token_params}" }
42
42
  uri = URI.parse(provider.access_uri)
43
43
  request_path = "#{uri.path}"
44
44
  response = oauth_access_connection("#{uri.scheme}://#{uri.host}").post(request_path, "#{token_params}").body
45
45
  response.expires_in = provider.session_timeout if response.expires_in.nil?
46
- SparkApi.logger.debug("[oauth2] New session created #{response}")
46
+ SparkApi.logger.debug { "[oauth2] New session created #{response}" }
47
47
  response
48
48
  rescue Faraday::Error::ConnectionFailed => e
49
49
  if @client.ssl_verify && e.message =~ /certificate verify failed/
50
- SparkApi.logger.error(SparkApi::Errors.ssl_verification_error)
50
+ SparkApi.logger.error { SparkApi::Errors.ssl_verification_error }
51
51
  end
52
52
  raise e
53
53
  end
@@ -10,7 +10,7 @@ module SparkApi
10
10
  end
11
11
  def authenticate
12
12
  if(provider.code.nil?)
13
- SparkApi.logger.debug("[oauth2] No authoriztion code present. Redirecting to #{authorization_url}.")
13
+ SparkApi.logger.debug { "[oauth2] No authoriztion code present. Redirecting to #{authorization_url}." }
14
14
  provider.redirect(authorization_url)
15
15
  end
16
16
  if needs_refreshing?
@@ -21,12 +21,12 @@ module SparkApi
21
21
  end
22
22
 
23
23
  def refresh()
24
- SparkApi.logger.debug("[oauth2] Refresh oauth session.")
24
+ SparkApi.logger.debug { "[oauth2] Refresh oauth session." }
25
25
  refresher = GrantTypeRefresh.new(client,provider,session)
26
26
  refresher.params = {"redirect_uri" => @provider.redirect_uri}
27
27
  refresher.authenticate
28
28
  rescue ClientError => e
29
- SparkApi.logger.info("[oauth2] Refreshing token failed, the library will try and authenticate from scratch: #{e.message}")
29
+ SparkApi.logger.info { "[oauth2] Refreshing token failed, the library will try and authenticate from scratch: #{e.message}" }
30
30
  nil
31
31
  end
32
32
 
@@ -12,7 +12,7 @@ module SparkApi
12
12
  def authenticate
13
13
  new_session = nil
14
14
  unless @session.refresh_token.nil?
15
- SparkApi.logger.debug("[oauth2] Refreshing authentication to #{provider.access_uri} using [#{session.refresh_token}]")
15
+ SparkApi.logger.debug { "[oauth2] Refreshing authentication to #{provider.access_uri} using [#{session.refresh_token}]" }
16
16
  new_session = create_session(token_params)
17
17
  end
18
18
  new_session
@@ -27,7 +27,7 @@ module SparkApi
27
27
  conn.options[:timeout] = self.timeout
28
28
  conn.adapter Faraday.default_adapter
29
29
  end
30
- SparkApi.logger.debug("Connection: #{conn.inspect}")
30
+ SparkApi.logger.debug { "Connection: #{conn.inspect}" }
31
31
  conn
32
32
  end
33
33
 
@@ -19,7 +19,7 @@ module SparkApi
19
19
  env[:body] = decompress_body(env)
20
20
 
21
21
  body = MultiJson.decode(env[:body])
22
- SparkApi.logger.debug("Response Body: #{body.inspect}")
22
+ SparkApi.logger.debug{ "Response Body: #{body.inspect}" }
23
23
  unless body.is_a?(Hash) && body.key?("D")
24
24
  raise InvalidResponse, "The server response could not be understood"
25
25
  end
@@ -60,7 +60,7 @@ module SparkApi
60
60
  when 500
61
61
  raise ClientError, {:message => response.message, :code => response.code, :status => env[:status]}
62
62
  when 200..299
63
- SparkApi.logger.debug("Success!")
63
+ SparkApi.logger.debug { "Success!" }
64
64
  else
65
65
  raise ClientError, {:message => response.message, :code => response.code, :status => env[:status]}
66
66
  end
@@ -111,7 +111,6 @@ module SparkApi
111
111
  Note.build_subclass.tap do |note|
112
112
  note.prefix = "/listings/#{self.ListingKey}"
113
113
  note.element_name = "/my/notes"
114
- SparkApi.logger.info("Note.path: #{note.path}")
115
114
  end
116
115
  end
117
116
 
@@ -148,7 +147,6 @@ module SparkApi
148
147
  return save!(arguments)
149
148
  rescue BadResourceRequest => e
150
149
  self.errors << {:code => e.code, :message => e.message}
151
- SparkApi.logger.debug("BHDEBUG: #{e.inspect}")
152
150
  if e.code == 1053
153
151
  @constraints = []
154
152
  e.details.each do |detail|
@@ -157,16 +155,16 @@ module SparkApi
157
155
  end
158
156
  end
159
157
  end
160
- SparkApi.logger.warn("Failed to save resource #{self}: #{e.message}")
158
+ SparkApi.logger.warn { "Failed to save resource #{self}: #{e.message}" }
161
159
  rescue NotFound => e
162
- SparkApi.logger.error("Failed to save resource #{self}: #{e.message}")
160
+ SparkApi.logger.error { "Failed to save resource #{self}: #{e.message}" }
163
161
  end
164
162
  false
165
163
  end
166
164
  def save!(arguments={})
167
165
  writable_changed_keys = changed & WRITEABLE_FIELDS
168
166
  if writable_changed_keys.empty?
169
- SparkApi.logger.warn("No supported listing change detected")
167
+ SparkApi.logger.warn { "No supported listing change detected" }
170
168
  else
171
169
  results = connection.put "#{self.class.path}/#{self.Id}", build_hash(writable_changed_keys), arguments
172
170
  @contstraints = []
@@ -183,9 +181,9 @@ module SparkApi
183
181
  begin
184
182
  return reorder_photos!(arguments)
185
183
  rescue BadResourceRequest => e
186
- SparkApi.logger.warn("Failed to save resource #{self}: #{e.message}")
184
+ SparkApi.logger.warn { "Failed to save resource #{self}: #{e.message}" }
187
185
  rescue NotFound => e
188
- SparkApi.logger.error("Failed to save resource #{self}: #{e.message}")
186
+ SparkApi.logger.error { "Failed to save resource #{self}: #{e.message}" }
189
187
  end
190
188
  false
191
189
  end
@@ -209,7 +207,14 @@ module SparkApi
209
207
  def ExpirationDate=(value)
210
208
  write_attribute("ExpirationDate", value)
211
209
  end
212
-
210
+
211
+ def respond_to?(method_symbol, include_all=false)
212
+ if super
213
+ true
214
+ else
215
+ attributes['StandardFields'].include?(method_symbol.to_s) rescue false
216
+ end
217
+ end
213
218
 
214
219
  private
215
220
 
@@ -13,10 +13,10 @@ module SparkApi
13
13
  end
14
14
 
15
15
  def ListingIds=(listing_ids)
16
- attributes["ListingIds"] = Array(listing_ids)
16
+ write_attribute("ListingIds", Array(listing_ids))
17
17
  end
18
18
  def Name=(name)
19
- attributes["Name"] = name
19
+ write_attribute("Name", name)
20
20
  end
21
21
 
22
22
  def path
@@ -43,7 +43,7 @@ module SparkApi
43
43
  end
44
44
 
45
45
  def activate_client_from_config(symbol)
46
- SparkApi.logger.debug("Loading multiclient [#{symbol.to_s}] from config")
46
+ SparkApi.logger.debug { "Loading multiclient [#{symbol.to_s}] from config" }
47
47
  yaml = YamlConfig.build(symbol.to_s)
48
48
  if(yaml.oauth2?)
49
49
  Client.new(yaml.client_keys.merge({
@@ -1,3 +1,4 @@
1
+ require 'json'
1
2
  require 'cgi'
2
3
 
3
4
  module SparkApi
@@ -70,27 +71,27 @@ module SparkApi
70
71
  response = authenticator.request(method, request_path, nil, request_opts)
71
72
  else
72
73
  post_data = process_request_body(body)
73
- SparkApi.logger.debug("#{method.to_s.upcase} Data: #{post_data}")
74
+ SparkApi.logger.debug { "#{method.to_s.upcase} Data: #{post_data}" }
74
75
  response = authenticator.request(method, request_path, post_data, request_opts)
75
76
  end
76
77
  request_time = Time.now - start_time
77
- SparkApi.logger.debug("[#{(request_time * 1000).to_i}ms] Api: #{method.to_s.upcase} #{request_path}")
78
+ SparkApi.logger.debug { "[#{(request_time * 1000).to_i}ms] Api: #{method.to_s.upcase} #{request_path}" }
78
79
  rescue PermissionDenied => e
79
80
  if(ResponseCodes::SESSION_TOKEN_EXPIRED == e.code)
80
81
  unless (attempts +=1) > 1
81
- SparkApi.logger.debug("Retrying authentication")
82
+ SparkApi.logger.debug { "Retrying authentication" }
82
83
  authenticate
83
84
  retry
84
85
  end
85
86
  end
86
87
  # No luck authenticating... KABOOM!
87
- SparkApi.logger.error("Authentication failed or server is sending us expired tokens, nothing we can do here.")
88
+ SparkApi.logger.error { "Authentication failed or server is sending us expired tokens, nothing we can do here." }
88
89
  raise
89
90
  end
90
91
  response.body
91
92
  rescue Faraday::Error::ConnectionFailed => e
92
93
  if self.ssl_verify && e.message =~ /certificate verify failed/
93
- SparkApi.logger.error(SparkApi::Errors.ssl_verification_error)
94
+ SparkApi.logger.error { SparkApi::Errors.ssl_verification_error }
94
95
  end
95
96
  raise e
96
97
  end
@@ -0,0 +1,9 @@
1
+ {
2
+ "D": {
3
+ "ListingIds": [
4
+ "20110112234857732941000000",
5
+ "20110302120238448431000000",
6
+ "20110510011212354751000000"
7
+ ]
8
+ }
9
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "D": {
3
+ "ListingIds": [
4
+ "20110112234857732941000000",
5
+ "20110302120238448431000000",
6
+ "20110510011212354751000000"
7
+ ]
8
+ }
9
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "D": {
3
+ "Name": "My Cart's Name"
4
+ }
5
+ }
@@ -14,7 +14,6 @@ require 'spark_api'
14
14
 
15
15
  FileUtils.mkdir 'log' unless File.exists? 'log'
16
16
 
17
- # TODO, really we should change the library to support configuration without overriding
18
17
  module SparkApi
19
18
  def self.logger
20
19
  if @logger.nil?
@@ -43,14 +43,24 @@ describe ListingCart do
43
43
  resource.ListingCount.should eq(10)
44
44
  end
45
45
 
46
- on_put_it "should save a listing cart" do
46
+ on_put_it "should save a listing cart Name" do
47
47
  stub_api_get("/#{subject.class.element_name}", 'listing_carts/listing_cart.json')
48
48
  resource = subject.class.get.first
49
- stub_api_put("/#{subject.class.element_name}/#{resource.Id}", 'listing_carts/new.json', 'success.json')
49
+ stub_api_put("/#{subject.class.element_name}/#{resource.Id}", 'listing_carts/put_name.json', 'success.json')
50
50
  resource.Name = "My Cart's Name"
51
+ resource.changed?.should be(true)
52
+ resource.save.should be(true)
53
+ resource.ResourceUri.should eq("/v1/listingcarts/20100912153422758914000000")
54
+ end
55
+
56
+ on_put_it "should save a listing cart ListingIds" do
57
+ stub_api_get("/#{subject.class.element_name}", 'listing_carts/listing_cart.json')
58
+ resource = subject.class.get.first
59
+ stub_api_put("/#{subject.class.element_name}/#{resource.Id}", 'listing_carts/put_ids.json', 'success.json')
51
60
  resource.ListingIds = ['20110112234857732941000000',
52
61
  '20110302120238448431000000',
53
62
  '20110510011212354751000000']
63
+ resource.changed?.should be(true)
54
64
  resource.save.should be(true)
55
65
  resource.ResourceUri.should eq("/v1/listingcarts/20100912153422758914000000")
56
66
  end
@@ -97,6 +97,28 @@ describe Listing do
97
97
  it "should return full address" do
98
98
  @listing.full_address.should eq("100 Someone's St, Fargo, ND 55320")
99
99
  end
100
+
101
+ it "should provide shortcut methods to standard fields" do
102
+ @listing.StreetName.should eq("Someone's")
103
+ @listing.YearBuilt.should eq(nil)
104
+ @listing.BuildingAreaTotal.should eq("1321.0")
105
+ @listing.PublicRemarks.should eq(nil)
106
+ @listing.PostalCode.should eq("55320")
107
+ @listing.ListPrice.should eq("100000.0")
108
+ end
109
+
110
+ it "should report that it responds to shortcut methods to standard fields" do
111
+ @listing.should respond_to(:StreetName)
112
+ @listing.should respond_to(:YearBuilt)
113
+ @listing.should respond_to(:BuildingAreaTotal)
114
+ @listing.should respond_to(:PublicRemarks)
115
+ @listing.should respond_to(:PostalCode)
116
+ @listing.should respond_to(:ListPrice)
117
+
118
+ @listing.should_not respond_to(:BogusField)
119
+ @listing.StandardFields['BogusField'] = 'bogus'
120
+ @listing.should respond_to(:BogusField)
121
+ end
100
122
  end
101
123
 
102
124
  describe "class methods" do