josephholsten-rets4r 1.1.16 → 1.1.17
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +187 -3
- data/CONTRIBUTORS +2 -0
- data/NEWS +183 -0
- data/Rakefile +1 -1
- data/VERSION.yml +2 -2
- data/lib/rets4r.rb +2 -0
- data/lib/rets4r/client.rb +16 -15
- data/lib/rets4r/client/parsers/compact.rb +3 -2
- data/lib/rets4r/client/parsers/compact_nokogiri.rb +37 -11
- data/lib/rets4r/client/parsers/response_parser.rb +1 -5
- data/lib/rets4r/client/transaction.rb +3 -0
- data/lib/rets4r/core_ext/array/extract_options.rb +15 -0
- data/lib/rets4r/core_ext/class/attribute_accessors.rb +58 -0
- data/lib/rets4r/core_ext/hash/keys.rb +46 -0
- data/lib/rets4r/core_ext/hash/slice.rb +39 -0
- data/lib/rets4r/listing_mapper.rb +17 -0
- data/lib/rets4r/listing_service.rb +35 -0
- data/lib/rets4r/loader.rb +4 -8
- data/test/compact_nokogiri_test.rb +18 -2
- data/test/data/1.5/count_only_compact.xml +3 -0
- data/test/data/1.5/search_compact_big.xml +136 -0
- data/test/data/listing_service.yml +36 -0
- data/test/listing_mapper_test.rb +112 -0
- data/test/test_helper.rb +12 -0
- data/test/test_parser.rb +3 -0
- metadata +25 -8
- data/lib/rets4r/client/metadataindex.rb +0 -82
- data/test/test_metadataindex.rb +0 -36
@@ -0,0 +1,36 @@
|
|
1
|
+
# This file specifies the access information for the listing service #
|
2
|
+
# To access the standard RETS demo server, use:
|
3
|
+
#
|
4
|
+
test:
|
5
|
+
url: http://demo.crt.realtors.org:6103/rets/login
|
6
|
+
username: Joe
|
7
|
+
password: Schmoe
|
8
|
+
version: 1.7.2
|
9
|
+
resource: Property
|
10
|
+
class: RES
|
11
|
+
object_type: Photo
|
12
|
+
select:
|
13
|
+
ListingID: :mls
|
14
|
+
AgentID: :agent_id
|
15
|
+
ModificationTimestamp: :rets_update_at
|
16
|
+
Status: :status
|
17
|
+
# ListDate: :list_date
|
18
|
+
ListPrice: :list_price
|
19
|
+
# ClosePrice: :close_price
|
20
|
+
# ContractDate: :contract_date
|
21
|
+
StreetNumber: :street_number
|
22
|
+
StreetName: :street_name
|
23
|
+
StreetDirection: :street_direction
|
24
|
+
Unit: :unit_number
|
25
|
+
ZipCode: :zip_code
|
26
|
+
City: :city
|
27
|
+
County: :county
|
28
|
+
# Rooms: :rooms
|
29
|
+
# State: :state
|
30
|
+
# Board: :board
|
31
|
+
LivingArea: :living_area
|
32
|
+
Baths: :baths
|
33
|
+
Bedrooms: :beds
|
34
|
+
Garage: :garage
|
35
|
+
SqFt: :square_feet
|
36
|
+
YearBuilt: :year_built
|
@@ -0,0 +1,112 @@
|
|
1
|
+
$:.unshift File.expand_path(File.join(File.dirname(__FILE__)))
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class ListingMapperTest < Test::Unit::TestCase
|
5
|
+
context "ListingMapper" do
|
6
|
+
should "access select" do
|
7
|
+
config = RETS4R::ListingService.connection
|
8
|
+
mapper = RETS4R::ListingMapper.new(config)
|
9
|
+
assert_equal config[:select], mapper.select
|
10
|
+
end
|
11
|
+
should "map from rets keys to record keys" do
|
12
|
+
original = {
|
13
|
+
"ListingID"=>"11322886",
|
14
|
+
"AgentID"=>"000533246",
|
15
|
+
"Status"=>"act",
|
16
|
+
"ListPrice"=>"239000",
|
17
|
+
"StreetNumber"=>"8317",
|
18
|
+
"StreetName"=>"Thompson",
|
19
|
+
"StreetDirection"=>"",
|
20
|
+
"Unit"=>"",
|
21
|
+
"ZipCode"=>"79606-6652",
|
22
|
+
"City"=>"Abilene",
|
23
|
+
"County"=>"Taylor",
|
24
|
+
"State"=>"TX",
|
25
|
+
"LotSize"=>"LTS.5-.99A",
|
26
|
+
"SqFt"=>"2825",
|
27
|
+
"LivingArea"=>"2",
|
28
|
+
"Bedrooms"=>"4",
|
29
|
+
"Garage"=>"PARATTACHE,PAROPENER,PARREAR,PARSIDE",
|
30
|
+
"YearBuilt"=>"2005",
|
31
|
+
"AgentName"=>"CD Boyd, II",
|
32
|
+
|
33
|
+
"GARAGECAP"=>"2",
|
34
|
+
"BATHSFULLBASEMENT"=>"",
|
35
|
+
"BATHSFULLLEVEL1"=>"",
|
36
|
+
"BATHSFULLLEVEL2"=>"",
|
37
|
+
"BATHSFULLLEVEL3"=>"",
|
38
|
+
"STORIES"=>"2",
|
39
|
+
"INTERIOR"=>"INFBAY-WIN,INFCABLE-A,INFDECLTNG,INFHIGHSPD,INFLOFT,INFSOUND-W,INFVAUL-CL,INFWIND-CO",
|
40
|
+
"ACRESCULTIVATED"=>"",
|
41
|
+
"CARPORTCAP"=>"0",
|
42
|
+
"TAXUNEXEMPT"=>"5876",
|
43
|
+
"STREETDIRSUFFIX"=>"",
|
44
|
+
"NUMSTOCKTANKS"=>"",
|
45
|
+
"LOTDIM"=>"87X182",
|
46
|
+
"ACRESPRICE"=>"662049",
|
47
|
+
"FIREPLACES"=>"1",
|
48
|
+
"SUBDIVISION"=>"Belle Vista Estates",
|
49
|
+
"UTILITIES"=>"STUASPHALT,UTLCITY-SE,UTLCITY-WA,STUCONCRET",
|
50
|
+
"LISTSTATUSFLAG"=>"",
|
51
|
+
"NUMDININGAREAS"=>"2",
|
52
|
+
"SQFTPRICE"=>"84.6",
|
53
|
+
"MAPPAGE"=>"9999",
|
54
|
+
"NUMBARNS"=>"",
|
55
|
+
"UIDPRP"=>"3211078",
|
56
|
+
"NUMRESIDENCE"=>"",
|
57
|
+
"LISTPRICELOW"=>"0",
|
58
|
+
"MAPBOOK"=>"OT",
|
59
|
+
"LOTNUM"=>"",
|
60
|
+
"OFFICELIST_OFFICENAM1"=>"McClure, REALTORS",
|
61
|
+
"ACRES"=>"0.361",
|
62
|
+
"AGENTSELL_FULLNAME"=>"",
|
63
|
+
"BATHSHALFLEVEL1"=>"",
|
64
|
+
"PROPSUBTYPE"=>"S",
|
65
|
+
"ROOMBEDBATHDESC"=>"BBFJET-TUB,BBFLIN-CLO,BBFSEP-SHO,BBFW+I-CLO",
|
66
|
+
"BATHSHALFLEVEL2"=>"",
|
67
|
+
"LISTPRICEORIG"=>"239000",
|
68
|
+
"BATHSHALFLEVEL3"=>"",
|
69
|
+
"UID"=>"3211078",
|
70
|
+
"OFFICELIST"=>"FMAB",
|
71
|
+
"BATHSHALFBASEMENT"=>"",
|
72
|
+
"STORIESBLDG"=>"",
|
73
|
+
"REMARKS"=>"Custom home built in 05'. Growing neighborhood convienient to Wylie schools. Abundant living areas and and open space floor plan.Could be 5th BDRM, or upstair BDRM & Bath could be another living area. Perfect office next to Master. Gourmet sized kitchen, granite countertops, barell ceilings, wonderful storage space!!!!",
|
74
|
+
"STREETNUMDISPLAY"=>"8317",
|
75
|
+
"PROPSUBTYPEDISPLAY"=>"RES-S",
|
76
|
+
"BATHSHALF"=>"0",
|
77
|
+
"STYLE"=>"STYRANCH",
|
78
|
+
"COMMONFEATURES"=>"",
|
79
|
+
"OFFICESELL_OFFICENAM2"=>"",
|
80
|
+
"BATHSFULL"=>"3",
|
81
|
+
"MAPCOORD"=>"none",
|
82
|
+
"SQFTSOURCE"=>"TAX",
|
83
|
+
"NUMLAKES"=>"",
|
84
|
+
"NUMWELLS"=>"",
|
85
|
+
"NUMPONDS"=>"",
|
86
|
+
"LOTDESC"=>"LTDSUBDIV"}
|
87
|
+
mapper = RETS4R::ListingMapper.new
|
88
|
+
actual = mapper.map(original)
|
89
|
+
expected = {
|
90
|
+
:mls => "11322886",
|
91
|
+
:agent_id =>"000533246",
|
92
|
+
:rets_updated_at => nil,
|
93
|
+
:status=>"act",
|
94
|
+
:list_price =>"239000",
|
95
|
+
:street_number =>"8317",
|
96
|
+
:street_direction => "",
|
97
|
+
:street_name=>"Thompson",
|
98
|
+
:unit_number =>"",
|
99
|
+
:zip_code =>"79606-6652",
|
100
|
+
:city => "Abilene",
|
101
|
+
:county =>"Taylor",
|
102
|
+
:square_feet =>"2825",
|
103
|
+
:living_area => "2",
|
104
|
+
:baths =>nil,
|
105
|
+
:beds => "4",
|
106
|
+
:garage => "PARATTACHE,PAROPENER,PARREAR,PARSIDE",
|
107
|
+
:year_built => "2005",
|
108
|
+
}
|
109
|
+
expected.merge(actual).keys.each{|k| assert_equal expected[k], actual[k], "mismatched on key #{k}"}
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
$:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rets4r'
|
5
|
+
require 'rubygems'
|
6
|
+
require 'mocha'
|
7
|
+
require 'shoulda'
|
8
|
+
|
9
|
+
# Configure ListingService
|
10
|
+
listing_service_config_file = File.expand_path(File.join('test', 'data', 'listing_service.yml'))
|
11
|
+
RETS4R::ListingService.configurations = YAML.load_file(listing_service_config_file)
|
12
|
+
RETS4R::ListingService.env = 'test'
|
data/test/test_parser.rb
CHANGED
@@ -56,6 +56,9 @@ module RETS4R
|
|
56
56
|
assert_equal "Datum5", transaction.response[1]['Second']
|
57
57
|
assert_equal "Datum6", transaction.response[1]['Third']
|
58
58
|
|
59
|
+
# Check for compatibility
|
60
|
+
assert_equal transaction.data, transaction.response
|
61
|
+
|
59
62
|
assert_equal nil, transaction.secondary_response
|
60
63
|
end
|
61
64
|
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: josephholsten-rets4r
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 1
|
7
|
+
- 1
|
8
|
+
- 17
|
9
|
+
version: 1.1.17
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Scott Patterson
|
@@ -12,7 +17,7 @@ autorequire:
|
|
12
17
|
bindir: bin
|
13
18
|
cert_chain: []
|
14
19
|
|
15
|
-
date: 2010-
|
20
|
+
date: 2010-03-03 00:00:00 -06:00
|
16
21
|
default_executable:
|
17
22
|
dependencies: []
|
18
23
|
|
@@ -39,6 +44,7 @@ files:
|
|
39
44
|
- CONTRIBUTORS
|
40
45
|
- GPL
|
41
46
|
- LICENSE
|
47
|
+
- NEWS
|
42
48
|
- README.rdoc
|
43
49
|
- RUBYS
|
44
50
|
- Rakefile
|
@@ -56,27 +62,36 @@ files:
|
|
56
62
|
- lib/rets4r/client/data.rb
|
57
63
|
- lib/rets4r/client/dataobject.rb
|
58
64
|
- lib/rets4r/client/metadata.rb
|
59
|
-
- lib/rets4r/client/metadataindex.rb
|
60
65
|
- lib/rets4r/client/parsers/compact.rb
|
61
66
|
- lib/rets4r/client/parsers/compact_nokogiri.rb
|
62
67
|
- lib/rets4r/client/parsers/metadata.rb
|
63
68
|
- lib/rets4r/client/parsers/response_parser.rb
|
64
69
|
- lib/rets4r/client/transaction.rb
|
70
|
+
- lib/rets4r/core_ext/array/extract_options.rb
|
71
|
+
- lib/rets4r/core_ext/class/attribute_accessors.rb
|
72
|
+
- lib/rets4r/core_ext/hash/keys.rb
|
73
|
+
- lib/rets4r/core_ext/hash/slice.rb
|
74
|
+
- lib/rets4r/listing_mapper.rb
|
75
|
+
- lib/rets4r/listing_service.rb
|
65
76
|
- lib/rets4r/loader.rb
|
66
77
|
- lib/tasks/annotations.rake
|
67
78
|
- lib/tasks/coverage.rake
|
68
79
|
- test/compact_nokogiri_test.rb
|
69
80
|
- test/data/1.5/bad_compact.xml
|
81
|
+
- test/data/1.5/count_only_compact.xml
|
70
82
|
- test/data/1.5/error.xml
|
71
83
|
- test/data/1.5/invalid_compact.xml
|
72
84
|
- test/data/1.5/login.xml
|
73
85
|
- test/data/1.5/metadata.xml
|
74
86
|
- test/data/1.5/search_compact.xml
|
87
|
+
- test/data/1.5/search_compact_big.xml
|
75
88
|
- test/data/1.5/search_unescaped_compact.xml
|
89
|
+
- test/data/listing_service.yml
|
90
|
+
- test/listing_mapper_test.rb
|
76
91
|
- test/loader_test.rb
|
77
92
|
- test/test_auth.rb
|
78
93
|
- test/test_client.rb
|
79
|
-
- test/
|
94
|
+
- test/test_helper.rb
|
80
95
|
- test/test_parser.rb
|
81
96
|
has_rdoc: true
|
82
97
|
homepage: http://rets4r.rubyforge.org/
|
@@ -93,23 +108,25 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
93
108
|
requirements:
|
94
109
|
- - ">="
|
95
110
|
- !ruby/object:Gem::Version
|
111
|
+
segments:
|
112
|
+
- 0
|
96
113
|
version: "0"
|
97
|
-
version:
|
98
114
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
115
|
requirements:
|
100
116
|
- - ">="
|
101
117
|
- !ruby/object:Gem::Version
|
118
|
+
segments:
|
119
|
+
- 0
|
102
120
|
version: "0"
|
103
|
-
version:
|
104
121
|
requirements: []
|
105
122
|
|
106
123
|
rubyforge_project: rets4r
|
107
|
-
rubygems_version: 1.3.
|
124
|
+
rubygems_version: 1.3.6
|
108
125
|
signing_key:
|
109
126
|
specification_version: 3
|
110
127
|
summary: A native Ruby implementation of RETS (Real Estate Transaction Standard).
|
111
128
|
test_files:
|
112
129
|
- test/test_auth.rb
|
113
130
|
- test/test_client.rb
|
114
|
-
- test/
|
131
|
+
- test/test_helper.rb
|
115
132
|
- test/test_parser.rb
|
@@ -1,82 +0,0 @@
|
|
1
|
-
module RETS4R
|
2
|
-
class Client
|
3
|
-
# Provides a means of indexing metadata to allow faster searching of it.
|
4
|
-
# This is in dire need of a review and cleanup, so I advise you not to use it until that has been done.
|
5
|
-
class MetadataIndex
|
6
|
-
# Constructor that takes an array of Metadata objects as its sole argument.
|
7
|
-
def initialize(metadata)
|
8
|
-
@metadata = metadata
|
9
|
-
@index = index(@metadata)
|
10
|
-
end
|
11
|
-
|
12
|
-
# WARNING! Not working properly (does NOT pass unit test)
|
13
|
-
# This is more of a free form search than #lookup, but it is also slower because it must iterate
|
14
|
-
# through the entire metadata array. This also returns multiple matches, which #lookup doesn't do.
|
15
|
-
def search(type, attributes = {})
|
16
|
-
matches = []
|
17
|
-
|
18
|
-
@metadata.each do |meta|
|
19
|
-
catch :mismatch do
|
20
|
-
if meta.type == type
|
21
|
-
attributes.each do |k,v|
|
22
|
-
throw :mismatch unless meta.attributes[k] == v
|
23
|
-
end
|
24
|
-
|
25
|
-
matches << meta
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
return matches
|
31
|
-
end
|
32
|
-
|
33
|
-
# This is a streamlined and probably the preferred method for looking up metadata because it
|
34
|
-
# uses a index to quickly access the data. The downside is that it is not very flexible. This also
|
35
|
-
# only returns one (the "best") match. If you need multiple matches, then you should use #search.
|
36
|
-
# Tests show about a 690% speed increase by using #lookup over #search, so you've been warned.
|
37
|
-
def lookup(type, *attributes)
|
38
|
-
key = type
|
39
|
-
key << attributes.join('')
|
40
|
-
|
41
|
-
@index[key]
|
42
|
-
end
|
43
|
-
|
44
|
-
private
|
45
|
-
|
46
|
-
# Provided an array of metadata, it indexes it for faster lookup.
|
47
|
-
# Takes a +Metadata+ object as its argument.
|
48
|
-
def index(metadata)
|
49
|
-
index = {}
|
50
|
-
|
51
|
-
metadata.each do |meta|
|
52
|
-
key = generate_key(meta)
|
53
|
-
|
54
|
-
index[key] = meta
|
55
|
-
end
|
56
|
-
|
57
|
-
return index
|
58
|
-
end
|
59
|
-
|
60
|
-
# Used to generate the key for a specified piece of metadata. Takes a +Metadata+ object as its
|
61
|
-
# argument.
|
62
|
-
def generate_key(meta)
|
63
|
-
key = meta.type
|
64
|
-
|
65
|
-
case (meta.type)
|
66
|
-
when 'METADATA-LOOKUP'
|
67
|
-
key << meta.attributes['Resource']
|
68
|
-
when 'METADATA-LOOKUP_TYPE'
|
69
|
-
key << meta.attributes['Resource'] << meta.attributes['Lookup']
|
70
|
-
when 'METADATA-CLASS'
|
71
|
-
key << meta.attributes['Resource']
|
72
|
-
when 'METADATA-OBJECT'
|
73
|
-
key << meta.attributes['Resource']
|
74
|
-
when 'METADATA-TABLE'
|
75
|
-
key << meta.attributes['Resource'] << meta.attributes['Class']
|
76
|
-
end
|
77
|
-
|
78
|
-
return key
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
data/test/test_metadataindex.rb
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
$:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
2
|
-
|
3
|
-
require 'rets4r/client/metadataindex'
|
4
|
-
require 'rets4r/client/transaction'
|
5
|
-
require 'rets4r/client/metadata'
|
6
|
-
require 'test/unit'
|
7
|
-
|
8
|
-
module RETS4R
|
9
|
-
class TestMetadataIndex < Test::Unit::TestCase
|
10
|
-
|
11
|
-
def test_truth
|
12
|
-
end
|
13
|
-
|
14
|
-
# FIXME: reenable MetadataIndex tests
|
15
|
-
# def setup
|
16
|
-
# File.open('test/data/1.5/metadata.xml') do |file|
|
17
|
-
# @trans = Marshal.load(file)
|
18
|
-
# end
|
19
|
-
#
|
20
|
-
# @index = MetadataIndex.new(@trans.data)
|
21
|
-
# end
|
22
|
-
|
23
|
-
# FIXME: reenable test_lookup_search
|
24
|
-
# # Ensure that our lookup and search functions, although different, will return the same data
|
25
|
-
# # for the same criteria.
|
26
|
-
# def test_lookup_search
|
27
|
-
# assert_equal("Club House", @index.lookup('METADATA-LOOKUP_TYPE', 'Property', 'HOAMENITIS_Lkp_2')[0]['LongValue'])
|
28
|
-
#
|
29
|
-
# puts @index.search('METADATA-LOOKUP_TYPE', {'Resource' => 'Property', 'Lookup' => 'HOAMENITIS_Lkp_2'}).inspect
|
30
|
-
# assert_equal( \
|
31
|
-
# @index.lookup('METADATA-LOOKUP_TYPE', 'Property', 'HOAMENITIS_Lkp_2'), \
|
32
|
-
# @index.search('METADATA-LOOKUP_TYPE', {'Resource' => 'Property', 'Lookup' => 'HOAMENITIS_Lkp_2'}).inspect \
|
33
|
-
# )
|
34
|
-
# end
|
35
|
-
end
|
36
|
-
end
|