rets 0.1.4 → 0.1.5

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 CHANGED
@@ -1,3 +1,9 @@
1
+ ### 0.1.5 / 2012-03-17
2
+
3
+ * fix: retries raise error after too many failures
4
+ * fix: raise error for failed multipart object request
5
+ * fix: retries start with a clean slate, fixing authorization errors during retry
6
+
1
7
  ### 0.1.4 / 2012-03-12
2
8
 
3
9
  * fix: an MLS uses lower case in RETS tag
data/lib/rets.rb CHANGED
@@ -8,7 +8,7 @@ require 'net/http/persistent'
8
8
  require 'nokogiri'
9
9
 
10
10
  module Rets
11
- VERSION = '0.1.4'
11
+ VERSION = '0.1.5'
12
12
 
13
13
  AuthorizationFailure = Class.new(ArgumentError)
14
14
  InvalidRequest = Class.new(ArgumentError)
data/lib/rets/client.rb CHANGED
@@ -13,16 +13,17 @@ module Rets
13
13
  @options = options
14
14
  clean_setup
15
15
  end
16
-
16
+
17
17
  def clean_setup
18
-
19
- @capabilities = nil
20
- @cookies = nil
21
- @metadata = nil
22
- @cached_metadata = nil
23
-
18
+
19
+ @capabilities = nil
20
+ @cookies = nil
21
+ @metadata = nil
22
+ @cached_metadata = nil
23
+ @tries = nil
24
+ @connection = nil
24
25
  self.authorization = nil
25
- self.capabilities = nil
26
+ self.capabilities = nil
26
27
 
27
28
  uri = URI.parse(@options[:login_url])
28
29
 
@@ -88,6 +89,8 @@ module Rets
88
89
  self.logger.info "Retry #{retries}/3"
89
90
  clean_setup
90
91
  retry
92
+ else
93
+ raise e
91
94
  end
92
95
  end
93
96
  end
@@ -300,7 +303,7 @@ module Rets
300
303
  if Net::HTTPUnauthorized === response
301
304
  raise AuthorizationFailure, "Authorization failed, check credentials?"
302
305
  else
303
- check_errors(response)
306
+ ErrorChecker.check(response)
304
307
  self.capabilities = extract_capabilities(Nokogiri.parse(response.body))
305
308
  end
306
309
  end
@@ -311,7 +314,7 @@ module Rets
311
314
  handle_unauthorized_response(response)
312
315
 
313
316
  elsif Net::HTTPSuccess === response # 2xx
314
- check_errors(response)
317
+ ErrorChecker.check(response)
315
318
  else
316
319
  raise UnknownResponse, "Unable to handle response #{response.class}"
317
320
  end
@@ -319,25 +322,6 @@ module Rets
319
322
  return response
320
323
  end
321
324
 
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)
326
-
327
- rets_element = xml.xpath("/RETS")
328
- reply_text = (rets_element.attr("ReplyText") || rets_element.attr("replyText")).value
329
- reply_code = (rets_element.attr("ReplyCode") || rets_element.attr("replyCode")).value.to_i
330
-
331
- if reply_code.nonzero?
332
- raise InvalidRequest, "Got error code #{reply_code} (#{reply_text})."
333
- end
334
- end
335
-
336
- rescue Nokogiri::XML::SyntaxError => e
337
- logger.debug "Not xml"
338
- end
339
- end
340
-
341
325
  def handle_cookies(response)
342
326
  if cookies?(response)
343
327
  self.cookies = response.get_fields('set-cookie')
@@ -498,5 +482,26 @@ module Rets
498
482
  out.join("\n")
499
483
  end
500
484
 
485
+ class ErrorChecker
486
+ def self.check(response)
487
+ begin
488
+ if !response.body.empty?
489
+ xml = Nokogiri::XML.parse(response.body, nil, nil, Nokogiri::XML::ParseOptions::STRICT)
490
+
491
+ rets_element = xml.xpath("/RETS")
492
+ reply_text = (rets_element.attr("ReplyText") || rets_element.attr("replyText")).value
493
+ reply_code = (rets_element.attr("ReplyCode") || rets_element.attr("replyCode")).value.to_i
494
+
495
+ if reply_code.nonzero?
496
+ raise InvalidRequest, "Got error code #{reply_code} (#{reply_text})."
497
+ end
498
+ end
499
+
500
+ rescue Nokogiri::XML::SyntaxError => e
501
+ #Not xml
502
+ end
503
+ end
504
+ end
505
+
501
506
  end
