rets-hack 0.11

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.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +142 -0
  3. data/Manifest.txt +58 -0
  4. data/README.md +129 -0
  5. data/Rakefile +28 -0
  6. data/bin/rets +202 -0
  7. data/example/connect.rb +19 -0
  8. data/example/get-photos.rb +20 -0
  9. data/example/get-property.rb +16 -0
  10. data/lib/rets/client.rb +373 -0
  11. data/lib/rets/client_progress_reporter.rb +48 -0
  12. data/lib/rets/http_client.rb +133 -0
  13. data/lib/rets/locking_http_client.rb +34 -0
  14. data/lib/rets/measuring_http_client.rb +27 -0
  15. data/lib/rets/metadata/caching.rb +59 -0
  16. data/lib/rets/metadata/containers.rb +89 -0
  17. data/lib/rets/metadata/file_cache.rb +29 -0
  18. data/lib/rets/metadata/json_serializer.rb +27 -0
  19. data/lib/rets/metadata/lookup_table.rb +65 -0
  20. data/lib/rets/metadata/lookup_type.rb +19 -0
  21. data/lib/rets/metadata/marshal_serializer.rb +27 -0
  22. data/lib/rets/metadata/multi_lookup_table.rb +70 -0
  23. data/lib/rets/metadata/null_cache.rb +24 -0
  24. data/lib/rets/metadata/resource.rb +103 -0
  25. data/lib/rets/metadata/rets_class.rb +57 -0
  26. data/lib/rets/metadata/rets_object.rb +41 -0
  27. data/lib/rets/metadata/root.rb +155 -0
  28. data/lib/rets/metadata/table.rb +33 -0
  29. data/lib/rets/metadata/table_factory.rb +19 -0
  30. data/lib/rets/metadata/yaml_serializer.rb +27 -0
  31. data/lib/rets/metadata.rb +18 -0
  32. data/lib/rets/parser/compact.rb +117 -0
  33. data/lib/rets/parser/error_checker.rb +56 -0
  34. data/lib/rets/parser/multipart.rb +39 -0
  35. data/lib/rets.rb +269 -0
  36. data/test/fixtures.rb +324 -0
  37. data/test/helper.rb +14 -0
  38. data/test/test_caching.rb +89 -0
  39. data/test/test_client.rb +307 -0
  40. data/test/test_error_checker.rb +87 -0
  41. data/test/test_file_cache.rb +42 -0
  42. data/test/test_http_client.rb +132 -0
  43. data/test/test_json_serializer.rb +26 -0
  44. data/test/test_locking_http_client.rb +29 -0
  45. data/test/test_marshal_serializer.rb +26 -0
  46. data/test/test_metadata.rb +71 -0
  47. data/test/test_metadata_class.rb +50 -0
  48. data/test/test_metadata_lookup_table.rb +21 -0
  49. data/test/test_metadata_lookup_type.rb +21 -0
  50. data/test/test_metadata_multi_lookup_table.rb +60 -0
  51. data/test/test_metadata_object.rb +33 -0
  52. data/test/test_metadata_resource.rb +148 -0
  53. data/test/test_metadata_root.rb +151 -0
  54. data/test/test_metadata_table.rb +21 -0
  55. data/test/test_metadata_table_factory.rb +24 -0
  56. data/test/test_parser_compact.rb +115 -0
  57. data/test/test_parser_multipart.rb +39 -0
  58. data/test/test_yaml_serializer.rb +26 -0
  59. data/test/vcr_cassettes/unauthorized_response.yml +262 -0
  60. metadata +227 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: aa7eec964ae1e040ba2d291f5283432661b1a08c
