rets 0.8.1 → 0.9.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 40ba28e99fa147a1f23f7cf4e7e04fcd5c9a4218
4
- data.tar.gz: 8abca9ffb82c600b2f0ca9c6caf774c17eb0a4cb
3
+ metadata.gz: 6a9bf5e37008d7651782e347a520f24cb291931f
4
+ data.tar.gz: 22742e9f4a45db910f03358e45024ee25d8cb6e9
5
5
  SHA512:
6
- metadata.gz: c510f13d8823562c48a2fd87421ada813c3766846082c6dd8bdad442c4fe4922de65cbd0d2d486b7fcbe8fb48c69651b61fc844812bbc2e7b307152ca327d2e1
7
- data.tar.gz: 19f7bd93de8858158118108266f78d344c65c23f9f7c68ed20e19b7a77b0d42f4d187654c3a18ff817d5e35b1480b5e86741bd88acdf2a483a9510feb00777f8
6
+ metadata.gz: a742d37803a7c1354bb4f8d2c087b9a20b745c984286df5c243022cbb053612cb281350f589ca259494e955b7404bfd37db18ff2812441b2a560ad33485976f0
7
+ data.tar.gz: 250667d8536d504b41fc4192d8bb124237cd48bd663d061baccca0728b6408abd2d8776cd3ccf70ba6d7458a9a56e61f83a853510be725b264940be0e0c777b9
@@ -1,3 +1,7 @@
1
+ ### 0.9.0 / 2015-06-11
2
+
3
+ * feature: update to httpclient 2.6
4
+
1
5
  ### 0.8.1 / 2015-06-09
2
6
 
3
7
  * fix: actually make the httpclient version more specific this time
@@ -3,6 +3,9 @@ Manifest.txt
3
3
  README.md
4
4
  Rakefile
5
5
  bin/rets
6
+ example/connect.rb
7
+ example/get-photos.rb
8
+ example/get-property.rb
6
9
  lib/rets.rb
7
10
  lib/rets/client.rb
8
11
  lib/rets/client_progress_reporter.rb
@@ -17,10 +20,13 @@ lib/rets/metadata/rets_class.rb
17
20
  lib/rets/metadata/root.rb
18
21
  lib/rets/metadata/table.rb
19
22
  lib/rets/parser/compact.rb
23
+ lib/rets/parser/error_checker.rb
20
24
  lib/rets/parser/multipart.rb
21
25
  test/fixtures.rb
22
26
  test/helper.rb
23
27
  test/test_client.rb
28
+ test/test_error_checker.rb
29
+ test/test_http_client.rb
24
30
  test/test_locking_http_client.rb
25
31
  test/test_metadata.rb
26
32
  test/test_parser_compact.rb
data/Rakefile CHANGED
@@ -9,7 +9,8 @@ Hoe.plugin :gemspec
9
9
  Hoe.spec 'rets' do
10
10
  developer 'Estately, Inc. Open Source', 'opensource@estately.com'
11
11
 
12
- extra_deps << [ "httpclient", "~> 2.4.0" ]
12
+ extra_deps << [ "httpclient", "~> 2.6.0" ]
13
+ extra_deps << [ "http-cookie", "~> 1.0.0" ]
13
14
  extra_deps << [ "nokogiri", "~> 1.5" ]
14
15
 
15
16
  extra_dev_deps << [ "mocha", "~> 0.11" ]
@@ -0,0 +1,19 @@
1
+ require 'rets'
2
+
3
+ # Pass the :login_url, :username, :password and :version of RETS
4
+ client = Rets::Client.new({
5
+ login_url: 'login_url',
6
+ username: 'xxx',
7
+ password: 'xxx',
8
+ version: 'RETS/1.5'
9
+ })
10
+
11
+ begin
12
+ client.login
13
+ rescue => e
14
+ puts 'Error: ' + e.message
15
+ exit!
16
+ end
17
+
18
+ puts 'We connected! Lets log out...'
19
+ client.logout
@@ -0,0 +1,20 @@
1
+ require 'rets'
2
+
3
+
4
+ # Get all photos (*) for MLS ID 'mls_id'
5
+ # Pass :object_id (ie '0', '1,2', wildcard '*')
6
+ # The pass :resource (Property, Agent, MetaData, ...), :object_type (Photo, PhotoLarge), :rescource_id (ID of agent, MLS, ...)
7
+ photos = client.objects '*', {
8
+ resource: 'Property',
9
+ object_type: 'Photo',
10
+ resource_id: 'mls_id'
11
+ }
12
+
13
+ photos.each_with_index do |data, index|
14
+ File.open("property-#{index.to_s}.jpg", 'w') do |file|
15
+ file.write data.body
16
+ end
17
+ end
18
+
19
+ puts photos.length.to_s + ' photos saved.'
20
+ client.logout
@@ -0,0 +1,16 @@
1
+ require 'rets'
2
+
3
+
4
+ # Get one property
5
+ # Pass :first or :all
6
+ # Then :search_type (Property, Agent, ...), :class (Condo, Commerical, ...), :query and :limit
7
+ property = client.find :first, {
8
+ search_type: 'Property',
9
+ class: 'CLASS_NAME',
10
+ query: 'RETS_QUERY',
11
+ limit: 1
12
+ }
13
+
14
+ puts 'received property: '
15
+ puts property.inspect
16
+ client.logout
@@ -3,7 +3,7 @@ require 'digest/md5'
3
3
  require 'nokogiri'
