deepl_diff 2.0.0 → 2.2.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/deepl_diff.gemspec +9 -0
- data/lib/deepl_diff/chunker.rb +11 -6
- data/lib/deepl_diff/request.rb +32 -4
- data/lib/deepl_diff/tokenizer.rb +2 -1
- data/lib/deepl_diff/version.rb +1 -1
- metadata +8 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 83f226ab695b30cfc248762a7760bceb6bf9166d9a6f7a9bee620235309c33d2
|
|
4
|
+
data.tar.gz: cb0b0e175dce7ae19ba282fb86a8cc15fac1266fc373ee1b5c56dd0cac707fba
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0bd5a40578adf7e42ff6bae724f6983bae992af787bf4e0ade831353259683e097fc1a1f34cb25c3ac7a563faf6a75d6cf9e8983d7d2e973dbf9ec97a5897b30
|
|
7
|
+
data.tar.gz: b7abc9af4e0ee1f33c5dd3dafc764069776c7668a2c361bd74064c6068f4be3e98e399abedcb216d57dcb8e08e8010e89db487d3bf79f849962e6f5c08fe057a
|
data/deepl_diff.gemspec
CHANGED
|
@@ -33,6 +33,15 @@ between revisions of long texts.
|
|
|
33
33
|
"public gem pushes."
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
+
spec.post_install_message = <<~MESSAGE
|
|
37
|
+
deepl_diff is being replaced by translation_diff, which supports
|
|
38
|
+
translation providers other than DeepL.
|
|
39
|
+
|
|
40
|
+
This version of deepl_diff keeps working and will not change again.
|
|
41
|
+
|
|
42
|
+
https://rubygems.org/gems/translation_diff
|
|
43
|
+
MESSAGE
|
|
44
|
+
|
|
36
45
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
37
46
|
f.match(%r{^(test|spec|features)/})
|
|
38
47
|
end
|
data/lib/deepl_diff/chunker.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
class DeepLDiff::Chunker
|
|
4
4
|
class Error < StandardError; end
|
|
5
5
|
|
|
6
|
-
Chunk = Struct.new(:texts, :
|
|
6
|
+
Chunk = Struct.new(:texts, :escaped_size)
|
|
7
7
|
|
|
8
8
|
MAX_CHUNK_SIZE = 1700
|
|
9
9
|
COUNT_LIMIT = 300
|
|
@@ -39,20 +39,25 @@ class DeepLDiff::Chunker
|
|
|
39
39
|
|
|
40
40
|
def next_chunk?(tail, value)
|
|
41
41
|
tail.nil? ||
|
|
42
|
-
(
|
|
43
|
-
tail.texts.size
|
|
42
|
+
(escaped_size(value) + tail.escaped_size > limit) ||
|
|
43
|
+
tail.texts.size >= count_limit
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
# What the limit is about is the size of the request that goes over the
|
|
47
|
+
# wire, so every measurement here is of the escaped form. Mixing it with
|
|
48
|
+
# String#size lets a chunk of non-ASCII text run several times over.
|
|
49
|
+
def escaped_size(text)
|
|
47
50
|
CGI.escape(text).size
|
|
48
51
|
end
|
|
49
52
|
|
|
50
53
|
def update_chunk(chunk, value)
|
|
51
54
|
chunk.texts << value
|
|
52
|
-
chunk.
|
|
55
|
+
chunk.escaped_size += escaped_size(value)
|
|
53
56
|
end
|
|
54
57
|
|
|
55
58
|
def validate_value_size(value)
|
|
56
|
-
|
|
59
|
+
size = escaped_size(value)
|
|
60
|
+
|
|
61
|
+
raise Error, "Too long part #{size} > #{limit}" if size > limit
|
|
57
62
|
end
|
|
58
63
|
end
|
data/lib/deepl_diff/request.rb
CHANGED
|
@@ -3,18 +3,22 @@
|
|
|
3
3
|
class DeepLDiff::Request
|
|
4
4
|
extend Forwardable
|
|
5
5
|
|
|
6
|
+
class Error < StandardError; end
|
|
7
|
+
|
|
6
8
|
def_delegators :DeepLDiff, :api, :cache_store, :rate_limiter
|
|
7
9
|
def_delegators :"DeepLDiff::Linearizer", :linearize, :restore
|
|
8
10
|
|
|
9
11
|
def initialize(values, options)
|
|
10
12
|
@values = values
|
|
11
|
-
|
|
13
|
+
# #from and #to consume their keys so the rest can go to the API as-is.
|
|
14
|
+
# Copy first: the caller's hash is theirs, and it is often frozen.
|
|
15
|
+
@options = options.dup
|
|
12
16
|
end
|
|
13
17
|
|
|
14
18
|
def call
|
|
15
19
|
validate_globals
|
|
16
20
|
|
|
17
|
-
return values if
|
|
21
|
+
return values if same_language? || nothing_to_translate?
|
|
18
22
|
|
|
19
23
|
translation
|
|
20
24
|
end
|
|
@@ -31,6 +35,19 @@ class DeepLDiff::Request
|
|
|
31
35
|
@to ||= options.delete(:to) { nil }
|
|
32
36
|
end
|
|
33
37
|
|
|
38
|
+
# A detected language arrives as a String while :to is usually a Symbol, so
|
|
39
|
+
# the two have to be compared on equal footing or the short circuit never
|
|
40
|
+
# fires and the text gets translated into its own language.
|
|
41
|
+
def same_language?
|
|
42
|
+
!to.nil? && from.to_s.casecmp?(to.to_s)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Covers values holding no translatable text at all: "", nil, an empty
|
|
46
|
+
# collection, or a scalar the tokenizer has nothing to say about.
|
|
47
|
+
def nothing_to_translate?
|
|
48
|
+
text_tokens_texts.all?(&:empty?)
|
|
49
|
+
end
|
|
50
|
+
|
|
34
51
|
def detect_language
|
|
35
52
|
api.translate(text_tokens_texts.join(" ")[0..100], nil, to)
|
|
36
53
|
.detected_source_language.downcase
|
|
@@ -126,7 +143,12 @@ class DeepLDiff::Request
|
|
|
126
143
|
# Restores texts from tokens
|
|
127
144
|
# [..., "<b>Horoshiy</b> Malchik", ...]
|
|
128
145
|
def texts_translated
|
|
129
|
-
@texts_translated ||= tokens_translated.map do |group|
|
|
146
|
+
@texts_translated ||= tokens_translated.map.with_index do |group, index|
|
|
147
|
+
source = texts[index]
|
|
148
|
+
# Only strings are rebuilt from tokens. Anything else has no tokens to
|
|
149
|
+
# rebuild from; nil keeps collapsing to "" the way it always has.
|
|
150
|
+
next source unless source.nil? || source.is_a?(String)
|
|
151
|
+
|
|
130
152
|
group.map { |value, type| type == :text ? value : fix_ascii(value) }.join
|
|
131
153
|
end
|
|
132
154
|
end
|
|
@@ -138,7 +160,13 @@ class DeepLDiff::Request
|
|
|
138
160
|
|
|
139
161
|
def call_api(values)
|
|
140
162
|
check_rate_limit(values)
|
|
141
|
-
[api.translate(values, from, to, options)].flatten.map(&:text)
|
|
163
|
+
translations = [api.translate(values, from, to, options)].flatten.map(&:text)
|
|
164
|
+
return translations if translations.size == values.size
|
|
165
|
+
|
|
166
|
+
# Letting a short response through means shifting nils into the results,
|
|
167
|
+
# which surfaces much later as a NoMethodError far from the cause.
|
|
168
|
+
raise Error,
|
|
169
|
+
"API returned #{translations.size} translations for #{values.size} values"
|
|
142
170
|
end
|
|
143
171
|
|
|
144
172
|
def cache
|
data/lib/deepl_diff/tokenizer.rb
CHANGED
|
@@ -149,7 +149,8 @@ class DeepLDiff::Tokenizer < Ox::Sax
|
|
|
149
149
|
|
|
150
150
|
class << self
|
|
151
151
|
def tokenize(value)
|
|
152
|
-
|
|
152
|
+
# Anything that is not a string has no markup and no sentences in it.
|
|
153
|
+
return [] unless value.is_a?(String)
|
|
153
154
|
|
|
154
155
|
tokenizer = new(value).tap do |h|
|
|
155
156
|
Ox.sax_parse(h, StringIO.new(value), HTML_OPTIONS)
|
data/lib/deepl_diff/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: deepl_diff
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Islam Gagiev
|
|
@@ -127,6 +127,13 @@ metadata:
|
|
|
127
127
|
homepage_uri: https://github.com/Halvanhelv/deepl_diff
|
|
128
128
|
source_code_uri: https://github.com/Halvanhelv/deepl_diff
|
|
129
129
|
rubygems_mfa_required: 'true'
|
|
130
|
+
post_install_message: |
|
|
131
|
+
deepl_diff is being replaced by translation_diff, which supports
|
|
132
|
+
translation providers other than DeepL.
|
|
133
|
+
|
|
134
|
+
This version of deepl_diff keeps working and will not change again.
|
|
135
|
+
|
|
136
|
+
https://rubygems.org/gems/translation_diff
|
|
130
137
|
rdoc_options: []
|
|
131
138
|
require_paths:
|
|
132
139
|
- lib
|