deepl-rb 3.9.0 → 3.10.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.
- checksums.yaml +4 -4
- data/.gitlab-ci.yml +70 -52
- data/.rubocop.yml +26 -0
- data/CHANGELOG.md +429 -18
- data/Gemfile +4 -0
- data/README.md +981 -223
- data/Rakefile +18 -5
- data/VERSION +1 -1
- data/deepl-rb.gemspec +6 -6
- data/lib/deepl/admin_client.rb +183 -0
- data/lib/deepl/api.rb +30 -6
- data/lib/deepl/app_info.rb +20 -0
- data/lib/deepl/client.rb +969 -0
- data/lib/deepl/configuration.rb +56 -10
- data/lib/deepl/constants/admin_usage_group_by.rb +13 -0
- data/lib/deepl/constants/custom_tag_usage_aggregate_by.rb +13 -0
- data/lib/deepl/constants/document_status_code.rb +17 -0
- data/lib/deepl/constants/language_include.rb +17 -0
- data/lib/deepl/constants/language_resource_name.rb +21 -0
- data/lib/deepl/constants/tag_handling_version.rb +14 -0
- data/lib/deepl/deprecation.rb +42 -0
- data/lib/deepl/document_api.rb +41 -22
- data/lib/deepl/exceptions/bad_request.rb +1 -3
- data/lib/deepl/exceptions/connection_error.rb +37 -0
- data/lib/deepl/exceptions/document_not_ready_error.rb +17 -0
- data/lib/deepl/exceptions/document_translation_error.rb +17 -1
- data/lib/deepl/exceptions/error.rb +13 -1
- data/lib/deepl/exceptions/not_found.rb +8 -3
- data/lib/deepl/exceptions/not_supported.rb +6 -0
- data/lib/deepl/exceptions/request_error.rb +19 -2
- data/lib/deepl/exceptions/server_error.rb +7 -1
- data/lib/deepl/exceptions/validation_error.rb +14 -0
- data/lib/deepl/requests/admin/base.rb +94 -0
- data/lib/deepl/requests/admin/create_developer_key.rb +38 -0
- data/lib/deepl/requests/admin/custom_tag_usage_analytics.rb +38 -0
- data/lib/deepl/requests/admin/list_developer_keys.rb +28 -0
- data/lib/deepl/requests/admin/update_developer_key.rb +35 -0
- data/lib/deepl/requests/admin/usage_analytics.rb +36 -0
- data/lib/deepl/requests/base.rb +229 -59
- data/lib/deepl/requests/correct.rb +57 -0
- data/lib/deepl/requests/document/download.rb +11 -3
- data/lib/deepl/requests/document/get_status.rb +2 -2
- data/lib/deepl/requests/document/upload.rb +43 -10
- data/lib/deepl/requests/glossary/create.rb +6 -2
- data/lib/deepl/requests/glossary/language_pairs.rb +20 -4
- data/lib/deepl/requests/language_resources.rb +41 -0
- data/lib/deepl/requests/languages.rb +28 -4
- data/lib/deepl/requests/languages_for_resource.rb +54 -0
- data/lib/deepl/requests/multilingual_glossary/create.rb +37 -0
- data/lib/deepl/requests/multilingual_glossary/destroy.rb +36 -0
- data/lib/deepl/requests/multilingual_glossary/destroy_dictionary.rb +51 -0
- data/lib/deepl/requests/multilingual_glossary/entries.rb +66 -0
- data/lib/deepl/requests/multilingual_glossary/find.rb +35 -0
- data/lib/deepl/requests/multilingual_glossary/helpers.rb +63 -0
- data/lib/deepl/requests/multilingual_glossary/list.rb +39 -0
- data/lib/deepl/requests/multilingual_glossary/replace_dictionary.rb +41 -0
- data/lib/deepl/requests/multilingual_glossary/update.rb +40 -0
- data/lib/deepl/requests/rephrase.rb +5 -9
- data/lib/deepl/requests/spoken_terms/create.rb +37 -0
- data/lib/deepl/requests/spoken_terms/destroy.rb +36 -0
- data/lib/deepl/requests/spoken_terms/destroy_term_list.rb +41 -0
- data/lib/deepl/requests/spoken_terms/entries.rb +46 -0
- data/lib/deepl/requests/spoken_terms/find.rb +35 -0
- data/lib/deepl/requests/spoken_terms/helpers.rb +67 -0
- data/lib/deepl/requests/spoken_terms/list.rb +35 -0
- data/lib/deepl/requests/spoken_terms/replace_term_list.rb +41 -0
- data/lib/deepl/requests/spoken_terms/update.rb +40 -0
- data/lib/deepl/requests/style_profile/base.rb +83 -0
- data/lib/deepl/requests/style_profile/create.rb +35 -0
- data/lib/deepl/requests/style_profile/destroy.rb +34 -0
- data/lib/deepl/requests/style_profile/find.rb +33 -0
- data/lib/deepl/requests/style_profile/list.rb +43 -0
- data/lib/deepl/requests/style_profile/update.rb +35 -0
- data/lib/deepl/requests/style_rule/create.rb +1 -1
- data/lib/deepl/requests/style_rule/create_custom_instruction.rb +4 -2
- data/lib/deepl/requests/style_rule/destroy.rb +4 -2
- data/lib/deepl/requests/style_rule/destroy_custom_instruction.rb +5 -3
- data/lib/deepl/requests/style_rule/find.rb +4 -2
- data/lib/deepl/requests/style_rule/find_custom_instruction.rb +5 -3
- data/lib/deepl/requests/style_rule/helpers.rb +35 -0
- data/lib/deepl/requests/style_rule/list.rb +1 -1
- data/lib/deepl/requests/style_rule/update.rb +4 -2
- data/lib/deepl/requests/style_rule/update_configured_rules.rb +4 -2
- data/lib/deepl/requests/style_rule/update_custom_instruction.rb +5 -3
- data/lib/deepl/requests/translate.rb +52 -20
- data/lib/deepl/requests/translation_memory/base.rb +1 -4
- data/lib/deepl/requests/translation_memory/create_export.rb +1 -1
- data/lib/deepl/requests/translation_memory/create_import.rb +1 -1
- data/lib/deepl/requests/translation_memory/destroy.rb +1 -1
- data/lib/deepl/requests/translation_memory/download_export.rb +4 -0
- data/lib/deepl/requests/translation_memory/find.rb +1 -1
- data/lib/deepl/requests/translation_memory/find_job.rb +1 -1
- data/lib/deepl/requests/translation_memory/list.rb +2 -1
- data/lib/deepl/requests/translation_memory/segments.rb +3 -2
- data/lib/deepl/requests/translation_memory/storage_base.rb +40 -8
- data/lib/deepl/requests/translation_memory/upload_file.rb +1 -1
- data/lib/deepl/requests/usage.rb +28 -1
- data/lib/deepl/requests/write_improvements.rb +35 -0
- data/lib/deepl/resources/admin_usage_report.rb +73 -0
- data/lib/deepl/resources/custom_tag_usage_report.rb +59 -0
- data/lib/deepl/resources/developer_key.rb +57 -0
- data/lib/deepl/resources/document_handle.rb +24 -25
- data/lib/deepl/resources/document_translation_status.rb +23 -4
- data/lib/deepl/resources/language.rb +10 -2
- data/lib/deepl/resources/language_resource.rb +57 -0
- data/lib/deepl/resources/language_support.rb +56 -0
- data/lib/deepl/resources/multilingual_glossary.rb +112 -0
- data/lib/deepl/resources/spoken_terms.rb +61 -0
- data/lib/deepl/resources/style_profile.rb +44 -0
- data/lib/deepl/resources/style_rule.rb +3 -0
- data/lib/deepl/resources/text.rb +18 -2
- data/lib/deepl/resources/translation_memory.rb +8 -2
- data/lib/deepl/resources/translation_memory_import.rb +1 -1
- data/lib/deepl/resources/translation_memory_job.rb +23 -3
- data/lib/deepl/resources/translation_memory_segments.rb +8 -6
- data/lib/deepl/resources/usage.rb +93 -4
- data/lib/deepl/style_rule_api.rb +11 -0
- data/lib/deepl/translation_memory_api.rb +104 -24
- data/lib/deepl/utils/client_builder.rb +54 -0
- data/lib/deepl/utils/document_poller.rb +70 -0
- data/lib/deepl/utils/exception_builder.rb +3 -2
- data/lib/deepl/utils/http_client_builder.rb +79 -0
- data/lib/deepl/utils/number_parser.rb +34 -0
- data/lib/deepl/utils/term_validator.rb +33 -0
- data/lib/deepl/utils/time_parser.rb +14 -0
- data/lib/deepl.rb +166 -41
- data/lib/http_client_options.rb +21 -1
- data/lib/version.rb +1 -1
- data/spec/fixtures.rb +33 -0
- data/spec/offline/admin_client_spec.rb +551 -0
- data/spec/offline/client_spec.rb +273 -0
- data/spec/{api → offline}/configuration_spec.rb +45 -3
- data/spec/{constants → offline}/constants_spec.rb +23 -1
- data/spec/offline/correct_text_spec.rb +50 -0
- data/spec/offline/deprecation_spec.rb +32 -0
- data/spec/offline/errors_spec.rb +92 -0
- data/spec/offline/glossaries_spec.rb +98 -0
- data/spec/offline/http_client_spec.rb +319 -0
- data/spec/offline/languages_spec.rb +155 -0
- data/spec/offline/module_methods_spec.rb +13 -0
- data/spec/offline/multilingual_glossaries_spec.rb +358 -0
- data/spec/offline/offline_helper.rb +71 -0
- data/spec/offline/rephrase_text_spec.rb +73 -0
- data/spec/offline/spoken_terms_spec.rb +215 -0
- data/spec/offline/style_profiles_spec.rb +266 -0
- data/spec/offline/style_rules_spec.rb +318 -0
- data/spec/offline/translate_document_spec.rb +606 -0
- data/spec/offline/translate_text_spec.rb +286 -0
- data/spec/offline/translation_memories_client_spec.rb +256 -0
- data/spec/offline/translation_memories_spec.rb +463 -0
- data/spec/offline/usage_spec.rb +151 -0
- data/spec/real_api/admin_client_spec.rb +77 -0
- data/spec/real_api/correct_text_spec.rb +20 -0
- data/spec/real_api/glossaries_spec.rb +28 -0
- data/spec/real_api/languages_spec.rb +27 -0
- data/spec/real_api/multilingual_glossaries_spec.rb +53 -0
- data/spec/real_api/proxy_spec.rb +41 -0
- data/spec/real_api/real_api_helper.rb +65 -0
- data/spec/real_api/rephrase_text_spec.rb +16 -0
- data/spec/real_api/spoken_terms_spec.rb +56 -0
- data/spec/real_api/style_profiles_spec.rb +46 -0
- data/spec/real_api/style_rules_spec.rb +46 -0
- data/spec/real_api/translate_document_spec.rb +18 -0
- data/spec/real_api/translate_text_spec.rb +16 -0
- data/spec/real_api/translation_memories_spec.rb +56 -0
- data/spec/real_api/usage_spec.rb +20 -0
- data/spec/spec_helper.rb +1 -50
- metadata +116 -76
- data/.circleci/config.yml +0 -27
- data/.github/workflows/add_issues_to_kanban.yml +0 -16
- data/spec/api/api_spec.rb +0 -20
- data/spec/api/deepl_spec.rb +0 -262
- data/spec/integration_tests/document_api_spec.rb +0 -211
- data/spec/integration_tests/document_error_paths_spec.rb +0 -33
- data/spec/integration_tests/glossary_api_spec.rb +0 -114
- data/spec/integration_tests/glossary_error_paths_spec.rb +0 -107
- data/spec/integration_tests/integration_test_utils.rb +0 -178
- data/spec/integration_tests/languages_api_spec.rb +0 -54
- data/spec/integration_tests/languages_error_paths_spec.rb +0 -25
- data/spec/integration_tests/rephrase_api_spec.rb +0 -90
- data/spec/integration_tests/rephrase_error_paths_spec.rb +0 -53
- data/spec/integration_tests/smoke_test_spec.rb +0 -24
- data/spec/integration_tests/style_rule_api_spec.rb +0 -117
- data/spec/integration_tests/style_rule_error_paths_spec.rb +0 -45
- data/spec/integration_tests/translate_api_spec.rb +0 -117
- data/spec/integration_tests/translate_error_paths_spec.rb +0 -48
- data/spec/integration_tests/translation_memory_api_spec.rb +0 -244
- data/spec/integration_tests/translation_memory_error_paths_spec.rb +0 -87
- data/spec/integration_tests/usage_api_spec.rb +0 -29
- data/spec/integration_tests/usage_error_paths_spec.rb +0 -18
- data/spec/requests/document/upload_spec.rb +0 -130
- data/spec/requests/extra_body_parameters_types_spec.rb +0 -82
- data/spec/requests/glossary/create_spec.rb +0 -44
- data/spec/requests/glossary/destroy_spec.rb +0 -27
- data/spec/requests/glossary/entries_spec.rb +0 -27
- data/spec/requests/glossary/find_spec.rb +0 -28
- data/spec/requests/glossary/language_pairs_spec.rb +0 -27
- data/spec/requests/glossary/list_spec.rb +0 -27
- data/spec/requests/languages_spec.rb +0 -27
- data/spec/requests/rephrase_spec.rb +0 -46
- data/spec/requests/style_rule/create_custom_instruction_spec.rb +0 -30
- data/spec/requests/style_rule/create_spec.rb +0 -29
- data/spec/requests/style_rule/destroy_custom_instruction_spec.rb +0 -28
- data/spec/requests/style_rule/destroy_spec.rb +0 -27
- data/spec/requests/style_rule/find_custom_instruction_spec.rb +0 -29
- data/spec/requests/style_rule/find_spec.rb +0 -28
- data/spec/requests/style_rule/list_spec.rb +0 -27
- data/spec/requests/style_rule/update_configured_rules_spec.rb +0 -31
- data/spec/requests/style_rule/update_custom_instruction_spec.rb +0 -32
- data/spec/requests/style_rule/update_spec.rb +0 -29
- data/spec/requests/translate_spec.rb +0 -338
- data/spec/requests/translation_memory/create_export_spec.rb +0 -37
- data/spec/requests/translation_memory/create_import_spec.rb +0 -61
- data/spec/requests/translation_memory/destroy_spec.rb +0 -36
- data/spec/requests/translation_memory/download_export_spec.rb +0 -54
- data/spec/requests/translation_memory/find_job_spec.rb +0 -37
- data/spec/requests/translation_memory/find_spec.rb +0 -36
- data/spec/requests/translation_memory/list_spec.rb +0 -27
- data/spec/requests/translation_memory/segments_spec.rb +0 -58
- data/spec/requests/translation_memory/upload_file_spec.rb +0 -55
- data/spec/requests/usage_spec.rb +0 -27
- data/spec/resources/custom_instruction_spec.rb +0 -32
- data/spec/resources/glossary_spec.rb +0 -38
- data/spec/resources/language_pair_spec.rb +0 -23
- data/spec/resources/language_spec.rb +0 -45
- data/spec/resources/style_rule_spec.rb +0 -68
- data/spec/resources/text_spec.rb +0 -23
- data/spec/resources/translation_memory_export_spec.rb +0 -38
- data/spec/resources/translation_memory_import_spec.rb +0 -30
- data/spec/resources/translation_memory_job_spec.rb +0 -109
- data/spec/resources/translation_memory_segments_spec.rb +0 -78
- data/spec/resources/translation_memory_spec.rb +0 -52
- data/spec/resources/usage_spec.rb +0 -35
- data/spec/support/live_mock_server.rb +0 -12
- data/spec/support/managed_glossary.rb +0 -65
- data/spec/support/managed_style_rule.rb +0 -17
- data/spec/support/managed_translation_memory.rb +0 -55
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Copyright 2026 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.md file.
|
|
4
|
+
# frozen_string_literal: true
|
|
5
|
+
|
|
6
|
+
module DeepL
|
|
7
|
+
module Requests
|
|
8
|
+
class Correct < Base
|
|
9
|
+
include WriteImprovements
|
|
10
|
+
|
|
11
|
+
attr_reader :text, :target_lang
|
|
12
|
+
|
|
13
|
+
def initialize(api, text, target_lang = nil, options = {}, additional_headers = {})
|
|
14
|
+
super(api, options, additional_headers)
|
|
15
|
+
@text = text
|
|
16
|
+
@target_lang = target_lang
|
|
17
|
+
validate_text!
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def request
|
|
21
|
+
payload = { text: text_arrayified }
|
|
22
|
+
payload[:target_lang] = target_lang unless target_lang.nil?
|
|
23
|
+
build_texts(*execute_request_with_retries(post_request(payload)))
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def details
|
|
27
|
+
"HTTP Headers: #{loggable_headers}\nPayload #{{ text: text, target_lang: target_lang }}"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def to_s
|
|
31
|
+
"POST #{uri.request_uri}"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def text_arrayified
|
|
37
|
+
text.is_a?(Array) ? text : [text]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def validate_text!
|
|
41
|
+
return unless text_arrayified.empty? || text_arrayified.any? { |t| t.to_s.empty? }
|
|
42
|
+
|
|
43
|
+
raise ArgumentError,
|
|
44
|
+
'`text` must be a non-empty string or a non-empty array of non-empty strings'
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def build_texts(request, response)
|
|
48
|
+
texts = build_improvements(text_arrayified.size, request, response)
|
|
49
|
+
text.is_a?(Array) ? texts : texts.first
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def path
|
|
53
|
+
'write/correct'
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -22,7 +22,7 @@ module DeepL
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def details
|
|
25
|
-
"HTTP Headers: #{
|
|
25
|
+
"HTTP Headers: #{loggable_headers}\nPayload #{{ document_key: document_key }}"
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def to_s
|
|
@@ -31,12 +31,20 @@ module DeepL
|
|
|
31
31
|
|
|
32
32
|
private
|
|
33
33
|
|
|
34
|
+
# Binary mode: text mode would convert newlines on Windows and transcode the bytes when
|
|
35
|
+
# Encoding.default_internal is set.
|
|
34
36
|
def extract_file(_request, response)
|
|
35
|
-
File.
|
|
37
|
+
File.binwrite(@output_file, response.body)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def validate_response!(response, request = nil)
|
|
41
|
+
raise Exceptions::DocumentNotReadyError.new(response, request) if response.code == '503'
|
|
42
|
+
|
|
43
|
+
super
|
|
36
44
|
end
|
|
37
45
|
|
|
38
46
|
def path
|
|
39
|
-
"document/#{document_id}/result"
|
|
47
|
+
"document/#{escape_path_segment(document_id)}/result"
|
|
40
48
|
end
|
|
41
49
|
end
|
|
42
50
|
end
|
|
@@ -21,7 +21,7 @@ module DeepL
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def details
|
|
24
|
-
"HTTP Headers: #{
|
|
24
|
+
"HTTP Headers: #{loggable_headers}\nPayload #{{ document_key: document_key }}"
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def to_s
|
|
@@ -36,7 +36,7 @@ module DeepL
|
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def path
|
|
39
|
-
"document/#{document_id}"
|
|
39
|
+
"document/#{escape_path_segment(document_id)}"
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
42
|
end
|
|
@@ -9,11 +9,12 @@ module DeepL
|
|
|
9
9
|
class Upload < Base
|
|
10
10
|
attr_reader :input_file_path, :source_lang, :target_lang, :filename
|
|
11
11
|
|
|
12
|
-
SUPPORTED_OPTIONS = %w[formality glossary_id output_format].freeze
|
|
12
|
+
SUPPORTED_OPTIONS = %w[formality glossary_id output_format enable_watermark].freeze
|
|
13
13
|
|
|
14
14
|
def initialize(api, input_file_path, source_lang, target_lang, filename = nil, # rubocop:disable Metrics/ParameterLists
|
|
15
15
|
options = {}, additional_headers = {})
|
|
16
|
-
|
|
16
|
+
# Options set to nil are unset and not sent.
|
|
17
|
+
super(api, options.compact, additional_headers)
|
|
17
18
|
@input_file_path = input_file_path
|
|
18
19
|
@source_lang = source_lang
|
|
19
20
|
@target_lang = target_lang
|
|
@@ -30,7 +31,7 @@ module DeepL
|
|
|
30
31
|
end
|
|
31
32
|
|
|
32
33
|
def details
|
|
33
|
-
"HTTP Headers: #{
|
|
34
|
+
"HTTP Headers: #{loggable_headers}\nPayload #{[
|
|
34
35
|
['file', "File at #{input_file_path} opened in binary mode"],
|
|
35
36
|
['source_lang', source_lang], ['target_lang', target_lang], ['filename', filename]
|
|
36
37
|
]}"
|
|
@@ -43,10 +44,9 @@ module DeepL
|
|
|
43
44
|
private
|
|
44
45
|
|
|
45
46
|
def build_base_form_data(input_file)
|
|
46
|
-
form_data = [
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
]
|
|
47
|
+
form_data = [['file', input_file]]
|
|
48
|
+
form_data.push(['source_lang', source_lang]) unless source_lang.nil?
|
|
49
|
+
form_data.push(['target_lang', target_lang])
|
|
50
50
|
filename_param = filename || File.basename(input_file_path)
|
|
51
51
|
form_data.push(['filename', filename_param]) unless filename_param.nil?
|
|
52
52
|
add_extra_options_to_form(form_data)
|
|
@@ -56,7 +56,9 @@ module DeepL
|
|
|
56
56
|
def add_extra_options_to_form(form_data)
|
|
57
57
|
add_supported_options_to_form(form_data)
|
|
58
58
|
add_glossary_ids_to_form(form_data)
|
|
59
|
+
add_glossary_to_form(form_data)
|
|
59
60
|
add_style_rule_to_form(form_data)
|
|
61
|
+
add_style_profile_to_form(form_data)
|
|
60
62
|
add_translation_memory_to_form(form_data)
|
|
61
63
|
add_translation_memory_threshold_to_form(form_data)
|
|
62
64
|
end
|
|
@@ -66,10 +68,22 @@ module DeepL
|
|
|
66
68
|
# comma-separated `glossary_ids` field. Requires `source_lang`, cannot be combined with
|
|
67
69
|
# the singular `glossary_id` option, and allows at most 5 IDs.
|
|
68
70
|
def add_glossary_ids_to_form(form_data)
|
|
69
|
-
glossary_ids = build_glossary_ids_param
|
|
71
|
+
glossary_ids = build_glossary_ids_param
|
|
72
|
+
# Text translation detects the source language for glossaries; documents do not.
|
|
73
|
+
if !glossary_ids.nil? && source_lang.nil?
|
|
74
|
+
raise ArgumentError, 'The `glossary_ids` option requires `source_lang` to be set'
|
|
75
|
+
end
|
|
76
|
+
|
|
70
77
|
form_data.push(['glossary_ids', glossary_ids.join(',')]) unless glossary_ids.nil?
|
|
71
78
|
end
|
|
72
79
|
|
|
80
|
+
# Resolves the `glossary` option (an ID string, a `DeepL::Resources::Glossary` or a
|
|
81
|
+
# `DeepL::Resources::MultilingualGlossary`) and appends it as a `glossary_id` field.
|
|
82
|
+
def add_glossary_to_form(form_data)
|
|
83
|
+
glossary_id = build_glossary_param
|
|
84
|
+
form_data.push(['glossary_id', glossary_id]) unless glossary_id.nil?
|
|
85
|
+
end
|
|
86
|
+
|
|
73
87
|
# Serializes the `style_rule` option and appends it to the form data as a `style_id`
|
|
74
88
|
# field. Mirrors text translation: accepts either a style rule ID string or a
|
|
75
89
|
# `DeepL::Resources::StyleRule` object.
|
|
@@ -77,10 +91,24 @@ module DeepL
|
|
|
77
91
|
return unless option?(:style_rule)
|
|
78
92
|
|
|
79
93
|
rule = delete_option(:style_rule)
|
|
94
|
+
return if rule.nil?
|
|
95
|
+
|
|
80
96
|
style_id = rule.is_a?(DeepL::Resources::StyleRule) ? rule.style_id : rule
|
|
81
97
|
form_data.push(['style_id', style_id.to_s])
|
|
82
98
|
end
|
|
83
99
|
|
|
100
|
+
# Serializes the `style_profile` option (a style profile ID string or a
|
|
101
|
+
# `DeepL::Resources::StyleProfile` object) as a `style_profile_id` field.
|
|
102
|
+
def add_style_profile_to_form(form_data)
|
|
103
|
+
return unless option?(:style_profile)
|
|
104
|
+
|
|
105
|
+
profile = delete_option(:style_profile)
|
|
106
|
+
return if profile.nil?
|
|
107
|
+
|
|
108
|
+
profile = profile.style_profile_id if profile.is_a?(DeepL::Resources::StyleProfile)
|
|
109
|
+
form_data.push(['style_profile_id', profile.to_s])
|
|
110
|
+
end
|
|
111
|
+
|
|
84
112
|
# Serializes the `translation_memory` option and appends it to the form data as a
|
|
85
113
|
# `translation_memory_id` field. Mirrors text translation: the `translation_memory`
|
|
86
114
|
# option accepts either a translation memory ID string or a
|
|
@@ -89,6 +117,8 @@ module DeepL
|
|
|
89
117
|
return unless option?(:translation_memory)
|
|
90
118
|
|
|
91
119
|
tm = delete_option(:translation_memory)
|
|
120
|
+
return if tm.nil?
|
|
121
|
+
|
|
92
122
|
tm_id = tm.is_a?(DeepL::Resources::TranslationMemory) ? tm.translation_memory_id : tm
|
|
93
123
|
form_data.push(['translation_memory_id', tm_id.to_s])
|
|
94
124
|
end
|
|
@@ -99,20 +129,23 @@ module DeepL
|
|
|
99
129
|
return unless option?(:translation_memory_threshold)
|
|
100
130
|
|
|
101
131
|
threshold = delete_option(:translation_memory_threshold)
|
|
132
|
+
return if threshold.nil?
|
|
133
|
+
|
|
102
134
|
form_data.push(['translation_memory_threshold', threshold.to_s])
|
|
103
135
|
end
|
|
104
136
|
|
|
105
137
|
def add_supported_options_to_form(form_data)
|
|
106
138
|
SUPPORTED_OPTIONS.each do |option_name|
|
|
107
139
|
option_value = option(option_name)
|
|
108
|
-
form_data.push([option_name, option_value]) unless option_value.nil?
|
|
140
|
+
form_data.push([option_name, option_value.to_s]) unless option_value.nil?
|
|
109
141
|
end
|
|
110
142
|
end
|
|
111
143
|
|
|
112
144
|
def build_doc_handle(request, response)
|
|
113
145
|
parsed_response = JSON.parse(response.body)
|
|
114
146
|
Resources::DocumentHandle.new(parsed_response['document_id'],
|
|
115
|
-
parsed_response['document_key'], request, response
|
|
147
|
+
parsed_response['document_key'], request, response,
|
|
148
|
+
api: api)
|
|
116
149
|
end
|
|
117
150
|
|
|
118
151
|
def path
|
|
@@ -27,7 +27,7 @@ module DeepL
|
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def details
|
|
30
|
-
"HTTP Headers: #{
|
|
30
|
+
"HTTP Headers: #{loggable_headers}\nPayload #{{
|
|
31
31
|
name: name, source_lang: source_lang, target_lang: target_lang, entries: entries_to_tsv,
|
|
32
32
|
entries_format: entries_format
|
|
33
33
|
}}"
|
|
@@ -42,7 +42,11 @@ module DeepL
|
|
|
42
42
|
def entries_to_tsv
|
|
43
43
|
return entries if entries.is_a?(String)
|
|
44
44
|
|
|
45
|
-
entries.reduce('')
|
|
45
|
+
entries.reduce('') do |tsv, entry|
|
|
46
|
+
source = Utils::TermValidator.validate!(entry.first)
|
|
47
|
+
target = Utils::TermValidator.validate!(entry.last)
|
|
48
|
+
"#{tsv}#{source}\t#{target}\n"
|
|
49
|
+
end
|
|
46
50
|
end
|
|
47
51
|
|
|
48
52
|
def build_glossary(request, response)
|
|
@@ -23,14 +23,30 @@ module DeepL
|
|
|
23
23
|
|
|
24
24
|
def build_language_pair_list(request, response)
|
|
25
25
|
data = JSON.parse(response.body)
|
|
26
|
-
data
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
sources = langs_where(data, 'usable_as_source')
|
|
27
|
+
targets = langs_where(data, 'usable_as_target')
|
|
28
|
+
|
|
29
|
+
sources.product(targets).each_with_object([]) do |(source, target), pairs|
|
|
30
|
+
next if source == target
|
|
31
|
+
|
|
32
|
+
pairs << Resources::LanguagePair.new(source, target, request, response)
|
|
29
33
|
end
|
|
30
34
|
end
|
|
31
35
|
|
|
36
|
+
def langs_where(data, usable_key)
|
|
37
|
+
data.select { |language| language[usable_key] }.map { |language| language['lang'] }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def uri
|
|
41
|
+
@uri ||= URI("#{host}/v3/#{path}?resource=glossary")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def get_request # rubocop:disable Naming/AccessorMethodName
|
|
45
|
+
Net::HTTP::Get.new(uri.request_uri, add_json_content_type(headers))
|
|
46
|
+
end
|
|
47
|
+
|
|
32
48
|
def path
|
|
33
|
-
'
|
|
49
|
+
'languages'
|
|
34
50
|
end
|
|
35
51
|
end
|
|
36
52
|
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Copyright 2026 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
|
+
class LanguageResources < Base
|
|
9
|
+
def initialize(api, options = {})
|
|
10
|
+
super
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def request
|
|
14
|
+
build_language_resource_list(*execute_request_with_retries(get_request))
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def to_s
|
|
18
|
+
"GET #{uri.request_uri}"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def build_language_resource_list(request, response)
|
|
24
|
+
data = JSON.parse(response.body)
|
|
25
|
+
data.map { |resource| Resources::LanguageResource.new(resource, request, response) }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def uri
|
|
29
|
+
@uri ||= URI("#{host}/v3/#{path}")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def get_request # rubocop:disable Naming/AccessorMethodName
|
|
33
|
+
Net::HTTP::Get.new(uri.request_uri, add_json_content_type(headers))
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def path
|
|
37
|
+
'languages/resources'
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -6,8 +6,15 @@
|
|
|
6
6
|
module DeepL
|
|
7
7
|
module Requests
|
|
8
8
|
class Languages < Base
|
|
9
|
+
SUPPORTED_TYPES = %w[source target].freeze
|
|
10
|
+
|
|
9
11
|
def initialize(api, options = {})
|
|
10
12
|
super
|
|
13
|
+
@type = (delete_option(:type) || :source).to_s
|
|
14
|
+
return if SUPPORTED_TYPES.include?(@type)
|
|
15
|
+
|
|
16
|
+
raise Exceptions::ValidationError, "Unsupported `type` option: #{@type.inspect} " \
|
|
17
|
+
"(supported: #{SUPPORTED_TYPES.join(', ')})"
|
|
11
18
|
end
|
|
12
19
|
|
|
13
20
|
def request
|
|
@@ -20,15 +27,32 @@ module DeepL
|
|
|
20
27
|
|
|
21
28
|
private
|
|
22
29
|
|
|
30
|
+
def target?
|
|
31
|
+
@type == 'target'
|
|
32
|
+
end
|
|
33
|
+
|
|
23
34
|
def build_languages(request, response)
|
|
24
35
|
data = JSON.parse(response.body)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
request, response)
|
|
36
|
+
usable_key = target? ? 'usable_as_target' : 'usable_as_source'
|
|
37
|
+
data.select { |language| language[usable_key] }.map do |language|
|
|
38
|
+
build_language(language, request, response)
|
|
29
39
|
end
|
|
30
40
|
end
|
|
31
41
|
|
|
42
|
+
def build_language(language, request, response)
|
|
43
|
+
supports_formality = target? ? language.fetch('features', {}).to_h.key?('formality') : nil
|
|
44
|
+
Resources::Language.new(language['lang'].upcase, language['name'], supports_formality,
|
|
45
|
+
request, response, client: api.client?)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def uri
|
|
49
|
+
@uri ||= URI("#{host}/v3/#{path}?resource=translate_text")
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def get_request # rubocop:disable Naming/AccessorMethodName
|
|
53
|
+
Net::HTTP::Get.new(uri.request_uri, add_json_content_type(headers))
|
|
54
|
+
end
|
|
55
|
+
|
|
32
56
|
def path
|
|
33
57
|
'languages'
|
|
34
58
|
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Copyright 2026 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
|
+
class LanguagesForResource < Base
|
|
9
|
+
def initialize(api, resource, options = {})
|
|
10
|
+
super(api, options)
|
|
11
|
+
@resource = resource.to_s
|
|
12
|
+
raise ArgumentError, 'resource must not be empty' if @resource.empty?
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def request
|
|
16
|
+
build_language_support_list(*execute_request_with_retries(get_request))
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def to_s
|
|
20
|
+
"GET #{uri.request_uri}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def build_language_support_list(request, response)
|
|
26
|
+
data = JSON.parse(response.body)
|
|
27
|
+
data.map { |language| Resources::LanguageSupport.new(language, request, response) }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def uri
|
|
31
|
+
@uri ||= begin
|
|
32
|
+
base_uri = URI("#{host}/v3/#{path}")
|
|
33
|
+
base_uri.query = build_query_string
|
|
34
|
+
base_uri
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# include is sent as repeated include=<value> parameters
|
|
39
|
+
def build_query_string
|
|
40
|
+
params = [['resource', @resource]]
|
|
41
|
+
Array(option(:include)).each { |value| params << ['include', value.to_s] }
|
|
42
|
+
encode_query(params)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def get_request # rubocop:disable Naming/AccessorMethodName
|
|
46
|
+
Net::HTTP::Get.new(uri.request_uri, add_json_content_type(headers))
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def path
|
|
50
|
+
'languages'
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Copyright 2026 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.md file.
|
|
4
|
+
# frozen_string_literal: true
|
|
5
|
+
|
|
6
|
+
module DeepL
|
|
7
|
+
module Requests
|
|
8
|
+
module MultilingualGlossary
|
|
9
|
+
class Create < Base
|
|
10
|
+
include Helpers
|
|
11
|
+
|
|
12
|
+
attr_reader :name, :dictionaries
|
|
13
|
+
|
|
14
|
+
def initialize(api, name, dictionaries, options = {})
|
|
15
|
+
super(api, options)
|
|
16
|
+
@name = name
|
|
17
|
+
@dictionaries = dictionaries.map { |dictionary| dictionary_payload(dictionary) }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def request
|
|
21
|
+
payload = { name: name, dictionaries: dictionaries }
|
|
22
|
+
build_glossary(*execute_request_with_retries(post_request(payload)))
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def to_s
|
|
26
|
+
"POST #{uri.request_uri}"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def path
|
|
32
|
+
'glossaries'
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Copyright 2026 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.md file.
|
|
4
|
+
# frozen_string_literal: true
|
|
5
|
+
|
|
6
|
+
module DeepL
|
|
7
|
+
module Requests
|
|
8
|
+
module MultilingualGlossary
|
|
9
|
+
class Destroy < Base
|
|
10
|
+
include Helpers
|
|
11
|
+
|
|
12
|
+
attr_reader :id
|
|
13
|
+
|
|
14
|
+
def initialize(api, id, options = {})
|
|
15
|
+
super(api, options)
|
|
16
|
+
@id = glossary_id(id)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def request
|
|
20
|
+
execute_request_with_retries(delete_request)
|
|
21
|
+
nil
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def to_s
|
|
25
|
+
"DELETE #{uri.request_uri}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def path
|
|
31
|
+
glossary_path(id)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Copyright 2026 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.md file.
|
|
4
|
+
# frozen_string_literal: true
|
|
5
|
+
|
|
6
|
+
module DeepL
|
|
7
|
+
module Requests
|
|
8
|
+
module MultilingualGlossary
|
|
9
|
+
class DestroyDictionary < Base
|
|
10
|
+
include Helpers
|
|
11
|
+
|
|
12
|
+
attr_reader :id, :source_lang, :target_lang
|
|
13
|
+
|
|
14
|
+
def initialize(api, id, source_lang, target_lang, options = {})
|
|
15
|
+
super(api, options)
|
|
16
|
+
@id = glossary_id(id)
|
|
17
|
+
@source_lang = source_lang
|
|
18
|
+
@target_lang = target_lang
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def request
|
|
22
|
+
execute_request_with_retries(delete_request)
|
|
23
|
+
nil
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def to_s
|
|
27
|
+
"DELETE #{uri.request_uri}"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def delete_request
|
|
33
|
+
http_headers = add_json_content_type(headers)
|
|
34
|
+
Net::HTTP::Delete.new(uri.request_uri, http_headers)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def uri
|
|
38
|
+
@uri ||= begin
|
|
39
|
+
base_uri = URI("#{host}/v3/#{path}")
|
|
40
|
+
base_uri.query = encode_query(source_lang: source_lang, target_lang: target_lang)
|
|
41
|
+
base_uri
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def path
|
|
46
|
+
glossary_path(id, 'dictionaries')
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Copyright 2026 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.md file.
|
|
4
|
+
# frozen_string_literal: true
|
|
5
|
+
|
|
6
|
+
module DeepL
|
|
7
|
+
module Requests
|
|
8
|
+
module MultilingualGlossary
|
|
9
|
+
class Entries < Base
|
|
10
|
+
include Helpers
|
|
11
|
+
|
|
12
|
+
attr_reader :id, :source_lang, :target_lang
|
|
13
|
+
|
|
14
|
+
def initialize(api, id, source_lang, target_lang, options = {})
|
|
15
|
+
super(api, options)
|
|
16
|
+
@id = glossary_id(id)
|
|
17
|
+
@source_lang = source_lang
|
|
18
|
+
@target_lang = target_lang
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def request
|
|
22
|
+
build_entries(*execute_request_with_retries(get_request))
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def to_s
|
|
26
|
+
"GET #{uri.request_uri}"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def get_request # rubocop:disable Naming/AccessorMethodName
|
|
32
|
+
http_headers = add_json_content_type(headers)
|
|
33
|
+
Net::HTTP::Get.new(uri.request_uri, http_headers)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# The API wraps the dictionary in a list, which is empty if the glossary has no
|
|
37
|
+
# dictionary for the language pair.
|
|
38
|
+
def build_entries(request, response)
|
|
39
|
+
dictionary = (JSON.parse(response.body)['dictionaries'] || []).first
|
|
40
|
+
if dictionary.nil?
|
|
41
|
+
raise Exceptions::NotFound.new(
|
|
42
|
+
response, request,
|
|
43
|
+
"Glossary #{id} has no dictionary for #{source_lang} -> #{target_lang}"
|
|
44
|
+
)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
Resources::MultilingualGlossaryDictionaryEntries.from_response(
|
|
48
|
+
dictionary, request, response
|
|
49
|
+
)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def uri
|
|
53
|
+
@uri ||= begin
|
|
54
|
+
base_uri = URI("#{host}/v3/#{path}")
|
|
55
|
+
base_uri.query = encode_query(source_lang: source_lang, target_lang: target_lang)
|
|
56
|
+
base_uri
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def path
|
|
61
|
+
glossary_path(id, 'entries')
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Copyright 2026 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.md file.
|
|
4
|
+
# frozen_string_literal: true
|
|
5
|
+
|
|
6
|
+
module DeepL
|
|
7
|
+
module Requests
|
|
8
|
+
module MultilingualGlossary
|
|
9
|
+
class Find < Base
|
|
10
|
+
include Helpers
|
|
11
|
+
|
|
12
|
+
attr_reader :id
|
|
13
|
+
|
|
14
|
+
def initialize(api, id, options = {})
|
|
15
|
+
super(api, options)
|
|
16
|
+
@id = glossary_id(id)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def request
|
|
20
|
+
build_glossary(*execute_request_with_retries(get_request))
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def to_s
|
|
24
|
+
"GET #{uri.request_uri}"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def path
|
|
30
|
+
glossary_path(id)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|