cubesmart 0.4.0 → 0.6.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '04490c967861512d4d25fd09f917727d68f6d49f67b8c8c3c6c6cb35e49c0eec'
4
- data.tar.gz: 35323ecbb630e3124f67aa1b424a7bf9c87e9d27a48a3790238c314548b1eadc
3
+ metadata.gz: 85d1ddedfe264f2f4222c108695490f532df6c6e4ca15603793ab238ae252d6a
4
+ data.tar.gz: 9fa27011d2d71cb6a88ba3d94ea5aa66425d3c16c44a64bb598f550ebaf9e1c8
5
5
  SHA512:
6
- metadata.gz: a217dd096b6923431d7282a06fb581b87dc660d2b3c94ee778a6531c855390d314dd04846e649887b312e2da18a7f60418461bc7d74b7c91d0c2550102dff6e8
7
- data.tar.gz: e50bda05ca0c0944682c1c759ffff34dd32042a9739d527f55de1d7d8826893d3dcfa5fd4ecd066893052bd7f1512617b3b6a02e99e404fdf81b2cc06e1dcc4e
6
+ metadata.gz: 05f744c51f4a5e7f0690e48b04241d74e042aaff8f0463c6ac2464022fd1ebda9fa31163acd342a0f61edb9b580d7fc6872d5cab5a2112ccc537922575d31c56
7
+ data.tar.gz: 5d264cd65e2a48d0bb2efe3e16aa7992b98c6f1666f74edc94495cba81d5eb156ce9aabd09ead70e0b2024f4e197844da0456e7778d4d5206c505b6f2aa536ec
data/README.md CHANGED
@@ -20,6 +20,7 @@ require 'cubesmart'
20
20
  CubeSmart.configure do |config|
21
21
  config.user_agent = '../..' # ENV['CUBESMART_USER_AGENT']
22
22
  config.timeout = 30 # ENV['CUBESMART_TIMEOUT']
23
+ config.proxy_url = 'http://user:pass@superproxy.zenrows.com:1337' # ENV['CUBESMART_PROXY_URL']
23
24
  end
