rubillow 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. data/.gitignore +6 -0
  2. data/.rspec +2 -0
  3. data/.yardopts +4 -0
  4. data/Gemfile +3 -0
  5. data/Gemfile.lock +43 -0
  6. data/LICENSE +21 -0
  7. data/README.md +64 -0
  8. data/Rakefile +38 -0
  9. data/lib/rubillow.rb +29 -0
  10. data/lib/rubillow/configuration.rb +31 -0
  11. data/lib/rubillow/home_valuation.rb +141 -0
  12. data/lib/rubillow/models.rb +83 -0
  13. data/lib/rubillow/models/addressable.rb +38 -0
  14. data/lib/rubillow/models/chart.rb +34 -0
  15. data/lib/rubillow/models/comps.rb +35 -0
  16. data/lib/rubillow/models/deep_comps.rb +35 -0
  17. data/lib/rubillow/models/deep_search_result.rb +44 -0
  18. data/lib/rubillow/models/demographic_value.rb +28 -0
  19. data/lib/rubillow/models/demographics.rb +149 -0
  20. data/lib/rubillow/models/images.rb +24 -0
  21. data/lib/rubillow/models/linkable.rb +39 -0
  22. data/lib/rubillow/models/monthly_payments.rb +64 -0
  23. data/lib/rubillow/models/posting.rb +37 -0
  24. data/lib/rubillow/models/postings.rb +64 -0
  25. data/lib/rubillow/models/property_basics.rb +36 -0
  26. data/lib/rubillow/models/property_chart.rb +26 -0
  27. data/lib/rubillow/models/rate_summary.rb +38 -0
  28. data/lib/rubillow/models/region.rb +44 -0
  29. data/lib/rubillow/models/region_chart.rb +30 -0
  30. data/lib/rubillow/models/region_children.rb +30 -0
  31. data/lib/rubillow/models/search_result.rb +19 -0
  32. data/lib/rubillow/models/updated_property_details.rb +87 -0
  33. data/lib/rubillow/models/zestimateable.rb +77 -0
  34. data/lib/rubillow/models/zpidable.rb +25 -0
  35. data/lib/rubillow/mortgage.rb +75 -0
  36. data/lib/rubillow/neighborhood.rb +129 -0
  37. data/lib/rubillow/postings.rb +46 -0
  38. data/lib/rubillow/property_details.rb +107 -0
  39. data/lib/rubillow/request.rb +67 -0
  40. data/lib/rubillow/version.rb +4 -0
  41. data/rubillow.gemspec +31 -0
  42. data/spec/rubillow/configuration_spec.rb +10 -0
  43. data/spec/rubillow/home_valuation_spec.rb +91 -0
  44. data/spec/rubillow/models/comps_spec.rb +71 -0
  45. data/spec/rubillow/models/deep_comps_spec.rb +93 -0
  46. data/spec/rubillow/models/deep_search_results_spec.rb +47 -0
  47. data/spec/rubillow/models/demographics_spec.rb +60 -0
  48. data/spec/rubillow/models/monthly_payments_spec.rb +20 -0
  49. data/spec/rubillow/models/posting_spec.rb +28 -0
  50. data/spec/rubillow/models/postings_spec.rb +15 -0
  51. data/spec/rubillow/models/property_chart_spec.rb +18 -0
  52. data/spec/rubillow/models/rate_summary_spec.rb +14 -0
  53. data/spec/rubillow/models/region_chart_spec.rb +19 -0
  54. data/spec/rubillow/models/region_children_spec.rb +11 -0
  55. data/spec/rubillow/models/search_result_spec.rb +68 -0
  56. data/spec/rubillow/models/updated_property_details_spec.rb +57 -0
  57. data/spec/rubillow/models_spec.rb +46 -0
  58. data/spec/rubillow/mortgage_spec.rb +37 -0
  59. data/spec/rubillow/neighborhood_spec.rb +55 -0
  60. data/spec/rubillow/postings_spec.rb +19 -0
  61. data/spec/rubillow/property_details_spec.rb +67 -0
  62. data/spec/rubillow/request_spec.rb +65 -0
  63. data/spec/rubillow/rubillow_spec.rb +13 -0
  64. data/spec/spec_helper.rb +15 -0
  65. data/spec/support/have_configuration_matcher.rb +23 -0
  66. data/spec/xml/general_failure.xml +12 -0
  67. data/spec/xml/get_chart.xml +18 -0
  68. data/spec/xml/get_comps.xml +252 -0
  69. data/spec/xml/get_deep_comps.xml +307 -0
  70. data/spec/xml/get_deep_search_results.xml +66 -0
  71. data/spec/xml/get_demographics.xml +791 -0
  72. data/spec/xml/get_monthly_payments.xml +33 -0
  73. data/spec/xml/get_rate_summary.xml +21 -0
  74. data/spec/xml/get_region_chart.xml +25 -0
  75. data/spec/xml/get_region_children.xml +870 -0
  76. data/spec/xml/get_region_postings.xml +2660 -0
  77. data/spec/xml/get_search_results.xml +55 -0
  78. data/spec/xml/get_updated_property_details.xml +74 -0
  79. data/spec/xml/get_zestimate.xml +56 -0
  80. data/spec/xml/near_limit.xml +13 -0
  81. metadata +324 -0
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ pkg/*
4
+ coverage
5
+ doc
6
+ .yardoc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format progress
2
+ --color
data/.yardopts ADDED
@@ -0,0 +1,4 @@
1
+ --no-private
2
+ lib/**/*.rb
3
+ -
4
+ LICENSE
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,43 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rubillow (0.0.1)
5
+ activesupport (~> 3.0.10)
6
+ i18n (~> 0.6.0)
7
+ nokogiri (~> 1.5.0)
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ activesupport (3.0.10)
13
+ bluecloth (2.1.0)
14
+ bourne (1.0)
15
+ mocha (= 0.9.8)
16
+ diff-lcs (1.1.2)
17
+ i18n (0.6.0)
18
+ mocha (0.9.8)
19
+ rake
20
+ nokogiri (1.5.0)
21
+ rake (0.9.2)
22
+ rcov (0.9.10)
23
+ rspec (2.6.0)
24
+ rspec-core (~> 2.6.0)
25
+ rspec-expectations (~> 2.6.0)
26
+ rspec-mocks (~> 2.6.0)
27
+ rspec-core (2.6.4)
28
+ rspec-expectations (2.6.0)
29
+ diff-lcs (~> 1.1.2)
30
+ rspec-mocks (2.6.0)
31
+ yard (0.7.2)
32
+
33
+ PLATFORMS
34
+ ruby
35
+
36
+ DEPENDENCIES
37
+ bluecloth (>= 2.1.0)
38
+ bourne (~> 1.0)
39
+ mocha (~> 0.9.8)
40
+ rcov (~> 0.9.10)
41
+ rspec (~> 2.6)
42
+ rubillow!
43
+ yard (>= 0.6.8)
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2011 Matthew Vince
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,64 @@
1
+ # Rubillow
2
+
3
+ Rubillow is a ruby library to access the [Zillow API](http://www.zillow.com/howto/api/APIOverview.htm).
4
+
5
+ Supports all of the API methods, with real ruby classes returned for each call.
6
+
7
+ ### [Home Valuation API](http://www.zillow.com/howto/api/HomeValuationAPIOverview.htm)
8
+ * [GetSearchResults](http://www.zillow.com/howto/api/GetSearchResults.htm)
9
+ * [GetZestimate](http://www.zillow.com/howto/api/GetZestimate.htm)
10
+ * [GetChart](http://www.zillow.com/howto/api/GetChart.htm)
11
+ * [GetComps](http://www.zillow.com/howto/api/GetComps.htm)
12
+
13
+ ### [Neighborhood Data](http://www.zillow.com/webtools/neighborhood-data/)
14
+ * [GetDemographics](http://www.zillow.com/howto/api/GetDemographics.htm)
15
+ * [GetRegionChildren](http://www.zillow.com/howto/api/GetRegionChildren.htm)
16
+ * [GetRegionChart](http://www.zillow.com/howto/api/GetRegionChart.htm)
17
+
18
+ ### [Mortgage API](http://www.zillow.com/howto/api/MortgageAPIOverview.htm)
19
+ * [GetRateSummary](http://www.zillow.com/howto/api/GetRateSummary.htm)
20
+ * [GetMonthlyPayments](http://www.zillow.com/howto/api/GetMonthlyPayments.htm)
21
+
22
+ ### [Property Details API](http://www.zillow.com/howto/api/PropertyDetailsAPIOverview.htm)
23
+ * [GetDeepSearchResults](http://www.zillow.com/howto/api/GetDeepSearchResults.htm)
24
+ * [GetDeepComps](http://www.zillow.com/howto/api/GetDeepComps.htm)
25
+ * [GetUpdatedPropertyDetails](http://www.zillow.com/howto/api/GetUpdatedPropertyDetails.htm)
26
+
27
+ ### [Postings API](http://www.zillow.com/howto/api/GetRegionPostings.htm)
28
+ * [GetRegionPostings](http://www.zillow.com/howto/api/GetRegionPostings.htm)
29
+
30
+ # Installing
31
+
32
+ gem install rubillow
33
+
34
+ or add the following to your Gemfile:
35
+
36
+ gem "rubillow"
37
+
38
+ # Examples
39
+
40
+ Adding setup into an initializer:
41
+
42
+ Rubillow.configure do |configuration|
43
+ configuration.zwsid = "abcd1234"
44
+ end
45
+
46
+ Getting property Zestimate:
47
+
48
+ property = Rubillow::HomeValuation.zestimate({ :zpid => '48749425' })
49
+ if property.success?
50
+ puts property.price
51
+ end
52
+
53
+ # Documentation
54
+
55
+ You should find the documentation for your version of Rubillow on [Rubygems](http://rubygems.org/gems/rubillow).
56
+
57
+ # More Information
58
+
59
+ * [Rubygems](http://rubygems.org/gems/rubillow)
60
+ * [Issues](http://github.com/synewaves/rubillow/issues)
61
+
62
+ # License
63
+
64
+ Rubillow uses the MIT license. See LICENSE for more details.
data/Rakefile ADDED
@@ -0,0 +1,38 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ # require 'rcov/rcovtask'
4
+ require "yard"
5
+
6
+ desc "Run specs"
7
+ RSpec::Core::RakeTask.new do |t|
8
+ t.pattern = "spec/**/*_spec.rb"
9
+ end
10
+
11
+ desc "Run specs with coverage"
12
+ RSpec::Core::RakeTask.new("spec_rcov") do |t|
13
+ t.pattern = "spec/**/*_spec.rb"
14
+ t.rcov = true
15
+ t.rcov_opts = %w{--exclude spec,gems}
16
+ t.rcov_opts << %[-o "coverage"]
17
+ end
18
+
19
+ # RSpec::Rake::SpecTask.new("rcov_spec") do |t|
20
+ # t.spec_files = FileList['spec/**/*_spec.rb']
21
+ # t.spec_opts = ['--color']
22
+ # t.rcov = true
23
+ # t.rcov_opts = ['--exclude', '^spec,/gems/']
24
+ # end
25
+
26
+ # desc 'Performs code coverage.'
27
+ # Rcov::RcovTask.new do |t|
28
+ # t.test_files = FileList['spec/*_spec.rb']
29
+ # t.verbose = true
30
+ # end
31
+
32
+ # desc "Clean files generated by rake tasks"
33
+ # task :clobber => [:clobber_rcov]
34
+
35
+ YARD::Rake::YardocTask.new do |t|
36
+ end
37
+
38
+ task :default => :spec
data/lib/rubillow.rb ADDED
@@ -0,0 +1,29 @@
1
+ require "rubillow/version"
2
+ require "rubillow/configuration"
3
+ require "rubillow/request"
4
+ require "rubillow/home_valuation"
5
+ require "rubillow/mortgage"
6
+ require "rubillow/postings"
7
+ require "rubillow/property_details"
8
+ require "rubillow/neighborhood"
9
+ require "rubillow/models"
10
+
11
+ # Top-level interface to Rubillow
12
+ module Rubillow
13
+ # Call this method to modify defaults in your initializers.
14
+ #
15
+ # @example
16
+ # Rubillow.configure do |configuration|
17
+ # configuration.zwsid = "abcd1234"
18
+ # end
19
+ #
20
+ # @yield [Configuration] The current configuration.
21
+ def self.configure
22
+ yield(configuration)
23
+ end
24
+
25
+ # @return [Configuration] Current configuration.
26
+ def self.configuration
27
+ @@configuration ||= Configuration.new
28
+ end
29
+ end
@@ -0,0 +1,31 @@
1
+ module Rubillow
2
+ # Configuration options
3
+ class Configuration
4
+ # @return [String] HTTP host (defaults to +www.zillow.com+)
5
+ attr_accessor :host
6
+
7
+ # @return [Integer] HTTP port (defaults to +80+)
8
+ attr_accessor :port
9
+
10
+ # @return [String] relative service path (defaults to +webservice/+)
11
+ attr_accessor :path
12
+
13
+ # @return [String] Zillow API key. See {http://www.zillow.com/howto/api/APIOverview.htm}.
14
+ attr_accessor :zwsid
15
+
16
+ # @return [Integer] HTTP connection timeout seconds (defaults to +2+)
17
+ attr_accessor :http_open_timeout
18
+
19
+ # @return [Integer] HTTP read timeout seconds (defaults to +2+)
20
+ attr_accessor :http_read_timeout
21
+
22
+ # @private
23
+ def initialize
24
+ self.host = "www.zillow.com"
25
+ self.port = 80
26
+ self.path = "webservice/"
27
+ self.http_open_timeout = 2
28
+ self.http_read_timeout = 2
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,141 @@
1
+ module Rubillow
2
+ # Interface for the Home Valuation API.
3
+ #
4
+ # Read the more about this API at: {http://www.zillow.com/howto/api/HomeValuationAPIOverview.htm}
5
+ class HomeValuation
6
+ # Retrieve a property by the specified address.
7
+ #
8
+ # Read more at: {http://www.zillow.com/howto/api/GetSearchResults.htm}.
9
+ #
10
+ # @example
11
+ # data = Rubillow::HomeValuation.search_results({ :address => '2114 Bigelow Ave', :citystatezip => 'Seattle, WA' })
12
+ #
13
+ # if data.success?
14
+ # puts data.zpid # "48749425"
15
+ # puts data.price # "1032000"
16
+ # end
17
+ #
18
+ # @param [Hash] options The options for the API request.
19
+ # @option options [String] :address The address of the property to search. (required)
20
+ # @option options [String] :citystatezip The city+state combination and/or ZIP code for which to search. Note that giving both city and state is required. Using just one will not work. (required)
21
+ # @return [Models::SearchResult] Property information.
22
+ def self.search_results(options = {})
23
+ options = {
24
+ :zws_id => Rubillow.configuration.zwsid,
25
+ :address => nil,
26
+ :citystatezip => nil,
27
+ }.merge!(options)
28
+
29
+ if options[:address].nil?
30
+ raise ArgumentError, "The address option is required"
31
+ end
32
+ if options[:citystatezip].nil?
33
+ raise ArgumentError, "The citystatezip option is required"
34
+ end
35
+
36
+ Models::SearchResult.new(Rubillow::Request.get("GetSearchResults", options))
37
+ end
38
+
39
+ # Retrieve a zestimate for the specified property.
40
+ #
41
+ # Read more at: {http://www.zillow.com/howto/api/GetZestimate.htm}.
42
+ #
43
+ # @example
44
+ # data = Rubillow::HomeValuation.zestimate({ :zpid => '48749425' })
45
+ #
46
+ # if data.success?
47
+ # puts data.zpid # "48749425"
48
+ # puts data.price # "1032000"
49
+ # puts data.value_change # "5900"
50
+ # end
51
+ #
52
+ # @param [Hash] options The options for the API request.
53
+ # @option options [Integer] :zpid The Zillow Property ID of the property. (required)
54
+ # @return [Models::SearchResult] Property pricing information.
55
+ def self.zestimate(options = {})
56
+ options = {
57
+ :zws_id => Rubillow.configuration.zwsid,
58
+ :zpid => nil,
59
+ }.merge!(options)
60
+
61
+ if options[:zpid].nil?
62
+ raise ArgumentError, "The zpid option is required"
63
+ end
64
+
65
+ Models::SearchResult.new(Rubillow::Request.get("GetZestimate", options))
66
+ end
67
+
68
+ # Retrieve a chart for the specified property.
69
+ #
70
+ # Read more at: {http://www.zillow.com/howto/api/GetChart.htm}.
71
+ #
72
+ # @example
73
+ # chart = Rubillow::HomeValuation.chart({ :zpid => '48749425', :height => '300', :width => '150' })
74
+ #
75
+ # if chart.success?
76
+ # puts chart.to_html
77
+ # end
78
+ #
79
+ # @param [Hash] options The options for the API request.
80
+ # @option options [Integer] :zpid The Zillow Property ID of the property. (required)
81
+ # @option options [String] :unit-type Show the percent change ("percent"), or dollar change ("dollar"). (required)
82
+ # @option options [Integer] :width The width of the image; between 200 and 600, inclusive.
83
+ # @option options [Integer] :height The height of the image; between 100 and 300, inclusive.
84
+ # @option options [Integer] :chartDuration The duration of past data to show. Valid values are "1year", "5years" and "10years". If unspecified, the value defaults to "1year".
85
+ # @return [Models::PropertyChart] Property chart.
86
+ def self.chart(options = {})
87
+ options = {
88
+ :zws_id => Rubillow.configuration.zwsid,
89
+ :zpid => nil,
90
+ :unit_type => nil,
91
+ :width => nil,
92
+ :height => nil,
93
+ :chartDuration => nil,
94
+ }.merge!(options)
95
+
96
+ if options[:zpid].nil?
97
+ raise ArgumentError, "The zpid option is required"
98
+ end
99
+ if options[:unit_type].nil?
100
+ raise ArgumentError, "The unit_type option is required"
101
+ end
102
+
103
+ Models::PropertyChart.new(Rubillow::Request.get("GetChart", options))
104
+ end
105
+
106
+ # Retrieve a list of comps for the specified property.
107
+ #
108
+ # Read more at: {http://www.zillow.com/howto/api/GetComps.htm}.
109
+ #
110
+ # @example
111
+ # data = Rubillow::HomeValuation.comps({ :zpid => '48749425', :count => 5 })
112
+ #
113
+ # if data.success?
114
+ # puts data.principal.price # "1032000"
115
+ # data.comparables.each do |comp|
116
+ # puts comparables.price
117
+ # end
118
+ # end
119
+ #
120
+ # @param [Hash] options The options for the API request.
121
+ # @option options [Integer] :zpid The Zillow Property ID of the property. (required)
122
+ # @option options [Integer] :count The number of comps to return, between 1 and 25 inclusive. (required)
123
+ # @return [Models::Comps] Comps Property information and comps list.
124
+ def self.comps(options = {})
125
+ options = {
126
+ :zws_id => Rubillow.configuration.zwsid,
127
+ :zpid => nil,
128
+ :count => nil,
129
+ }.merge!(options)
130
+
131
+ if options[:zpid].nil?
132
+ raise ArgumentError, "The zpid option is required"
133
+ end
134
+ if options[:count].nil?
135
+ raise ArgumentError, "The count option is required"
136
+ end
137
+
138
+ Models::Comps.new(Rubillow::Request.get("GetComps", options))
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,83 @@
1
+ require "nokogiri"
2
+ require "active_support/core_ext/string"
3
+ require "active_support/inflector"
4
+
5
+ module Rubillow
6
+ # Sub module for returned and parsed web service data
7
+ module Models
8
+ # Base class for data models
9
+ class Base
10
+ # @return [String] the raw XML content from the service
11
+ attr_accessor :xml
12
+
13
+ # @private
14
+ # @return [Nokogiri::XML::Reader] xml parser
15
+ attr_accessor :parser
16
+
17
+ # @return [String] response message
18
+ attr_accessor :message
19
+
20
+ # @return [Integer] response code
21
+ attr_accessor :code
22
+
23
+ # @return [Boolean] nearing API's daily request limit
24
+ attr_accessor :near_limit
25
+
26
+ # @private
27
+ # Initialize the model
28
+ #
29
+ # @param [String] xml the raw XML from the service
30
+ def initialize(xml)
31
+ if !xml.blank?
32
+ @xml = xml
33
+ @parser = Nokogiri::XML(xml) { |cfg| cfg.noblanks }
34
+ parse
35
+ else
36
+ @code = -1
37
+ @message = 'Error connecting to remote service.'
38
+ end
39
+ end
40
+
41
+ # Was the request successful?
42
+ # @return [Boolean] +true+ on successful request
43
+ def success?
44
+ @code.to_i == 0
45
+ end
46
+
47
+ protected
48
+
49
+ # @private
50
+ # Parses the xml content
51
+ def parse
52
+ @message = @parser.xpath('//message/text').text
53
+ @code = @parser.xpath('//message/code').text.to_i
54
+
55
+ limit = @parser.xpath('//message/limit-warning')
56
+ @near_limit = !limit.empty? && limit.text.downcase == "true"
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ require "rubillow/models/zpidable"
63
+ require "rubillow/models/linkable"
64
+ require "rubillow/models/addressable"
65
+ require "rubillow/models/zestimateable"
66
+ require "rubillow/models/property_basics"
67
+ require "rubillow/models/images"
68
+ require "rubillow/models/search_result"
69
+ require "rubillow/models/chart"
70
+ require "rubillow/models/property_chart"
71
+ require "rubillow/models/comps"
72
+ require "rubillow/models/rate_summary"
73
+ require "rubillow/models/monthly_payments"
74
+ require "rubillow/models/postings"
75
+ require "rubillow/models/posting"
76
+ require "rubillow/models/deep_search_result"
77
+ require "rubillow/models/deep_comps"
78
+ require "rubillow/models/updated_property_details"
79
+ require "rubillow/models/demographics"
80
+ require "rubillow/models/demographic_value"
81
+ require "rubillow/models/region_children"
82
+ require "rubillow/models/region_chart"
83
+ require "rubillow/models/region"