Class: CubeSmart::Facility

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

Overview

A facility (address + geocode + prices) on cubesmart.com.

e.g. www.cubesmart.com/arizona-self-storage/chandler-self-storage/2.html

Defined Under Namespace

Classes: ParseError

Constant Summary collapse

DEFAULT_EMAIL =
'[email protected]'
DEFAULT_PHONE =
'1-877-279-7585'
SITEMAP_URL =
'https://www.cubesmart.com/sitemap-facility.xml'
PRICE_SELECTOR =
%w[small medium large].map do |group|
  ".#{group}-group ul.csStorageSizeDimension li.csStorageSizeDimension"
end.join(', ')
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)
  • phone (String) (defaults to: DEFAULT_PHONE)
  • email (String) (defaults to: DEFAULT_EMAIL)
  • prices (Array<Price>) (defaults to: [])


100
101
102
103
104
105
106
107
108
109
# File 'lib/cubesmart/facility.rb', line 100

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:



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

def address
  @address
end

#emailString

Returns:

  • (String)


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

def email
  @email
end

#geocodeGeocode

Returns:



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

def geocode
  @geocode
end

#idString

Returns:

  • (String)


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

def id
  @id
end

#nameString

Returns:

  • (String)


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

def name
  @name
end

#phoneString

Returns:

  • (String)


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

def phone
  @phone
end

#pricesArray<Price>

Returns:



51
52
53
# File 'lib/cubesmart/facility.rb', line 51

def prices
  @prices
end

#urlString

Returns:

  • (String)


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

def url
  @url
end

Class Method Details

.fetch(url:) ⇒ Facility

Parameters:

  • url (String)

Returns:



61
62
63
64
# File 'lib/cubesmart/facility.rb', line 61

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

.parse(url:, document:) ⇒ Facility

Parameters:

  • url (String)
  • document (Nokogiri::HTML::Document)

Returns:



70
71
72
73
74
75
76
77
78
79
80
# File 'lib/cubesmart/facility.rb', line 70

def self.parse(url:, document:)
  data = parse_json_ld(document:)

  id = ID_REGEX.match(url)[:id]
  name = data['name']
  address = Address.parse(data: data['address'])
  geocode = Geocode.parse(data: data['geo'])
  prices = document.css(PRICE_SELECTOR).map { |element| Price.parse(element: element) }

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

.parse_json_ld(document:) ⇒ Hash

Parameters:

  • document (Nokogiri::HTML::Document)

Returns:

  • (Hash)

Raises:



87
88
89
90
# File 'lib/cubesmart/facility.rb', line 87

def self.parse_json_ld(document:)
  graph = JSON.parse(document.at_xpath('//script[contains(text(), "@graph")]').text)['@graph']
  graph.find { |entry| entry['@type'] == 'SelfStorage' } || raise(ParseError, 'missing @graph')
end

.sitemapSitemap

Returns:



54
55
56
# File 'lib/cubesmart/facility.rb', line 54

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

Instance Method Details

#inspectString

Returns:

  • (String)


112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/cubesmart/facility.rb', line 112

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)


126
127
128
# File 'lib/cubesmart/facility.rb', line 126

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