4
4
 
5
5
  module Rets
6
- VERSION = '0.8.1'
6
+ VERSION = '0.9.0'
7
7
 
8
8
  MalformedResponse = Class.new(ArgumentError)
9
9
  UnknownResponse = Class.new(ArgumentError)
@@ -1,3 +1,4 @@
1
+ require 'http-cookie'
1
2
  require 'httpclient'
2
3
  require 'logger'
3
4
 
@@ -335,8 +336,8 @@ module Rets
335
336
  hash
336
337
  end
337
338
 
338
- def save_cookie_store(force=nil)
339
- @http_client.save_cookie_store(force)
339
+ def save_cookie_store
340
+ @http_client.save_cookie_store
340
341
  end
341
342
 
342
343
  def http_get(url, params=nil, extra_headers={})
@@ -52,13 +52,10 @@ module Rets
52
52
  end
53
53
  end
54
54
 
55
- def save_cookie_store(force=nil)
55
+ def save_cookie_store
56
56
  if options[:cookie_store]
57
- if force
58
- @http.cookie_manager.save_all_cookies(true, true, true)
59
- else
60
- @http.save_cookie_store
61
- end
57
+ #save session cookies
58
+ @http.cookie_manager.save_cookies(true)
62
59
  end
63
60
  end
64
61
 
@@ -82,9 +79,12 @@ module Rets
82
79
  end
83
80
 
84
81
  def http_cookie(name)
85
- http.cookies.each do |c|
86
- return c.value if c.name.downcase == name.downcase && c.match?(URI.parse(login_url))
82
+ @http.cookie_manager.cookies(login_url).each do |c|
83
+ if c.name.downcase == name.downcase
84
+ return c.value
85
+ end
87
86
  end
87
+
88
88
  nil
89
89
  end
90
90
  end
@@ -19,8 +19,8 @@ module Rets
19
19
  end
20
20
  end
21
21
 
22
- def save_cookie_store(force=nil)
23
- @http_client.save_cookie_store(force)
22
+ def save_cookie_store
23
+ @http_client.save_cookie_store
24
24
  end
25
25
 
26
26
  def lock_around(&block)
@@ -20,8 +20,8 @@ module Rets
20
20
  end
21
21
  end
22
22
 
23
- def save_cookie_store(force=nil)
24
- @http_client.save_cookie_store(force)
23
+ def save_cookie_store
24
+ @http_client.save_cookie_store
25
25
  end
26
26
  end
27
27
  end
@@ -0,0 +1,49 @@
1
+ module Rets
2
+ module Parser
3
+ class ErrorChecker
4
+ def self.check(response)
5
+ # some RETS servers returns HTTP code 412 when session cookie expired, yet the response body
6
+ # passes XML check. We need to special case for this situation.
7
+ # This method is also called from multipart.rb where there are headers and body but no status_code
8
+ if response.respond_to?(:status_code) && response.status_code == 412
9
+ raise HttpError, "HTTP status: #{response.status_code}, body: #{response.body}"
10
+ end
11
+
12
+ # some RETS servers return success code in XML body but failure code 4xx in http status
13
+ # If xml body is present we ignore http status
14
+
15
+ if !response.body.empty?
16
+ begin
17
+ xml = Nokogiri::XML.parse(response.body, nil, nil, Nokogiri::XML::ParseOptions::STRICT)
18
+
19
+ rets_element = xml.xpath("/RETS")
20
+ unless rets_element.empty?
21
+ reply_text = (rets_element.attr("ReplyText") || rets_element.attr("replyText")).value
22
+ reply_code = (rets_element.attr("ReplyCode") || rets_element.attr("replyCode")).value.to_i
23
+
24
+ if reply_code == NoRecordsFound::ERROR_CODE
25
+ raise NoRecordsFound.new(reply_text)
26
+ elsif reply_code == NoObjectFound::ERROR_CODE
27
+ raise NoObjectFound.new(reply_text)
28
+ elsif reply_code.nonzero?
29
+ raise InvalidRequest.new(reply_code, reply_text)
30
+ else
31
+ return
32
+ end
33
+ end
34
+ rescue Nokogiri::XML::SyntaxError
35
+ #Not xml
36
+ end
37
+ end
38
+
39
+ if response.respond_to?(:ok?) && ! response.ok?
40
+ if response.status_code == 401
41
+ raise AuthorizationFailure.new(response.status_code, response.body)
42
+ else
43
+ raise HttpError, "HTTP status: #{response.status_code}, body: #{response.body}"
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -5,7 +5,6 @@ class TestHttpClient < MiniTest::Test
5
5
  @cm = WebAgent::CookieManager.new
