blockfrost-ruby 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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