502
507
  end
@@ -28,9 +28,14 @@ module Rets
28
28
  next # not a valid chunk.
29
29
  end
30
30
  end
31
-
31
+ check_for_invalids_parts!(parts)
32
32
  parts
33
33
  end
34
+
35
+ def self.check_for_invalids_parts!(parts)
36
+ return unless parts.length == 1 && parts.first.headers['content-type'] == 'text/xml'
37
+ Client::ErrorChecker.check(parts.first)
38
+ end
34
39
  end
35
40
  end
36
41
  end
data/test/test_client.rb CHANGED
@@ -437,6 +437,13 @@ DIGEST
437
437
  @client.find(:all, :foo => :bar)
438
438
  end
439
439
 
440
+ def test_find_retries_on_errors
441
+ @client.stubs(:find_every).raises(Rets::AuthorizationFailure)
442
+ assert_raise Rets::AuthorizationFailure do
443
+ @client.find(:all, :foo => :bar)
444
+ end
445
+ end
446
+
440
447
  def test_find_provides_default_values
441
448
  @client.expects(:build_key_values).
442
449
  with("QueryType" => "DMQL2", "Format" => "COMPACT", "Query" => "x", "Foo" => "bar").
@@ -28,4 +28,12 @@ class TestParserMultipart < Test::Unit::TestCase
28
28
  parts = Rets::Parser::Multipart.parse(MULTIPART_RESPONSE_URLS, "rets.object.content.boundary.1330546052739")
29
29
  assert_equal 'http://foobarmls.com/RETS//MediaDisplay/98/hr2890998-1.jpg', parts[0].headers['location']
30
30
  end
31
+
32
+ def test_parse_with_error
33
+ raw = "\r\n--89467f8e0c6b48158c8f1883910212ec\r\nContent-Type: text/xml\r\nContent-ID: foo\r\nObject-ID: *\r\n\r\n<RETS ReplyCode=\"20403\" ReplyText=\"No Object Found\" />\r\n\r\n--89467f8e0c6b48158c8f1883910212ec--\r\n"
34
+ boundary = "89467f8e0c6b48158c8f1883910212ec"
35
+ assert_raise Rets::InvalidRequest do
36
+ Rets::Parser::Multipart.parse(raw, boundary)
37
+ end
38
+ end
31
39
  end
metadata CHANGED
@@ -1,85 +1,114 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: rets
3
- version: !ruby/object:Gem::Version
4
- version: 0.1.4
3
+ version: !ruby/object:Gem::Version
4
+ hash: 17
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 5
10
+ version: 0.1.5
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Estately, Inc. Open Source
9
14
  - Ben Bleything
10
15
  autorequire:
11
16
  bindir: bin
12
17
  cert_chain: []
13
- date: 2012-03-12 00:00:00.000000000 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
18
+
19
+ date: 2012-03-19 00:00:00 Z
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
16
22
  name: net-http-persistent
17
- requirement: &70169260555460 !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
18
25
  none: false
19
- requirements:
26
+ requirements:
20
27
  - - ~>
21
- - !ruby/object:Gem::Version
22
- version: '1.7'
28
+ - !ruby/object:Gem::Version
29
+ hash: 1
30
+ segments:
31
+ - 1
32
+ - 7
33
+ version: "1.7"
23
34
  type: :runtime
24
- prerelease: false
25
- version_requirements: *70169260555460
26
- - !ruby/object:Gem::Dependency
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
27
37
  name: nokogiri
28
- requirement: &70169260555040 !ruby/object:Gem::Requirement
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
29
40
  none: false
30
- requirements:
41
+ requirements:
31
42
  - - ~>
32
- - !ruby/object:Gem::Version
43
+ - !ruby/object:Gem::Version
44
+ hash: 15
45
+ segments:
46
+ - 1
47
+ - 4
48
+ - 4
33
49
  version: 1.4.4
34
50
  type: :runtime
35
- prerelease: false
36
- version_requirements: *70169260555040
37
- - !ruby/object:Gem::Dependency
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
38
53
  name: mocha