24
25
  ```
25
26
 
@@ -11,9 +11,53 @@ module CubeSmart
11
11
  # @return [Integer]
12
12
  attr_accessor :timeout
13
13
 
14
+ # @attribute [rw] proxy_url
15
+ # @return [String]
16
+ attr_accessor :proxy_url
17
+
14
18
  def initialize
15
19
  @user_agent = ENV.fetch('CUBESMART_USER_AGENT', "cubesmart.rb/#{VERSION}")
16
20
  @timeout = Integer(ENV.fetch('CUBESMART_TIMEOUT', 60))
21
+ @proxy_url = ENV.fetch('CUBESMART_PROXY_URL', nil)
22
+ end
23
+
24
+ # @return [Boolean]
25
+ def proxy?
26
+ !@proxy_url.nil?
27
+ end
28
+
29
+ # @return [URI]
30
+ def proxy_uri
31
+ @proxy_uri ||= URI.parse(proxy_url) if proxy?
32
+ end
33
+
34
+ # @return [Integer]
35
+ def proxy_port
36
+ proxy_uri&.port
37
+ end
38
+
39
+ def proxy_host
40
+ proxy_uri&.host
41
+ end
42
+
43
+ # @return [String]
44
+ def proxy_scheme
45
+ proxy_uri&.scheme
46
+ end
47
+
48
+ # @return [String]
49
+ def proxy_username
50
+ proxy_uri&.user
51
+ end
52
+
53
+ # @return [String]
54
+ def proxy_password
55
+ proxy_uri&.password
56
+ end
57
+
58
+ # @return [Array]
59
+ def proxy_options
60
+ [proxy_host, proxy_port, proxy_username, proxy_password]
17
61
  end
18
62
  end
19
63
  end
@@ -27,6 +27,8 @@ module CubeSmart
27
27
  connection = HTTP.persistent(HOST)
28
28
  connection = connection.headers('User-Agent' => config.user_agent) if config.user_agent
29
29
  connection = connection.timeout(config.timeout) if config.timeout
30
+ connection = connection.via(*config.proxy_options) if config.proxy?
31
+
30
32
  connection
31
33
  end
32
34
  end
@@ -3,6 +3,8 @@
3
3
  module CubeSmart
4
4
  # The dimensions (width + depth + sqft) of a price.
5
5
  class Dimensions
6
+ DEFAULT_HEIGHT = 8 # feet
7
+
6
8
  # @attribute [rw] depth
7
9
  # @return [Integer]
8
10
  attr_accessor :depth
@@ -11,17 +13,17 @@ module CubeSmart
11
13
  # @return [Integer]
12
14
  attr_accessor :width
13
15
 
14
- # @attribute [rw] sqft
16
+ # @attribute [rw] height
15
17
  # @return [Integer]
16
- attr_accessor :sqft
18
+ attr_accessor :height
17
19
 
18
20
  # @param depth [Integer]
19
21
  # @param width [Integer]
20
- # @param sqft [Integer]
21
- def initialize(depth:, width:, sqft:)
22
+ # @param height [Integer]
23
+ def initialize(depth:, width:, height: DEFAULT_HEIGHT)
22
24
  @depth = depth
23
25
  @width = width
24
- @sqft = sqft
26
+ @height = height
25
27
  end
26
28
 
27
29
  # @return [String]
@@ -29,11 +31,21 @@ module CubeSmart
29
31
  props = [
30
32
  "depth=#{@depth.inspect}",
31
33
  "width=#{@width.inspect}",
32
- "sqft=#{@sqft.inspect}"
34
+ "height=#{@height.inspect}"
33
35
  ]
34
36
  "#<#{self.class.name} #{props.join(' ')}>"
35
37
  end
36
38
 
39
+ # @return [Integer]
40
+ def sqft
41
+ Integer(@width * @depth)
42
+ end
43
+
44
+ # @return [Integer]
45
+ def cuft
46
+ Integer(@width * @depth * @height)
47
+ end
48
+
37
49
  # @return [String] e.g. "10' × 10' (100 sqft)"
38
50
  def text
39
51
  "#{format('%g', @width)}' × #{format('%g', @depth)}' (#{@sqft} sqft)"
@@ -49,8 +61,7 @@ module CubeSmart
49
61
 
50
62
  width = Float(match[:width])
51
63
  depth = Float(match[:depth])
52
- sqft = Integer(width * depth)
53
- new(depth:, width:, sqft:)
64
+ new(depth:, width:, height: DEFAULT_HEIGHT)
54
65
  end
55
66
  end
56
67
  end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CubeSmart
4
+ # The features (e.g. climate-controlled, inside-drive-up-access, outside-drive-up-access, etc) of a price.
5
+ class Features
6
+ # @param element [Nokogiri::XML::Element]
7
+ #
8
+ # @return [Features]
9
+ def self.parse(element:)
10
+ text = element.text
11
+
12
+ new(
13
+ climate_controlled: text.include?('Climate controlled'),
14
+ inside_drive_up_access: text.include?('Inside drive-up access'),
15
+ outside_drive_up_access: text.include?('Outside drive-up access'),
16
+ first_floor_access: text.include?('1st floor access')
17
+ )
18
+ end
19
+
20
+ # @param climate_controlled [Boolean]
21
+ # @param inside_drive_up_access [Boolean]
22
+ # @param outside_drive_up_access [Boolean]
23
+ # @param first_floor_access [Boolean]
24
+ def initialize(climate_controlled:, inside_drive_up_access:, outside_drive_up_access:, first_floor_access:)
25
+ @climate_controlled = climate_controlled
26
+ @inside_drive_up_access = inside_drive_up_access
27
+ @outside_drive_up_access = outside_drive_up_access
28
+ @first_floor_access = first_floor_access
29
+ end
30
+
31
+ # @return [String]
32
+ def inspect
33
+ props = [
34
+ "climate_controlled=#{@climate_controlled}",
35
+ "inside_drive_up_access=#{@inside_drive_up_access}",
36
+ "outside_drive_up_access=#{@outside_drive_up_access}",
37
+ "first_floor_access=#{@first_floor_access}"
38
+ ]
39
+
40
+ "#<#{self.class.name} #{props.join(' ')}>"
41
+ end
42
+
43
+ # @return [String] e.g. "Climate Controlled + First Floor Access"
44
+ def text
45
+ amenities.join(' + ')
46
+ end
47
+
48
+ # @return [Array<String>]
49
+ def amenities
50
+ [].tap do |amenities|
51
+ amenities << 'Climate Controlled' if climate_controlled?
52
+ amenities << 'Inside Drive-Up Access' if inside_drive_up_access?
53
+ amenities << 'Outside Drive-Up Access' if outside_drive_up_access?
54
+ amenities << 'First Floor Access' if first_floor_access?
55
+ end
56
+ end
57
+
58
+ # @return [Boolean]
59
+ def climate_controlled?
60
+ @climate_controlled
61
+ end
62
+
63
+ # @return [Boolean]
64
+ def inside_drive_up_access?
65
+ @inside_drive_up_access
66
+ end
67
+
68
+ # @return [Boolean]
69
+ def outside_drive_up_access?
70
+ @outside_drive_up_access
71
+ end
72
+
73
+ # @return [Boolean]
74
+ def drive_up_access?
75
+ inside_drive_up_access? || outside_drive_up_access?
76
+ end
77
+
78
+ # @return [Boolean]
79
+ def first_floor_access?
80
+ @first_floor_access
81
+ end
82
+ end
83
+ end
@@ -11,16 +11,22 @@ module CubeSmart
11
11
  # @return [Dimensions]
12
12
  attr_accessor :dimensions
13
13
 
14
+ # @attribute [rw] features
15
+ # @return [Features]
16
+ attr_accessor :features
17
+
14
18
  # @attribute [rw] rates
15
19
  # @return [Rates]
16
20
  attr_accessor :rates
17
21
 
18
22
  # @param id [String]
19
23
  # @param dimensions [Dimensions]
24
+ # @param features [Features]
20
25
  # @param rates [Rates]
21
- def initialize(id:, dimensions:, rates:)
26
+ def initialize(id:, dimensions:, features:, rates:)
22
27
  @id = id
23
28
  @dimensions = dimensions
29
+ @features = features
24
30
  @rates = rates
25
31
  end
26
32
 
@@ -29,6 +35,7 @@ module CubeSmart
29
35
  props = [
30
36
  "id=#{@id.inspect}",
31
37
  "dimensions=#{@dimensions.inspect}",
38
+ "features=#{@features.inspect}",
32
39
  "rates=#{@rates.inspect}"
33
40
  ]
34
41
  "#<#{self.class.name} #{props.join(' ')}>"
@@ -36,20 +43,18 @@ module CubeSmart
36
43
 
37
44
  # @return [String] e.g. "123 | 5' × 5' (25 sqft) | $100 (street) / $90 (web)"
38
45
  def text
39
- "#{@id} | #{@dimensions.text} | #{@rates.text}"
46
+ "#{@id} | #{@dimensions.text} | #{@rates.text} | #{@features.text}"
40
47
  end
41
48
 
42
49
  # @param element [Nokogiri::XML::Element]
43
50
  #
44
51
  # @return [Price]
45
52
  def self.parse(element:)
46
- id = element.attr('id')
47
- dimensions = Dimensions.parse(element:)
48
- rates = Rates.parse(element:)
49
53
  new(
50
- id:,
51
- dimensions: dimensions,
52
- rates: rates
54
+ id: element.attr('id'),
55
+ dimensions: Dimensions.parse(element:),
56
+ features: Features.parse(element:),
57
+ rates: Rates.parse(element:)
53
58
  )
54
59
  end
55
60
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CubeSmart
4
- VERSION = '0.4.0'
4
+ VERSION = '0.6.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cubesmart
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Sylvestre
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-12-04 00:00:00.000000000 Z
11
+ date: 2024-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http
@@ -101,6 +101,7 @@ files:
101
101
  - lib/cubesmart/crawler.rb
102
102
  - lib/cubesmart/dimensions.rb
103
103
  - lib/cubesmart/facility.rb
104
+ - lib/cubesmart/features.rb
104
105
  - lib/cubesmart/fetch_error.rb
105
106
  - lib/cubesmart/geocode.rb
106
107
  - lib/cubesmart/link.rb