deepl-rb 3.6.1 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab-ci.yml +5 -0
  3. data/CHANGELOG.md +19 -1
  4. data/README.md +153 -22
  5. data/Rakefile +2 -0
  6. data/VERSION +1 -1
  7. data/deepl-rb.gemspec +31 -4
  8. data/lib/deepl/requests/base.rb +16 -0
  9. data/lib/deepl/requests/document/upload.rb +6 -5
  10. data/lib/deepl/requests/style_rule/create.rb +46 -0
  11. data/lib/deepl/requests/style_rule/create_custom_instruction.rb +45 -0
  12. data/lib/deepl/requests/style_rule/destroy.rb +39 -0
  13. data/lib/deepl/requests/style_rule/destroy_custom_instruction.rb +40 -0
  14. data/lib/deepl/requests/style_rule/find.rb +40 -0
  15. data/lib/deepl/requests/style_rule/find_custom_instruction.rb +41 -0
  16. data/lib/deepl/requests/style_rule/update.rb +42 -0
  17. data/lib/deepl/requests/style_rule/update_configured_rules.rb +41 -0
  18. data/lib/deepl/requests/style_rule/update_custom_instruction.rb +47 -0
  19. data/lib/deepl/requests/translate.rb +15 -2
  20. data/lib/deepl/requests/translation_memory/list.rb +58 -0
  21. data/lib/deepl/resources/style_rule.rb +2 -1
  22. data/lib/deepl/resources/translation_memory.rb +25 -0
  23. data/lib/deepl/style_rule_api.rb +44 -0
  24. data/lib/deepl/translation_memory_api.rb +17 -0
  25. data/lib/deepl.rb +68 -51
  26. data/lib/version.rb +1 -1
  27. data/spec/fixtures/vcr_cassettes/style_rules_crud.yml +926 -0
  28. data/spec/fixtures/vcr_cassettes/translate_texts.yml +1 -1
  29. data/spec/fixtures/vcr_cassettes/translation_memories.yml +74 -0
  30. data/spec/integration_tests/style_rule_api_spec.rb +56 -0
  31. data/spec/integration_tests/translation_memory_api_spec.rb +70 -0
  32. data/spec/requests/style_rule/create_custom_instruction_spec.rb +54 -0
  33. data/spec/requests/style_rule/create_spec.rb +45 -0
  34. data/spec/requests/style_rule/destroy_custom_instruction_spec.rb +54 -0
  35. data/spec/requests/style_rule/destroy_spec.rb +54 -0
  36. data/spec/requests/style_rule/find_custom_instruction_spec.rb +56 -0
  37. data/spec/requests/style_rule/find_spec.rb +56 -0
  38. data/spec/requests/style_rule/list_spec.rb +58 -0
  39. data/spec/requests/style_rule/update_configured_rules_spec.rb +52 -0
  40. data/spec/requests/style_rule/update_custom_instruction_spec.rb +58 -0
  41. data/spec/requests/style_rule/update_spec.rb +48 -0
  42. data/spec/requests/translate_spec.rb +1 -2
  43. data/spec/requests/translation_memory/list_spec.rb +61 -0
  44. data/spec/resources/translation_memory_spec.rb +35 -0
  45. metadata +30 -3