39
- requirement: &70169260554620 !ruby/object:Gem::Requirement
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
40
56
  none: false
41
- requirements:
57
+ requirements:
42
58
  - - ~>
43
- - !ruby/object:Gem::Version
59
+ - !ruby/object:Gem::Version
60
+ hash: 35
61
+ segments:
62
+ - 0
63
+ - 9
64
+ - 12
44
65
  version: 0.9.12
45
66
  type: :development
46
- prerelease: false
47
- version_requirements: *70169260554620
48
- - !ruby/object:Gem::Dependency
67
+ version_requirements: *id003
68
+ - !ruby/object:Gem::Dependency
49
69
  name: rdoc
50
- requirement: &70169260554200 !ruby/object:Gem::Requirement
70
+ prerelease: false
71
+ requirement: &id004 !ruby/object:Gem::Requirement
51
72
  none: false
52
- requirements:
73
+ requirements:
53
74
  - - ~>
54
- - !ruby/object:Gem::Version
55
- version: '3.10'
75
+ - !ruby/object:Gem::Version
76
+ hash: 19
77
+ segments:
78
+ - 3
79
+ - 10
80
+ version: "3.10"
56
81
  type: :development
57
- prerelease: false
58
- version_requirements: *70169260554200
59
- - !ruby/object:Gem::Dependency
82
+ version_requirements: *id004
83
+ - !ruby/object:Gem::Dependency
60
84
  name: hoe
61
- requirement: &70169260553780 !ruby/object:Gem::Requirement
85
+ prerelease: false
86
+ requirement: &id005 !ruby/object:Gem::Requirement
62
87
  none: false
63
- requirements:
88
+ requirements:
64
89
  - - ~>
65
- - !ruby/object:Gem::Version
66
- version: '2.13'
90
+ - !ruby/object:Gem::Version
91
+ hash: 35
92
+ segments:
93
+ - 2
94
+ - 16
95
+ version: "2.16"
67
96
  type: :development
68
- prerelease: false
69
- version_requirements: *70169260553780
70
- description: ! 'A pure-ruby library for fetching data from [RETS] servers.
71
-
72
-
73
- [RETS]: http://www.rets.org'
74
- email:
97
+ version_requirements: *id005
98
+ description: |-
99
+ A pure-ruby library for fetching data from [RETS] servers.
100
+
101
+ [RETS]: http://www.rets.org
102
+ email:
75
103
  - opensource@estately.com
76
104
  - ben@bleything.net
77
- executables:
105
+ executables:
78
106
  - rets
79
107
  extensions: []
80
- extra_rdoc_files:
108
+
109
+ extra_rdoc_files:
81
110
  - Manifest.txt
82
- files:
111
+ files:
83
112
  - CHANGELOG.md
84
113
  - Manifest.txt
85
114
  - README.md
@@ -106,31 +135,39 @@ files:
106
135
  - .gemtest
107
136
  homepage: http://github.com/estately/rets
108
137
  licenses: []
138
+
109
139
  post_install_message:
110
- rdoc_options:
140
+ rdoc_options:
111
141
  - --main
112
142
  - README.md
113
- require_paths:
143
+ require_paths:
114
144
  - lib
115
- required_ruby_version: !ruby/object:Gem::Requirement
145
+ required_ruby_version: !ruby/object:Gem::Requirement
116
146
  none: false
117
- requirements:
118
- - - ! '>='
119
- - !ruby/object:Gem::Version
120
- version: '0'
121
- required_rubygems_version: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ hash: 3
151
+ segments:
152
+ - 0
153
+ version: "0"
154
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
155
  none: false
123
- requirements:
124
- - - ! '>='
125
- - !ruby/object:Gem::Version
126
- version: '0'
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ hash: 3
160
+ segments:
161
+ - 0
162
+ version: "0"
127
163
  requirements: []
164
+
128
165
  rubyforge_project: rets
129
- rubygems_version: 1.8.15
166
+ rubygems_version: 1.8.10
130
167
  signing_key:
131
168
  specification_version: 3
132
169
  summary: A pure-ruby library for fetching data from [RETS] servers
133
- test_files:
170
+ test_files:
134
171
  - test/test_client.rb
135
172
  - test/test_metadata.rb
136
173
  - test/test_parser_compact.rb