crowdin-api 1.2.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +102 -43
  3. data/README.md +37 -6
  4. data/bin/crowdin-console +1 -1
  5. data/crowdin-api.gemspec +1 -2
  6. data/lib/crowdin-api/api_resources/bundles.rb +81 -0
  7. data/lib/crowdin-api/{api-resources → api_resources}/dictionaries.rb +8 -10
  8. data/lib/crowdin-api/{api-resources → api_resources}/distributions.rb +25 -32
  9. data/lib/crowdin-api/{api-resources → api_resources}/glossaries.rb +64 -82
  10. data/lib/crowdin-api/{api-resources → api_resources}/labels.rb +28 -47
  11. data/lib/crowdin-api/api_resources/languages.rb +61 -0
  12. data/lib/crowdin-api/api_resources/machine_translation_engines.rb +79 -0
  13. data/lib/crowdin-api/api_resources/projects.rb +124 -0
  14. data/lib/crowdin-api/api_resources/reports.rb +120 -0
  15. data/lib/crowdin-api/{api-resources → api_resources}/screenshots.rb +47 -61
  16. data/lib/crowdin-api/{api-resources → api_resources}/source_files.rb +68 -131
  17. data/lib/crowdin-api/{api-resources → api_resources}/source_strings.rb +19 -24
  18. data/lib/crowdin-api/api_resources/storages.rb +54 -0
  19. data/lib/crowdin-api/{api-resources → api_resources}/string_comments.rb +18 -23
  20. data/lib/crowdin-api/{api-resources → api_resources}/string_translations.rb +64 -91
  21. data/lib/crowdin-api/{api-resources → api_resources}/tasks.rb +30 -41
  22. data/lib/crowdin-api/api_resources/teams.rb +135 -0
  23. data/lib/crowdin-api/{api-resources → api_resources}/translation_memory.rb +38 -52
  24. data/lib/crowdin-api/{api-resources → api_resources}/translation_status.rb +24 -30
  25. data/lib/crowdin-api/{api-resources → api_resources}/translations.rb +41 -58
  26. data/lib/crowdin-api/api_resources/users.rb +161 -0
  27. data/lib/crowdin-api/api_resources/vendors.rb +21 -0
  28. data/lib/crowdin-api/{api-resources → api_resources}/webhooks.rb +19 -24
  29. data/lib/crowdin-api/api_resources/workflows.rb +59 -0
  30. data/lib/crowdin-api/client/client.rb +134 -39
  31. data/lib/crowdin-api/client/configuration.rb +12 -12
  32. data/lib/crowdin-api/client/version.rb +1 -1
  33. data/lib/crowdin-api/core/errors.rb +1 -0
  34. data/lib/crowdin-api/core/errors_raisers.rb +1 -1
  35. data/lib/crowdin-api/core/fetch_all_extensions.rb +14 -0
  36. data/lib/crowdin-api/core/request.rb +50 -90
  37. data/lib/crowdin-api/core/send_request.rb +67 -0
  38. data/lib/crowdin-api.rb +18 -24
  39. data/spec/api_resources/bundles_spec.rb +61 -0
  40. data/spec/api_resources/dictionaries_spec.rb +23 -0
  41. data/spec/api_resources/distributions_spec.rb +71 -0
  42. data/spec/api_resources/glossaries_spec.rb +167 -0
  43. data/spec/api_resources/labels_spec.rb +71 -0
  44. data/spec/api_resources/languages_spec.rb +51 -0
  45. data/spec/api_resources/machine_translation_engines_spec.rb +63 -0
  46. data/spec/api_resources/projects_spec.rb +215 -0
  47. data/spec/api_resources/reports_spec.rb +95 -0
  48. data/spec/api_resources/screenshots_spec.rb +134 -0
  49. data/spec/api_resources/source_files_spec.rb +184 -0
  50. data/spec/api_resources/source_strings_spec.rb +51 -0
  51. data/spec/api_resources/storages_spec.rb +41 -0
  52. data/spec/api_resources/string_comments_spec.rb +51 -0
  53. data/spec/api_resources/string_translations_spec.rb +141 -0
  54. data/spec/api_resources/tasks_spec.rb +79 -0
  55. data/spec/api_resources/teams_spec.rb +100 -0
  56. data/spec/api_resources/translation_memory_spec.rb +114 -0
  57. data/spec/api_resources/translation_status_spec.rb +61 -0
  58. data/spec/api_resources/translations_spec.rb +107 -0
  59. data/spec/api_resources/users_spec.rb +117 -0
  60. data/spec/api_resources/vendors_spec.rb +13 -0
  61. data/spec/api_resources/webhooks_spec.rb +51 -0
  62. data/spec/api_resources/workflows_spec.rb +41 -0
  63. data/spec/spec_helper.rb +23 -2
  64. data/spec/unit/client_spec.rb +85 -0
  65. metadata +67 -43
  66. data/bin/setup +0 -6
  67. data/lib/crowdin-api/api-resources/languages.rb +0 -82
  68. data/lib/crowdin-api/api-resources/machine_translation_engines.rb +0 -74
  69. data/lib/crowdin-api/api-resources/projects.rb +0 -148
  70. data/lib/crowdin-api/api-resources/reports.rb +0 -138
  71. data/lib/crowdin-api/api-resources/storages.rb +0 -106
  72. data/lib/crowdin-api/api-resources/teams.rb +0 -144
  73. data/lib/crowdin-api/api-resources/users.rb +0 -129
  74. data/lib/crowdin-api/api-resources/vendors.rb +0 -21
  75. data/lib/crowdin-api/api-resources/workflows.rb +0 -62
  76. data/lib/crowdin-api/core/utils.rb +0 -10
  77. data/spec/client/client-instance_spec.rb +0 -14
  78. data/spec/client/configuration-instance_spec.rb +0 -72
