wfrmls 0.3.0 → 0.3.1
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.
- data/History.txt +4 -1
- data/Rakefile +2 -0
- data/bin/wfrmls +6 -1
- data/lib/wfrmls.rb +1 -1
- data/lib/wfrmls/cli/options.rb +12 -3
- data/lib/wfrmls/ie.rb +123 -21
- data/test/ie_test.rb +35 -0
- metadata +5 -4
data/History.txt
CHANGED
data/Rakefile
CHANGED
data/bin/wfrmls
CHANGED
data/lib/wfrmls.rb
CHANGED
data/lib/wfrmls/cli/options.rb
CHANGED
@@ -7,9 +7,9 @@ module Wfrmls #:nodoc:
|
|
7
7
|
class << self
|
8
8
|
alias_method :parse!, :new
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
attr_reader :address
|
12
|
-
|
12
|
+
|
13
13
|
def initialize(*args)
|
14
14
|
address = ''
|
15
15
|
|
@@ -22,7 +22,11 @@ module Wfrmls #:nodoc:
|
|
22
22
|
#opt.on("-r [PATH]", "Require [PATH] before executing") do |path|
|
23
23
|
# @paths_to_require << path
|
24
24
|
#end
|
25
|
-
|
25
|
+
|
26
|
+
opt.on("-c", "Comp this address") do
|
27
|
+
@comp = true
|
28
|
+
end
|
29
|
+
|
26
30
|
opt.on("-h", "-?", "--help", "Show this message") do
|
27
31
|
puts opt
|
28
32
|
exit
|
@@ -38,6 +42,11 @@ module Wfrmls #:nodoc:
|
|
38
42
|
@address = argv.dup.join(' ')
|
39
43
|
end
|
40
44
|
|
45
|
+
def comp?
|
46
|
+
@comp
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
41
50
|
def version
|
42
51
|
Wfrmls::VERSION
|
43
52
|
end
|
data/lib/wfrmls/ie.rb
CHANGED
@@ -31,32 +31,52 @@ module Wfrmls
|
|
31
31
|
def lookup_address(addr)
|
32
32
|
goto 'http://www.utahrealestate.com/search/form/type/1/name/full?advanced_search=1'
|
33
33
|
residential_full_search
|
34
|
-
|
35
34
|
status
|
36
|
-
|
37
|
-
@ie.text_field(:id, 'street').set addr.street
|
38
|
-
@ie.text_field(:id, 'housenum').set addr.number
|
39
|
-
|
40
|
-
city(addr.city)
|
35
|
+
address(addr)
|
41
36
|
|
42
37
|
result_count = @ie.span(:id, 'action_search_count').text.to_i
|
43
38
|
|
44
39
|
if result_count > 0
|
45
|
-
|
46
|
-
@ie.button(:id, 'SEARCH_button').click
|
47
|
-
begin
|
48
|
-
sleep 1
|
49
|
-
@ie.checkbox(:id, 'ListingController').click
|
50
|
-
rescue
|
51
|
-
retry
|
52
|
-
end
|
53
|
-
|
54
|
-
@ie.select_list(:id, 'report-selector').set('Full Report')
|
40
|
+
show_full_listings
|
55
41
|
else
|
56
42
|
show_tax_data(addr)
|
57
43
|
end
|
58
44
|
end
|
59
45
|
|
46
|
+
def show_full_listings
|
47
|
+
@ie.button(:id, 'SEARCH_button').click
|
48
|
+
sleep_until { @ie.checkbox(:id, 'ListingController').exists? }
|
49
|
+
@ie.checkbox(:id, 'ListingController').click
|
50
|
+
@ie.select_list(:id, 'report-selector').set('Full Report')
|
51
|
+
end
|
52
|
+
|
53
|
+
def comp(addr)
|
54
|
+
# TODO remove the sleeps
|
55
|
+
house_details = collect_property_details(addr)
|
56
|
+
goto 'http://www.utahrealestate.com/search/form/type/1/name/full?advanced_search=1'
|
57
|
+
|
58
|
+
@ie.button(:id, 'CLEAR_button').click
|
59
|
+
|
60
|
+
sleep 3
|
61
|
+
|
62
|
+
residential_full_search
|
63
|
+
status
|
64
|
+
city(addr.city)
|
65
|
+
|
66
|
+
@ie.text_field(:id, 'days_back_status').set('120')
|
67
|
+
|
68
|
+
|
69
|
+
@ie.text_field(:name, 'tot_sqf1').set((house_details[:house_size] - 200).to_s)
|
70
|
+
@ie.text_field(:name, 'tot_sqf2').set((house_details[:house_size] + 200).to_s)
|
71
|
+
|
72
|
+
@ie.text_field(:name, 'yearblt1').set((house_details[:year_built] - 6).to_s)
|
73
|
+
@ie.text_field(:name, 'yearblt2').set((house_details[:year_built] + 6).to_s)
|
74
|
+
|
75
|
+
sleep 3
|
76
|
+
|
77
|
+
show_full_listings
|
78
|
+
end
|
79
|
+
|
60
80
|
def status
|
61
81
|
settings = ['Active', 'Sold', 'Under Contract', 'Expired']
|
62
82
|
@ie.div(:id, 'status1Container_clear_button').click
|
@@ -80,6 +100,12 @@ module Wfrmls
|
|
80
100
|
sleep_until { @ie.dd(:id, 'left_search_criteria').text.include? 'City is' }
|
81
101
|
end
|
82
102
|
|
103
|
+
def address(addr)
|
104
|
+
@ie.text_field(:id, 'street').set addr.street
|
105
|
+
@ie.text_field(:id, 'housenum').set addr.number
|
106
|
+
city(addr.city)
|
107
|
+
end
|
108
|
+
|
83
109
|
def sleep_until &block
|
84
110
|
count = 0
|
85
111
|
until yield block
|
@@ -92,13 +118,33 @@ module Wfrmls
|
|
92
118
|
def show_tax_data(addr)
|
93
119
|
goto "http://www.utahrealestate.com/taxdata/index?county%5B%5D=2&county%5B%5D=8&searchtype=house&searchbox=#{addr.number}"
|
94
120
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
121
|
+
rows = find_tax_data_rows_by_house_and_street(addr)
|
122
|
+
|
123
|
+
case rows.size
|
124
|
+
when 0
|
125
|
+
puts "#{addr} not found in tax data"
|
126
|
+
when 1
|
127
|
+
click_link rows[0]
|
128
|
+
else
|
129
|
+
puts 'Possible matches:'
|
130
|
+
rows.each do |item|
|
131
|
+
puts item.cell(:class, 'last-col').text
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def click_link(item)
|
137
|
+
item.link(:index, 1).click
|
138
|
+
end
|
139
|
+
|
140
|
+
def find_tax_data_rows_by_house_and_street(addr)
|
141
|
+
rows = []
|
142
|
+
@ie.table(:class, 'tax-data').rows.to_a[1..-1].each do |row|
|
143
|
+
if row.cell(:class, 'last-col').text.include? addr.street.upcase
|
144
|
+
rows << row
|
100
145
|
end
|
101
146
|
end
|
147
|
+
rows
|
102
148
|
end
|
103
149
|
|
104
150
|
def goto(url)
|
@@ -108,5 +154,61 @@ module Wfrmls
|
|
108
154
|
@ie.goto url
|
109
155
|
end
|
110
156
|
end
|
157
|
+
|
158
|
+
def collect_property_details(addr)
|
159
|
+
show_tax_data(addr) unless @ie.url.include? 'taxdata/details'
|
160
|
+
|
161
|
+
doc = @ie.xmlparser_document_object
|
162
|
+
|
163
|
+
details = {}
|
164
|
+
|
165
|
+
doc.search('tr/th').each do |item|
|
166
|
+
case nbsp2sp(item.text)
|
167
|
+
when /NAME:/
|
168
|
+
details[:owner] = item.parent.search('td').text
|
169
|
+
when /ADDRESS:/
|
170
|
+
details[:address] = item.parent.search('td').text.strip
|
171
|
+
when /PARCEL SPECIFIC INFO:/
|
172
|
+
nbsp2sp(item.parent.search('td').text) =~ /Total Acres: ([.0-9]+)/
|
173
|
+
details[:lot_size] = $1
|
174
|
+
when /VALUATION SPECIFIC INFO:/
|
175
|
+
nbsp2sp(item.parent.search('td').text) =~ /Final Value: (\$[0-9,]+)/
|
176
|
+
details[:tax_value] = $1
|
177
|
+
when /GENERAL INFO:/
|
178
|
+
nbsp2sp(item.parent.search('td').text) =~ /Yr Built: ([0-9]+)/
|
179
|
+
details[:year_built] = $1.to_i
|
180
|
+
when /AREA INFO:/
|
181
|
+
house_size = 0
|
182
|
+
data = nbsp2sp(item.parent.search('td').text)
|
183
|
+
data =~ /Main Floor Area: ([,0-9]+)/
|
184
|
+
house_size += $1.sub(',','').to_i if $1
|
185
|
+
data =~ /Basement Area: ([,0-9]+)/
|
186
|
+
house_size += $1.sub(',','').to_i if $1
|
187
|
+
data =~ /Upper Floor Area: ([,0-9]+)/
|
188
|
+
house_size += $1.sub(',','').to_i if $1
|
189
|
+
details[:house_size] = house_size
|
190
|
+
when /EXTERIOR:/
|
191
|
+
details[:exterior] ||= {}
|
192
|
+
data = nbsp2sp(item.parent.search('td').text)
|
193
|
+
data =~ /Ext. Wall Type: (\w+)/
|
194
|
+
details[:exterior][:wall] = $1
|
195
|
+
data =~ /Masonry Trim: (\w+)/
|
196
|
+
details[:exterior][:masonry_trim] = $1
|
197
|
+
when /CARPORT & GARAGE INFO:/
|
198
|
+
data = nbsp2sp(item.parent.search('td').text)
|
199
|
+
data =~ /(.*): ([,0-9]+)/
|
200
|
+
if $1
|
201
|
+
key = $1.gsub(/[- ]/, '_').downcase.to_sym
|
202
|
+
details[key] = $2
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
details
|
208
|
+
end
|
209
|
+
|
210
|
+
def nbsp2sp(s)
|
211
|
+
s.gsub("\xC2\xA0", ' ')
|
212
|
+
end
|
111
213
|
end
|
112
214
|
end
|
data/test/ie_test.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'wfrmls/ie'
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'flexmock/test_unit'
|
5
|
+
|
6
|
+
class WfrmlsTest < Test::Unit::TestCase
|
7
|
+
def test_show_tax_data_with_nothing_found
|
8
|
+
ie = flexmock('ie') do |item|
|
9
|
+
#item.should_receive(:table)
|
10
|
+
#item.should_receive(:rows)
|
11
|
+
end
|
12
|
+
addr = flexmock('addr') do |item|
|
13
|
+
item.should_receive(:number).returns('1')
|
14
|
+
item.should_receive(:to_s).and_return('address')
|
15
|
+
end
|
16
|
+
ie = Wfrmls::IE.new(ie, nil, nil)
|
17
|
+
flexmock(ie) do |m|
|
18
|
+
m.should_receive(:goto)
|
19
|
+
m.should_receive(:find_tax_data_rows_by_house_and_street).
|
20
|
+
and_return([])
|
21
|
+
|
22
|
+
m.should_receive(:puts).with('address not found in tax data')
|
23
|
+
end
|
24
|
+
|
25
|
+
ie.show_tax_data(addr)
|
26
|
+
end
|
27
|
+
|
28
|
+
def xxxtest_collect_property_details
|
29
|
+
ie = Watir::Browser.new
|
30
|
+
ie = Wfrmls::IE.new(ie, nil, nil)
|
31
|
+
|
32
|
+
addr = StreetAddress::US.parse('3537 W 2400 S, SYRACUSE, UT')
|
33
|
+
ie.collect_property_details(addr)
|
34
|
+
end
|
35
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wfrmls
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- zhon
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-01-
|
12
|
+
date: 2010-01-27 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -93,5 +93,6 @@ rubygems_version: 1.3.5
|
|
93
93
|
signing_key:
|
94
94
|
specification_version: 3
|
95
95
|
summary: Help searching the WFRMLS
|
96
|
-
test_files:
|
97
|
-
|
96
|
+
test_files:
|
97
|
+
- test/ie_test.rb
|
98
|
+
- test/wfrmls_test.rb
|