@@ -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.md file.
4
+ # frozen_string_literal: true
5
+
6
+ module DeepL
7
+ module Requests
8
+ module StyleRule
9
+ class FindCustomInstruction < Base
10
+ def initialize(api, style_id, instruction_id, options = {})
11
+ super(api, options)
12
+ @style_id = style_id
13
+ @instruction_id = instruction_id
14
+ end
15
+
16
+ def request
17
+ build_custom_instruction(*execute_request_with_retries(get_request))
18
+ end
19
+
20
+ def to_s
21
+ "GET #{uri.request_uri}"
22
+ end
23
+
24
+ private
25
+
26
+ def build_custom_instruction(_request, response)
27
+ data = JSON.parse(response.body)
28
+ DeepL::Resources::CustomInstruction.new(data)
29
+ end
30
+
31
+ def uri
32
+ @uri ||= URI("#{host}/v3/#{path}")
33
+ end
34
+
35
+ def path
36
+ "style_rules/#{@style_id}/custom_instructions/#{@instruction_id}"
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,42 @@
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 StyleRule
9
+ class Update < Base
10
+ def initialize(api, style_id, name, options = {})
11
+ super(api, options)
12
+ @style_id = style_id
13
+ @name = name
14
+ end
15
+
16
+ def request
17
+ payload = { name: @name }
18
+ build_style_rule(*execute_request_with_retries(patch_request(payload)))
19
+ end
20
+
21
+ def to_s
22
+ "PATCH #{uri.request_uri}"
23
+ end
24
+
25
+ private
26
+
27
+ def build_style_rule(request, response)
28
+ data = JSON.parse(response.body)
29
+ DeepL::Resources::StyleRule.new(data, request, response)
30
+ end
31
+
32
+ def uri
33
+ @uri ||= URI("#{host}/v3/#{path}")
34
+ end
35
+
36
+ def path
37
+ "style_rules/#{@style_id}"
38
+ end
39
+ end
40
+ end
41
+ end
42
+ 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.md file.
4
+ # frozen_string_literal: true
5
+
6
+ module DeepL
7
+ module Requests
8
+ module StyleRule
9
+ class UpdateConfiguredRules < Base
10
+ def initialize(api, style_id, configured_rules, options = {})
11
+ super(api, options)
12
+ @style_id = style_id
13
+ @configured_rules = configured_rules
14
+ end
15
+
16
+ def request
17
+ build_style_rule(*execute_request_with_retries(put_request(@configured_rules)))
18
+ end
19
+
20
+ def to_s
21
+ "PUT #{uri.request_uri}"
22
+ end
23
+
24
+ private
25
+
26
+ def build_style_rule(request, response)
27
+ data = JSON.parse(response.body)
28
+ DeepL::Resources::StyleRule.new(data, request, response)
29
+ end
30
+
31
+ def uri
32
+ @uri ||= URI("#{host}/v3/#{path}")
33
+ end
34
+
35
+ def path
36
+ "style_rules/#{@style_id}/configured_rules"
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,47 @@
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 StyleRule
9
+ class UpdateCustomInstruction < Base
10
+ def initialize(api, style_id, instruction_id, label, prompt, # rubocop:disable Metrics/ParameterLists
11
+ source_language = nil, options = {})
12
+ super(api, options)
13
+ @style_id = style_id
14
+ @instruction_id = instruction_id
15
+ @label = label
16
+ @prompt = prompt
17
+ @source_language = source_language
18
+ end
19
+
20
+ def request
21
+ payload = { label: @label, prompt: @prompt }
22
+ payload[:source_language] = @source_language if @source_language
23
+ build_custom_instruction(*execute_request_with_retries(put_request(payload)))
24
+ end
25
+
26
+ def to_s
27
+ "PUT #{uri.request_uri}"
28
+ end
29
+
30
+ private
31
+
32
+ def build_custom_instruction(_request, response)
33
+ data = JSON.parse(response.body)
34
+ DeepL::Resources::CustomInstruction.new(data)
35
+ end
36
+
37
+ def uri
38
+ @uri ||= URI("#{host}/v3/#{path}")
39
+ end
40
+
41
+ def path
42
+ "style_rules/#{@style_id}/custom_instructions/#{@instruction_id}"
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -39,12 +39,12 @@ module DeepL
39
39
  tweak_parameters!
40
40
  end
41
41
 
42
- def request # rubocop:disable Metrics/MethodLength
42
+ def request # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity
43
43
  text_arrayified = text.is_a?(Array) ? text : [text]
44
44
  payload = { text: text_arrayified, source_lang: source_lang, target_lang: target_lang }
45
45
 
46
46
  if option?(:style_rule)
47
- style_rule = option(:style_rule)
47
+ style_rule = delete_option(:style_rule)
48
48
  payload[:style_id] = if style_rule.is_a?(DeepL::Resources::StyleRule)
49
49
  style_rule.style_id
50
50
  else
@@ -52,6 +52,19 @@ module DeepL
52
52
  end
53
53
  end
54
54
 
55
+ if option?(:translation_memory)
56
+ tm = delete_option(:translation_memory)
57
+ payload[:translation_memory_id] = if tm.is_a?(DeepL::Resources::TranslationMemory)
58
+ tm.translation_memory_id
59
+ else
60
+ tm.to_s
61
+ end
62
+ end
63
+
64
+ if option?(:translation_memory_threshold)
65
+ payload[:translation_memory_threshold] = delete_option(:translation_memory_threshold)
66
+ end
67
+
55
68
  build_texts(*execute_request_with_retries(post_request(payload)))