@@ -7,26 +7,24 @@ module Crowdin
7
7
  project_id || raise_project_id_is_required_error
8
8
 
9
9
  request = Web::Request.new(
10
- self,
10
+ connection,
11
11
  :get,
12
- "/projects/#{project_id}/webhooks",
13
- query
12
+ "#{config.target_api_url}/projects/#{project_id}/webhooks",
13
+ { params: query }
14
14
  )
15
-
16
- request.perform
15
+ Web::SendRequest.new(request).perform
17
16
  end
18
17
 
19
18
  def add_webhook(query = {}, project_id = config.project_id)
20
19
  project_id || raise_project_id_is_required_error
21
20
 
22
21
  request = Web::Request.new(
23
- self,
22
+ connection,
24
23
  :post,
25
- "/projects/#{project_id}/webhooks",
26
- query
24
+ "#{config.target_api_url}/projects/#{project_id}/webhooks",
25
+ { params: query }
27
26
  )
28
-
29
- request.perform
27
+ Web::SendRequest.new(request).perform
30
28
  end
31
29
 
32
30
  def get_webhook(webhook_id = nil, project_id = config.project_id)
@@ -34,12 +32,11 @@ module Crowdin
34
32
  project_id || raise_project_id_is_required_error
35
33
 
36
34
  request = Web::Request.new(
37
- self,
35
+ connection,
38
36
  :get,
39
- "/projects/#{project_id}/webhooks/#{webhook_id}"
37
+ "#{config.target_api_url}/projects/#{project_id}/webhooks/#{webhook_id}"
40
38
  )
41
-
42
- request.perform
39
+ Web::SendRequest.new(request).perform
43
40
  end
44
41
 
45
42
  def delete_webhook(webhook_id = nil, project_id = config.project_id)
@@ -47,26 +44,24 @@ module Crowdin
47
44
  project_id || raise_project_id_is_required_error
48
45
 
49
46
  request = Web::Request.new(
50
- self,
47
+ connection,
51
48
  :delete,
52
- "/projects/#{project_id}/webhooks/#{webhook_id}"
49
+ "#{config.target_api_url}/projects/#{project_id}/webhooks/#{webhook_id}"
53
50
  )
54
-
55
- request.perform
51
+ Web::SendRequest.new(request).perform
56
52
  end
57
53
 
58
- def edit_screenshot(webhook_id = nil, query = {}, project_id = config.project_id)
54
+ def edit_webhook(webhook_id = nil, query = {}, project_id = config.project_id)
59
55
  webhook_id || raise_parameter_is_required_error(:webhook_id)
