jschairb-rets4r 1.1.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/.document +5 -0
  2. data/CHANGELOG +566 -0
  3. data/CONTRIBUTORS +7 -0
  4. data/Gemfile +10 -0
  5. data/LICENSE +29 -0
  6. data/MANIFEST +62 -0
  7. data/NEWS +186 -0
  8. data/README.rdoc +43 -0
  9. data/RUBYS +56 -0
  10. data/Rakefile +50 -0
  11. data/TODO +35 -0
  12. data/examples/client_get_object.rb +49 -0
  13. data/examples/client_login.rb +39 -0
  14. data/examples/client_mapper.rb +17 -0
  15. data/examples/client_metadata.rb +42 -0
  16. data/examples/client_parser.rb +9 -0
  17. data/examples/client_search.rb +49 -0
  18. data/examples/settings.yml +114 -0
  19. data/lib/rets4r.rb +14 -0
  20. data/lib/rets4r/auth.rb +73 -0
  21. data/lib/rets4r/client.rb +487 -0
  22. data/lib/rets4r/client/data.rb +14 -0
  23. data/lib/rets4r/client/dataobject.rb +28 -0
  24. data/lib/rets4r/client/exceptions.rb +116 -0
  25. data/lib/rets4r/client/links.rb +32 -0
  26. data/lib/rets4r/client/metadata.rb +15 -0
  27. data/lib/rets4r/client/parsers/compact.rb +42 -0
  28. data/lib/rets4r/client/parsers/compact_nokogiri.rb +91 -0
  29. data/lib/rets4r/client/parsers/metadata.rb +92 -0
  30. data/lib/rets4r/client/parsers/response_parser.rb +100 -0
  31. data/lib/rets4r/client/requester.rb +143 -0
  32. data/lib/rets4r/client/transaction.rb +31 -0
  33. data/lib/rets4r/core_ext/array/extract_options.rb +15 -0
  34. data/lib/rets4r/core_ext/class/attribute_accessors.rb +58 -0
  35. data/lib/rets4r/core_ext/hash/keys.rb +46 -0
  36. data/lib/rets4r/core_ext/hash/slice.rb +39 -0
  37. data/lib/rets4r/listing_mapper.rb +17 -0
  38. data/lib/rets4r/listing_service.rb +35 -0
  39. data/lib/rets4r/loader.rb +8 -0
  40. data/lib/tasks/annotations.rake +121 -0
  41. data/lib/tasks/coverage.rake +13 -0
  42. data/rets4r.gemspec +24 -0
  43. data/spec/rets4r_compact_data_parser_spec.rb +7 -0
  44. data/test/data/1.5/bad_compact.xml +7 -0
  45. data/test/data/1.5/count_only_compact.xml +3 -0
  46. data/test/data/1.5/error.xml +1 -0
  47. data/test/data/1.5/invalid_compact.xml +4 -0
  48. data/test/data/1.5/login.xml +16 -0
  49. data/test/data/1.5/metadata.xml +0 -0
  50. data/test/data/1.5/search_compact.xml +8 -0
  51. data/test/data/1.5/search_compact_big.xml +136 -0
  52. data/test/data/1.5/search_unescaped_compact.xml +8 -0
  53. data/test/data/listing_service.yml +36 -0
  54. data/test/test_auth.rb +68 -0
  55. data/test/test_client.rb +342 -0
  56. data/test/test_client_links.rb +39 -0
  57. data/test/test_compact_nokogiri.rb +64 -0
  58. data/test/test_helper.rb +12 -0
  59. data/test/test_listing_mapper.rb +112 -0
  60. data/test/test_loader.rb +24 -0
  61. data/test/test_parser.rb +96 -0
  62. data/test/test_quality.rb +57 -0
  63. metadata +211 -0
