rets 0.1.1 → 0.1.2
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/CHANGELOG.md +4 -0
- data/lib/rets.rb +1 -1
- data/lib/rets/client.rb +52 -25
- data/test/test_client.rb +17 -0
- metadata +8 -8
data/CHANGELOG.md
CHANGED
data/lib/rets.rb
CHANGED
data/lib/rets/client.rb
CHANGED
@@ -10,22 +10,32 @@ module Rets
|
|
10
10
|
attr_writer :capabilities, :metadata
|
11
11
|
|
12
12
|
def initialize(options)
|
13
|
+
@options = options
|
14
|
+
clean_setup
|
15
|
+
end
|
16
|
+
|
17
|
+
def clean_setup
|
18
|
+
|
13
19
|
@capabilities = nil
|
14
20
|
@cookies = nil
|
15
21
|
@metadata = nil
|
22
|
+
@cached_metadata = nil
|
23
|
+
|
24
|
+
self.authorization = nil
|
25
|
+
self.capabilities = nil
|
16
26
|
|
17
|
-
uri = URI.parse(options[:login_url])
|
27
|
+
uri = URI.parse(@options[:login_url])
|
18
28
|
|
19
|
-
uri.user = options.key?(:username) ? CGI.escape(options[:username]) : nil
|
20
|
-
uri.password = options.key?(:password) ? CGI.escape(options[:password]) : nil
|
29
|
+
uri.user = @options.key?(:username) ? CGI.escape(@options[:username]) : nil
|
30
|
+
uri.password = @options.key?(:password) ? CGI.escape(@options[:password]) : nil
|
21
31
|
|
22
|
-
self.options = DEFAULT_OPTIONS.merge(options)
|
32
|
+
self.options = DEFAULT_OPTIONS.merge(@options)
|
23
33
|
self.uri = uri
|
24
34
|
|
25
|
-
self.logger = options[:logger] || FakeLogger.new
|
35
|
+
self.logger = @options[:logger] || FakeLogger.new
|
26
36
|
|
27
|
-
self.session = options[:session] if options[:session]
|
28
|
-
@cached_metadata = options[:metadata] || nil
|
37
|
+
self.session = @options[:session] if @options[:session]
|
38
|
+
@cached_metadata = @options[:metadata] || nil
|
29
39
|
end
|
30
40
|
|
31
41
|
|
@@ -59,14 +69,29 @@ module Rets
|
|
59
69
|
#
|
60
70
|
def find(quantity, opts = {})
|
61
71
|
case quantity
|
62
|
-
when :first then
|
63
|
-
when :all then
|
72
|
+
when :first then find_with_retries(opts.merge(:limit => 1)).first
|
73
|
+
when :all then find_with_retries(opts)
|
64
74
|
else raise ArgumentError, "First argument must be :first or :all"
|
65
75
|
end
|
66
76
|
end
|
67
77
|
|
68
78
|
alias search find
|
69
79
|
|
80
|
+
def find_with_retries(opts = {})
|
81
|
+
retries = 0
|
82
|
+
begin
|
83
|
+
find_every(opts)
|
84
|
+
rescue AuthorizationFailure, InvalidRequest => e
|
85
|
+
if retries < 3
|
86
|
+
retries += 1
|
87
|
+
self.logger.warn "Failed with message: #{e.message}"
|
88
|
+
self.logger.info "Retry #{retries}/3"
|
89
|
+
clean_setup
|
90
|
+
retry
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
70
95
|
def find_every(opts = {})
|
71
96
|
search_uri = capability_url("Search")
|
72
97
|
|
@@ -275,6 +300,7 @@ module Rets
|
|
275
300
|
if Net::HTTPUnauthorized === response
|
276
301
|
raise AuthorizationFailure, "Authorization failed, check credentials?"
|
277
302
|
else
|
303
|
+
check_errors(response)
|
278
304
|
self.capabilities = extract_capabilities(Nokogiri.parse(response.body))
|
279
305
|
end
|
280
306
|
end
|
@@ -285,31 +311,32 @@ module Rets
|
|
285
311
|
handle_unauthorized_response(response)
|
286
312
|
|
287
313
|
elsif Net::HTTPSuccess === response # 2xx
|
288
|
-
|
289
|
-
|
290
|
-
|
314
|
+
check_errors(response)
|
315
|
+
else
|
316
|
+
raise UnknownResponse, "Unable to handle response #{response.class}"
|
317
|
+
end
|
291
318
|
|
292
|
-
|
293
|
-
|
319
|
+
return response
|
320
|
+
end
|
294
321
|
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
322
|
+
def check_errors(response)
|
323
|
+
begin
|
324
|
+
if !response.body.empty?
|
325
|
+
xml = Nokogiri::XML.parse(response.body, nil, nil, Nokogiri::XML::ParseOptions::STRICT)
|
299
326
|
|
300
|
-
|
301
|
-
|
327
|
+
reply_text = xml.xpath("/RETS").attr("ReplyText").value
|
328
|
+
reply_code = xml.xpath("/RETS").attr("ReplyCode").value.to_i
|
302
329
|
|
330
|
+
if reply_code.nonzero?
|
331
|
+
raise InvalidRequest, "Got error code #{reply_code} (#{reply_text})."
|
332
|
+
end
|
303
333
|
end
|
304
334
|
|
305
|
-
|
306
|
-
|
335
|
+
rescue Nokogiri::XML::SyntaxError => e
|
336
|
+
logger.debug "Not xml"
|
307
337
|
end
|
308
|
-
|
309
|
-
return response
|
310
338
|
end
|
311
339
|
|
312
|
-
|
313
340
|
def handle_cookies(response)
|
314
341
|
if cookies?(response)
|
315
342
|
self.cookies = response.get_fields('set-cookie')
|
data/test/test_client.rb
CHANGED
@@ -116,6 +116,18 @@ class TestClient < Test::Unit::TestCase
|
|
116
116
|
end
|
117
117
|
end
|
118
118
|
|
119
|
+
def test_handle_unauthorize_response_handles_rets_errors
|
120
|
+
response = Net::HTTPSuccess.new("", "", "")
|
121
|
+
response.stubs(:body => RETS_ERROR)
|
122
|
+
@client.stubs(:build_auth)
|
123
|
+
@client.stubs(:extract_digest_header)
|
124
|
+
@client.stubs(:raw_request).returns(response)
|
125
|
+
|
126
|
+
assert_raise Rets::InvalidRequest do
|
127
|
+
@client.handle_unauthorized_response(response)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
119
131
|
def test_handle_response_handles_rets_valid_response
|
120
132
|
response = Net::HTTPSuccess.new("", "", "")
|
121
133
|
response.stubs(:body => RETS_REPLY)
|
@@ -420,6 +432,11 @@ DIGEST
|
|
420
432
|
end
|
421
433
|
end
|
422
434
|
|
435
|
+
def test_find_retries_on_errors
|
436
|
+
@client.stubs(:find_every).raises(Rets::AuthorizationFailure).then.raises(Rets::InvalidRequest).then.returns([])
|
437
|
+
@client.find(:all, :foo => :bar)
|
438
|
+
end
|
439
|
+
|
423
440
|
def test_find_provides_default_values
|
424
441
|
@client.expects(:build_key_values).
|
425
442
|
with("QueryType" => "DMQL2", "Format" => "COMPACT", "Query" => "x", "Foo" => "bar").
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rets
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 2
|
10
|
+
version: 0.1.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Estately, Inc. Open Source
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2012-
|
19
|
+
date: 2012-02-17 00:00:00 Z
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
name: net-http-persistent
|
@@ -88,11 +88,11 @@ dependencies:
|
|
88
88
|
requirements:
|
89
89
|
- - ~>
|
90
90
|
- !ruby/object:Gem::Version
|
91
|
-
hash:
|
91
|
+
hash: 25
|
92
92
|
segments:
|
93
93
|
- 2
|
94
|
-
-
|
95
|
-
version: "2.
|
94
|
+
- 13
|
95
|
+
version: "2.13"
|
96
96
|
type: :development
|
97
97
|
version_requirements: *id005
|
98
98
|
description: |-
|
@@ -163,7 +163,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
163
163
|
requirements: []
|
164
164
|
|
165
165
|
rubyforge_project: rets
|
166
|
-
rubygems_version: 1.8.
|
166
|
+
rubygems_version: 1.8.15
|
167
167
|
signing_key:
|
168
168
|
specification_version: 3
|
169
169
|
summary: A pure-ruby library for fetching data from [RETS] servers
|