60
56
  project_id || raise_project_id_is_required_error
61
57
 
62
58
  request = Web::Request.new(
63
- self,
59
+ connection,
64
60
  :patch,
65
- "/projects/#{project_id}/webhooks/#{webhook_id}",
66
- query
61
+ "#{config.target_api_url}/projects/#{project_id}/webhooks/#{webhook_id}",
62
+ { params: query }
67
63
  )
68
-
69
- request.perform
64
+ Web::SendRequest.new(request).perform
70
65
  end
71
66
  end
72
67
  end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Crowdin
4
+ module ApiResources
5
+ module Workflows
6
+ # -- For Enterprise mode only --
7
+
8
+ def list_workflow_steps(query = {}, project_id = config.project_id)
9
+ enterprise_mode? || raise_only_for_enterprise_mode_error
10
+ project_id || raise_project_id_is_required_error
11
+
12
+ request = Web::Request.new(
13
+ connection,
14
+ :get,
15
+ "#{config.target_api_url}/projects/#{project_id}/workflow-steps",
16
+ { params: query }
17
+ )
18
+ Web::SendRequest.new(request).perform
19
+ end
20
+
21
+ def get_workflow_step(step_id = nil, project_id = config.project_id)
22
+ enterprise_mode? || raise_only_for_enterprise_mode_error
23
+ step_id || raise_parameter_is_required_error(:step_id)
24
+ project_id || raise_project_id_is_required_error
25
+
26
+ request = Web::Request.new(
27
+ connection,
28
+ :get,
29
+ "#{config.target_api_url}/projects/#{project_id}/workflow-steps/#{step_id}"
30
+ )
31
+ Web::SendRequest.new(request).perform
32
+ end
33
+
34
+ def list_workflow_templates(query = {})
35
+ enterprise_mode? || raise_only_for_enterprise_mode_error
36
+
37
+ request = Web::Request.new(
38
+ connection,
39
+ :get,
40
+ "#{config.target_api_url}/workflow-templates",
41
+ { params: query }
42
+ )
43
+ Web::SendRequest.new(request).perform
44
+ end
45
+
46
+ def get_workflow_template(template_id = nil)
47
+ enterprise_mode? || raise_only_for_enterprise_mode_error
48
+ template_id || raise_parameter_is_required_error(:template_id)
49
+
50
+ request = Web::Request.new(
51
+ connection,
52
+ :get,
53
+ "#{config.target_api_url}/workflow-templates/#{template_id}"
54
+ )
55
+ Web::SendRequest.new(request).perform
56
+ end
57
+ end
58
+ end
59
+ end
@@ -20,76 +20,171 @@ module Crowdin
20
20
  # crowdin.list_projects
21
21
  #
22
22
  class Client
23
- extend Utils
24
-
25
- # API Resources modules
26
- API_RESOURCES_MODULES = %i[Storages Languages Projects Workflows SourceFiles Translations SourceStrings
27
- StringTranslations StringComments Screenshots Glossaries TranslationMemory
28
- MachineTranslationEngines Reports Tasks Users Teams Vendors Webhooks
29
- Dictionaries Distributions Labels TranslationStatus].freeze
30
-
31
- # Error Raisers modules
32
- ERROR_RAISERS_MODULES = %i[ApiErrorsRaiser ClientErrorsRaiser].freeze
33
-
34
- # Processing all API Resources modules to include them to the Client
23
+ # Processing API Resources modules to include them to the Client
35
24
  API_RESOURCES_MODULES.each do |module_name|
36
- Client.send(:include, fetch_module_full_name_from_string("Crowdin::ApiResources::#{module_name}"))
25
+ Client.send(:include, Object.const_get("Crowdin::ApiResources::#{module_name}"))
37
26
  end
38
27
 
39
- # Processing all Error Raisers modules to include them to the Client
28
+ # Processing Error Raisers modules to include them to the Client
40
29
  ERROR_RAISERS_MODULES.each do |module_name|