56
69
  end
57
70
 
@@ -0,0 +1,58 @@
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 TranslationMemory
9
+ class List < Base
10
+ def initialize(api, options = {})
11
+ super
12
+ end
13
+
14
+ def request
15
+ build_translation_memory_list(*execute_request_with_retries(get_request))
16
+ end
17
+
18
+ def to_s
19
+ "GET #{uri.request_uri}"
20
+ end
21
+
22
+ private
23
+
24
+ def get_request # rubocop:disable Naming/AccessorMethodName
25
+ http_headers = add_json_content_type(headers)
26
+ Net::HTTP::Get.new(uri.request_uri, http_headers)
27
+ end
28
+
29
+ def build_translation_memory_list(request, response)
30
+ data = JSON.parse(response.body)
31
+ data['translation_memories'].map do |tm|
32
+ Resources::TranslationMemory.new(tm, request, response)
33
+ end
34
+ end
35
+
36
+ def uri
37
+ @uri ||= begin
38
+ base_uri = URI("#{host}/v3/#{path}")
39
+ query_string = build_query_string
40
+ base_uri.query = query_string unless query_string.empty?
41
+ base_uri
42
+ end
43
+ end
44
+
45
+ def build_query_string
46
+ params = {}
47
+ params['page'] = option(:page).to_s if option?(:page)
48
+ params['page_size'] = option(:page_size).to_s if option?(:page_size)
49
+ URI.encode_www_form(params)
50
+ end
51
+
52
+ def path
53
+ 'translation_memories'
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -29,9 +29,10 @@ module DeepL
29
29
  end
30
30
 
31
31
  class CustomInstruction
32
- attr_reader :label, :prompt, :source_language
32
+ attr_reader :id, :label, :prompt, :source_language
33
33
 
34
34
  def initialize(custom_instruction_data)
35
+ @id = custom_instruction_data['id']
35
36
  @label = custom_instruction_data['label']
36
37
  @prompt = custom_instruction_data['prompt']
37
38
  @source_language = custom_instruction_data['source_language']
@@ -0,0 +1,25 @@
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 Resources
8
+ class TranslationMemory < Base
9
+ attr_reader :translation_memory_id, :name, :source_language, :target_languages, :segment_count
10
+
11
+ def initialize(translation_memory, *args)
12
+ super(*args)
13
+ @translation_memory_id = translation_memory['translation_memory_id']
14
+ @name = translation_memory['name']
15
+ @source_language = translation_memory['source_language']
16
+ @target_languages = translation_memory['target_languages'] || []
17
+ @segment_count = translation_memory['segment_count'] || 0
18
+ end
19
+
20
+ def to_s
21
+ "#{translation_memory_id} - #{name}"
22
+ end
23
+ end
24
+ end
25
+ end
@@ -13,5 +13,49 @@ module DeepL
13
13
  def list(options = {})
14
14
  DeepL::Requests::StyleRule::List.new(@api, options).request
15
15
  end
16
+
17
+ def create(name, language, options = {})
18
+ DeepL::Requests::StyleRule::Create.new(@api, name, language, options).request
19
+ end
20
+
21
+ def find(style_id, options = {})
22
+ DeepL::Requests::StyleRule::Find.new(@api, style_id, options).request
23
+ end
24
+
25
+ def update_name(style_id, name, options = {})
26
+ DeepL::Requests::StyleRule::Update.new(@api, style_id, name, options).request
27
+ end
28
+
29
+ def destroy(style_id, options = {})
30
+ DeepL::Requests::StyleRule::Destroy.new(@api, style_id, options).request
31
+ end
32
+
33
+ def update_configured_rules(style_id, configured_rules, options = {})
34
+ DeepL::Requests::StyleRule::UpdateConfiguredRules.new(@api, style_id, configured_rules,
35
+ options).request
36
+ end
37
+
38
+ def create_custom_instruction(style_id, label, prompt, source_language = nil, options = {})
39
+ DeepL::Requests::StyleRule::CreateCustomInstruction.new(@api, style_id, label, prompt,
40
+ source_language, options).request
41
+ end
42
+
43
+ def find_custom_instruction(style_id, instruction_id, options = {})
44
+ DeepL::Requests::StyleRule::FindCustomInstruction.new(@api, style_id, instruction_id,
45
+ options).request
46
+ end
47
+
48
+ def update_custom_instruction(style_id, instruction_id, label,
49
+ prompt, source_language = nil,
50
+ options = {})
51
+ DeepL::Requests::StyleRule::UpdateCustomInstruction.new(@api, style_id, instruction_id,
52
+ label, prompt, source_language,
53
+ options).request
54
+ end
55
+
56
+ def destroy_custom_instruction(style_id, instruction_id, options = {})
57
+ DeepL::Requests::StyleRule::DestroyCustomInstruction.new(@api, style_id, instruction_id,
58
+ options).request
59
+ end
16
60
  end