4
+ data.tar.gz: 597bbab53e0a16701d8b070cf193f7d4bc015053
5
+ SHA512:
6
+ metadata.gz: 4946f647c2cc1a67f644018c50918cfb6fd992ce13eda38de79db7ea5f842f7e7aa10dadb8244b7f4ef908cac4c4ebe564cad1a2191bc1819972a70e66d7278f
7
+ data.tar.gz: 994a48a22bef9a8f03a1195a685339e9d6d2a29a985172962e312d072b1487b8f37a51819afe22765f1d5fbd2627afa65f6c0a0dbe1917ce6a61302b77b17466
data/CHANGELOG.md ADDED
@@ -0,0 +1,142 @@
1
+ ### 0.11.0 / NOT RELEASED YET
2
+
3
+ * fix: fix retry logging
4
+ * feature: allow retries to be configured for all query types in client settings
5
+ * feature: allow configrable wait time between retries
6
+ * feature: detect errors as error messages in a response body delivered with HTTP 200
7
+
8
+ ### 0.10.1 / 2016-05-04
9
+
10
+ * fix: handle invalid codepoints in character references
11
+
12
+ ### 0.10.0 / 2016-02-29
13
+
14
+ * fix: ensure cookie store exists #133
15
+ * feature: make cached capabilities case insensitive #136
16
+ * feature: add specific classes for each rets error #137
17
+ * feature: whitelist RETS search options #142
18
+ * feature: simplify metadata caching #134
19
+ * feature: use a SAX parser #98
20
+ * fix: save capabilities to avoid double logins #148
21
+ * feature: login on authorization error #155
22
+ * add basic support for DataDictionary feeds #156
23
+ * fix: count always returns a number #161
24
+ * feature: make lookup tables case insensitive #163
25
+ * feature: update to httpclient 2.7 #165
26
+ * fix: getObject now works with non-multipart responses #166
27
+ * fix: getObject works with multiple ids #167
28
+ * feature: store rets object metadata #168
29
+ * feature: add a code of conduct #171
30
+
31
+ ### 0.9.0 / 2015-06-11
32
+
33
+ * feature: update to httpclient 2.6
34
+
35
+ ### 0.8.1 / 2015-06-09
36
+
37
+ * fix: actually make the httpclient version more specific this time
38
+
39
+ ### 0.8.0 / 2015-06-09
40
+
41
+ * feature: reduce memory usage on parsing metadata
42
+ * fix: correctly raise authorization error when given XHTML instead of XML
43
+ * fix: unescape HTML encoded responses
44
+ * fix: make httpclient version requirement more specific
45
+ * feature: add ability to print metadata to a file
46
+ * fix: remove Gemfile.lock from repository
47
+
48
+ ### 0.7.0 / 2015-01-16
49
+
50
+ * feature: optionally treat No Records Found as not an error
51
+ * fix: update httpclient version, patches SSL vulnerabilities
52
+ * feature: work around bogus http status codes that don't agree with XML body
53
+
54
+ ### 0.6.0 / 2014-11-26
55
+
56
+ * fix: fix spelling error that created misleading exceptions
57
+ * feature: track stats for http requests sent
58
+ * feature: raise an exception if the login action doesn't return an http 200 status
59
+ * feature: add better class description and more fields to print tree
60
+ * feature: support http proxies
61
+ * feature: customizable http timeouts
62
+ * feature: add logging http headers when in debug mode
63
+ * feature: strip invalid utf8 from responses before parsing
64
+ * fix: don't raise an exception on a 401 after logout
65
+ * fix: treat no matching records status without a count node as a zero count
66
+ * feature: add an option for loading custom ca_certs
67
+ * feature: remove invalid resource types from metadata
68
+ * feature: special case http 412
69
+ * feature: add max_retries option
70
+
71
+ ### 0.5.1 / 2013-10-30
72
+
73
+ * fix: 0.5.0 was broken, fix gem Manifest to fix gem
74
+
75
+ ### 0.5.0 / 2013-09-05
76
+
77
+ * feature: Allow client.count to get integer count
78
+ * feature: Allow for downcased capability names
79
+ * fix: Handle the rets element being empty
80
+ * feature: Instrument rets client with stats reporting
81
+ * feature: Add a locking client
82
+ * feature: Support Basic Authentication
83
+
84
+ ### 0.4.0 / 2012-08-29
85
+
86
+ * fix: update authentication header to uri matches path
87
+
88
+ ### 0.3.0 / 2012-07-31
89
+
90
+ * correctly handle digest authentication
91
+
92
+ ### 0.3.0.rc.0 / 2012-07-26
93
+
94
+ * feature: significantly better handling of authorization failures
95
+
96
+ ### 0.2.1 / 2012-04-20
97
+
98
+ * fix: better handling of malformed RETS responses
99
+
100
+ ### 0.2.0 / 2012-04-20
101
+
102
+ * feature: Ruby 1.9 compatibility!
103
+
104
+ ### 0.1.7 / 2012-04-05
105
+
106
+ * feature: key_field lookup for resources
107
+
108
+ ### 0.1.6 / 2012-04-03
109
+
110
+ * fix: user_agent authentication
111
+
112
+ ### 0.1.5 / 2012-03-17
113
+
114
+ * fix: retries raise error after too many failures
115
+ * fix: raise error for failed multipart object request
116
+ * fix: retries start with a clean slate, fixing authorization errors during retry
117
+
118
+ ### 0.1.4 / 2012-03-12
119
+
120
+ * fix: an MLS uses lower case in RETS tag
121
+
122
+ ### 0.1.3 / 2012-03-05
123
+
124
+ * fixes to support location=1 in getobject query
125
+
126
+ ### 0.1.2 / 2012-02-17
127
+
128
+ * bugfix - check ReplyCode in login, retry on errors
129
+
130
+ ### 0.1.1 / 2012-01-11
131
+
132
+ * bugfix - prevent infinite loop in login
133
+
134
+ # rets Changelog
135
+
136
+ ### 0.1.0 / 2011-06-23
137
+
138
+ * First public release!
139
+
140
+ ### 0.0.1 / 2011-03-24
141
+
142
+ * Project Created
data/Manifest.txt ADDED
@@ -0,0 +1,58 @@
1
+ CHANGELOG.md
2
+ Manifest.txt
3
+ README.md
4
+ Rakefile
5
+ bin/rets
6
+ example/connect.rb
7
+ example/get-photos.rb
8
+ example/get-property.rb
9
+ lib/rets.rb
10
+ lib/rets/client.rb
11
+ lib/rets/client_progress_reporter.rb
12
+ lib/rets/http_client.rb
13
+ lib/rets/locking_http_client.rb
14
+ lib/rets/measuring_http_client.rb
15
+ lib/rets/metadata.rb
16
+ lib/rets/metadata/caching.rb
17
+ lib/rets/metadata/containers.rb
18
+ lib/rets/metadata/file_cache.rb
19
+ lib/rets/metadata/json_serializer.rb
20
+ lib/rets/metadata/lookup_table.rb
21
+ lib/rets/metadata/lookup_type.rb
22
+ lib/rets/metadata/marshal_serializer.rb
23
+ lib/rets/metadata/multi_lookup_table.rb
24
+ lib/rets/metadata/null_cache.rb
25
+ lib/rets/metadata/resource.rb
26
+ lib/rets/metadata/rets_class.rb
27
+ lib/rets/metadata/rets_object.rb
28
+ lib/rets/metadata/root.rb
29
+ lib/rets/metadata/table.rb
30
+ lib/rets/metadata/table_factory.rb
31
+ lib/rets/metadata/yaml_serializer.rb
32
+ lib/rets/parser/compact.rb
33
+ lib/rets/parser/error_checker.rb
34
+ lib/rets/parser/multipart.rb
35
+ test/fixtures.rb
36
+ test/helper.rb
37
+ test/test_caching.rb
38
+ test/test_client.rb
39
+ test/test_error_checker.rb
40
+ test/test_file_cache.rb
41
+ test/test_http_client.rb
42
+ test/test_json_serializer.rb
43
+ test/test_locking_http_client.rb
44
+ test/test_marshal_serializer.rb
45
+ test/test_metadata.rb
46
+ test/test_metadata_class.rb
47
+ test/test_metadata_lookup_table.rb
48
+ test/test_metadata_lookup_type.rb
49
+ test/test_metadata_multi_lookup_table.rb
50
+ test/test_metadata_object.rb
51
+ test/test_metadata_resource.rb
52
+ test/test_metadata_root.rb
53
+ test/test_metadata_table.rb
54
+ test/test_metadata_table_factory.rb
55
+ test/test_parser_compact.rb
56
+ test/test_parser_multipart.rb
57
+ test/test_yaml_serializer.rb
58
+ test/vcr_cassettes/unauthorized_response.yml
data/README.md ADDED
@@ -0,0 +1,129 @@
1
+ # rets
2
+
3
+ * http://github.com/estately/rets
4
+
5
+ ## DESCRIPTION:
6
+
7
+ [![Build Status](https://secure.travis-ci.org/estately/rets.png?branch=master)](http://travis-ci.org/estately/rets)
8
+ A pure-ruby library for fetching data from [RETS] servers.
9
+
10
+ If you're looking for a slick CLI interface check out [retscli](https://github.com/summera/retscli), which is an awesome tool for exploring metadata or learning about RETS.
11
+
12
+ [RETS]: http://www.rets.org
13
+
14
+ ## REQUIREMENTS:
15
+
16
+ * [httpclient]
17
+ * [nokogiri]
18
+
19
+ [httpclient]: https://github.com/nahi/httpclient
20
+ [nokogiri]: http://nokogiri.org
21
+
22
+ ## INSTALLATION:
23
+ ```
24
+ gem install rets
25
+
26
+ # or add it to your Gemfile if using Bundler then run bundle install
27
+ gem 'rets'
28
+ ```
29
+
30
+ ## EXAMPLE USAGE:
31
+
32
+ We need work in this area! There are currently a few guideline examples in the `example` folder on connecting, fetching a property's data, and fetching a property's photos.
33
+
34
+ ## Metadata caching
35
+
36
+ Metadata, which is loaded when a client is first started, can be slow
37
+ to fetch. To avoid the cost of fetching metadata every time the
38
+ client is started, metadata can be cached.
39
+
40
+ To cache metadata, pass the :metadata_cache option to the client when
41
+ you start it. The library comes with a predefined metadata cache that
42
+ persists the metadata to a file. It is created with the path to which
43
+ the cached metadata should be written:
44
+
45
+ metadata_cache = Rets::Metadata::FileCache.new("/tmp/metadata")
46
+
47
+ When you create the RETS client, pass it the metadata cache:
48
+
49
+ client = Rets::Client.new(
50
+ ...
51
+ metadata_cache: metadata_cache
52
+ )
53
+
54
+ If you want to persist to something other than a file, create your own
55
+ metadata cache object and pass it in. It should have the same interface
56
+ as the built-in Metadata::FileCache class:
57
+
58
+ class MyMetadataCache
59
+
60
+ # Save the metadata. Should yield an IO-like object to a block;
61
+ # that block will serialize the metadata to that object.
62
+ def save(&block)
63
+ end
64
+
65
+ # Load the metadata. Should yield an IO-like object to a block;
66
+ # that block will deserialize the metadata from that object and
67
+ # return the metadata. Returns the metadata, or nil if it could
68
+ # not be loaded.
69
+ def load(&block)
70
+ end
71
+
72
+ end
73
+
74
+ By default, the metadata is serialized using Marshal. You may select
75
+ JSON or YAML instead, or define your own serialization mechanism, using the
76
+ :metadata_serializer option when you create the Rets::Client:
77
+
78
+ client = Rets::Client.new(
79
+ ...
80
+ metadata_serializer: Rets::Metadata::JsonSerializer.new
81
+ )
82
+
83
+ The built-in serializers are:
84
+
85
+ * Rets::Metadata::JsonSerializer
86
+ * Rets::Metadata::MarshalSerializer
87
+ * Rets::Metadata::YamlSerializer
88
+
89
+ To define your own serializer, create an object with this interface:
90
+
91
+ class MySerializer
92
+
93
+ # Serialize to a file. The library reserves the right to change
94
+ # the type or contents of o, so don't depend on it being
95
+ # anything in particular.
96
+ def save(file, o)
97
+ end
98
+
99
+ # Deserialize from a file. If the metadata cannot be
100
+ # deserialized, return nil.
101
+ def load(file)
102
+ end
103
+
104
+ end
105
+
106
+ ## LICENSE:
107
+
108
+ (The MIT License)
109
+
110
+ Copyright (c) 2011 Estately, Inc. <opensource@estately.com>
111
+
112
+ Permission is hereby granted, free of charge, to any person obtaining
113
+ a copy of this software and associated documentation files (the
114
+ 'Software'), to deal in the Software without restriction, including
115
+ without limitation the rights to use, copy, modify, merge, publish,
116
+ distribute, sublicense, and/or sell copies of the Software, and to
117
+ permit persons to whom the Software is furnished to do so, subject to
118
+ the following conditions:
119
+
120
+ The above copyright notice and this permission notice shall be included
121
+ in all copies or substantial portions of the Software.
122
+
123
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
124
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
125
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
126
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
127
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
128
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
129
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,28 @@
1
+ require 'rubygems'
2
+ require 'hoe'
3
+ require 'rake/testtask'
4
+
5
+ Hoe.plugin :git, :doofus
6
+ Hoe.plugin :travis
7
+ Hoe.plugin :gemspec
8
+
9
+ Hoe.spec 'rets' do
10
+ developer 'Estately, Inc. Open Source', 'opensource@estately.com'
11
+
12
+ extra_deps << [ "httpclient", "~> 2.7.0" ]
13
+ extra_deps << [ "http-cookie", "~> 1.0.0" ]
14
+ extra_deps << [ "nokogiri", "~> 1.5" ]
15
+
16
+ extra_dev_deps << [ "mocha", "~> 1.1.0" ]
17
+ extra_dev_deps << [ "vcr", "~> 2.2" ]
18
+ extra_dev_deps << [ "webmock", "~> 1.8" ]
19
+
20
+ ### Use markdown for changelog and readme
21
+ self.history_file = 'CHANGELOG.md'
22
+ self.readme_file = 'README.md'
23
+ end
24
+
25
+
26
+ Rake::TestTask.new do |t|
27
+ t.pattern = "test/test_*.rb"
28
+ end
data/bin/rets ADDED
@@ -0,0 +1,202 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "optparse"
4
+ require "pp"
5
+
6
+ require "rubygems"
7
+
8
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
9
+ require "rets"
10
+
11
+ class RetsCli
12
+ def self.parse(args)
13
+
14
+ actions = %w(metadata search count object)
15
+ options = {:count => 5}
16
+
17
+ opts = OptionParser.new do |opts|
18
+ opts.banner = "Usage: #{File.basename($0)} URL [options] [query]"
19
+
20
+ opts.separator ""
21
+ opts.separator "Authentication options:"
22
+
23
+ opts.on("-U", "--username USERNAME", "The username to authenticate with.") do |username|
24
+ options[:username] = username
25
+ end
26
+
27
+ opts.on("-P", "--password [PASSWORD]", "The password to authenticate with.","Prompts if no argument is provided.") do |password|
28
+ options[:password] = password #or prompt # TODO
29
+ end
30
+
31
+ opts.on("-A", "--agent AGENT", "User-Agent header to provide.") do |agent|
32
+ options[:agent] = agent
33
+ end
34
+
35
+ opts.on("-B", "--agent-password [PASSWORD]", "User-Agent password to provide.") do |ua_password|
36
+ options[:ua_password] = ua_password
37
+ end
38
+
39
+ opts.separator ""
40
+ opts.separator "Actions:"
41
+
42
+ opts.on("-p", "--capabilities", "Print capabilities of the RETS server.") do |capabilities|
43
+ options[:capabilities] = capabilities
44
+ end
45
+
46
+ opts.on("-a", "--action ACTION", actions, "Action to perform (#{actions.join(",")}).") do |action|
47
+ options[:action] = action
48
+ end
49
+
50
+ opts.on("-m", "--metadata [FORMAT]", %w(tree long short), "Print metadata.", "Format is short, long or tree.", "Defaults to short.") do |format|
51
+ options[:action] = "metadata"
52
+ options[:metadata_format] = format || "short"
53
+ end
54
+
55
+ opts.separator ""
56
+ opts.separator "Search action options:"
57
+
58
+ opts.on("-r", "--resource NAME", "Name of resource to search for.") do |name|
59
+ options[:resource] = name
60
+ end
61
+
62
+ opts.on("-c", "--class NAME", "Name of class to search for.") do |name|
63
+ options[:class] = name
64
+ end
65
+
66
+ opts.on("-n", "--number LIMIT", Integer, "Return LIMIT results. Defaults to 5.") do |limit|
67
+ options[:limit] = limit
68
+ end
69
+
70
+ opts.separator ""
71
+ opts.separator "Misc options:"
72
+
73
+ opts.on_tail("-v", "--verbose", "Be verbose.") do |verbose|
74
+ logger = Class.new do
75
+ def method_missing(method, *a, &b)
76
+ puts a
77
+ end
78
+ end
79
+
80
+ options[:logger] = logger.new
81
+ end
82
+
83
+ opts.on_tail("-h", "--help", "Show this message") do
84
+ puts opts
85
+ exit
86
+ end
87
+
88
+ opts.on_tail("--version", "Show version") do
89
+ puts Rets::VERSION
90
+ exit
91
+ end
92
+
93
+ end
94
+
95
+ begin
96
+ opts.parse!(args.empty? ? ["-h"] : args)
97
+ rescue OptionParser::InvalidArgument => e
98
+ abort e.message
99
+ end
100
+
101
+ options
102
+ end
103
+
104
+ end
105
+
106
+ options = RetsCli.parse(ARGV)
107
+ url = ARGV[0] or abort "Need login URL"
108
+ query = ARGV[1]
109
+
110
+ client = Rets::Client.new(options.merge(:login_url => url))
111
+
112
+ if options[:capabilities]
113
+ pp client.capabilities
114
+ end
115
+
116
+ case options[:action]
117
+ when "metadata" then
118
+ metadata = client.metadata
119
+
120
+ if options[:metadata_format] != "tree"
121
+ preferred_fields = %w(ClassName SystemName ResourceID StandardName VisibleName MetadataEntryID KeyField)
122
+
123
+
124
+ # All types except system
125
+ types = Rets::METADATA_TYPES.map { |t| t.downcase.to_sym } - [:system]
126
+
127
+ types.each do |type|
128
+ # if RowContainer ...
129
+ rows = metadata[type]
130
+
131
+ puts type.to_s.capitalize
132
+ puts "="*40
133
+
134
+ print_key_value = lambda do |k,v|
135
+ key = "#{k}:".ljust(35)
136
+ value = "#{v}".ljust(35)
137
+
138
+ puts [key, value].join
139
+ end
140
+
141
+ rows.each do |row|
142
+ top, rest = row.partition { |k,v| preferred_fields.include?(k) }
143
+
144
+ top.each(&print_key_value)
145
+
146
+ rest.sort_by{|k,v|k}.each(&print_key_value) if options[:metadata_format] == "long"
147
+
148
+ puts
149
+ end
150
+
151
+ puts
152
+ end
153
+
154
+ # Tree format
155
+ else
156
+ metadata.print_tree
157
+ end
158
+
159
+ when "search" then
160
+ pp client.find(:all,
161
+ :search_type => options[:resource],
162
+ :class => options[:class],
163
+ :query => query,
164
+ :count => Rets::Client::COUNT.exclude,
165
+ :limit => options[:limit])
166
+
167
+ when "count" then
168
+ pp client.find(:all,
169
+ :search_type => options[:resource],
170
+ :class => options[:class],
171
+ :query => query,
172
+ :count => Rets::Client::COUNT.only,
173
+ :limit => options[:limit])
174
+
175
+ when "object" then
176
+
177
+ def write_objects(parts)
178
+ parts.each do |part|
179
+ cid = part.headers["content-id"].to_i
180
+ oid = part.headers["object-id"].to_i
181
+
182
+ File.open("tmp/#{cid}-#{oid}", "wb") do |f|
183
+ puts f.path
184
+
185
+ f.write part.body
186
+ end
187
+ end
188
+ end
189
+
190
+ parts = client.all_objects(
191
+ :resource => "Property",
192
+ :resource_id => 90020062739, # id from KeyField for a given property
193
+ :object_type => "Photo"
194
+ )
195
+
196
+ parts.each { |pt| p pt.headers }
197
+
198
+ write_objects(parts)
199
+
200
+ end
201
+
202
+ client.logout
@@ -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