41
- Client.send(:include, fetch_module_full_name_from_string("Crowdin::Errors::#{module_name}"))
30
+ Client.send(:include, Object.const_get("Crowdin::Errors::#{module_name}"))
42
31
  end
43
32
 
33
+ include Web::FetchAllExtensions
34
+
35
+ # Config instance that includes configuration options for the Client
44
36
  attr_reader :config
37
+ # Instance with established connection through RestClient to the Crowdin API
45
38
  attr_reader :connection
39
+ # Instance with options and headers for RestClient connection
46
40
  attr_reader :options
41
+ # Logger instance
47
42
  attr_reader :logger
48
43
 
49
44
  def initialize(&block)
50
45
  build_configuration(&block)
51
46
 
52
- check_logger
53
- check_rest_client_proxy
47
+ update_logger
48
+ update_rest_client_proxy
54
49
 
55
50
  build_connection
56
51
  end
57
52
 
58
- def log!(message)
59
- !config.logger_enabled? || logger.debug(message)
53
+ def log(message)
54
+ !logger_enabled? || logger.debug(message)
60
55
  end
61
56
 
62
57
  def logger=(logger)
63
- raise_logger_are_not_enabled_error unless config.logger_enabled?
58
+ raise_logger_are_not_enabled_error unless logger_enabled?
59
+
64
60
  @logger = logger
61
+ update_rest_client_logger
65
62
  end
66
63
 
67
- private
68
-
69
- def build_configuration
70
- @config = Crowdin::Configuration.new
71
- yield config if block_given?
64
+ def enterprise_mode?
65
+ !!config.organization_domain
72
66
  end
73
67
 
74
- def build_connection
75
- @connection ||= ::RestClient::Resource.new(config.base_url, build_options)
68
+ def logger_enabled?
69
+ config.logger_enabled?
76
70
  end
77
71
 
78
- def build_options
79
- @options ||= config.options.merge(headers: config.headers)
72
+ #
73
+ # FetchAll options:
74
+ # * limit, Integer, default: 500 | How many records need to load per one request
75
+ # * offset, Integer, default: 0 | How many records need to skip
76
+ # * request_delay, Integer (seconds), default: 0 | Delay between requests
77
+ #
78
+ #
79
+ # Note: Please, specify project_id while Client initialization if you need to use methods that need it within FetchAll
80
+ #
81
+ # === Example
82
+ #
83
+ # @crowdin.fetch_all(:list_projects)
84
+ #
85
+ # with specified options
86
+ #
87
+ # @crowdin.fetch_all(:list_projects, { limit: 10, request_delay: 1 })
88
+ #
89
+ # playing with response per fetch. Note: the block actually don't make any effect to finite result
90
+ #
91
+ # @crowdin.fetch_all(:list_projects, { limit: 10, request_delay: 1 }) { |response| puts response['data'] }
92
+ #
93
+ # also you can specify retry configuration to handle some exceptions
94
+ #
95
+ # Retry configuration options:
96
+ # * request_delay, Integer (seconds), default: 0 | Delay between retries
97
+ # * retries_count, Integer, default: 0
98
+ # * error_messages, Array
99
+ #
100
+ # @crowdin.fetch_all(:list_projects, {}, { request_delay: 2, retries_count: 3, error_messages: ['401'] })
101
+ #
102
+ # fetch all execution will be terminated if response error are same as in error_messages array
103
+ # otherwise system will retry so many times, as indicated at tries_count
104
+ #
105
+ def fetch_all(api_resource, opts = {}, retry_opts = {})
106
+ unless Web::FetchAllExtensions::API_RESOURCES_FOR_FETCH_ALL.include?(api_resource)
107
+ raise(Errors::FetchAllProcessingError, "#{api_resource} method aren't supported for FetchAll")
108
+ end
109
+
110
+ limit = opts[:limit] || Web::FetchAllExtensions::MAX_ITEMS_COUNT_PER_REQUEST
111
+ offset = opts[:offset] || 0
112
+ request_delay = opts[:request_delay] || 0
113
+
114
+ retry_request_delay = retry_opts[:request_delay] || 0
115
+ retries_count = retry_opts[:retries_count] || 0
116
+ retry_error_messages = retry_opts[:error_messages] || []
117
+
118
+ result = []
119
+ loop do
120
+ response = case api_resource
121
+ when :list_terms
122
+ send(api_resource, opts[:glossary_id], { limit: limit, offset: offset }.merge(opts))
123
+ when :list_file_revisions
124
+ send(api_resource, opts[:file_id], { limit: limit, offset: offset }.merge(opts))
125
+ else
126
+ send(api_resource, { limit: limit, offset: offset }.merge(opts))
127
+ end
128
+
129
+ if response.is_a?(String) && response.match('Something went wrong')
130
+ if retries_count.positive?
131
+ retry_error_messages.each do |message|
132
+ break if response.match(message)
133
+ end
134
+
135
+ retries_count -= 1
136
+ sleep retry_request_delay
137
+ else
138
+ raise(Errors::FetchAllProcessingError, response)
139
+ end
140
+ else
141
+ yield response if block_given?
142
+ deserialized_response = response['data']
143
+ result.concat(deserialized_response)
144
+ offset += deserialized_response.size
145
+ break if deserialized_response.size < limit
146
+ end
147
+
148
+ sleep request_delay
149
+ end
150
+ result
151
+ rescue StandardError => e
152
+ raise(Errors::FetchAllProcessingError, "FetchAll wasn't processed. Details - #{e.message}")
80
153
  end