17
61
  end
@@ -0,0 +1,17 @@
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
+ class TranslationMemoryApi
8
+ def initialize(api, options = {})
9
+ @api = api
10
+ @options = options
11
+ end
12
+
13
+ def list(options = {})
14
+ DeepL::Requests::TranslationMemory::List.new(@api, options).request
15
+ end
16
+ end
17
+ end
data/lib/deepl.rb CHANGED
@@ -8,71 +8,83 @@ require 'json'
8
8
  require 'net/http'
9
9
 
10
10
  # -- Exceptions
11
- require 'deepl/exceptions/error'
12
- require 'deepl/exceptions/request_error'
13
- require 'deepl/exceptions/authorization_failed'
14
- require 'deepl/exceptions/bad_request'
15
- require 'deepl/exceptions/limit_exceeded'
16
- require 'deepl/exceptions/quota_exceeded'
17
- require 'deepl/exceptions/not_found'
18
- require 'deepl/exceptions/not_supported'
19
- require 'deepl/exceptions/request_entity_too_large'
20
- require 'deepl/exceptions/document_translation_error'
21
- require 'deepl/exceptions/server_error'
11
+ require_relative 'deepl/exceptions/error'
12
+ require_relative 'deepl/exceptions/request_error'
13
+ require_relative 'deepl/exceptions/authorization_failed'
14
+ require_relative 'deepl/exceptions/bad_request'
15
+ require_relative 'deepl/exceptions/limit_exceeded'
16
+ require_relative 'deepl/exceptions/quota_exceeded'
17
+ require_relative 'deepl/exceptions/not_found'
18
+ require_relative 'deepl/exceptions/not_supported'
19
+ require_relative 'deepl/exceptions/request_entity_too_large'
20
+ require_relative 'deepl/exceptions/document_translation_error'
21
+ require_relative 'deepl/exceptions/server_error'
22
22
 
23
23
  # -- Requests
24
- require 'deepl/requests/base'
25
- require 'deepl/requests/document/download'
26
- require 'deepl/requests/document/get_status'
27
- require 'deepl/requests/document/upload'
28
- require 'deepl/requests/glossary/create'
29
- require 'deepl/requests/glossary/destroy'
30
- require 'deepl/requests/glossary/entries'
31
- require 'deepl/requests/glossary/find'
32
- require 'deepl/requests/glossary/language_pairs'
33
- require 'deepl/requests/glossary/list'
34
- require 'deepl/requests/style_rule/list'
35
- require 'deepl/requests/languages'
36
- require 'deepl/requests/translate'
37
- require 'deepl/requests/usage'
38
- require 'deepl/requests/rephrase'
24
+ require_relative 'deepl/requests/base'
25
+ require_relative 'deepl/requests/document/download'
26
+ require_relative 'deepl/requests/document/get_status'
27
+ require_relative 'deepl/requests/document/upload'
28
+ require_relative 'deepl/requests/glossary/create'
29
+ require_relative 'deepl/requests/glossary/destroy'
30
+ require_relative 'deepl/requests/glossary/entries'
31
+ require_relative 'deepl/requests/glossary/find'
32
+ require_relative 'deepl/requests/glossary/language_pairs'
33
+ require_relative 'deepl/requests/glossary/list'
34
+ require_relative 'deepl/requests/style_rule/list'
35
+ require_relative 'deepl/requests/style_rule/create'
36
+ require_relative 'deepl/requests/style_rule/find'
37
+ require_relative 'deepl/requests/style_rule/update'
38
+ require_relative 'deepl/requests/style_rule/destroy'
39
+ require_relative 'deepl/requests/style_rule/update_configured_rules'
40
+ require_relative 'deepl/requests/style_rule/create_custom_instruction'
41
+ require_relative 'deepl/requests/style_rule/find_custom_instruction'
42
+ require_relative 'deepl/requests/style_rule/update_custom_instruction'
43
+ require_relative 'deepl/requests/style_rule/destroy_custom_instruction'
44
+ require_relative 'deepl/requests/translation_memory/list'
45
+ require_relative 'deepl/requests/languages'
46
+ require_relative 'deepl/requests/translate'
47
+ require_relative 'deepl/requests/usage'
48
+ require_relative 'deepl/requests/rephrase'
39
49
 
