Class: PublicStorage::Facility

Inherits:
Object
  • Object
show all
Defined in:
lib/publicstorage/facility.rb

Overview

Constant Summary collapse

SITEMAP_URL =
'https://www.publicstorage.com/sitemap_0-product.xml'
DEFAULT_PHONE =
'1-800-742-8048'
DEFAULT_EMAIL =
'customerservice@publicstorage.com'
NAME_SELECTOR =
'.plp-page-header'
PRICE_SELECTOR =
'.units-results-section .unit-list-group .unit-list-item'
LD_SELECTOR =
'script[type="application/ld+json"]'
ID_REGEX =
/(?<id>\d+)\.html/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id:, url:, name:, address:, geocode:, phone: DEFAULT_PHONE, email: DEFAULT_EMAIL, prices: []) ⇒ Facility

Returns a new instance of Facility.

Parameters:

  • id (String)
  • url (String)
  • name (String)
  • address (Address)
  • geocode (Geocode)
  • prices (Array<Price>) (defaults to: [])


124
125
126
127
128
129
130
131
132
133
# File 'lib/publicstorage/facility.rb', line 124

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

#addressAddress

Returns:



39
40
41
# File 'lib/publicstorage/facility.rb', line 39

def address
  @address
end

#emailString

Returns:

  • (String)


35
36
37
# File 'lib/publicstorage/facility.rb', line 35

def email
  @email
end

#geocodeGeocode

Returns:



43
44
45
# File 'lib/publicstorage/facility.rb', line 43

def geocode
  @geocode
end

#idInteger

Returns:

  • (Integer)


19
20
21
# File 'lib/publicstorage/facility.rb', line 19

def id
  @id
end

#nameString

Returns:

  • (String)


27
28
29
# File 'lib/publicstorage/facility.rb', line 27

def name
  @name
end

#phoneString

Returns:

  • (String)


31
32
33
# File 'lib/publicstorage/facility.rb', line 31

def phone
  @phone
end

#pricesArray<Price>

Returns:



47
48
49
# File 'lib/publicstorage/facility.rb', line 47

def prices
  @prices
end

#urlString

Returns:

  • (String)


23
24
25
# File 'lib/publicstorage/facility.rb', line 23

def url
  @url
end

Class Method Details

.crawlObject



103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/publicstorage/facility.rb', line 103

def self.crawl
  sitemap.links.each do |link|
    url = link.loc

    facility = fetch(url:)
    puts facility.text

    facility.prices.each do |price|
      puts price.text
    end

    puts
  end
end

.fetch(url:) ⇒ Facility

Parameters:

  • url (String)

Returns:



57
58
59
60
# File 'lib/publicstorage/facility.rb', line 57

def self.fetch(url:)
  document = Crawler.html(url:)
  parse(url:, document:)
end

.parse(url:, document:) ⇒ Facility

Parameters:

  • document (NokoGiri::XML::Document)

Returns:



65
66
67
68
69
70
71
72
73
74
# File 'lib/publicstorage/facility.rb', line 65

def self.parse(url:, document:)
  data = parse_ld(document: document)
  id = parse_id(data: data)
  name = parse_name(document: document)
  address = Address.parse(data: data['address'])
  geocode = Geocode.parse(data: data['geo'])
  prices = parse_prices(document: document)

  new(id:, url:, name:, address:, geocode:, prices:)
end

.parse_id(data:) ⇒ Integer

Parameters:

  • data (Hash)

Returns:

  • (Integer)


79
80
81
# File 'lib/publicstorage/facility.rb', line 79

def self.parse_id(data:)
  Integer(data['url'].match(ID_REGEX)[:id])
end

.parse_ld(document:) ⇒ Hash

Parameters:

  • document (NokoGiri::XML::Document)

Returns:

  • (Hash)


99
100
101
# File 'lib/publicstorage/facility.rb', line 99

def self.parse_ld(document:)
  JSON.parse(document.at_css(LD_SELECTOR).text).find { |entry| entry['@type'] == 'SelfStorage' }
end

.parse_name(document:) ⇒ String

Parameters:

  • document (NokoGiri::XML::Document)

Returns:

  • (String)


86
87
88
# File 'lib/publicstorage/facility.rb', line 86

def self.parse_name(document:)
  document.at_css(NAME_SELECTOR).text.gsub(/\s+/, ' ').strip
end

.parse_prices(document:) ⇒ Object

Parameters:

  • docunent (NokoGiri::XML::Document)


92
93
94
# File 'lib/publicstorage/facility.rb', line 92

def self.parse_prices(document:)
  document.css(PRICE_SELECTOR).map { |element| Price.parse(element:) }
end

.sitemapSitemap

Returns:



50
51
52
# File 'lib/publicstorage/facility.rb', line 50

def self.sitemap
  Sitemap.fetch(url: SITEMAP_URL)
end

Instance Method Details

#inspectString

Returns:

  • (String)


136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/publicstorage/facility.rb', line 136

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

#textString

Returns:

  • (String)


150
151
152
# File 'lib/publicstorage/facility.rb', line 150

def text
  "#{@id} | #{@name} | #{@address.text} | #{@geocode.text}"
end