81
154
 
82
- def set_default_logger
83
- require 'logger'
84
- @logger ||= Logger.new($stderr)
85
- end
155
+ private
86
156
 
87
- def check_rest_client_proxy
88
- ENV['http_proxy'] ? ::RestClient.proxy = ENV['http_proxy'] : false
89
- end
157
+ def build_configuration
158
+ @config = Crowdin::Configuration.new
159
+ yield config if block_given?
160
+ end
90
161
 
91
- def check_logger
92
- config.logger_enabled? ? set_default_logger : config.enable_logger = false
93
- end
162
+ def build_connection
163
+ build_options
164
+ @connection ||= ::RestClient::Resource.new(config.base_url, options)
165
+ end
166
+
167
+ def build_options
168
+ @options ||= config.options.merge(headers: config.headers)
169
+ end
170
+
171
+ def set_default_logger
172
+ require 'logger'
173
+
174
+ @logger ||= Logger.new($stdout)
175
+ update_rest_client_logger
176
+ end
177
+
178
+ def update_rest_client_logger
179
+ ::RestClient.log = @logger
180
+ end
181
+
182
+ def update_rest_client_proxy
183
+ ENV['http_proxy'] ? ::RestClient.proxy = ENV.fetch('http_proxy') : false
184
+ end
185
+
186
+ def update_logger
187
+ config.logger_enabled? ? set_default_logger : config.enable_logger = false
188
+ end
94
189
  end
95
190
  end
@@ -5,12 +5,12 @@ module Crowdin
5
5
  attr_accessor :api_token
6
6
  attr_accessor :project_id
7
7
  attr_accessor :organization_domain
8
+
8
9
  attr_accessor :enable_logger
10
+ alias logger_enabled? enable_logger
9
11
 
10
12
  attr_reader :target_api_url
11
13
 
12
- alias logger_enabled? enable_logger
13
-
14
14
  def initialize
15
15
  @target_api_url = '/api/v2'
16
16
  end
@@ -33,16 +33,16 @@ module Crowdin
33
33
  end
34
34
 
35
35
  def base_url
36
- if enterprise_mode?
37
- organization_domain.include?('.com') ? organization_domain : "https://#{organization_domain}.api.crowdin.com"
38
- else
39
- 'https://api.crowdin.com'
40
- end
41
- end
42
-
43
- def organization_domain?
44
- !!organization_domain
36
+ @base_url ||=
37
+ if !!organization_domain
38
+ if organization_domain.include?('.com')
39
+ "https://#{organization_domain}"
40
+ else
41
+ "https://#{organization_domain}.api.crowdin.com"
42
+ end
43
+ else
44
+ 'https://api.crowdin.com'
45
+ end
45
46
  end
46
- alias enterprise_mode? organization_domain?
47
47
  end
48
48
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Crowdin
4
4
  class Client
