rets 0.8.1 → 0.9.0

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