6
6
 
7
7
  @http = HTTPClient.new
8
- @http.cookie_manager = @cm
9
8
 
10
9
  @logger = Rets::Client::FakeLogger.new
11
10
  @logger.stubs(:debug?).returns(false)
@@ -13,20 +12,6 @@ class TestHttpClient < MiniTest::Test
13
12
  @http_client = Rets::HttpClient.new(@http, {}, @logger, "http://rets.rets.com/somestate/login.aspx")
14
13
  end
15
14
 
16
- def test_http_cookie_with_webagent_cookie
17
- cookie1 = "RETS-Session-ID=879392834723043209; path=/; domain=rets.rets.com; expires=Wednesday, 31-Dec-2037 12:00:00 GMT"
18
- @cm.parse(cookie1, URI.parse("http://www.rets.rets.com"))
19
-
20
- cookie2 = "Foo=Bar; path=/; domain=rets.rets.com; expires=Wednesday, 31-Dec-2037 12:00:00 GMT"
21
- @cm.parse(cookie2, URI.parse("http://www.rets.rets.com"))
22
-
23
- assert_equal "879392834723043209", @http_client.http_cookie('RETS-Session-ID')
24
- end
25
-
26
- def test_http_cookie_without_webagent_cookie
27
- assert_equal nil, @http_client.http_cookie('RETS-Session-ID')
28
- end
29
-
30
15
  def test_http_get_delegates_to_client
31
16
  url = 'foo@example.com'
32
17
  response = stub(:response)
@@ -46,4 +31,66 @@ class TestHttpClient < MiniTest::Test
46
31
 
47
32
  assert_equal @http_client.http_post(url, {}), response
48
33
  end