5
- VERSION = '1.2.0'
5
+ VERSION = '1.4.0'
6
6
  end
7
7
  end
@@ -4,5 +4,6 @@ module Crowdin
4
4
  module Errors
5
5
  class OnlyForEnterpriseModeError < StandardError; end
6
6
  class LoggerAreNotEnabledError < StandardError; end
7
+ class FetchAllProcessingError < StandardError; end
7
8
  end
8
9
  end
@@ -6,7 +6,7 @@ module Crowdin
6
6
  module ClientErrorsRaiser
7
7
  def raise_logger_are_not_enabled_error
8
8
  raise(LoggerAreNotEnabledError, 'Logger are not enabled in your Client configuration, enable it ' \
9
- 'before setting your own logger')
9
+ 'before setting your logger')
10
10
  end
11
11
  end
12
12
 
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Crowdin
4
+ module Web
5
+ module FetchAllExtensions
6
+ MAX_ITEMS_COUNT_PER_REQUEST = 500.freeze
7
+ API_RESOURCES_FOR_FETCH_ALL = %i[list_vendors list_dictionaries list_directories list_distributions
8
+ list_workflow_templates list_languages list_labels list_mts list_files
9
+ list_projects list_groups list_branches list_strings list_storages
10
+ list_string_comments list_tasks list_user_tasks list_webhooks
11
+ list_terms list_file_revisions list_bundles].freeze
12
+ end
13
+ end
14
+ end
@@ -3,116 +3,76 @@
3
3
  module Crowdin
4
4
  module Web
5
5
  class Request
6
- attr_reader :client
7
-
8
- def initialize(client, method, path, query = {}, headers = {}, destination = nil)
9
- @client = client
10
- @method = method
11
- @full_path = client.config.target_api_url + path
12
- @payload = perform_payload(query)
13
- @headers = headers
14
- @destination = destination
15
- @errors = []
6
+ attr_reader :connection
7
+ attr_reader :method
8
+ attr_reader :payload
9
+
10
+ def initialize(connection, method, url, payload = {})
11
+ @connection = connection[url]
12
+ @method = method
13
+ @payload = build_payload(payload)
16
14
  end
17
15
 
18
- def perform
19
- process_request!
20
- process_response!
16
+ def get?
17
+ method.eql?(:get)
21
18
  end
22
19
 
23
- private
24
-
25
- def process_request!
26
- return @response = client.connection[@full_path].delete if delete_request?
27
- return @response = client.connection[@full_path].get(@payload) if get_request?
28
-
29
- client.connection[@full_path].send(@method, @payload, @headers) { |response, _, _| @response = response }
30
- rescue StandardError => error
31
- client.log! error
32
-
33
- @errors << "Something went wrong while request proccessing. Details - #{error.class}"
20
+ def get
21
+ connection.get(prepare_payload(payload[:params]))
34
22
  end
35
23
 
36
- def process_response!
37
- return fetch_errors if @errors.any?
38
-
39
- begin
40
- if @response
41
- client.log! "args: #{@response.request.args}"
42
-
43
- if @response.body.empty?
44
- @response.code
45
- else
46
- doc = JSON.parse(@response.body)
47
-
48
- client.log! "body: #{doc}"
49
-
50
- data = fetch_response_data(doc)
51
-
52
- @errors.any? ? fetch_errors : data
53
- end
54
- end
55
- rescue StandardError => error
56
- client.log! error
57
-
58
- @errors << "Something went wrong while response proccessing. Details - #{error.class}"
59
-
60
- fetch_errors
61
- end
24
+ def delete?
25
+ method.eql?(:delete)
62
26
  end
63
27
 
64
- def perform_payload(query)
65
- return query if query.is_a?(File)
66
-
67
- get_request? ? { params: fetch_cleared_query(query) } : fetch_cleared_query(query).to_json
28
+ def delete
29
+ connection.delete
68
30
  end
69
31
 
