blockfrost-ruby 0.1.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.
Files changed (34) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +39 -0
  5. data/CHANGELOG.md +5 -0
  6. data/Gemfile +10 -0
  7. data/LICENSE +201 -0
  8. data/README.md +134 -0
  9. data/Rakefile +8 -0
  10. data/blockfrost-ruby.gemspec +40 -0
  11. data/lib/blockfrost-ruby.rb +98 -0
  12. data/lib/blockfrostruby/config.yml +4 -0
  13. data/lib/blockfrostruby/configuration.rb +30 -0
  14. data/lib/blockfrostruby/constants.rb +9 -0
  15. data/lib/blockfrostruby/endpoints/cardano/accounts_endpoints.rb +99 -0
  16. data/lib/blockfrostruby/endpoints/cardano/addresses_endpoints.rb +47 -0
  17. data/lib/blockfrostruby/endpoints/cardano/assets_endpoints.rb +70 -0
  18. data/lib/blockfrostruby/endpoints/cardano/blocks_endpoints.rb +84 -0
  19. data/lib/blockfrostruby/endpoints/cardano/epochs_endpoints.rb +105 -0
  20. data/lib/blockfrostruby/endpoints/cardano/health_endpoints.rb +28 -0
  21. data/lib/blockfrostruby/endpoints/cardano/ledger_endpoints.rb +14 -0
  22. data/lib/blockfrostruby/endpoints/cardano/metadata_endpoints.rb +40 -0
  23. data/lib/blockfrostruby/endpoints/cardano/metrics_endpoints.rb +21 -0
  24. data/lib/blockfrostruby/endpoints/cardano/network_endpoints.rb +14 -0
  25. data/lib/blockfrostruby/endpoints/cardano/nutlink_endpoints.rb +50 -0
  26. data/lib/blockfrostruby/endpoints/cardano/pools_endpoints.rb +102 -0
  27. data/lib/blockfrostruby/endpoints/cardano/transactions_endpoints.rb +99 -0
  28. data/lib/blockfrostruby/endpoints/custom_endpoints.rb +26 -0
  29. data/lib/blockfrostruby/endpoints/ipfs/ipfs_endpoints.rb +58 -0
  30. data/lib/blockfrostruby/params.rb +66 -0
  31. data/lib/blockfrostruby/request.rb +216 -0
  32. data/lib/blockfrostruby/validator.rb +219 -0
  33. data/lib/blockfrostruby/version.rb +5 -0
  34. metadata +82 -0
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Example pool_id: pool1g3vqq9cj30cmp4e57y3jpqzuj2hl72twp5qdlh2v89ejk4vnazs
4
+
5
+ require_relative '../../../blockfrostruby/request'
6
+ require_relative '../../../blockfrostruby/params'
7
+
8
+ module PoolsEndpoints
9
+ extend Request
10
+ extend Params
11
+
12
+ # Calls get request on (@url)/pools.
13
+ #
14
+ # @param params [Hash] - params passed by user.
15
+ # @return [Hash] formatted result with status and body keys.
16
+ def get_pools(params = {})
17
+ params = Params.define_params(params, @config)
18
+ Request.get_response("#{@url}/pools", @project_id, params)
19
+ end
20
+
21
+ # Calls get request on (@url)/pools/retired.
22
+ #
23
+ # @param params [Hash] - params passed by user.
24
+ # @return [Hash] formatted result with status and body keys.
25
+ def get_list_of_retired_pools(params = {})
26
+ params = Params.define_params(params, @config)
27
+ Request.get_response("#{@url}/pools/retired", @project_id, params)
28
+ end
29
+
30
+ # Calls get request on (@url)/pools/retiring.
31
+ #
32
+ # @param params [Hash] - params passed by user.
33
+ # @return [Hash] formatted result with status and body keys.
34
+ def get_list_of_retiring_pools(params = {})
35
+ params = Params.define_params(params, @config)
36
+ Request.get_response("#{@url}/pools/retiring", @project_id, params)
37
+ end
38
+
39
+ # Calls get request on (@url)/pools/(pool_id).
40
+ #
41
+ # @param pool_id [String] will be added to the url for get request.
42
+ # @return [Hash] formatted result with status and body keys.
43
+ def get_pool(pool_id)
44
+ Request.get_response("#{@url}/pools/#{pool_id}", @project_id)
45
+ end
46
+
47
+ # Calls get request on (@url)/pools/(pool_id)/history.
48
+ #
49
+ # @param pool_id [String] will be added to the url for get request.
50
+ # @param params [Hash] - params passed by user.
51
+ # @return [Hash] formatted result with status and body keys.
52
+ def get_pool_history(pool_id, params = {})
53
+ params = Params.define_params(params, @config)
54
+ Request.get_response("#{@url}/pools/#{pool_id}/history", @project_id, params)
55
+ end
56
+
57
+ # Calls get request on (@url)/pools/(pool_id)/metadata.
58
+ #
59
+ # @param pool_id [String] will be added to the url for get request.
60
+ # @return [Hash] formatted result with status and body keys.
61
+ def get_pool_metadata(pool_id)
62
+ Request.get_response("#{@url}/pools/#{pool_id}/metadata", @project_id)
63
+ end
64
+
65
+ # Calls get request on (@url)/pools/(pool_id)/relays.
66
+ #
67
+ # @param pool_id [String] will be added to the url for get request.
68
+ # @return [Hash] formatted result with status and body keys.
69
+ def get_pool_relays(pool_id)
70
+ Request.get_response("#{@url}/pools/#{pool_id}/relays", @project_id)
71
+ end
72
+
73
+ # Calls get request on (@url)/pools/(pool_id)/delegators.
74
+ #
75
+ # @param pool_id [String] will be added to the url for get request.
76
+ # @param params [Hash] - params passed by user.
77
+ # @return [Hash] formatted result with status and body keys.
78
+ def get_pool_delegators(pool_id, params = {})
79
+ params = Params.define_params(params, @config)
80
+ Request.get_response("#{@url}/pools/#{pool_id}/delegators", @project_id, params)
81
+ end
82
+
83
+ # Calls get request on (@url)/pools/(pool_id)/blocks.
84
+ #
85
+ # @param pool_id [String] will be added to the url for get request.
86
+ # @param params [Hash] - params passed by user.
87
+ # @return [Hash] formatted result with status and body keys.
88
+ def get_pool_blocks(pool_id, params = {})
89
+ params = Params.define_params(params, @config)
90
+ Request.get_response("#{@url}/pools/#{pool_id}/blocks", @project_id, params)
91
+ end
92
+
93
+ # Calls get request on (@url)/pools/(pool_id)/updates.
94
+ #
95
+ # @param pool_id [String] will be added to the url for get request.
96
+ # @param params [Hash] - params passed by user.
97
+ # @return [Hash] formatted result with status and body keys.
98
+ def get_pool_updates(pool_id, params = {})
99
+ params = Params.define_params(params, @config)
100
+ Request.get_response("#{@url}/pools/#{pool_id}/updates", @project_id, params)
101
+ end
102
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Example hash: f6780212de5df00d10d929d0ca33dc2ff60cc57f38bd2b3cb3b2dea36f0c20b6
4
+
5
+ require_relative '../../../blockfrostruby/request'
6
+ require_relative '../../../blockfrostruby/params'
7
+
8
+ module TransactionsEndpoints
9
+ extend Request
10
+ extend Params
11
+
12
+ # Calls get request on (@url)/txs/(hash).
13
+ #
14
+ # @param hash [String] will be added to the url for get request.
15
+ # @return [Hash] formatted result with status and body keys.
16
+ def get_transaction(hash)
17
+ Request.get_response("#{@url}/txs/#{hash}", @project_id)
18
+ end
19
+
20
+ # Calls get request on (@url)/txs/(hash)/utxos.
21
+ #
22
+ # @param hash [String] will be added to the url for get request.
23
+ # @return [Hash] formatted result with status and body keys.
24
+ def get_transaction_utxos(hash)
25
+ Request.get_response("#{@url}/txs/#{hash}/utxos", @project_id)
26
+ end
27
+
28
+ # Calls get request on (@url)/txs/(hash)/stakes.
29
+ #
30
+ # @param hash [String] will be added to the url for get request.
31
+ # @return [Hash] formatted result with status and body keys.
32
+ def get_transaction_stakes(hash)
33
+ Request.get_response("#{@url}/txs/#{hash}/stakes", @project_id)
34
+ end
35
+
36
+ # Calls get request on (@url)/txs/(hash)/delegations.
37
+ #
38
+ # @param hash [String] will be added to the url for get request.
39
+ # @return [Hash] formatted result with status and body keys.
40
+ def get_transaction_delegations(hash)
41
+ Request.get_response("#{@url}/txs/#{hash}/delegations", @project_id)
42
+ end
43
+
44
+ # Calls get request on (@url)/txs/(hash)/withdrawals.
45
+ #
46
+ # @param hash [String] will be added to the url for get request.
47
+ # @return [Hash] formatted result with status and body keys.
48
+ def get_transaction_withdrawals(hash)
49
+ Request.get_response("#{@url}/txs/#{hash}/withdrawals", @project_id)
50
+ end
51
+
52
+ # Calls get request on (@url)/txs/(hash)/mirs.
53
+ #
54
+ # @param hash [String] will be added to the url for get request.
55
+ # @return [Hash] formatted result with status and body keys.
56
+ def get_transaction_mirs(hash)
57
+ Request.get_response("#{@url}/txs/#{hash}/mirs", @project_id)
58
+ end
59
+
60
+ # Calls get request on (@url)/txs/(hash)/pool_updates.
61
+ #
62
+ # @param hash [String] will be added to the url for get request.
63
+ # @return [Hash] formatted result with status and body keys.
64
+ def get_transaction_pool_updates(hash)
65
+ Request.get_response("#{@url}/txs/#{hash}/pool_updates", @project_id)
66
+ end
67
+
68
+ # Calls get request on (@url)/txs/(hash)/pool_retires.
69
+ #
70
+ # @param hash [String] will be added to the url for get request.
71
+ # @return [Hash] formatted result with status and body keys.
72
+ def get_transaction_pool_retires(hash)
73
+ Request.get_response("#{@url}/txs/#{hash}/pool_retires", @project_id)
74
+ end
75
+
76
+ # Calls get request on (@url)/txs/(hash)/metadata.
77
+ #
78
+ # @param hash [String] will be added to the url for get request.
79
+ # @return [Hash] formatted result with status and body keys.
80
+ def get_transaction_metadata(hash)
81
+ Request.get_response("#{@url}/txs/#{hash}/metadata", @project_id)
82
+ end
83
+
84
+ # Calls get request on (@url)/txs/(hash)/metadata/cbor.
85
+ #
86
+ # @param hash [String] will be added to the url for get request.
87
+ # @return [Hash] formatted result with status and body keys.
88
+ def get_transaction_metadata_in_cbor(hash)
89
+ Request.get_response("#{@url}/txs/#{hash}/metadata/cbor", @project_id)
90
+ end
91
+
92
+ # Calls post request on (@url)/txs/submit.
93
+ #
94
+ # @param transaction_data [String] will be added to the url for get request.
95
+ # @return [Hash] formatted result with status and body keys.
96
+ def submit_transaction(transaction_data)
97
+ Request.post_request_cbor("#{@url}/tx/submit", @project_id, transaction_data)
98
+ end
99
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../blockfrostruby/request'
4
+ require_relative '../../blockfrostruby/params'
5
+
6
+ module CustomEndpoints
7
+ extend Request
8
+ extend Params
9
+
10
+ # Add url from object and calls get request on specified url.
11
+ #
12
+ # @param custom_url [string] url to request. Url from object will be added before this param.
13
+ # @param params [Hash] - params passed by user.
14
+ # @return [Hash] formatted result with status and body keys.
15
+ def get_custom_url(custom_url, params = {})
16
+ params = Params.define_params(params, @config)
17
+ Request.get_response("#{@url}/#{custom_url}", @project_id, params)
18
+ end
19
+
20
+ # Return a string with a link to documentation.
21
+ #
22
+ # @return [String] link to documentation.
23
+ def get_help_info
24
+ 'See the documentation here - https://github.com/blockfrost/blockfrost-ruby'
25
+ end
26
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../blockfrostruby/request'
4
+ require_relative '../../../blockfrostruby/params'
5
+
6
+ module IPFSEndpoints
7
+ extend Request
8
+ extend Params
9
+
10
+ # Calls get request on (@url)/ipfs/pin/list
11
+ #
12
+ # @param params [Hash] - params passed by user.
13
+ # @return [Hash] formatted result with status and body keys.
14
+ def get_localstorage_pinned_objects_list(params = {})
15
+ params = Params.define_params(params, @config)
16
+ Request.get_response("#{@url}/ipfs/pin/list", @project_id, params)
17
+ end
18
+
19
+ # Calls get request on (@url)/ipfs/pin/list/(ipfs_path)
20
+ #
21
+ # @param ipfs_path [String] will be added to the url for get request.
22
+ # @return [Hash] formatted result with status and body keys.
23
+ def get_localstorage_pinned_object(ipfs_path)
24
+ Request.get_response("#{@url}/ipfs/pin/list/#{ipfs_path}", @project_id)
25
+ end
26
+
27
+ # Calls get request on (@url)/ipfs/gateway/(ipfs_path)
28
+ #
29
+ # @param ipfs_path [String] will be added to the url for get request.
30
+ # @return [Hash] formatted result with status and body keys.
31
+ def get_relay_to_ipfs_gateway(ipfs_path)
32
+ Request.get_response("#{@url}/ipfs/gateway/#{ipfs_path}", @project_id)
33
+ end
34
+
35
+ # Calls post request on (@url)/ipfs/add
36
+ #
37
+ # @param filepath [String] will be added to the url for get request.
38
+ # @return [Hash] formatted result with status and body keys.
39
+ def add_a_file(filepath)
40
+ Request.post_file("#{@url}/ipfs/add", @project_id, filepath)
41
+ end
42
+
43
+ # Calls post request on (@url)/ipfs/pin/add/(ipfs_path)
44
+ #
45
+ # @param ipfs_path [String] will be added to the url for get request.
46
+ # @return [Hash] formatted result with status and body keys.
47
+ def pin_an_object(ipfs_path)
48
+ Request.post_request_raw("#{@url}/ipfs/pin/add/#{ipfs_path}", @project_id)
49
+ end
50
+
51
+ # Calls post request on (@url)/ipfs//pin/remove/(ipfs_path)
52
+ #
53
+ # @param ipfs_path [String] will be added to the url for get request.
54
+ # @return [Hash] formatted result with status and body keys.
55
+ def remove_pinned_object(ipfs_path)
56
+ Request.post_request_raw("#{@url}/ipfs/pin/remove/#{ipfs_path}", @project_id)
57
+ end
58
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'configuration'
4
+ require_relative 'validator'
5
+
6
+ module Params
7
+ include Configuration
8
+ include Validator
9
+
10
+ class << self
11
+ # Calling from endpoints to define params which should be passed to Request class.
12
+ # It exctracts only permitted params, validates them, compares with params defined in config.
13
+ # If param = default API param (ex. count = 100 ) and it shouldn't be added to the url, the method cut this param.
14
+ # Also if there is no parallel_requests passing, it adds the parallel_requests value from object config.
15
+ #
16
+ # @param params [Hash] includes passed hash to constructor.
17
+ # @return [Hash] hash with valid params.
18
+ def define_params(params, config)
19
+ result = extract_params(params)
20
+ Validator.validate_params(result)
21
+ result[:order] = define_order(result[:order], config)
22
+ result[:count] = define_count(result[:count], config)
23
+ result[:parallel_requests] = define_parallel_requests(result[:parallel_requests], config)
24
+ result[:sleep_between_retries_ms] = define_sleep_between_retries(result[:sleep_between_retries_ms], config)
25
+ result.compact
26
+ end
27
+
28
+ private
29
+
30
+ def extract_params(params)
31
+ params.transform_keys(&:to_sym).slice(:order, :page, :count, :from, :to, :from_page, :to_page,
32
+ :parallel_requests, :sleep_between_retries_ms)
33
+ end
34
+
35
+ def define_order(order_param, object_config)
36
+ default_config = Configuration.default_config
37
+ order_in_default_config = default_config[:use_asc_order_as_default] == true ? 'asc' : 'desc'
38
+ order_in_object_config = object_config[:use_asc_order_as_default] == true ? 'asc' : 'desc'
39
+ define_value(order_in_default_config, order_in_object_config, order_param)
40
+ end
41
+
42
+ def define_count(count_param, object_config)
43
+ default_config = Configuration.default_config
44
+ count_in_default_config = default_config[:default_count_per_page]
45
+ count_in_object_config = object_config[:default_count_per_page]
46
+ define_value(count_in_default_config, count_in_object_config, count_param)
47
+ end
48
+
49
+ def define_value(default_config_value, object_config_value, params_value)
50
+ result = params_value || object_config_value
51
+ # Need to do this to avoid adding ?param=value to request if it is default as in the API
52
+ result = nil if result == default_config_value
53
+ result
54
+ end
55
+
56
+ def define_parallel_requests(params_value, object_config)
57
+ object_config_value = object_config[:parallel_requests]
58
+ params_value.nil? ? object_config_value : params_value
59
+ end
60
+
61
+ def define_sleep_between_retries(params_value, object_config)
62
+ object_config_value = object_config[:sleep_between_retries_ms]
63
+ params_value.nil? ? object_config_value : params_value
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,216 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'json'
5
+
6
+ require_relative './version'
7
+ require_relative './constants'
8
+
9
+ module Request
10
+ include Blockfrostruby
11
+
12
+ class << self
13
+ # Get response from passed URL, add params to request, add specific headers and format the response.
14
+ # If [:from_page] specified, calls the concurrent fetching process, else get response from single page.
15
+ #
16
+ # @param url [String] the url to request.
17
+ # @param project_id [String] the project_id to pass to url in headers.
18
+ # @param params [Hash] params to add to request, allowed :order, :page, :count, :from, :to.
19
+ # @return [Hash] formatted result with status and body keys.
20
+ def get_response(url, project_id, params = {})
21
+ params[:from_page] ? get_pages_multi(url, project_id, params) : get_response_from_url(url, project_id, params)
22
+ end
23
+
24
+ # Post raw request to url, with no body or params.
25
+ #
26
+ # @param url [String] the url to request.
27
+ # @param project_id [String] the project_id to pass to url in headers.
28
+ # @return [Hash] formatted result with status and body keys.
29
+ def post_request_raw(url, project_id)
30
+ uri = URI(url)
31
+ request = create_post_request(uri, project_id)
32
+ request['Content-Type'] = 'text/plain'
33
+ response = send_request(uri, request)
34
+ format_response(response)
35
+ end
36
+
37
+ # Post request to url, in application/cbor format with body.
38
+ #
39
+ # @param url [String] the url to request.
40
+ # @param project_id [String] the project_id to pass to url in headers.
41
+ # @param body [String] for pass to url.
42
+ # @return [Hash] formatted result with status and body keys.
43
+ def post_request_cbor(url, project_id, body)
44
+ uri = URI(url)
45
+ request = create_post_request(uri, project_id)
46
+ request['Content-Type'] = 'application/cbor'
47
+ request.body = body
48
+ response = send_request(uri, request)
49
+ format_response(response)
50
+ end
51
+
52
+ # Post file to url, in multipart/form-data.
53
+ #
54
+ # @param url [String] the url to request.
55
+ # @param project_id [String] the project_id to pass to url in headers.
56
+ # @param filepath [String] path to file for uploading.
57
+ # @return [Hash] formatted result with status and body keys.
58
+ def post_file(url, project_id, filepath)
59
+ uri = URI(url)
60
+ file = [['upload', File.open(filepath)]]
61
+ request = create_post_request(uri, project_id)
62
+ request.set_form file, 'multipart/form-data'
63
+ response = send_request(uri, request)
64
+ format_response(response)
65
+ end
66
+
67
+ private
68
+
69
+ def format_response(response)
70
+ content_type = response.header.content_type
71
+ able_to_parse = ['application/json', 'application/octet-stream'].include?(content_type)
72
+ body = able_to_parse ? JSON.parse(response.body) : response.body
73
+ body = format_keys_to_symbols(body)
74
+ { status: response.code.to_i, body: body }
75
+ end
76
+
77
+ def format_keys_to_symbols(body)
78
+ return body unless body.is_a?(Array) || body.is_a?(Hash)
79
+
80
+ if body.is_a?(Array)
81
+ result = body.map do |element|
82
+ element = element.transform_keys(&:to_sym) if element.is_a?(Hash)
83
+ element
84
+ end
85
+ end
86
+ result = body.transform_keys(&:to_sym) if body.is_a?(Hash)
87
+ result
88
+ end
89
+
90
+ def add_params_to_url(url, params)
91
+ sliced_params = params.slice(:order, :page, :count, :from, :to).compact
92
+ return url if sliced_params.empty?
93
+
94
+ request_params = sliced_params.map { |k, v| "#{k}=#{v}" }.join('&')
95
+ "#{url}?#{request_params}"
96
+ end
97
+
98
+ def sdk_identificator
99
+ "Blockfrost-Ruby, version: #{Blockfrostruby::VERSION}"
100
+ end
101
+
102
+ def create_get_request(uri, project_id)
103
+ req = Net::HTTP::Get.new(uri)
104
+ req['project_id'] = project_id
105
+ req['User-Agent'] = sdk_identificator
106
+ req
107
+ end
108
+
109
+ def create_post_request(uri, project_id)
110
+ req = Net::HTTP::Post.new(uri)
111
+ req['project_id'] = project_id
112
+ req['User-Agent'] = sdk_identificator
113
+ req
114
+ end
115
+
116
+ def send_request(uri, req)
117
+ Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') { |http| http.request(req) }
118
+ end
119
+
120
+ def get_response_from_url(url, project_id, params = {})
121
+ uri = URI(add_params_to_url(url, params))
122
+ request = create_get_request(uri, project_id)
123
+ response = send_request(uri, request)
124
+ format_response(response)
125
+ end
126
+
127
+ def get_pages(url, project_id, params = {})
128
+ responses = []
129
+ page_number = params[:from_page]
130
+
131
+ loop do
132
+ break if params[:to_page] && (page_number > params[:to_page])
133
+
134
+ response = get_response_from_page(url, project_id, page_number, params)
135
+
136
+ break if response.nil?
137
+
138
+ responses << response
139
+ page_number += 1
140
+ end
141
+ format_pages_results(responses)
142
+ end
143
+
144
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
145
+ def get_pages_multi(url, project_id, params = {})
146
+ parallel_requests = params[:parallel_requests]
147
+ sleep_retries = params[:sleep_between_retries_ms]
148
+ responses = []
149
+ numbers = []
150
+ page_number = params[:from_page]
151
+ threads = []
152
+ stops = false
153
+ loop do
154
+ parallel_requests.times do |i|
155
+ threads << Thread.new(page_number) do
156
+ local_page_number = page_number + i
157
+
158
+ stops = true if params[:to_page] && (local_page_number > params[:to_page])
159
+ next if params[:to_page] && (local_page_number > params[:to_page])
160
+
161
+ response = get_response_from_page(url, project_id, local_page_number, params)
162
+
163
+ stops = true if response.nil?
164
+ next if response.nil?
165
+
166
+ raise ScriptError, "You've been reached your daily limit" if response[:status].to_i == 402
167
+
168
+ if response[:status].to_i == 418
169
+ raise ScriptError,
170
+ "You've been temporary banned for too many requests"
171
+ end
172
+
173
+ if response[:status].to_i == 429
174
+ (1..MAX_RETRIES_IN_PARALLEL_REQUESTS).each do
175
+ sleep sleep_retries / 1000.0
176
+ response = get_response_from_page(url, project_id, local_page_number, params)
177
+ break if response[:status].to_i == 200
178
+ end
179
+ end
180
+ raise ScriptError, 'Please, try again later' if response[:status].to_i == 429
181
+
182
+ responses << { page_number: local_page_number, response: response }
183
+ numbers << local_page_number
184
+ page_number += 1
185
+ end
186
+ end
187
+
188
+ threads.each(&:join)
189
+ break if params[:to_page] && (page_number > params[:to_page])
190
+ break if stops == true
191
+
192
+ numbers.sort!
193
+ raise 'The response includes duplicated results, reduce the number of parallel_requests and try again' if numbers != numbers.uniq
194
+ end
195
+ responses.sort! { |el1, el2| el1[:page_number] <=> el2[:page_number] }.map! { |el| el[:response] }
196
+ format_pages_results(responses)
197
+ end
198
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
199
+
200
+ def get_response_from_page(url, project_id, page_number, params = {})
201
+ params_to_pass = params.slice(:order, :count).merge(page: page_number)
202
+ response = get_response_from_url(url, project_id, params_to_pass)
203
+ return if response[:body].empty?
204
+
205
+ response
206
+ end
207
+
208
+ def format_pages_results(responses)
209
+ result = { status: nil, body: [] }
210
+ result[:body] = responses.map { |r| r[:body] }.flatten
211
+ result[:status] = responses.flatten.map { |r| r[:status] }[-1]
212
+ result[:status] = result[:status].to_i if result[:status]
213
+ result
214
+ end
215
+ end
216
+ end