deepl-rb 2.5.3 → 3.0.1
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 +4 -4
- data/.github/workflows/add_issues_to_kanban.yml +16 -0
- data/.gitlab-ci.yml +135 -0
- data/.rubocop.yml +27 -0
- data/CHANGELOG.md +39 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/CONTRIBUTING.md +37 -0
- data/Gemfile +3 -1
- data/LICENSE.md +1 -0
- data/README.md +115 -5
- data/Rakefile +7 -5
- data/SECURITY.md +58 -0
- data/VERSION +1 -1
- data/deepl-rb.gemspec +36 -20
- data/lib/deepl/api.rb +11 -1
- data/lib/deepl/configuration.rb +34 -3
- data/lib/deepl/document_api.rb +121 -0
- data/lib/deepl/exceptions/authorization_failed.rb +3 -0
- data/lib/deepl/exceptions/bad_request.rb +3 -0
- data/lib/deepl/exceptions/document_translation_error.rb +15 -0
- data/lib/deepl/exceptions/error.rb +6 -0
- data/lib/deepl/exceptions/limit_exceeded.rb +7 -0
- data/lib/deepl/exceptions/not_found.rb +3 -0
- data/lib/deepl/exceptions/not_supported.rb +3 -0
- data/lib/deepl/exceptions/quota_exceeded.rb +3 -0
- data/lib/deepl/exceptions/request_entity_too_large.rb +3 -0
- data/lib/deepl/exceptions/request_error.rb +4 -2
- data/lib/deepl/exceptions/server_error.rb +18 -0
- data/lib/deepl/glossary_api.rb +3 -0
- data/lib/deepl/requests/base.rb +89 -34
- data/lib/deepl/requests/document/download.rb +44 -0
- data/lib/deepl/requests/document/get_status.rb +44 -0
- data/lib/deepl/requests/document/upload.rb +64 -0
- data/lib/deepl/requests/glossary/create.rb +15 -1
- data/lib/deepl/requests/glossary/destroy.rb +8 -1
- data/lib/deepl/requests/glossary/entries.rb +8 -1
- data/lib/deepl/requests/glossary/find.rb +8 -1
- data/lib/deepl/requests/glossary/language_pairs.rb +9 -2
- data/lib/deepl/requests/glossary/list.rb +9 -2
- data/lib/deepl/requests/languages.rb +9 -2
- data/lib/deepl/requests/translate.rb +33 -11
- data/lib/deepl/requests/usage.rb +9 -2
- data/lib/deepl/resources/base.rb +3 -0
- data/lib/deepl/resources/document_handle.rb +57 -0
- data/lib/deepl/resources/document_translation_status.rb +54 -0
- data/lib/deepl/resources/glossary.rb +3 -0
- data/lib/deepl/resources/language.rb +3 -0
- data/lib/deepl/resources/language_pair.rb +3 -0
- data/lib/deepl/resources/text.rb +3 -0
- data/lib/deepl/resources/usage.rb +3 -0
- data/lib/deepl/utils/backoff_timer.rb +46 -0
- data/lib/deepl/utils/exception_builder.rb +18 -13
- data/lib/deepl.rb +47 -0
- data/lib/http_client_options.rb +22 -0
- data/license_checker.sh +8 -0
- data/spec/api/api_spec.rb +8 -4
- data/spec/api/configuration_spec.rb +92 -18
- data/spec/api/deepl_spec.rb +225 -86
- data/spec/fixtures/vcr_cassettes/deepl_document.yml +95 -0
- data/spec/fixtures/vcr_cassettes/deepl_document_download.yml +1214 -0
- data/spec/fixtures/vcr_cassettes/deepl_glossaries.yml +812 -23
- data/spec/fixtures/vcr_cassettes/deepl_languages.yml +28 -17
- data/spec/fixtures/vcr_cassettes/deepl_translate.yml +161 -53
- data/spec/fixtures/vcr_cassettes/deepl_usage.yml +93 -3
- data/spec/fixtures/vcr_cassettes/glossaries.yml +1237 -15
- data/spec/fixtures/vcr_cassettes/languages.yml +159 -44
- data/spec/fixtures/vcr_cassettes/translate_texts.yml +9742 -12
- data/spec/fixtures/vcr_cassettes/usage.yml +134 -2
- data/spec/integration_tests/document_api_spec.rb +155 -0
- data/spec/integration_tests/integration_test_utils.rb +170 -0
- data/spec/requests/glossary/create_spec.rb +23 -13
- data/spec/requests/glossary/destroy_spec.rb +33 -17
- data/spec/requests/glossary/entries_spec.rb +31 -17
- data/spec/requests/glossary/find_spec.rb +31 -17
- data/spec/requests/glossary/language_pairs_spec.rb +17 -7
- data/spec/requests/glossary/list_spec.rb +21 -11
- data/spec/requests/languages_spec.rb +31 -21
- data/spec/requests/translate_spec.rb +125 -131
- data/spec/requests/usage_spec.rb +17 -7
- data/spec/resources/glossary_spec.rb +15 -12
- data/spec/resources/language_pair_spec.rb +10 -7
- data/spec/resources/language_spec.rb +21 -18
- data/spec/resources/text_spec.rb +10 -7
- data/spec/resources/usage_spec.rb +16 -13
- data/spec/spec_helper.rb +63 -6
- metadata +32 -9
data/lib/deepl/requests/base.rb
CHANGED
@@ -1,19 +1,29 @@
|
|
1
|
+
# Copyright 2018 Daniel Herzog
|
2
|
+
# Use of this source code is governed by an MIT
|
3
|
+
# license that can be found in the LICENSE.md file.
|
1
4
|
# frozen_string_literal: true
|
2
5
|
|
3
6
|
module DeepL
|
4
7
|
module Requests
|
5
|
-
class Base
|
8
|
+
class Base # rubocop:disable Metrics/ClassLength
|
6
9
|
attr_reader :api, :response, :options
|
7
10
|
|
8
|
-
def initialize(api, options = {})
|
11
|
+
def initialize(api, options = {}, additional_headers = {})
|
9
12
|
@api = api
|
10
13
|
@options = options
|
14
|
+
@additional_headers = additional_headers
|
15
|
+
@num_retries = 0
|
16
|
+
@backoff_timer = Utils::BackoffTimer.new
|
11
17
|
end
|
12
18
|
|
13
19
|
def request
|
14
20
|
raise NotImplementedError
|
15
21
|
end
|
16
22
|
|
23
|
+
def details
|
24
|
+
"HTTP Headers #{headers}"
|
25
|
+
end
|
26
|
+
|
17
27
|
private
|
18
28
|
|
19
29
|
def option?(name)
|
@@ -36,43 +46,81 @@ module DeepL
|
|
36
46
|
end
|
37
47
|
end
|
38
48
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
49
|
+
# Files to reset: list of file objects to rewind when retrying the request
|
50
|
+
def execute_request_with_retries(req, files_to_reset = []) # rubocop:disable all
|
51
|
+
api.configuration.logger&.info("Request to the DeepL API: #{self}")
|
52
|
+
api.configuration.logger&.debug("Request details: #{details}")
|
53
|
+
loop do
|
54
|
+
resp = api.http_client.request(req)
|
55
|
+
validate_response!(resp)
|
56
|
+
return [req, resp]
|
57
|
+
rescue DeepL::Exceptions::Error => e
|
58
|
+
raise e unless should_retry?(resp, e, @backoff_timer.num_retries)
|
59
|
+
|
60
|
+
unless e.nil?
|
61
|
+
api.configuration.logger&.info("Encountered a retryable exception: #{e.message}")
|
62
|
+
end
|
63
|
+
api.configuration.logger&.info("Starting retry #{@backoff_timer.num_retries + 1} for " \
|
64
|
+
"request #{request} after sleeping for " \
|
65
|
+
"#{format('%.2f', @backoff_timer.time_until_deadline)}")
|
66
|
+
files_to_reset.each(&:rewind)
|
67
|
+
@backoff_timer.sleep_until_deadline
|
68
|
+
next
|
69
|
+
rescue Net::HTTPBadResponse, Net::HTTPServerError, Net::HTTPFatalError, Timeout::Error,
|
70
|
+
SocketError => e
|
71
|
+
unless e.nil?
|
72
|
+
api.configuration.logger&.info("Encountered a retryable exception: #{e.message}")
|
73
|
+
end
|
74
|
+
api.configuration.logger&.info("Starting retry #{@backoff_timer.num_retries + 1} for " \
|
75
|
+
"request #{request} after sleeping for " \
|
76
|
+
"#{format('%.2f', @backoff_timer.time_until_deadline)}")
|
77
|
+
files_to_reset.each(&:rewind)
|
78
|
+
@backoff_timer.sleep_until_deadline
|
79
|
+
next
|
80
|
+
end
|
46
81
|
end
|
47
82
|
|
48
|
-
def
|
49
|
-
|
50
|
-
|
83
|
+
def should_retry?(response, exception, num_retries)
|
84
|
+
return false if num_retries >= api.configuration.max_network_retries
|
85
|
+
return exception.should_retry? if response.nil?
|
51
86
|
|
52
|
-
|
53
|
-
[request, response]
|
87
|
+
response.is_a?(Net::HTTPTooManyRequests) || response.is_a?(Net::HTTPInternalServerError)
|
54
88
|
end
|
55
89
|
|
56
|
-
def
|
57
|
-
|
58
|
-
|
90
|
+
def post_request(payload)
|
91
|
+
http_headers = add_json_content_type(headers)
|
92
|
+
post_req = Net::HTTP::Post.new(uri.path, http_headers)
|
93
|
+
post_req.body = payload.merge(options).to_json
|
94
|
+
post_req
|
95
|
+
end
|
59
96
|
|
60
|
-
|
61
|
-
|
97
|
+
def post_request_with_file(form_data)
|
98
|
+
http_headers = add_multipart_form_content_type(headers)
|
99
|
+
post_req = Net::HTTP::Post.new(uri.request_uri, http_headers)
|
100
|
+
# options are passed in `form_data`
|
101
|
+
form_data += options.map { |key, value| [key.to_s, value.to_s] }
|
102
|
+
post_req.set_form(form_data, 'multipart/form-data')
|
103
|
+
post_req
|
62
104
|
end
|
63
105
|
|
64
|
-
def
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
end
|
106
|
+
def get_request # rubocop:disable Naming/AccessorMethodName
|
107
|
+
http_headers = add_json_content_type(headers)
|
108
|
+
get_req = Net::HTTP::Get.new(uri.path, http_headers)
|
109
|
+
get_req.body = options.to_json
|
110
|
+
get_req
|
70
111
|
end
|
71
112
|
|
72
|
-
def
|
113
|
+
def delete_request
|
114
|
+
http_headers = add_json_content_type(headers)
|
115
|
+
del_req = Net::HTTP::Delete.new(uri.path, http_headers)
|
116
|
+
del_req.body = options.to_json
|
117
|
+
del_req
|
118
|
+
end
|
119
|
+
|
120
|
+
def validate_response!(response)
|
73
121
|
return if response.is_a?(Net::HTTPSuccess)
|
74
122
|
|
75
|
-
raise Utils::ExceptionBuilder.new(
|
123
|
+
raise Utils::ExceptionBuilder.new(response).build
|
76
124
|
end
|
77
125
|
|
78
126
|
def path
|
@@ -84,12 +132,8 @@ module DeepL
|
|
84
132
|
end
|
85
133
|
|
86
134
|
def uri
|
87
|
-
@uri ||=
|
88
|
-
|
89
|
-
new_query = URI.decode_www_form(uri.query || '') + query_params.to_a
|
90
|
-
uri.query = URI.encode_www_form(new_query)
|
91
|
-
uri
|
92
|
-
end
|
135
|
+
@uri ||= URI(url)
|
136
|
+
@uri
|
93
137
|
end
|
94
138
|
|
95
139
|
def host
|
@@ -101,7 +145,18 @@ module DeepL
|
|
101
145
|
end
|
102
146
|
|
103
147
|
def headers
|
104
|
-
{ 'Authorization' => "DeepL-Auth-Key #{api.configuration.auth_key}"
|
148
|
+
{ 'Authorization' => "DeepL-Auth-Key #{api.configuration.auth_key}",
|
149
|
+
'User-Agent' => api.configuration.user_agent }.merge(@additional_headers)
|
150
|
+
end
|
151
|
+
|
152
|
+
def add_json_content_type(headers_to_add_to)
|
153
|
+
headers_to_add_to['Content-Type'] = 'application/json'
|
154
|
+
headers_to_add_to
|
155
|
+
end
|
156
|
+
|
157
|
+
def add_multipart_form_content_type(headers_to_add_to)
|
158
|
+
headers_to_add_to['Content-Type'] = 'multipart/form-data'
|
159
|
+
headers_to_add_to
|
105
160
|
end
|
106
161
|
end
|
107
162
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# Copyright 2024 DeepL SE (https://www.deepl.com)
|
2
|
+
# Use of this source code is governed by an MIT
|
3
|
+
# license that can be found in the LICENSE file.
|
4
|
+
# frozen_string_literal: true
|
5
|
+
|
6
|
+
module DeepL
|
7
|
+
module Requests
|
8
|
+
module Document
|
9
|
+
class Download < Base
|
10
|
+
attr_reader :document_id, :document_key
|
11
|
+
|
12
|
+
def initialize(api, document_id, document_key, output_file)
|
13
|
+
super(api, {})
|
14
|
+
@document_id = document_id
|
15
|
+
@document_key = document_key
|
16
|
+
@output_file = output_file
|
17
|
+
end
|
18
|
+
|
19
|
+
def request
|
20
|
+
payload = { document_key: document_key }
|
21
|
+
extract_file(*execute_request_with_retries(post_request(payload)))
|
22
|
+
end
|
23
|
+
|
24
|
+
def details
|
25
|
+
"HTTP Headers: #{headers}\nPayload #{{ document_key: document_key }}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_s
|
29
|
+
"POST #{uri.request_uri}"
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def extract_file(_request, response)
|
35
|
+
File.write(@output_file, response.body)
|
36
|
+
end
|
37
|
+
|
38
|
+
def path
|
39
|
+
"document/#{document_id}/result"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# Copyright 2024 DeepL SE (https://www.deepl.com)
|
2
|
+
# Use of this source code is governed by an MIT
|
3
|
+
# license that can be found in the LICENSE file.
|
4
|
+
# frozen_string_literal: true
|
5
|
+
|
6
|
+
module DeepL
|
7
|
+
module Requests
|
8
|
+
module Document
|
9
|
+
class GetStatus < Base
|
10
|
+
attr_reader :document_id, :document_key
|
11
|
+
|
12
|
+
def initialize(api, document_id, document_key, options = {}, additional_headers = {})
|
13
|
+
super(api, options, additional_headers)
|
14
|
+
@document_id = document_id
|
15
|
+
@document_key = document_key
|
16
|
+
end
|
17
|
+
|
18
|
+
def request
|
19
|
+
payload = { document_key: document_key }
|
20
|
+
build_doc_translation_status(*execute_request_with_retries(post_request(payload)))
|
21
|
+
end
|
22
|
+
|
23
|
+
def details
|
24
|
+
"HTTP Headers: #{headers}\nPayload #{{ document_key: document_key }}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
"POST #{uri.request_uri}"
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def build_doc_translation_status(request, response)
|
34
|
+
document_translation_status = JSON.parse(response.body)
|
35
|
+
Resources::DocumentTranslationStatus.new(document_translation_status, request, response)
|
36
|
+
end
|
37
|
+
|
38
|
+
def path
|
39
|
+
"document/#{document_id}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# Copyright 2024 DeepL SE (https://www.deepl.com)
|
2
|
+
# Use of this source code is governed by an MIT
|
3
|
+
# license that can be found in the LICENSE file.
|
4
|
+
# frozen_string_literal: true
|
5
|
+
|
6
|
+
module DeepL
|
7
|
+
module Requests
|
8
|
+
module Document
|
9
|
+
class Upload < Base
|
10
|
+
attr_reader :input_file_path, :source_lang, :target_lang, :filename
|
11
|
+
|
12
|
+
SUPPORTED_OPTIONS = %w[formality glossary_id output_format].freeze
|
13
|
+
|
14
|
+
def initialize(api, input_file_path, source_lang, target_lang, filename = nil, # rubocop:disable Metrics/ParameterLists
|
15
|
+
options = {}, additional_headers = {})
|
16
|
+
super(api, options, additional_headers)
|
17
|
+
@input_file_path = input_file_path
|
18
|
+
@source_lang = source_lang
|
19
|
+
@target_lang = target_lang
|
20
|
+
@filename = filename
|
21
|
+
end
|
22
|
+
|
23
|
+
def request # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
24
|
+
input_file = File.open(input_file_path, 'rb')
|
25
|
+
form_data = [
|
26
|
+
['file', input_file], ['source_lang', source_lang],
|
27
|
+
['target_lang', target_lang]
|
28
|
+
]
|
29
|
+
filename_param = filename || File.basename(input_file_path)
|
30
|
+
form_data.push(['filename', filename_param]) unless filename_param.nil?
|
31
|
+
# Manually add options due to multipart/form-data request
|
32
|
+
SUPPORTED_OPTIONS.each do |option|
|
33
|
+
form_data.push([option, options[option]]) unless options[option].nil?
|
34
|
+
end
|
35
|
+
build_doc_handle(*execute_request_with_retries(post_request_with_file(form_data),
|
36
|
+
[input_file]))
|
37
|
+
end
|
38
|
+
|
39
|
+
def details
|
40
|
+
"HTTP Headers: #{headers}\nPayload #{[
|
41
|
+
['file', "File at #{input_file_path} opened in binary mode"],
|
42
|
+
['source_lang', source_lang], ['target_lang', target_lang], ['filename', filename]
|
43
|
+
]}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_s
|
47
|
+
"POST #{uri.request_uri}"
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def build_doc_handle(request, response)
|
53
|
+
parsed_response = JSON.parse(response.body)
|
54
|
+
Resources::DocumentHandle.new(parsed_response['document_id'],
|
55
|
+
parsed_response['document_key'], request, response)
|
56
|
+
end
|
57
|
+
|
58
|
+
def path
|
59
|
+
'document'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -1,3 +1,6 @@
|
|
1
|
+
# Copyright 2022 Daniel Herzog
|
2
|
+
# Use of this source code is governed by an MIT
|
3
|
+
# license that can be found in the LICENSE.md file.
|
1
4
|
# frozen_string_literal: true
|
2
5
|
|
3
6
|
module DeepL
|
@@ -20,7 +23,18 @@ module DeepL
|
|
20
23
|
name: name, source_lang: source_lang, target_lang: target_lang, entries: entries_to_tsv,
|
21
24
|
entries_format: entries_format
|
22
25
|
}
|
23
|
-
build_glossary(*
|
26
|
+
build_glossary(*execute_request_with_retries(post_request(payload)))
|
27
|
+
end
|
28
|
+
|
29
|
+
def details
|
30
|
+
"HTTP Headers: #{headers}\nPayload #{{
|
31
|
+
name: name, source_lang: source_lang, target_lang: target_lang, entries: entries_to_tsv,
|
32
|
+
entries_format: entries_format
|
33
|
+
}}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_s
|
37
|
+
"POST #{uri.request_uri}"
|
24
38
|
end
|
25
39
|
|
26
40
|
private
|
@@ -1,3 +1,6 @@
|
|
1
|
+
# Copyright 2022 Daniel Herzog
|
2
|
+
# Use of this source code is governed by an MIT
|
3
|
+
# license that can be found in the LICENSE.md file.
|
1
4
|
# frozen_string_literal: true
|
2
5
|
|
3
6
|
module DeepL
|
@@ -12,7 +15,11 @@ module DeepL
|
|
12
15
|
end
|
13
16
|
|
14
17
|
def request
|
15
|
-
build_response(*
|
18
|
+
build_response(*execute_request_with_retries(delete_request))
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
"DELETE #{uri.request_uri}"
|
16
23
|
end
|
17
24
|
|
18
25
|
private
|
@@ -1,3 +1,6 @@
|
|
1
|
+
# Copyright 2022 Daniel Herzog
|
2
|
+
# Use of this source code is governed by an MIT
|
3
|
+
# license that can be found in the LICENSE.md file.
|
1
4
|
# frozen_string_literal: true
|
2
5
|
|
3
6
|
module DeepL
|
@@ -12,7 +15,11 @@ module DeepL
|
|
12
15
|
end
|
13
16
|
|
14
17
|
def request
|
15
|
-
build_entries(*
|
18
|
+
build_entries(*execute_request_with_retries(get_request))
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
"GET #{uri.request_uri}"
|
16
23
|
end
|
17
24
|
|
18
25
|
private
|
@@ -1,3 +1,6 @@
|
|
1
|
+
# Copyright 2022 Daniel Herzog
|
2
|
+
# Use of this source code is governed by an MIT
|
3
|
+
# license that can be found in the LICENSE.md file.
|
1
4
|
# frozen_string_literal: true
|
2
5
|
|
3
6
|
module DeepL
|
@@ -12,7 +15,11 @@ module DeepL
|
|
12
15
|
end
|
13
16
|
|
14
17
|
def request
|
15
|
-
build_glossary(*
|
18
|
+
build_glossary(*execute_request_with_retries(get_request))
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
"GET #{uri.request_uri}"
|
16
23
|
end
|
17
24
|
|
18
25
|
private
|
@@ -1,3 +1,6 @@
|
|
1
|
+
# Copyright 2022 Daniel Herzog
|
2
|
+
# Use of this source code is governed by an MIT
|
3
|
+
# license that can be found in the LICENSE.md file.
|
1
4
|
# frozen_string_literal: true
|
2
5
|
|
3
6
|
module DeepL
|
@@ -5,11 +8,15 @@ module DeepL
|
|
5
8
|
module Glossary
|
6
9
|
class LanguagePairs < Base
|
7
10
|
def initialize(api, options = {})
|
8
|
-
super
|
11
|
+
super
|
9
12
|
end
|
10
13
|
|
11
14
|
def request
|
12
|
-
build_language_pair_list(*
|
15
|
+
build_language_pair_list(*execute_request_with_retries(get_request))
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
"GET #{uri.request_uri}"
|
13
20
|
end
|
14
21
|
|
15
22
|
private
|
@@ -1,3 +1,6 @@
|
|
1
|
+
# Copyright 2022 Daniel Herzog
|
2
|
+
# Use of this source code is governed by an MIT
|
3
|
+
# license that can be found in the LICENSE.md file.
|
1
4
|
# frozen_string_literal: true
|
2
5
|
|
3
6
|
module DeepL
|
@@ -5,11 +8,15 @@ module DeepL
|
|
5
8
|
module Glossary
|
6
9
|
class List < Base
|
7
10
|
def initialize(api, options = {})
|
8
|
-
super
|
11
|
+
super
|
9
12
|
end
|
10
13
|
|
11
14
|
def request
|
12
|
-
build_glossary_list(*
|
15
|
+
build_glossary_list(*execute_request_with_retries(get_request))
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
"GET #{uri.request_uri}"
|
13
20
|
end
|
14
21
|
|
15
22
|
private
|
@@ -1,14 +1,21 @@
|
|
1
|
+
# Copyright 2021 Daniel Herzog
|
2
|
+
# Use of this source code is governed by an MIT
|
3
|
+
# license that can be found in the LICENSE.md file.
|
1
4
|
# frozen_string_literal: true
|
2
5
|
|
3
6
|
module DeepL
|
4
7
|
module Requests
|
5
8
|
class Languages < Base
|
6
9
|
def initialize(api, options = {})
|
7
|
-
super
|
10
|
+
super
|
8
11
|
end
|
9
12
|
|
10
13
|
def request
|
11
|
-
build_languages(*
|
14
|
+
build_languages(*execute_request_with_retries(get_request))
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
"GET #{uri.request_uri}"
|
12
19
|
end
|
13
20
|
|
14
21
|
private
|
@@ -1,17 +1,29 @@
|
|
1
|
+
# Copyright 2018 Daniel Herzog
|
2
|
+
# Use of this source code is governed by an MIT
|
3
|
+
# license that can be found in the LICENSE.md file.
|
1
4
|
# frozen_string_literal: true
|
2
5
|
|
3
6
|
module DeepL
|
4
7
|
module Requests
|
5
8
|
class Translate < Base
|
6
|
-
|
7
|
-
|
9
|
+
STRING_TO_BOOLEAN_MAP = { '1' => true, '0' => false }.freeze
|
10
|
+
BOOLEAN_TO_STRING_MAP = { true => '1', false => '0' }.freeze
|
11
|
+
STRING_TO_BOOLEAN_CONVERSION = ->(value) { STRING_TO_BOOLEAN_MAP[value] }
|
12
|
+
BOOLEAN_TO_STRING_CONVERSION = ->(value) { BOOLEAN_TO_STRING_MAP[value] }
|
13
|
+
STRING_TO_ARRAY_CONVERSION = lambda { |value|
|
14
|
+
if value.nil?
|
15
|
+
nil
|
16
|
+
else
|
17
|
+
(value.is_a?(Array) ? value : value.split(','))
|
18
|
+
end
|
19
|
+
}.freeze
|
8
20
|
OPTIONS_CONVERSIONS = {
|
9
|
-
split_sentences:
|
10
|
-
preserve_formatting:
|
11
|
-
outline_detection:
|
12
|
-
splitting_tags:
|
13
|
-
non_splitting_tags:
|
14
|
-
ignore_tags:
|
21
|
+
split_sentences: BOOLEAN_TO_STRING_CONVERSION,
|
22
|
+
preserve_formatting: STRING_TO_BOOLEAN_CONVERSION,
|
23
|
+
outline_detection: STRING_TO_BOOLEAN_CONVERSION,
|
24
|
+
splitting_tags: STRING_TO_ARRAY_CONVERSION,
|
25
|
+
non_splitting_tags: STRING_TO_ARRAY_CONVERSION,
|
26
|
+
ignore_tags: STRING_TO_ARRAY_CONVERSION
|
15
27
|
}.freeze
|
16
28
|
|
17
29
|
attr_reader :text, :source_lang, :target_lang, :ignore_tags, :splitting_tags,
|
@@ -27,15 +39,25 @@ module DeepL
|
|
27
39
|
end
|
28
40
|
|
29
41
|
def request
|
30
|
-
|
31
|
-
|
42
|
+
text_arrayified = text.is_a?(Array) ? text : [text]
|
43
|
+
payload = { text: text_arrayified, source_lang: source_lang, target_lang: target_lang }
|
44
|
+
build_texts(*execute_request_with_retries(post_request(payload)))
|
45
|
+
end
|
46
|
+
|
47
|
+
def details
|
48
|
+
"HTTP Headers: #{headers}\nPayload #{{ text: text, source_lang: source_lang,
|
49
|
+
target_lang: target_lang }}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_s
|
53
|
+
"POST #{uri.request_uri}"
|
32
54
|
end
|
33
55
|
|
34
56
|
private
|
35
57
|
|
36
58
|
def tweak_parameters!
|
37
59
|
OPTIONS_CONVERSIONS.each do |param, converter|
|
38
|
-
next unless option?(param) && converter[option(param)]
|
60
|
+
next unless option?(param) && !converter[option(param)].nil?
|
39
61
|
|
40
62
|
set_option(param, converter[option(param)])
|
41
63
|
end
|
data/lib/deepl/requests/usage.rb
CHANGED
@@ -1,14 +1,21 @@
|
|
1
|
+
# Copyright 2018 Daniel Herzog
|
2
|
+
# Use of this source code is governed by an MIT
|
3
|
+
# license that can be found in the LICENSE.md file.
|
1
4
|
# frozen_string_literal: true
|
2
5
|
|
3
6
|
module DeepL
|
4
7
|
module Requests
|
5
8
|
class Usage < Base
|
6
9
|
def initialize(api, options = {})
|
7
|
-
super
|
10
|
+
super
|
8
11
|
end
|
9
12
|
|
10
13
|
def request
|
11
|
-
build_usage(*
|
14
|
+
build_usage(*execute_request_with_retries(get_request))
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
"GET #{uri.request_uri}"
|
12
19
|
end
|
13
20
|
|
14
21
|
private
|
data/lib/deepl/resources/base.rb
CHANGED
@@ -0,0 +1,57 @@
|
|
1
|
+
# Copyright 2024 DeepL SE (https://www.deepl.com)
|
2
|
+
# Use of this source code is governed by an MIT
|
3
|
+
# license that can be found in the LICENSE file.
|
4
|
+
# frozen_string_literal: true
|
5
|
+
|
6
|
+
module DeepL
|
7
|
+
module Resources
|
8
|
+
class DocumentHandle < Base
|
9
|
+
attr_reader :document_id, :document_key
|
10
|
+
|
11
|
+
def initialize(document_id, document_key, *args)
|
12
|
+
super(*args)
|
13
|
+
|
14
|
+
@document_id = document_id
|
15
|
+
@document_key = document_key
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
"DocumentHandle: ID: #{document_id} - Key: #{document_key}"
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# For this DocumentHandle, waits until the document translation is finished and returns the
|
24
|
+
# final status of the document.
|
25
|
+
#
|
26
|
+
# @return [DeepL::Resources::DocumentTranslationStatus] Final status of the document
|
27
|
+
# translation.
|
28
|
+
|
29
|
+
def wait_until_document_translation_finished
|
30
|
+
doc_status = nil
|
31
|
+
max_tries = max_doc_status_queries
|
32
|
+
num_tries = 0
|
33
|
+
loop do
|
34
|
+
num_tries += 1
|
35
|
+
sleep(calculate_waiting_time(doc_status)) unless doc_status.nil?
|
36
|
+
doc_status = DeepL.document.get_status(self)
|
37
|
+
break if doc_status.finished? || num_tries > max_tries
|
38
|
+
end
|
39
|
+
doc_status
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def calculate_waiting_time(_resp)
|
45
|
+
# ignore _resp.seconds_remaining for now, while it is unreliable
|
46
|
+
5
|
47
|
+
end
|
48
|
+
|
49
|
+
def max_doc_status_queries
|
50
|
+
configured_value = DeepL.configuration.max_doc_status_queries
|
51
|
+
return configured_value unless configured_value.nil?
|
52
|
+
|
53
|
+
10
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|