zillow4r 0.1.0

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 (42) hide show
  1. data/Gemfile +18 -0
  2. data/Gemfile.lock +23 -0
  3. data/README.md +69 -0
  4. data/Rakefile +53 -0
  5. data/VERSION +1 -0
  6. data/lib/zillow4r.rb +49 -0
  7. data/lib/zillow4r/api.rb +25 -0
  8. data/lib/zillow4r/api/base.rb +5 -0
  9. data/lib/zillow4r/api/chart.rb +12 -0
  10. data/lib/zillow4r/api/comps.rb +13 -0
  11. data/lib/zillow4r/api/deep_comps.rb +13 -0
  12. data/lib/zillow4r/api/deep_search_results.rb +12 -0
  13. data/lib/zillow4r/api/demographics.rb +38 -0
  14. data/lib/zillow4r/api/region_chart.rb +12 -0
  15. data/lib/zillow4r/api/region_children.rb +14 -0
  16. data/lib/zillow4r/api/search_results.rb +12 -0
  17. data/lib/zillow4r/api/updated_property_details.rb +52 -0
  18. data/lib/zillow4r/api/zestimate.rb +15 -0
  19. data/lib/zillow4r/models.rb +189 -0
  20. data/test/fixtures/chart.xml +19 -0
  21. data/test/fixtures/comps.xml +189 -0
  22. data/test/fixtures/deep_comps.xml +536 -0
  23. data/test/fixtures/deep_search_results.xml +102 -0
  24. data/test/fixtures/demographics.xml +849 -0
  25. data/test/fixtures/region_chart.xml +18 -0
  26. data/test/fixtures/region_children.xml +868 -0
  27. data/test/fixtures/search_results.xml +91 -0
  28. data/test/fixtures/updated_property_details.xml +75 -0
  29. data/test/fixtures/zestimate.xml +93 -0
  30. data/test/test_helper.rb +26 -0
  31. data/test/unit/chart_test.rb +18 -0
  32. data/test/unit/comps_test.rb +50 -0
  33. data/test/unit/deep_comps_test.rb +50 -0
  34. data/test/unit/deep_search_results_test.rb +28 -0
  35. data/test/unit/demographics_test.rb +39 -0
  36. data/test/unit/region_chart_test.rb +18 -0
  37. data/test/unit/region_children_test.rb +41 -0
  38. data/test/unit/search_results_test.rb +28 -0
  39. data/test/unit/updated_property_details_test.rb +65 -0
  40. data/test/unit/zestimate_test.rb +52 -0
  41. data/zillow4r.gemspec +105 -0
  42. metadata +183 -0
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+ gem "nokogiri"
6
+
7
+ # Add dependencies to develop your gem here.
8
+ # Include everything needed to run rake, tests, features, etc.
9
+ group :development do
10
+ gem "mocha"
11
+ gem "bundler", "~> 1.0.0"
12
+ gem "jeweler", "~> 1.5.1"
13
+ gem "rcov", ">= 0"
14
+ end
15
+
16
+ group :test do
17
+ gem "mocha"
18
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,23 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ git (1.2.5)
5
+ jeweler (1.5.1)
6
+ bundler (~> 1.0.0)
7
+ git (>= 1.2.5)
8
+ rake
9
+ mocha (0.9.10)
10
+ rake
11
+ nokogiri (1.4.4)
12
+ rake (0.8.7)
13
+ rcov (0.9.9)
14
+
15
+ PLATFORMS
16
+ ruby
17
+
18
+ DEPENDENCIES
19
+ bundler (~> 1.0.0)
20
+ jeweler (~> 1.5.1)
21
+ mocha
22
+ nokogiri
23
+ rcov
data/README.md ADDED
@@ -0,0 +1,69 @@
1
+ Zillow4r
2
+ --------
3
+
4
+ Simple ruby interface for the [Zillow API](http://www.zillow.com/howto/api/APIOverview.htm).
5
+
6
+ ### Documentation & Requirements
7
+ * Nokogiri
8
+
9
+ ### Supported API Calls
10
+
11
+ As of version 0.1.0, we support the following API calls:
12
+
13
+ * [GetZestimate](http://www.zillow.com/howto/api/GetZestimate.htm)
14
+ * [GetSearchResults](http://www.zillow.com/howto/api/GetSearchResults.htm)
15
+ * [GetChart](http://www.zillow.com/howto/api/GetChart.htm)
16
+ * [GetComps](http://www.zillow.com/howto/api/GetComps.htm)
17
+ * [GetDeepComps](http://www.zillow.com/howto/api/GetDeepComps.htm)
18
+ * [GetDeepSearchResults](http://www.zillow.com/howto/api/GetDeepSearchResults.htm)
19
+ * [GetUpdatedPropertyDetails](http://www.zillow.com/howto/api/GetUpdatedPropertyDetails.htm)
20
+ * [GetDemographics](http://www.zillow.com/howto/api/GetDemographics.htm)
21
+ * [GetRegionChildren](http://www.zillow.com/howto/api/GetRegionChildren.htm)
22
+ * [GetRegionChart](http://www.zillow.com/howto/api/GetRegionChart.html)
23
+
24
+ To make these calls, you call the module method `Zillow4r.fetch_[name]` where name is the underscored
25
+ api call name without the "Get". For example, if you wanted to call the GetDeepSearchResults
26
+ API, call `Zillow4r.fetch_deep_search_results` with the search parameters specified by the API.
27
+
28
+ Note: Zillow4r will automatically add your ZWSID to the API request.
29
+
30
+ ### Examples
31
+
32
+ Basic usage:
33
+
34
+ require 'rubygems'
35
+ require 'zillow4r'
36
+
37
+ Zillow4r.zws_id = 'YOUR_API_KEY'
38
+
39
+ response = Zillow4r.fetch_updated_property_details(:zpid => 123456)
40
+ response.class
41
+ => Zillow4r::Api::UpdatedPropertyDetails
42
+
43
+ response = Zillow4r.fetch_search_results(:address => "2114 Bigelow Ave", :citystatezip => "Seattle, WA")
44
+ response.class
45
+ => Zillow4r::Api::SearchResults
46
+ response.results.class
47
+ => Array
48
+ response.results.first.class
49
+ => Zillow4r::Property
50
+
51
+ ### Models
52
+
53
+ Zillow4r uses several intermediate data models which represent repeated data structures contained within
54
+ Zillow's xml. These include:
55
+
56
+ * Zillow4r::Address
57
+ * Zillow4r::Links
58
+ * Zillow4r::Images
59
+ * Zillow4r::Region
60
+ * Zillow4r::Property
61
+ * Zillow4r::Posting
62
+ * Zillow4r::Zestimate
63
+ * Zillow4r::ComparableProperty
64
+
65
+ These models define the data that they contain through their position within the xml data.
66
+
67
+ ### Testing
68
+
69
+ Test cases are mocked using the sample API output provided for each API call in the documentation from Zillow.
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'rake'
11
+
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gem|
14
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
+ gem.name = "zillow4r"
16
+ gem.homepage = "http://github.com/chingor13/zillow4r"
17
+ gem.license = "MIT"
18
+ gem.summary = %Q{Simple ruby interface for the Zillow API}
19
+ gem.description = %Q{Simple ruby interface for the Zillow API. See http://www.zillow.com/howto/api/APIOverview.htm}
20
+ gem.email = "ching.jeff@gmail.com"
21
+ gem.authors = ["Jeff Ching"]
22
+ # Include your dependencies below. Runtime dependencies are required when using your gem,
23
+ # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
24
+ # gem.add_runtime_dependency 'jabber4r', '> 0.1'
25
+ # gem.add_development_dependency 'rspec', '> 1.2.3'
26
+ end
27
+ Jeweler::RubygemsDotOrgTasks.new
28
+
29
+ require 'rake/testtask'
30
+ Rake::TestTask.new(:test) do |test|
31
+ test.libs << 'lib' << 'test'
32
+ test.pattern = 'test/**/*_test.rb'
33
+ test.verbose = true
34
+ end
35
+
36
+ require 'rcov/rcovtask'
37
+ Rcov::RcovTask.new do |test|
38
+ test.libs << 'test'
39
+ test.pattern = 'test/**/*_test.rb'
40
+ test.verbose = true
41
+ end
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "zillow4r #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/lib/zillow4r.rb ADDED
@@ -0,0 +1,49 @@
1
+ require 'rubygems'
2
+ require 'open-uri'
3
+ require 'nokogiri'
4
+ require 'cgi'
5
+ module Zillow4r
6
+
7
+ HTTP_USER_AGENT = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1"
8
+ HTTP_ACCEPT = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
9
+ WEB_API_HOST = "www.zillow.com"
10
+ WEB_API_PORT = 80
11
+
12
+ class << self
13
+ attr_accessor :zws_id
14
+
15
+ def method_missing(a, *args)
16
+ if match = a.to_s.match(/^fetch_(.*)$/)
17
+ self.fetch(match[1], args[0])
18
+ else
19
+ super(a, *args)
20
+ end
21
+ end
22
+
23
+ def fetch(type, params = {})
24
+ klass = get_class(type)
25
+ path = build_path(klass, params)
26
+ url = "http://" + WEB_API_HOST + path
27
+ klass.new(open(url).read)
28
+ end
29
+
30
+ def build_path(klass, params)
31
+ p = ["zws-id=#{Zillow4r.zws_id}"]
32
+ params.each do |key,value|
33
+ p << "#{key}=#{CGI.escape(value.to_s)}"
34
+ end
35
+ "#{klass.path}?#{p.join('&')}"
36
+ end
37
+
38
+ private
39
+
40
+ def get_class(type)
41
+ class_name = type.split("_").map{|word| word[0..0].upcase + word[1..word.length]}.join("")
42
+ Zillow4r::Api.const_get(class_name)
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+ require 'zillow4r/models.rb'
49
+ require 'zillow4r/api.rb'
@@ -0,0 +1,25 @@
1
+ module Zillow4r
2
+ module Api
3
+ class Base < Zillow4r::Base
4
+ def self.path
5
+ raise "Need to set path for child class"
6
+ end
7
+
8
+ int_point "response_code", "message code", "data"
9
+ text_point "response_message", "message text", "data"
10
+
11
+ def data_error?
12
+ response_code.nil? || response_code > 500
13
+ end
14
+
15
+ def error?
16
+ response_code.nil? || response_code > 0
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ Dir.glob(File.dirname(__FILE__) + "/api/*.rb").each do |file|
23
+ require file
24
+ end
25
+
@@ -0,0 +1,5 @@
1
+ require 'nokogiri'
2
+ module Zillow4r
3
+ module Api
4
+ end
5
+ end
@@ -0,0 +1,12 @@
1
+ module Zillow4r
2
+ module Api
3
+ class Chart < Zillow4r::Api::Base
4
+ text_point :chart_url, "response url", :data
5
+
6
+ def self.path
7
+ "/webservice/GetChart.htm"
8
+ end
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ module Zillow4r
2
+ module Api
3
+ class Comps < Zillow4r::Api::Base
4
+ object_point :principal, "response properties principal", :data, Zillow4r::Property
5
+ array_point :comparables, "response/properties/comparables", :data, Zillow4r::ComparableProperty
6
+
7
+ def self.path
8
+ "/webservice/GetComps.htm"
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module Zillow4r
2
+ module Api
3
+ class DeepComps < Zillow4r::Api::Base
4
+ object_point :principal, "response properties principal", :data, Zillow4r::Property
5
+ array_point :comparables, "response/properties/comparables", :data, Zillow4r::ComparableProperty
6
+
7
+ def self.path
8
+ "/webservice/GetDeepComps.htm"
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ module Zillow4r
2
+ module Api
3
+ class DeepSearchResults < Zillow4r::Api::Base
4
+ array_point :results, "response/results", :data, Zillow4r::Property
5
+
6
+ def self.path
7
+ "/webservice/GetDeepSearchResults.htm"
8
+ end
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,38 @@
1
+ module Zillow4r
2
+ module Api
3
+ class Demographics < Zillow4r::Api::Base
4
+ object_point :region, "response region", :data, Zillow4r::Region
5
+ object_point :links, "response links", :data, Zillow4r::Links
6
+
7
+ # intermediate points
8
+ data_point :people_data_node, ["response pages", {"name" => "People"}, "tables", {"name" => "People Data"}, "data"], :data
9
+ data_point :owners_data_node, ["response pages", {"name" => "Homes & Real Estate"}, "tables", {"name" => "Census Summary-Occupancy"}, "data"], "data"
10
+
11
+ # city demographic values
12
+ float_point :city_median_age, [{"name" => "Median Age"}, "values city value"], :people_data_node
13
+ float_point :city_median_household_income, [{"name" => "Median Household Income"}, "values city value"], :people_data_node
14
+ float_point :city_average_household_size, [{"name" => "Average Household Size"}, "values city value"], :people_data_node
15
+ float_point :city_percent_of_homes_with_kids, [{"name" => "Homes With Kids"}, "values city value"], :people_data_node
16
+
17
+ # neighborhood demographic values
18
+ float_point :neighborhood_median_age, [{"name" => "Median Age"}, "values neighborhood value"], :people_data_node
19
+ float_point :neighborhood_median_household_income, [{"name" => "Median Household Income"}, "values neighborhood value"], :people_data_node
20
+ float_point :neighborhood_average_household_size, [{"name" => "Average Household Size"}, "values neighborhood value"], :people_data_node
21
+ float_point :neighborhood_percent_of_homes_with_kids, [{"name" => "Homes With Kids"}, "values neighborhood value"], :people_data_node
22
+
23
+ # nation demographic values
24
+ float_point :nation_median_age, [{"name" => "Median Age"}, "values nation value"], :people_data_node
25
+ float_point :nation_median_household_income, [{"name" => "Median Household Income"}, "values nation value"], :people_data_node
26
+ float_point :nation_average_household_size, [{"name" => "Average Household Size"}, "values nation value"], :people_data_node
27
+ float_point :nation_percent_of_homes_with_kids, [{"name" => "Homes With Kids"}, "values nation value"], :people_data_node
28
+
29
+ float_point :percent_owners, [{"name" => "Own"}, "value"], :owners_data_node
30
+ float_point :percent_renters, [{"name" => "Rent"}, "value"], :owners_data_node
31
+
32
+ def self.path
33
+ "/webservice/GetDemographics.htm"
34
+ end
35
+
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,12 @@
1
+ module Zillow4r
2
+ module Api
3
+ class RegionChart < Zillow4r::Api::Base
4
+ text_point :chart_url, "response url", :data
5
+
6
+ def self.path
7
+ "/webservice/GetRegionChart.htm"
8
+ end
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ module Zillow4r
2
+ module Api
3
+ class RegionChildren < Zillow4r::Api::Base
4
+ object_point :region, "response/region", :data, Zillow4r::Region
5
+ text_point :subregion_type, "response subregiontype", :data
6
+ array_point :children, "response/list", :data, Zillow4r::Region
7
+
8
+ def self.path
9
+ "/webservice/GetRegionChildren.htm"
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ module Zillow4r
2
+ module Api
3
+ class SearchResults < Zillow4r::Api::Base
4
+ array_point :results, "response/results", :data, Zillow4r::Property
5
+
6
+ def self.path
7
+ "/webservice/GetSearchResults.htm"
8
+ end
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,52 @@
1
+ module Zillow4r
2
+ module Api
3
+ class UpdatedPropertyDetails < Zillow4r::Api::Base
4
+ int_point :zpid, "response zpid", :data
5
+
6
+ # page views
7
+ int_point :page_view_count_month, "response pageviewcount currentmonth", :data
8
+ int_point :page_view_count_total, "response pageviewcount total", :data
9
+
10
+ object_point :address, "response address", :data, Zillow4r::Address
11
+ object_point :posting, "response posting", :data, Zillow4r::Posting
12
+
13
+ # price
14
+ int_point :price, "response price", :data
15
+ attribute_point :price_currency, "response price", :data, "currency"
16
+
17
+ object_point :links, "response links", :data, Zillow4r::Links
18
+ object_point :images, "response images image", :data, Zillow4r::Images
19
+
20
+ # facts
21
+ data_point :facts_data_node, "response editedfacts", :data
22
+ text_point :use_code, "usecode", :facts_data_node
23
+ int_point :bedrooms, "bedrooms", :facts_data_node
24
+ float_point :bathrooms, "bathrooms", :facts_data_node
25
+ int_point :finished_sq_ft, "finishedsqft", :facts_data_node
26
+ int_point :lot_sq_ft, "lotsizesqft", :facts_data_node
27
+ int_point :year_built, "yearbuilt", :facts_data_node
28
+ int_point :year_updated, "yearupdated", :facts_data_node
29
+ int_point :floors, "numfloors", :facts_data_node
30
+ text_point :basement, "basement", :facts_data_node
31
+ text_point :roof, "roof", :facts_data_node
32
+ text_point :view, "view", :facts_data_node
33
+ text_point :parking_type, "parkingtype", :facts_data_node
34
+ text_point :heating_sources, "heatingsources", :facts_data_node
35
+ text_point :heating_system, "heatingsystem", :facts_data_node
36
+ text_point :appliances, "appliances", :facts_data_node
37
+ text_point :floor_covering, "floorcovering", :facts_data_node
38
+ text_point :rooms, "rooms", :facts_data_node
39
+
40
+ # general info
41
+ text_point :home_description, "response homedescription", :data
42
+ text_point :neighborhood, "response neighborhood", :data
43
+ text_point :school_district, "response schooldistrict", :data
44
+ text_point :elementary_school, "response elementaryschool", :data
45
+ text_point :middle_school, "response middleschool", :data
46
+
47
+ def self.path
48
+ "/webservice/GetUpdatedPropertyDetails.htm"
49
+ end
50
+ end
51
+ end
52
+ end