34
+
35
+ class CookieManagement < MiniTest::Test
36
+ def setup
37
+ @cm = WebAgent::CookieManager.new
38
+ http = HTTPClient.new
39
+ http.cookie_manager = @cm
40
+ @client = Rets::HttpClient.new(http, {}, nil, "http://rets.rets.com/somestate/login.aspx")
41
+ end
42
+
43
+ def teardown
44
+ # Empty cookie jar
45
+ @cm.cookies = []
46
+ end
47
+
48
+ def test_http_cookie_with_one_cookie_from_one_domain
49
+ set_cookie = "RETS-Session-ID=879392834723043209; path=/; domain=rets.rets.com; expires=Wednesday, 31-Dec-2037 12:00:00 GMT"
50
+ @cm.parse(set_cookie, URI.parse("http://www.rets.rets.com"))
51
+ assert_equal "879392834723043209", @client.http_cookie('RETS-Session-ID')
52
+ end
53
+
54
+ def test_http_cookie_with_multiple_cookies_from_one_domain
55
+ # NOTE: Cookies are ordered alphabetically by name when retrieving
56
+ set_cookie_1 = "RETS-Session-ID=879392834723043209; path=/; domain=rets.rets.com; expires=Wednesday, 31-Dec-2037 12:00:00 GMT"
57
+ @cm.parse(set_cookie_1, URI.parse("http://www.rets.rets.com"))
58
+
59
+ set_cookie_2 = "Zoo=Bar; path=/; domain=rets.rets.com; expires=Wednesday, 31-Dec-2037 12:00:00 GMT"
60
+ @cm.parse(set_cookie_2, URI.parse("http://www.rets.rets.com"))
61
+
62
+ set_cookie_3 = "Foo=Bar; path=/; domain=rets.rets.com; expires=Wednesday, 31-Dec-2037 12:00:00 GMT"
63
+ @cm.parse(set_cookie_3, URI.parse("http://www.rets.rets.com"))
64
+
65
+ assert_equal "879392834723043209", @client.http_cookie('RETS-Session-ID')
66
+ end
67
+
68
+ def test_http_cookie_with_no_cookies_from_domain
69
+ assert_equal nil, @client.http_cookie('RETS-Session-ID')
70
+ end
71
+
72
+ def test_save_cookie_store
73
+ cookie_file = Tempfile.new('cookie_file').path
74
+
75
+ #setup cookie store
76
+ http_a = HTTPClient.new
77
+ http_a.set_cookie_store(cookie_file)
78
+ client_a = Rets::HttpClient.new(http_a, { cookie_store: cookie_file }, nil, "http://rets.rets.com/somestate/login.aspx")
79
+
80
+ #add cookie
81
+ cookie = "RETS-Session-ID=879392834723043209; path=/; domain=rets.rets.com; expires=Wednesday, 31-Dec-2037 12:00:00 GMT"
82
+ http_a.cookie_manager.parse(cookie, URI.parse("http://www.rets.rets.com"))
83
+
84
+ #save cookie
85
+ client_a.save_cookie_store
86
+
87
+ #create new HTTPCLient with same cookie store
88
+ http_b = HTTPClient.new
89
+ http_b.set_cookie_store(cookie_file)
90
+ client_b = Rets::HttpClient.new(http_b, { cookie_store: cookie_file }, nil, "http://rets.rets.com/somestate/login.aspx")
91
+
92
+ #check added cookie exists
93
+ assert_equal "879392834723043209", client_b.http_cookie('RETS-Session-ID')
94
+ end
95
+ end
49
96
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rets
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Estately, Inc. Open Source
@@ -16,14 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 2.4.0
19
+ version: 2.6.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 2.4.0
26
+ version: 2.6.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: http-cookie
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.0.0
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: nokogiri
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -100,14 +114,14 @@ dependencies:
100
114
  requirements:
101
115
  - - "~>"
102
116
  - !ruby/object:Gem::Version
103
- version: '3.6'
117
+ version: '3.13'
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
122
  - - "~>"
109
123
  - !ruby/object:Gem::Version
110
- version: '3.6'
124
+ version: '3.13'
111
125
  description: |-
112
126
  [![Build Status](https://secure.travis-ci.org/estately/rets.png?branch=master)](http://travis-ci.org/estately/rets)
113
127
  A pure-ruby library for fetching data from [RETS] servers.
@@ -129,6 +143,9 @@ files:
129
143
  - README.md
130
144
  - Rakefile
131
145
  - bin/rets
146
+ - example/connect.rb
147
+ - example/get-photos.rb
148
+ - example/get-property.rb
132
149
  - lib/rets.rb
133
150
  - lib/rets/client.rb
134
151
  - lib/rets/client_progress_reporter.rb
@@ -143,6 +160,7 @@ files:
143
160
  - lib/rets/metadata/root.rb
144
161
  - lib/rets/metadata/table.rb
145
162
  - lib/rets/parser/compact.rb
163
+ - lib/rets/parser/error_checker.rb
146
164
  - lib/rets/parser/multipart.rb
147
165
  - test/fixtures.rb
148
166
  - test/helper.rb
@@ -155,7 +173,8 @@ files:
155
173
  - test/test_parser_multipart.rb
156
174
  - test/vcr_cassettes/unauthorized_response.yml
157
175
  homepage: http://github.com/estately/rets
158
- licenses: []
176
+ licenses:
177
+ - MIT
159
178
  metadata: {}
160
179
  post_install_message:
161
180
  rdoc_options:
@@ -174,17 +193,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
174
193
  - !ruby/object:Gem::Version
175
194
  version: '0'
176
195
  requirements: []
177
- rubyforge_project: rets
178
- rubygems_version: 2.2.0
196
+ rubyforge_project:
197
+ rubygems_version: 2.2.3
179
198
  signing_key:
180
199
  specification_version: 4
181
200
  summary: "[![Build Status](https://secure.travis-ci.org/estately/rets.png?branch=master)](http://travis-ci.org/estately/rets)
182
201
  A pure-ruby library for fetching data from [RETS] servers"
183
- test_files:
184
- - test/test_client.rb
185
- - test/test_error_checker.rb
186
- - test/test_http_client.rb
187
- - test/test_locking_http_client.rb
188
- - test/test_metadata.rb
189
- - test/test_parser_compact.rb
190
- - test/test_parser_multipart.rb
202
+ test_files: []