rubillow 0.0.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.
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
@@ -0,0 +1,37 @@
1
+ module Rubillow
2
+ module Models
3
+ # A posting
4
+ class Posting < Base
5
+ include Zpidable
6
+ include Addressable
7
+ include Linkable
8
+ include PropertyBasics
9
+ include Images
10
+
11
+ # @return [Date] last date data was refreshed.
12
+ attr_accessor :last_refreshed_date
13
+
14
+ # @return [String] price
15
+ attr_accessor :price
16
+
17
+ protected
18
+
19
+ # @private
20
+ def parse
21
+ super
22
+
23
+ return if !success?
24
+
25
+ property = @parser.xpath('//property').first
26
+ extract_zpid(property)
27
+ extract_links(property)
28
+ extract_address(property)
29
+ extract_property_basics(property)
30
+ extract_images(property)
31
+
32
+ @last_refreshed_date = Date.strptime(@parser.xpath('//lastRefreshedDate').text, "%Y-%m-%d")
33
+ @price = @parser.xpath('//price').text
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,64 @@
1
+ module Rubillow
2
+ module Models
3
+ # List of postings
4
+ class Postings < Base
5
+ include Linkable
6
+
7
+ # @return [String] region id.
8
+ attr_accessor :region_id
9
+
10
+ # @return [Array] postings with MakeMeMove status ({Models::Posting}).
11
+ attr_accessor :make_me_move
12
+
13
+ # @return [Array] postings with FSBA status ({Models::Posting}).
14
+ attr_accessor :for_sale_by_owner
15
+
16
+ # @return [Array] postings with FSBO status ({Models::Posting}).
17
+ attr_accessor :for_sale_by_agent
18
+
19
+ # @return [Array] postings with reporting status ({Models::Posting}).
20
+ attr_accessor :report_for_sale
21
+
22
+ # @return [Array] postings with for rent status ({Models::Posting}).
23
+ attr_accessor :for_rent
24
+
25
+ protected
26
+
27
+ # @private
28
+ def parse
29
+ super
30
+
31
+ return if !success?
32
+
33
+ @region_id = @parser.xpath('//regionId').text
34
+
35
+ extract_links(@parser)
36
+
37
+ @make_me_move = []
38
+ @parser.xpath('//response/makeMeMove/result').each do |elm|
39
+ @make_me_move << Posting.new(elm.to_xml)
40
+ end
41
+
42
+ @for_sale_by_owner = []
43
+ @parser.xpath('//response/forSaleByOwner/result').each do |elm|
44
+ @for_sale_by_owner << Posting.new(elm.to_xml)
45
+ end
46
+
47
+ @for_sale_by_agent = []
48
+ @parser.xpath('//response/forSaleByAgent/result').each do |elm|
49
+ @for_sale_by_agent << Posting.new(elm.to_xml)
50
+ end
51
+
52
+ @report_for_sale = []
53
+ @parser.xpath('//response/reportForSale/result').each do |elm|
54
+ @report_for_sale << Posting.new(elm.to_xml)
55
+ end
56
+
57
+ @for_rent = []
58
+ @parser.xpath('//response/forRent/result').each do |elm|
59
+ @for_rent << Posting.new(elm.to_xml)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,36 @@
1
+ module Rubillow
2
+ module Models
3
+ # Common data for responses containing property information
4
+ module PropertyBasics
5
+ # @return [String] property type
6
+ attr_accessor :use_code
7
+
8
+ # @return [String] Size of lot in square feet
9
+ attr_accessor :lot_size_square_feet
10
+
11
+ # @return [String] Size of property in square feet
12
+ attr_accessor :finished_square_feet
13
+
14
+ # @return [String] number of bathrooms
15
+ attr_accessor :bathrooms
16
+
17
+ # @return [String] number of bedrooms
18
+ attr_accessor :bedrooms
19
+
20
+ # @return [String] total number of rooms
21
+ attr_accessor :total_rooms
22
+
23
+ protected
24
+
25
+ # @private
26
+ def extract_property_basics(xml)
27
+ @use_code = xml.xpath('//useCode').text
28
+ @lot_size_square_feet = xml.xpath('//lotSizeSqFt').text
29
+ @finished_square_feet = xml.xpath('//finishedSqFt').text
30
+ @bathrooms = xml.xpath('//bathrooms').text
31
+ @bedrooms = xml.xpath('//bedrooms').text
32
+ @total_rooms = xml.xpath('//totalRooms').text
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,26 @@
1
+ module Rubillow
2
+ module Models
3
+ # Chart for a property
4
+ class PropertyChart < Chart
5
+ # @return [String] url for chart
6
+ attr_accessor :graphs_and_data
7
+
8
+ # Returns HTML for the chart.
9
+ # @return [String] chart HTML.
10
+ def to_html
11
+ "<a href='#{@graphs_and_data}'>" + super + "</a>"
12
+ end
13
+
14
+ protected
15
+
16
+ # @private
17
+ def parse
18
+ super
19
+
20
+ return if !success?
21
+
22
+ @graphs_and_data = @parser.xpath('//response/graphsanddata').text
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,38 @@
1
+ module Rubillow
2
+ module Models
3
+ # Rate summary information
4
+ class RateSummary < Base
5
+ # @return [Hash] today's rates (:thirty_year_fixed, :fifteen_year_fixed, :five_one_arm).
6
+ #
7
+ # @example
8
+ # today[:thirty_year_fixed]
9
+ #
10
+ attr_accessor :today
11
+
12
+ # @return [Hash] last week's rates (:thirty_year_fixed, :fifteen_year_fixed, :five_one_arm).
13
+ #
14
+ # @example
15
+ # last_week[:thirty_year_fixed]
16
+ #
17
+ attr_accessor :last_week
18
+
19
+ protected
20
+
21
+ # @private
22
+ def parse
23
+ super
24
+
25
+ return if !success?
26
+
27
+ @today = {}
28
+ @last_week = {}
29
+ @today[:thiry_year_fixed] = @parser.xpath('//today/rate[@loanType="thirtyYearFixed"]').text
30
+ @today[:fifteen_year_fixed] = @parser.xpath('//today/rate[@loanType="fifteenYearFixed"]').text
31
+ @today[:five_one_arm] = @parser.xpath('//today/rate[@loanType="fiveOneARM"]').text
32
+ @last_week[:thiry_year_fixed] = @parser.xpath('//lastWeek/rate[@loanType="thirtyYearFixed"]').text
33
+ @last_week[:fifteen_year_fixed] = @parser.xpath('//lastWeek/rate[@loanType="fifteenYearFixed"]').text
34
+ @last_week[:five_one_arm] = @parser.xpath('//lastWeek/rate[@loanType="fiveOneARM"]').text
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,44 @@
1
+ module Rubillow
2
+ module Models
3
+ # Region information.
4
+ class Region < Base
5
+ # @return [String] region id.
6
+ attr_accessor :id
7
+
8
+ # @return [String] state.
9
+ attr_accessor :state
10
+
11
+ # @return [String] city.
12
+ attr_accessor :city
13
+
14
+ # @return [String] neighborhood.
15
+ attr_accessor :neighborhood
16
+
17
+ # @return [String] latitude.
18
+ attr_accessor :latitude
19
+
20
+ # @return [String] longitude.
21
+ attr_accessor :longitude
22
+
23
+ # @return [String] ZMM rate URL.
24
+ attr_accessor :zmmrateurl
25
+
26
+ protected
27
+
28
+ # @private
29
+ def parse
30
+ super
31
+
32
+ return if !success?
33
+
34
+ @id = @parser.xpath('//id').text
35
+ @state = @parser.xpath('//state').text
36
+ @city = @parser.xpath('//city').text
37
+ @neighborhood = @parser.xpath('//neighborhood').text
38
+ @latitude = @parser.xpath('//latitude').text
39
+ @longitude = @parser.xpath('//longitude').text
40
+ @zmmrateurl = @parser.xpath('//zmmrateurl').text
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,30 @@
1
+ module Rubillow
2
+ module Models
3
+ # Chart for a region
4
+ class RegionChart < Chart
5
+ include Linkable
6
+
7
+ # @return [String] url for chart
8
+ attr_accessor :link
9
+
10
+ # Returns HTML for the chart.
11
+ # @return [String] chart HTML.
12
+ def to_html
13
+ "<a href='#{@link}'>" + super + "</a>"
14
+ end
15
+
16
+ protected
17
+
18
+ # @private
19
+ def parse
20
+ super
21
+
22
+ return if !success?
23
+
24
+ extract_links(@parser)
25
+
26
+ @link = @parser.xpath('//response/link').text
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,30 @@
1
+ module Rubillow
2
+ module Models
3
+ # List of sub-regions for a region
4
+ class RegionChildren < Base
5
+ # @return [Models::Region] top-level region
6
+ attr_accessor :region
7
+
8
+ # @return [Array] sub-level regions ({Models::Region})
9
+ attr_accessor :regions
10
+
11
+ protected
12
+
13
+ # @private
14
+ def parse
15
+ super
16
+
17
+ return if !success?
18
+
19
+ @region = Region.new(@parser.xpath('//response/region').to_xml)
20
+
21
+ @regions = []
22
+ @parser.xpath('//response/list').children.each do |region|
23
+ if region.name == "region"
24
+ @regions << Region.new(region.to_xml)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,19 @@
1
+ module Rubillow
2
+ module Models
3
+ # Property search results
4
+ class SearchResult < Base
5
+ include Zestimateable
6
+
7
+ protected
8
+
9
+ # @private
10
+ def parse
11
+ super
12
+
13
+ return if !success?
14
+
15
+ extract_zestimate(@parser)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,87 @@
1
+ module Rubillow
2
+ module Models
3
+ # List of updated attributes for a property.
4
+ class UpdatedPropertyDetails < Base
5
+ include Zpidable
6
+ include Addressable
7
+ include Linkable
8
+ include Images
9
+
10
+ # @return [Hash] number of page views (:current_month, :total).
11
+ #
12
+ # @example
13
+ # puts page_views[:current_month]
14
+ #
15
+ attr_accessor :page_views
16
+
17
+ # @return [String] price.
18
+ attr_accessor :price
19
+
20
+ # @return [String] neighborhood.
21
+ attr_accessor :neighborhood
22
+
23
+ # @return [String] elementary school's name.
24
+ attr_accessor :elementary_school
25
+
26
+ # @return [String] middle school's name.
27
+ attr_accessor :middle_school
28
+
29
+ # @return [String] school district's name.
30
+ attr_accessor :school_district
31
+
32
+ # @return [String] Realtor provided home description
33
+ attr_accessor :home_description
34
+
35
+ # @return [Hash] posting information
36
+ #
37
+ # @example
38
+ # posting.each do |key, value|
39
+ # end
40
+ #
41
+ attr_accessor :posting
42
+
43
+ # @return [Hash] list of edited facts
44
+ #
45
+ # @example
46
+ # edited_facts.each do |key, value|
47
+ # end
48
+ #
49
+ attr_accessor :edited_facts
50
+
51
+ protected
52
+
53
+ # @private
54
+ def parse
55
+ super
56
+
57
+ return if !success?
58
+
59
+ extract_zpid(@parser)
60
+ extract_links(@parser)
61
+ extract_address(@parser)
62
+ extract_images(@parser)
63
+
64
+ @page_views = {
65
+ :current_month => @parser.xpath('//pageViewCount/currentMonth').text,
66
+ :total => @parser.xpath('//pageViewCount/total').text
67
+ }
68
+ @price = @parser.xpath('//price').text
69
+ @neighborhood = @parser.xpath('//neighborhood').text
70
+ @school_district = @parser.xpath('//schoolDistrict').text
71
+ @elementary_school = @parser.xpath('//elementarySchool').text
72
+ @middle_school = @parser.xpath('//middleSchool').text
73
+ @home_description = @parser.xpath('//homeDescription').text
74
+
75
+ @posting = {}
76
+ @parser.xpath('//posting').children.each do |elm|
77
+ @posting[elm.name.underscore.to_sym] = elm.text
78
+ end
79
+
80
+ @edited_facts = {}
81
+ @parser.xpath('//editedFacts').children.each do |elm|
82
+ @edited_facts[elm.name.underscore.to_sym] = elm.text
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,77 @@
1
+ module Rubillow
2
+ module Models
3
+ # Common data for responses containing Zestimate information
4
+ module Zestimateable
5
+ include Zpidable
6
+ include Addressable
7
+ include Linkable
8
+
9
+ # @return [String] price
10
+ attr_accessor :price
11
+
12
+ # @return [Date] last updated date
13
+ attr_accessor :last_updated
14
+
15
+ # @return [Hash] valuation range (values: Strings, keys: :low, :high)
16
+ #
17
+ # @example
18
+ # puts valuation_range[:low]
19
+ #
20
+ attr_accessor :valuation_range
21
+
22
+ # @return [String] change value
23
+ attr_accessor :change
24
+
25
+ # @return [String] duration of change value
26
+ attr_accessor :change_duration
27
+
28
+ # @return [String] percentile
29
+ attr_accessor :percentile
30
+
31
+ # @return [Hash] local real estate links (values: URL strings, keys: :overview, :for_sale_by_owner, :for_sale)
32
+ #
33
+ # @example
34
+ # puts local_real_estate[:overview]
35
+ #
36
+ attr_accessor :local_real_estate
37
+
38
+ # @return [String] region name
39
+ attr_accessor :region
40
+
41
+ # @return [String] region id
42
+ attr_accessor :region_id
43
+
44
+ # @return [String] region type
45
+ attr_accessor :region_type
46
+
47
+ protected
48
+
49
+ # @private
50
+ def extract_zestimate(xml)
51
+ extract_zpid(xml)
52
+ extract_links(xml)
53
+ extract_address(xml)
54
+
55
+ @price = xml.xpath('//zestimate/amount').text
56
+ @last_updated = Date.strptime(xml.xpath('//zestimate/last-updated').text, "%m/%d/%Y")
57
+ @valuation_range = {
58
+ :low => xml.xpath('//zestimate/valuationRange/low').text,
59
+ :high => xml.xpath('//zestimate/valuationRange/high').text,
60
+ }
61
+ @change = xml.xpath('//zestimate/valueChange').text
62
+ @change_duration = xml.xpath('//zestimate/valueChange').attr('duration').value
63
+ @percentile = xml.xpath('//zestimate/percentile').text
64
+
65
+ @region = xml.xpath('//localRealEstate/region').attribute('name').value
66
+ @region_id = xml.xpath('//localRealEstate/region').attribute('id').value
67
+ @region_type = xml.xpath('//localRealEstate/region').attribute('type').value
68
+
69
+ @local_real_estate = {
70
+ :overview => xml.xpath('//localRealEstate/region/links/overview').text,
71
+ :for_sale_by_owner => xml.xpath('//localRealEstate/region/links/forSaleByOwner').text,
72
+ :for_sale => xml.xpath('//localRealEstate/region/links/forSale').text,
73
+ }
74
+ end
75
+ end
76
+ end
77
+ end