70
- def download_file(url)
71
- download = URI.parse(url).open
72
- destination = @destination || download.meta['content-disposition']
73
- .match(/filename=("?)(.+)\1/)[2]
74
-
75
- IO.copy_stream(download, destination)
76
-
77
- destination
78
- rescue StandardError => error
79
- client.log! error
32
+ def process_with_body
33
+ connection.send(method, prepare_payload(payload[:params]), payload[:headers]) { |response, _, _| response }
34
+ end
80
35
 
81
- @errors << "Something went wrong while downloading file. Details - #{error.class}"
36
+ def post?
37
+ method.eql?(:post)
82
38
  end
39
+ alias post process_with_body
83
40
 
84
- def fetch_errors
85
- @errors.join(';')
41
+ def patch?
42
+ method.eql?(:patch)
86
43
  end
44
+ alias patch process_with_body
87
45
 
88
- def fetch_response_data(doc)
89
- if doc['data'].is_a?(Hash) && doc['data']['url'] && doc['data']['url'].include?('response-content-disposition')
90
- download_file(doc['data']['url'])
91
- else
92
- doc
93
- end
46
+ def put?
47
+ method.eql?(:put)
94
48
  end
49
+ alias put process_with_body
95
50
 
96
- def fetch_cleared_query(query)
97
- case query
98
- when Array
99
- query.map do |el|
100
- el.reject { |_, value| value.nil? }
101
- end.reject(&:empty?)
102
- when Hash
103
- query.reject { |_, value| value.nil? }
104
- else
105
- query
51
+ private
52
+
53
+ def build_payload(payload)
54
+ %i[params headers].each do |key|
55
+ payload[key] ||= {}
56
+ end
57
+ payload
106
58
  end
107
- end
108
59
 
109
- def get_request?
110
- @method.eql?(:get)
111
- end
60
+ def prepare_payload(params)
61
+ return params if params.is_a?(File)
112
62
 
113
- def delete_request?
114
- @method.eql?(:delete)
115
- end
63
+ get? ? { params: fetch_cleared_params(params) } : fetch_cleared_params(params).to_json
64
+ end
65
+
66
+ def fetch_cleared_params(params)
67
+ case params
68
+ when Array
69
+ params.map { |el| el.reject { |_, value| value.nil? } }.reject(&:empty?)
70
+ when Hash
71
+ params.reject { |_, value| value.nil? }
72
+ else
73
+ params
74
+ end
75
+ end
116
76
  end
117
77
  end
118
78
  end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Crowdin
4
+ module Web
5
+ class SendRequest
6
+ attr_reader :request
7
+
8
+ def initialize(request, file_destination = nil)
9
+ @request = request
10
+ @file_destination = file_destination
11
+ @errors = []
12
+ end
13
+
14
+ def perform
15
+ parse_response(process_request)
16
+ end
17
+
18
+ private
19
+
20
+ def process_request
21
+ request.send(request.method)
22
+ rescue StandardError => e
23
+ @errors << "Something went wrong while request processing. Details - #{e.message}"
24
+ end
25
+
26
+ def parse_response(response)
27
+ return @errors.join('; ') if @errors.any?
28
+
29
+ begin
30
+ if response
31
+ if response.body.empty?
32
+ response.code
33
+ else
34
+ parsed_body = JSON.parse(response.body)
35
+ parsed_response = fetch_response_data(parsed_body)
36
+
37
+ @errors.any? ? @errors.join('; ') : parsed_response
38
+ end
39
+ end
40
+ rescue StandardError => e
41
+ @errors << "Something went wrong while response processing. Details - #{e.message}"
42
+ @errors.join('; ')
43
+ end
44
+ end
45
+
46
+ def fetch_response_data(doc)
47
+ if doc['data'].is_a?(Hash) && doc['data']['url'] && doc['data']['url'].include?('response-content-disposition')
48
+ download_file(doc['data']['url'])
49
+ else
50
+ doc
51
+ end
52
+ end
53
+
54
+ def download_file(url)
55
+ download = URI.parse(url).open
56
+ destination = @file_destination || download.meta['content-disposition']
57
+ .match(/filename=("?)(.+)\1/)[2]
58
+
59
+ IO.copy_stream(download, destination)
60
+
61
+ destination
62
+ rescue StandardError => e
63
+ @errors << "Something went wrong while downloading file. Details - #{e.message}"
64
+ end
65
+ end
66
+ end
67
+ end