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 +4 -4
- data/CHANGELOG.md +4 -0
- data/Manifest.txt +6 -0
- data/Rakefile +2 -1
- data/example/connect.rb +19 -0
- data/example/get-photos.rb +20 -0
- data/example/get-property.rb +16 -0
- data/lib/rets.rb +1 -1
- data/lib/rets/client.rb +3 -2
- data/lib/rets/http_client.rb +8 -8
- data/lib/rets/locking_http_client.rb +2 -2
- data/lib/rets/measuring_http_client.rb +2 -2
- data/lib/rets/parser/error_checker.rb +49 -0
- data/test/test_http_client.rb +62 -15
- metadata +28 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a9bf5e37008d7651782e347a520f24cb291931f
|
4
|
+
data.tar.gz: 22742e9f4a45db910f03358e45024ee25d8cb6e9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a742d37803a7c1354bb4f8d2c087b9a20b745c984286df5c243022cbb053612cb281350f589ca259494e955b7404bfd37db18ff2812441b2a560ad33485976f0
|
7
|
+
data.tar.gz: 250667d8536d504b41fc4192d8bb124237cd48bd663d061baccca0728b6408abd2d8776cd3ccf70ba6d7458a9a56e61f83a853510be725b264940be0e0c777b9
|
data/CHANGELOG.md
CHANGED
data/Manifest.txt
CHANGED
@@ -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.
|
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" ]
|
data/example/connect.rb
ADDED
@@ -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
|
data/lib/rets.rb
CHANGED
data/lib/rets/client.rb
CHANGED
@@ -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
|
339
|
-
@http_client.save_cookie_store
|
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={})
|
data/lib/rets/http_client.rb
CHANGED
@@ -52,13 +52,10 @@ module Rets
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
def save_cookie_store
|
55
|
+
def save_cookie_store
|
56
56
|
if options[:cookie_store]
|
57
|
-
|
58
|
-
|
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
|
-
|
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
|
@@ -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
|
data/test/test_http_client.rb
CHANGED
@@ -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.
|
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.
|
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.
|
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.
|
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.
|
124
|
+
version: '3.13'
|
111
125
|
description: |-
|
112
126
|
[](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:
|
178
|
-
rubygems_version: 2.2.
|
196
|
+
rubyforge_project:
|
197
|
+
rubygems_version: 2.2.3
|
179
198
|
signing_key:
|
180
199
|
specification_version: 4
|
181
200
|
summary: "[](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: []
|