40
50
  # -- Responses and resources
41
- require 'deepl/resources/base'
42
- require 'deepl/resources/document_handle'
43
- require 'deepl/resources/document_translation_status'
44
- require 'deepl/resources/glossary'
45
- require 'deepl/resources/style_rule'
46
- require 'deepl/resources/language'
47
- require 'deepl/resources/language_pair'
48
- require 'deepl/resources/text'
49
- require 'deepl/resources/usage'
51
+ require_relative 'deepl/resources/base'
52
+ require_relative 'deepl/resources/document_handle'
53
+ require_relative 'deepl/resources/document_translation_status'
54
+ require_relative 'deepl/resources/glossary'
55
+ require_relative 'deepl/resources/style_rule'
56
+ require_relative 'deepl/resources/translation_memory'
57
+ require_relative 'deepl/resources/language'
58
+ require_relative 'deepl/resources/language_pair'
59
+ require_relative 'deepl/resources/text'
60
+ require_relative 'deepl/resources/usage'
50
61
 
51
62
  # -- Utils
52
- require 'deepl/utils/exception_builder'
53
- require 'deepl/utils/backoff_timer'
63
+ require_relative 'deepl/utils/exception_builder'
64
+ require_relative 'deepl/utils/backoff_timer'
54
65
 
55
66
  # -- Constants
56
- require 'deepl/constants/base_constant'
57
- require 'deepl/constants/formality'
58
- require 'deepl/constants/model_type'
59
- require 'deepl/constants/split_sentences'
60
- require 'deepl/constants/tag_handling'
61
- require 'deepl/constants/tone'
62
- require 'deepl/constants/writing_style'
67
+ require_relative 'deepl/constants/base_constant'
68
+ require_relative 'deepl/constants/formality'
69
+ require_relative 'deepl/constants/model_type'
70
+ require_relative 'deepl/constants/split_sentences'
71
+ require_relative 'deepl/constants/tag_handling'
72
+ require_relative 'deepl/constants/tone'
73
+ require_relative 'deepl/constants/writing_style'
63
74
 
64
75
  # -- HTTP Utils
65
- require 'http_client_options'
76
+ require_relative 'http_client_options'
66
77
 
67
78
  # -- Version
68
- require 'version'
79
+ require_relative 'version'
69
80
 
70
81
  # -- Other wrappers
71
- require 'deepl/api'
72
- require 'deepl/configuration'
73
- require 'deepl/document_api'
74
- require 'deepl/glossary_api'
75
- require 'deepl/style_rule_api'
82
+ require_relative 'deepl/api'
83
+ require_relative 'deepl/configuration'
84
+ require_relative 'deepl/document_api'
85
+ require_relative 'deepl/glossary_api'
86
+ require_relative 'deepl/style_rule_api'
87
+ require_relative 'deepl/translation_memory_api'
76
88
 
77
89
  # -- Gem interface
78
90
  module DeepL
@@ -108,6 +120,11 @@ module DeepL
108
120
  StyleRuleApi.new(api, options)
109
121
  end
110
122
 
123
+ def translation_memories(options = {})
124
+ configure if @configuration.nil?
125
+ TranslationMemoryApi.new(api, options)
126
+ end
127
+
111
128
  def rephrase(text, target_lang = nil, writing_style = nil, tone = nil, options = {}) # rubocop:disable Metrics/ParameterLists
112
129
  configure if @configuration.nil?
113
130
  Requests::Rephrase.new(api, text, target_lang, writing_style, tone, options).request
data/lib/version.rb CHANGED
@@ -4,5 +4,5 @@
4
4
  # frozen_string_literal: true
5
5
 
6
6
  module DeepL
7
- VERSION = '3.6.1'
7
+ VERSION = '3.7.0'
8
8
  end