Class: UHaul::Facility
- Inherits:
-
Object
- Object
- UHaul::Facility
- Defined in:
- lib/uhaul/facility.rb
Overview
A facility (address + geocode + prices) on uhaul.com.
e.g. www.uhaul.com/Locations/Self-Storage-near-Inglewood-CA-90301/712030/
Defined Under Namespace
Classes: ParseError
Constant Summary collapse
- PRICES_SELECTOR =
'#roomTypes > ul:not([id*="VehicleStorage"]) > li'
- SITEMAP_URLS =
%w[ https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-AL.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-AK.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-AZ.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-AR.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-CA.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-CO.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-CT.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-DC.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-DE.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-FL.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-GA.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-HI.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-ID.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-IL.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-IN.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-IA.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-KS.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-KY.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-LA.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-ME.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-MD.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-MA.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-MI.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-MN.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-MS.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-MO.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-MT.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-NE.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-NV.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-NH.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-NJ.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-NM.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-NY.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-NC.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-ND.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-OH.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-OK.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-OR.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-PA.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-RI.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-SC.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-SD.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-TN.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-TX.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-UT.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-VT.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-VA.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-WA.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-WV.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-WI.ashx https://www.uhaul.com/Locations/Sitemaps/Sitemap-for-Storage-in-WY.ashx ].freeze
- DEFAULT_EMAIL =
'service@uhaul.com'
- DEFAULT_PHONE =
'+1-800-468-4285'
Instance Attribute Summary collapse
- #address ⇒ Address
- #email ⇒ String
- #geocode ⇒ Geocode?
- #id ⇒ String
- #name ⇒ String
- #phone ⇒ String
- #prices ⇒ Array<Price>
- #url ⇒ String
Class Method Summary collapse
- .fetch(url:) ⇒ Facility
- .parse(url:, document:) ⇒ Facility
- .parse_ld_json_script(document:) ⇒ Hash
- .parse_ld_json_scripts(document:) ⇒ Array<Hash>
- .sitemap ⇒ Sitemap
- .sitemaps ⇒ Array<Sitemap>
Instance Method Summary collapse
-
#initialize(id:, url:, name:, address:, geocode:, phone: DEFAULT_PHONE, email: DEFAULT_EMAIL, prices: []) ⇒ Facility
constructor
A new instance of Facility.
- #inspect ⇒ String
- #text ⇒ String
Constructor Details
#initialize(id:, url:, name:, address:, geocode:, phone: DEFAULT_PHONE, email: DEFAULT_EMAIL, prices: []) ⇒ Facility
Returns a new instance of Facility.
167 168 169 170 171 172 173 174 175 176 |
# File 'lib/uhaul/facility.rb', line 167 def initialize(id:, url:, name:, address:, geocode:, phone: DEFAULT_PHONE, email: DEFAULT_EMAIL, prices: []) @id = id @url = url @name = name @address = address @geocode = geocode @phone = phone @email = email @prices = prices end |
Instance Attribute Details
#email ⇒ String
87 88 89 |
# File 'lib/uhaul/facility.rb', line 87 def email @email end |
#id ⇒ String
71 72 73 |
# File 'lib/uhaul/facility.rb', line 71 def id @id end |
#name ⇒ String
79 80 81 |
# File 'lib/uhaul/facility.rb', line 79 def name @name end |
#phone ⇒ String
83 84 85 |
# File 'lib/uhaul/facility.rb', line 83 def phone @phone end |
#url ⇒ String
75 76 77 |
# File 'lib/uhaul/facility.rb', line 75 def url @url end |
Class Method Details
.fetch(url:) ⇒ Facility
117 118 119 120 |
# File 'lib/uhaul/facility.rb', line 117 def self.fetch(url:) document = Crawler.html(url:) parse(url:, document:) end |
.parse(url:, document:) ⇒ Facility
126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/uhaul/facility.rb', line 126 def self.parse(url:, document:) data = parse_ld_json_script(document:) id = data['@id'].match(%r{(?<id>\d+)/#schema$})[:id] name = data['name'] geocode = Geocode.parse(data: data['geo']) address = Address.parse(data: data['address']) prices = document.css(PRICES_SELECTOR).map { |element| Price.parse(element:) }.compact new(id:, url:, name:, address:, geocode:, prices:) end |
.parse_ld_json_script(document:) ⇒ Hash
144 145 146 147 148 |
# File 'lib/uhaul/facility.rb', line 144 def self.parse_ld_json_script(document:) parse_ld_json_scripts(document:).find do |data| data['@type'] == 'SelfStorage' end || raise(ParseError, 'missing ld+json') end |
.parse_ld_json_scripts(document:) ⇒ Array<Hash>
153 154 155 156 157 |
# File 'lib/uhaul/facility.rb', line 153 def self.parse_ld_json_scripts(document:) elements = document.xpath('//script[@type="application/ld+json"]') elements.map { |element| element.text.empty? ? {} : JSON.parse(element.text) } end |
.sitemap ⇒ Sitemap
102 103 104 105 |
# File 'lib/uhaul/facility.rb', line 102 def self.sitemap links = sitemaps.map(&:links).reduce(&:+) Sitemap.new(links:) end |
.sitemaps ⇒ Array<Sitemap>
108 109 110 111 112 |
# File 'lib/uhaul/facility.rb', line 108 def self.sitemaps SITEMAP_URLS.map do |url| Sitemap.fetch(url:) end end |
Instance Method Details
#inspect ⇒ String
179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/uhaul/facility.rb', line 179 def inspect props = [ "id=#{@id.inspect}", "url=#{@url.inspect}", "address=#{@address.inspect}", "geocode=#{@geocode.inspect}", "phone=#{@phone.inspect}", "email=#{@email.inspect}", "prices=#{@prices.inspect}" ] "#<#{self.class.name} #{props.join(' ')}>" end |
#text ⇒ String
193 194 195 |
# File 'lib/uhaul/facility.rb', line 193 def text "#{@id} | #{@name} | #{@phone} | #{@email} | #{@address.text} | #{@geocode ? @geocode.text : 'N/A'}" end |