transparent_ruby_client 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9ccee1fb51ee40e78809ab8e96a30f8a990455f185311c67f4836427b4993381
4
+ data.tar.gz: cec0fb6f56a30a642cb699e3fa155a8a40d9967604972ddc448e98a8582009de
5
+ SHA512:
6
+ metadata.gz: b9f66d5647e3b37bb0023eb2f752316274627ef2bafb0c6597265048293473b4687511efcb26c0f24d747d2244278df0735f18e503e31d6544be4acc44f68873
7
+ data.tar.gz: 9832dc271e300d2b16f7a9148b5e2616c19d74679d6623c60bf884940e1c9e1b5227ddf69787a0e866bec559444ef64ccdea0e98557e0da3f01da7adadf49eb9
@@ -0,0 +1,179 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ require 'transparent/constants'
5
+ require 'sorbet-runtime'
6
+
7
+ module Transparent
8
+ # API wrapper/client
9
+ class Client
10
+ extend T::Sig
11
+
12
+ sig do
13
+ params(
14
+ latitude: Float,
15
+ longitude: Float,
16
+ radius_meters: Integer,
17
+ type: String,
18
+ subtype: String,
19
+ bedrooms: T.nilable(T::Array[T.untyped]),
20
+ bathrooms: T.nilable(T::Array[T.untyped]),
21
+ capacity: T.nilable(T::Array[T.untyped]),
22
+ pool: T.nilable(T::Boolean),
23
+ air_conditioning: T.nilable(T::Boolean),
24
+ kid_friendly: T.nilable(T::Boolean),
25
+ parking: T.nilable(T::Boolean),
26
+ hot_tub: T.nilable(T::Boolean),
27
+ active_days: T.nilable(T::Boolean)
28
+ ).returns(Hash)
29
+ end
30
+ def initialize(
31
+ latitude:,
32
+ longitude:,
33
+ radius_meters:,
34
+ type:,
35
+ subtype:,
36
+ bedrooms: [],
37
+ bathrooms: [],
38
+ capacity: [],
39
+ pool: nil,
40
+ air_conditioning: nil,
41
+ kid_friendly: nil,
42
+ parking: nil,
43
+ hot_tub: nil,
44
+ active_days: nil
45
+ )
46
+ @latitude = latitude
47
+ @longitude = longitude
48
+ @radius_meters = radius_meters
49
+ @type = type
50
+ @subtype = subtype
51
+
52
+ @optional_params = {
53
+ bedrooms: normalise_list(bedrooms),
54
+ bathrooms: normalise_list(bathrooms),
55
+ capacity: normalise_list(capacity),
56
+ pool: normalise_boolean(pool),
57
+ air_conditioning: normalise_boolean(air_conditioning),
58
+ kid_friendly: normalise_boolean(kid_friendly),
59
+ parking: normalise_boolean(parking),
60
+ hot_tub: normalise_boolean(hot_tub),
61
+ active_days: active_days
62
+ }.select do |_key, value|
63
+ value && !value.to_s.empty?
64
+ end
65
+ end
66
+
67
+ def aggregated
68
+ aggregated_request.run
69
+
70
+ return { fulfilled: false } if aggregated_response.body.empty? || !aggregated_response.success?
71
+
72
+ {
73
+ fulfilled: true,
74
+ data: {
75
+ adr: aggregated_object['year_average_adr'],
76
+ occupancy: aggregated_object['year_average_occupancy']
77
+ }
78
+ }
79
+ end
80
+
81
+ def combined
82
+ parallel_listings_and_aggregated_requests.run
83
+
84
+ return { fulfilled: false } unless both_responses_are_good?
85
+
86
+ {
87
+ fulfilled: true,
88
+ data: {
89
+ adr: aggregated_object['year_average_adr'],
90
+ occupancy: aggregated_object['year_average_occupancy'],
91
+ listings: listings_object.map do |listing|
92
+ {
93
+ adr: listing['year_total_revenue'].to_f / listing['active_days'],
94
+ occupancy: listing['year_total_occupancy']
95
+ }
96
+ end
97
+ }
98
+ }
99
+ end
100
+
101
+ private
102
+
103
+ attr_reader :latitude, :longitude, :radius_meters, :type, :subtype, :optional_params
104
+
105
+ def normalise_list(value)
106
+ T.must(value).join(',')
107
+ end
108
+
109
+ def normalise_boolean(value)
110
+ return nil unless value
111
+
112
+ !!value ? 1 : 0
113
+ end
114
+
115
+ def both_responses_are_good?
116
+ [aggregated_response, listings_response].all?(&:success?) &&
117
+ [aggregated_response, listings_response].none? { |r| r.body.empty? }
118
+ end
119
+
120
+ def parallel_listings_and_aggregated_requests
121
+ return @hydra if @hydra
122
+
123
+ @hydra = Typhoeus::Hydra.new
124
+ @hydra.queue(listings_request)
125
+ @hydra.queue(aggregated_request)
126
+ @hydra
127
+ end
128
+
129
+ def aggregated_object
130
+ @aggregated_object ||= JSON.parse(aggregated_response.body)
131
+ end
132
+
133
+ def listings_object
134
+ @listings_object ||= JSON.parse(listings_response.body)
135
+ end
136
+
137
+ def aggregated_response
138
+ @aggregated_response ||= aggregated_request.response
139
+ end
140
+
141
+ def listings_response
142
+ @listings_response ||= listings_request.response
143
+ end
144
+
145
+ def listings_request
146
+ @listings_request ||= Typhoeus::Request.new(
147
+ Constants::BASE_URI + Constants::ENDPOINT_URIS[:listings],
148
+ method: :get,
149
+ headers: {
150
+ apikey: Transparent.configuration.apikey
151
+ },
152
+ params: {
153
+ latitude: latitude,
154
+ longitude: longitude,
155
+ radius_meters: radius_meters,
156
+ type: type,
157
+ subtype: subtype
158
+ }.merge(optional_params)
159
+ )
160
+ end
161
+
162
+ def aggregated_request
163
+ @aggregated_request ||= Typhoeus::Request.new(
164
+ Constants::BASE_URI + Constants::ENDPOINT_URIS[:aggregated],
165
+ method: :get,
166
+ headers: {
167
+ apikey: Transparent.configuration.apikey
168
+ },
169
+ params: {
170
+ latitude: latitude,
171
+ longitude: longitude,
172
+ radius_meters: radius_meters,
173
+ type: type,
174
+ subtype: subtype
175
+ }.merge(optional_params)
176
+ )
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,17 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Transparent
5
+ class MissingConfiguration < StandardError; end
6
+
7
+ # API configuration
8
+ class Configuration
9
+ attr_writer :apikey
10
+
11
+ def apikey
12
+ raise MissingConfiguration unless @apikey
13
+
14
+ @apikey
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ # This module will expose the API client
5
+ module Transparent
6
+ module Constants
7
+ BASE_URI = 'https://listingroiapi.seetransparent.com/'
8
+ ENDPOINT_URIS = {
9
+ aggregated: 'aggregated',
10
+ listings: 'listings'
11
+ }.freeze
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ require 'transparent/configuration'
5
+ require 'transparent/client'
6
+
7
+ # This module will expose the API client
8
+ module Transparent
9
+ def self.configure
10
+ yield(configuration)
11
+ end
12
+
13
+ def self.configuration
14
+ @configuration ||= Configuration.new
15
+ end
16
+ end
metadata ADDED
@@ -0,0 +1,130 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: transparent_ruby_client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.4
5
+ platform: ruby
6
+ authors:
7
+ - Lavanda
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-06-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sorbet-runtime
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.5'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rubocop
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.85.1
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.85.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.9'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.9'
55
+ - !ruby/object:Gem::Dependency
56
+ name: webmock
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.8'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.8'
69
+ - !ruby/object:Gem::Dependency
70
+ name: typhoeus
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.4'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.4'
83
+ - !ruby/object:Gem::Dependency
84
+ name: sorbet
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.5'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.5'
97
+ description: A ruby client for https://listingroiapi.seetransparent.com/
98
+ email:
99
+ executables: []
100
+ extensions: []
101
+ extra_rdoc_files: []
102
+ files:
103
+ - lib/transparent.rb
104
+ - lib/transparent/client.rb
105
+ - lib/transparent/configuration.rb
106
+ - lib/transparent/constants.rb
107
+ homepage: https://rubygems.org/gems/transparent_ruby_client
108
+ licenses:
109
+ - MIT
110
+ metadata: {}
111
+ post_install_message:
112
+ rdoc_options: []
113
+ require_paths:
114
+ - lib
115
+ required_ruby_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ requirements: []
126
+ rubygems_version: 3.1.2
127
+ signing_key:
128
+ specification_version: 4
129
+ summary: A ruby client for https://listingroiapi.seetransparent.com/
130
+ test_files: []