rets 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
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