@@ -0,0 +1,39 @@
1
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
2
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "test"))
3
+ require 'test_helper'
4
+ require 'rets4r/client/links'
5
+
6
+ class TestClientLinks < Test::Unit::TestCase
7
+ def setup
8
+ @links = RETS4R::Client::Links.from_login_url('http://example.com/login')
9
+ @links['Logout'] = URI.parse('http://example.com/logout')
10
+ @links['GetMetadata'] = URI.parse('http://example.com/metadata')
11
+ @links['GetObject'] = URI.parse('http://example.com/objects')
12
+ @links['Search'] = URI.parse('http://example.com/search')
13
+ @links['Action'] = URI.parse('http://example.com/action')
14
+ end
15
+ def test_should_build_from_login_url
16
+ assert_equal normalize_url('http://example.com/login'), @links['Login'].to_s
17
+ end
18
+ def test_should_access_login
19
+ assert_equal normalize_url('http://example.com/login'), @links.login.to_s
20
+ end
21
+ def test_should_access_logout
22
+ assert_equal normalize_url('http://example.com/logout'), @links.logout.to_s
23
+ end
24
+ def test_should_access_metadata
25
+ assert_equal normalize_url('http://example.com/metadata'), @links.metadata.to_s
26
+ end
27
+ def test_should_access_object
28
+ assert_equal normalize_url('http://example.com/objects'), @links.objects.to_s
29
+ end
30
+ def test_should_access_search
31
+ assert_equal normalize_url('http://example.com/search'), @links.search.to_s
32
+ end
33
+ def test_should_access_action
34
+ assert_equal normalize_url('http://example.com/action'), @links.action.to_s
35
+ end
36
+ def normalize_url(url)
37
+ URI.parse(url).to_s
38
+ end
39
+ end
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "."))
3
+ require 'test_helper'
4
+
5
+ class CompactNokogiriTest < Test::Unit::TestCase
6
+ def test_should_do_stuff
7
+ file = File.expand_path(File.join('test', 'data', '1.5', 'search_compact.xml'))
8
+ listings = RETS4R::Client::CompactNokogiriParser.new(open(file)).to_a
9
+ assert_equal({"Third"=>"Datum3", "Second"=>"Datum2", "First"=>"Datum1"}, listings[0])
10
+ assert_equal({"Third"=>"Datum6", "Second"=>"Datum5", "First"=>"Datum4"}, listings[1])
11
+ end
12
+ def test_should_handle_big_data
13
+ file = File.expand_path(File.join('test', 'data', '1.5', 'bad_compact.xml'))
14
+ listings = RETS4R::Client::CompactNokogiriParser.new(open(file)).to_a
15
+ assert_equal 1, listings.length
16
+ assert_equal 79, listings.first.keys.length
17
+ end
18
+ def test_each_should_yield_between_results
19
+ file = File.expand_path(
20
+ File.join('test', 'data', '1.5', 'search_compact_big.xml'))
21
+ stat = File::Stat.new(file)
22
+ unless stat.size > stat.blksize
23
+ flunk "This test probably won't work on this machine.
24
+ It needs a test input file larger than the native block size."
25
+ end
26
+ stream = open(file)
27
+ positions = []
28
+ listings = RETS4R::Client::CompactNokogiriParser.new(stream).each do |row|
29
+ positions << stream.pos
30
+ end
31
+ assert positions.first < positions.last,
32
+ "data was yielded durring the reading of the stream"
33
+ end
34
+ def test_should_not_include_column_elements_in_keys
35
+ response = "<RETS ReplyCode=\"0\" ReplyText=\"Operation Successful\">\r\n<DELIMITER value=\"09\" />\r\n<COLUMNS>\tDISPLAYORDER\tINPUTDATE\tMEDIADESCR\tMEDIANAME\tMEDIASOURCE\tMEDIATYPE\tMODIFIED\tPICCOUNT\tPRIMARYPIC\tTABLEUID\tUID\t</COLUMNS>\r\n<DATA>\t7\t2009-09-17 07:08:19 \t\tNew 023.jpg\t3155895-11.jpg\tpic\t2009-09-17 07:09:32 \t11\tn\t3155895\t9601458\t</DATA>\r\n<MAXROWS />\r\n</RETS>\r\n"
36
+
37
+ assert RETS4R::Client::CompactNokogiriParser.new(StringIO.new(response)).map.first.keys.grep( /COLUMN/ ).empty?
38
+ end
39
+ context 'non-zero reply code' do
40
+ setup do
41
+ @response = <<-BODY
42
+ <?xml version="1.0"?>
43
+ <RETS ReplyCode="20203" ReplyText="User does not have access to Class named RES. Reference ID: 3fe82558-8015-4d9d-ab0c-776d9e4b5943" />
44
+ BODY
45
+ @parser = RETS4R::Client::CompactNokogiriParser.new(StringIO.new(@response))
46
+ end
47
+ should "raise the execption" do
48
+ assert_raise RETS4R::Client::MiscellaneousSearchErrorException do
49
+ @parser.to_a
50
+ end
51
+ end
52
+ context 'when i parse' do
53
+ should "contain the reply text in the exception message" do
54
+ message = ''
55
+ begin
56
+ @parser.to_a
57
+ rescue Exception => e
58
+ message = e.message
59
+ end
60
+ assert_equal "User does not have access to Class named RES. Reference ID: 3fe82558-8015-4d9d-ab0c-776d9e4b5943", message
61
+ end
62
+ end
63
+ end
64
+ end
@@ -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 'mocha'
6
+ require 'shoulda'
7
+ require 'rubygems'
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'
@@ -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
@@ -0,0 +1,24 @@
1
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
2
+
3
+ require 'rets4r'
4
+ require 'test/unit'
5
+
6
+ class LoaderTest < Test::Unit::TestCase
7
+ def test_should_pass_records_to_block
8
+ file = File.expand_path(File.join('test', 'data', '1.5', 'search_compact.xml'))
9
+
10
+ listings = []
11
+ RETS4R::Loader.load(open(file)) do |record|
12
+ listings << record
13
+ end
14
+
15
+ assert_equal 2, listings.length
16
+ assert_equal "Datum1", listings[0]['First']
17
+ assert_equal "Datum2", listings[0]['Second']
18
+ assert_equal "Datum3", listings[0]['Third']
19
+ assert_equal "Datum4", listings[1]['First']
20
+ assert_equal "Datum5", listings[1]['Second']
21
+ assert_equal "Datum6", listings[1]['Third']
22
+
23
+ end
24
+ end
@@ -0,0 +1,96 @@
1
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
2
+
3
+ require 'test/unit'
4
+ require 'rets4r'
5
+
6
+ module RETS4R
7
+ class Client
8
+ class TestParser < Test::Unit::TestCase
9
+ def setup
10
+ @parser = ResponseParser.new
11
+ end
12
+
13
+ DATA_DIR = 'test/data/1.5/'
14
+
15
+ def load_xml_from_file(file_name)
16
+ xml = ''
17
+
18
+ File.open(file_name) do |file|
19
+ file.each do |line|
20
+ xml << line
21
+ end
22
+ end
23
+
24
+ xml
25
+ end
26
+
27
+ def parse_to_transaction(xml_file_name)
28
+ @parser.parse_key_value(load_xml_from_file(xml_file_name))
29
+ end
30
+
31
+ # Test Cases
32
+
33
+ # TODO: verify test_search_compact header, metadata
34
+ def test_search_compact
35
+ xml = load_xml_from_file("#{DATA_DIR}search_compact.xml")
36
+ transaction = @parser.parse_results(xml, 'COMPACT')
37
+
38
+ assert_equal true, transaction.success?, "transaction should be successful"
39
+ assert_equal '0', transaction.reply_code
40
+ assert_equal 'SUCCESS', transaction.reply_text
41
+ assert_equal [], transaction.header
42
+ # XXX: this used to say, why?
43
+ # assert_equal false, transaction.header.empty?
44
+
45
+ assert_equal nil, transaction.metadata
46
+
47
+ assert_equal ?\t, transaction.delimiter
48
+ assert_equal "\t", transaction.ascii_delimiter
49
+ assert_equal true, transaction.maxrows?
50
+
51
+ assert_equal 2, transaction.response.length, 'response length should be 2'
52
+ assert_equal "Datum1", transaction.response[0]['First']
53
+ assert_equal "Datum2", transaction.response[0]['Second']
54
+ assert_equal "Datum3", transaction.response[0]['Third']
55
+ assert_equal "Datum4", transaction.response[1]['First']
56
+ assert_equal "Datum5", transaction.response[1]['Second']
57
+ assert_equal "Datum6", transaction.response[1]['Third']
58
+
59
+ # Check for compatibility
60
+ assert_equal transaction.data, transaction.response
61
+
62
+ assert_equal nil, transaction.secondary_response
63
+ end
64
+
65
+ def test_unescaped_search_compact
66
+ assert_raise(REXML::ParseException) do
67
+ @parser.parse_key_value(load_xml_from_file("#{DATA_DIR}search_unescaped_compact.xml"))
68
+ end
69
+ end
70
+
71
+ def test_invalid_search_compact
72
+ assert_raise(REXML::ParseException) do
73
+ @parser.parse_key_value(load_xml_from_file("#{DATA_DIR}search_unescaped_compact.xml"))
74
+ end
75
+ end
76
+
77
+ def test_login_results
78
+ transaction = parse_to_transaction("#{DATA_DIR}login.xml")
79
+
80
+ assert_equal(true, transaction.success?)
81
+ assert_equal('srealtor,1,11,11111', transaction.response['User'])
82
+ assert_equal('/rets/Login', transaction.response['Login'])
83
+ end
84
+
85
+ def test_error_results
86
+ xml = load_xml_from_file("#{DATA_DIR}error.xml")
87
+
88
+ exception = assert_raise(InvalidResourceException) do
89
+ @parser.parse_object_response(xml)
90
+ end
91
+
92
+ assert_equal('20400 - Invalid Invalidness.', exception.message)
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env ruby -w
2
+ libdir = File.expand_path('../../lib', __FILE__)
3
+ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
4
+
5
+ require "test/unit"
6
+
7
+ class TestQuality < Test::Unit::TestCase
8
+ def test_can_still_be_built
9
+ Dir.chdir(root) do
10
+ `gem build rets4r.gemspec`
11
+ assert_equal 0, $?
12
+ end
13
+ end
14
+
15
+ def test_has_no_malformed_whitespace
16
+ error_messages = []
17
+ Dir.chdir(root) do
18
+ File.read("MANIFEST").split("\n").each do |filename|
19
+ next if filename =~ /data/
20
+ error_messages << check_for_tab_characters(filename)
21
+ error_messages << check_for_extra_spaces(filename)
22
+ end
23
+ end
24
+ assert_well_formed error_messages.compact
25
+ end
26
+
27
+ def assert_well_formed(actual)
28
+ assert actual.empty?, actual.join("\n")
29
+ end
30
+
31
+ def check_for_tab_characters(filename)
32
+ failing_lines = []
33
+ File.readlines(filename).each_with_index do |line,number|
34
+ failing_lines << number + 1 if line =~ /\t/
35
+ end
36
+
37
+ unless failing_lines.empty?
38
+ "#{filename} has tab characters on lines #{failing_lines.join(', ')}"
39
+ end
40
+ end
41
+
42
+ def check_for_extra_spaces(filename)
43
+ failing_lines = []
44
+ File.readlines(filename).each_with_index do |line,number|
45
+ next if line =~ /^\s+#.*\s+\n$/
46
+ failing_lines << number + 1 if line =~ /\s+\n$/
47
+ end
48
+
49
+ unless failing_lines.empty?
50
+ "#{filename} has spaces on the EOL on lines #{failing_lines.join(', ')}"
51
+ end
52
+ end
53
+
54
+ def root
55
+ File.expand_path("../..", __FILE__)
56
+ end
57
+ end
metadata ADDED
@@ -0,0 +1,211 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jschairb-rets4r
3
+ version: !ruby/object:Gem::Version
4
+ hash: 55
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 1
9
+ - 18
10
+ version: 1.1.18
11
+ platform: ruby
12
+ authors:
13
+ - Scott Patterson
14
+ - John Wulff
15
+ - bgetting
16
+ - Jacob Basham
17
+ - Joseph Holsten
18
+ autorequire:
19
+ bindir: bin
20
+ cert_chain: []
21
+
22
+ date: 2011-01-05 00:00:00 -06:00
23
+ default_executable:
24
+ dependencies:
25
+ - !ruby/object:Gem::Dependency
26
+ name: nokogiri
27
+ prerelease: false
28
+ requirement: &id001 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ hash: 7
34
+ segments:
35
+ - 1
36
+ - 4
37
+ - 0
38
+ version: 1.4.0
39
+ type: :runtime
40
+ version_requirements: *id001
41
+ - !ruby/object:Gem::Dependency
42
+ name: mocha
43
+ prerelease: false
44
+ requirement: &id002 !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ hash: 3
50
+ segments:
51
+ - 0
52
+ version: "0"
53
+ type: :development
54
+ version_requirements: *id002
55
+ - !ruby/object:Gem::Dependency
56
+ name: shoulda
57
+ prerelease: false
58
+ requirement: &id003 !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ hash: 3
64
+ segments:
65
+ - 0
66
+ version: "0"
67
+ type: :development
68
+ version_requirements: *id003
69
+ - !ruby/object:Gem::Dependency
70
+ name: activesupport
71
+ prerelease: false
72
+ requirement: &id004 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ hash: 3
78
+ segments:
79
+ - 0
80
+ version: "0"
81
+ type: :development
82
+ version_requirements: *id004
83
+ description: RETS4R is a native Ruby interface to the RETS (Real Estate Transaction Standard). It currently is built for the 1.5 specification, but support for 1.7 and 2.0 are planned. It does not currently implement all of the specification, but the most commonly used portions. Specifically, there is no support for Update transactions.
84
+ email:
85
+ - scott.patterson@digitalaun.com
86
+ - john@johnwulff.com
87
+ - brian@terra-firma-design.com
88
+ - jacob@paperpigeons.net
89
+ - joseph@josephholsten.com
90
+ executables: []
91
+
92
+ extensions: []
93
+
94
+ extra_rdoc_files:
95
+ - CHANGELOG
96
+ - CONTRIBUTORS
97
+ - LICENSE
98
+ - MANIFEST
99
+ - NEWS
100
+ - README.rdoc
101
+ - RUBYS
102
+ - TODO
103
+ files:
104
+ - .document
105
+ - CHANGELOG
106
+ - CONTRIBUTORS
107
+ - Gemfile
108
+ - LICENSE
109
+ - MANIFEST
110
+ - NEWS
111
+ - README.rdoc
112
+ - RUBYS
113
+ - Rakefile
114
+ - TODO
115
+ - examples/client_get_object.rb
116
+ - examples/client_login.rb
117
+ - examples/client_mapper.rb
118
+ - examples/client_metadata.rb
119
+ - examples/client_parser.rb
120
+ - examples/client_search.rb
121
+ - examples/settings.yml
122
+ - lib/rets4r.rb
123
+ - lib/rets4r/auth.rb
124
+ - lib/rets4r/client.rb
125
+ - lib/rets4r/client/data.rb
126
+ - lib/rets4r/client/dataobject.rb
127
+ - lib/rets4r/client/exceptions.rb
128
+ - lib/rets4r/client/links.rb
129
+ - lib/rets4r/client/metadata.rb
130
+ - lib/rets4r/client/parsers/compact.rb
131
+ - lib/rets4r/client/parsers/compact_nokogiri.rb
132
+ - lib/rets4r/client/parsers/metadata.rb
133
+ - lib/rets4r/client/parsers/response_parser.rb
134
+ - lib/rets4r/client/requester.rb
135
+ - lib/rets4r/client/transaction.rb
136
+ - lib/rets4r/core_ext/array/extract_options.rb
137
+ - lib/rets4r/core_ext/class/attribute_accessors.rb
138
+ - lib/rets4r/core_ext/hash/keys.rb
139
+ - lib/rets4r/core_ext/hash/slice.rb
140
+ - lib/rets4r/listing_mapper.rb
141
+ - lib/rets4r/listing_service.rb
142
+ - lib/rets4r/loader.rb
143
+ - lib/tasks/annotations.rake
144
+ - lib/tasks/coverage.rake
145
+ - rets4r.gemspec
146
+ - spec/rets4r_compact_data_parser_spec.rb
147
+ - test/data/1.5/bad_compact.xml
148
+ - test/data/1.5/count_only_compact.xml
149
+ - test/data/1.5/error.xml
150
+ - test/data/1.5/invalid_compact.xml
151
+ - test/data/1.5/login.xml
152
+ - test/data/1.5/metadata.xml
153
+ - test/data/1.5/search_compact.xml
154
+ - test/data/1.5/search_compact_big.xml
155
+ - test/data/1.5/search_unescaped_compact.xml
156
+ - test/data/listing_service.yml
157
+ - test/test_auth.rb
158
+ - test/test_client.rb
159
+ - test/test_client_links.rb
160
+ - test/test_compact_nokogiri.rb
161
+ - test/test_helper.rb
162
+ - test/test_listing_mapper.rb
163
+ - test/test_loader.rb
164
+ - test/test_parser.rb
165
+ - test/test_quality.rb
166
+ has_rdoc: true
167
+ homepage: http://rets4r.rubyforge.org/
168
+ licenses: []
169
+
170
+ post_install_message:
171
+ rdoc_options:
172
+ - --charset=UTF-8
173
+ - --main
174
+ - README.rdoc
175
+ require_paths:
176
+ - lib
177
+ required_ruby_version: !ruby/object:Gem::Requirement
178
+ none: false
179
+ requirements:
180
+ - - ">="
181
+ - !ruby/object:Gem::Version
182
+ hash: 3
183
+ segments:
184
+ - 0
185
+ version: "0"
186
+ required_rubygems_version: !ruby/object:Gem::Requirement
187
+ none: false
188
+ requirements:
189
+ - - ">="
190
+ - !ruby/object:Gem::Version
191
+ hash: 3
192
+ segments:
193
+ - 0
194
+ version: "0"
195
+ requirements: []
196
+
197
+ rubyforge_project: rets4r
198
+ rubygems_version: 1.3.7
199
+ signing_key:
200
+ specification_version: 3
201
+ summary: RETS4R is a native Ruby interface to the RETS (Real Estate Transaction Standard)
202
+ test_files:
203
+ - test/test_auth.rb
204
+ - test/test_client.rb
205
+ - test/test_client_links.rb
206
+ - test/test_compact_nokogiri.rb
207
+ - test/test_helper.rb
208
+ - test/test_listing_mapper.rb
209
+ - test/test_loader.rb
210
+ - test/test_parser.rb
211
+ - test/test_quality.rb