fastlane-plugin-translate_gpt 0.1.6 → 0.1.8
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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5e16882ee4e890369a5c14b579f362303a3196e4238d4d3b3f685a9e6b4fb21a
|
4
|
+
data.tar.gz: 59719d66698e72c02ae4c625a68a9b5fe8d7dfc34023a5c329d0625bed27b2e9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 23f15a4ca667b24e958ca6775cd6894dc43b85ecf3e705f4270526af2428a1e7a947824b0bbf74132dbc0fa55059edd9020f1dad10946f5e345ae2d69d7997ac
|
7
|
+
data.tar.gz: d94703743059519b4e3c17ea988a7591c8f67b981d3d38a075ed8fc801ce952509c146e3fb3f92207102680b490cefbc103f325da85c0f7c7e1c2e0281255e0b
|
@@ -84,7 +84,9 @@ module Fastlane
|
|
84
84
|
description: "The path to the Localizable.strings file to be translated",
|
85
85
|
verify_block: proc do |value|
|
86
86
|
UI.user_error!("Invalid file path: #{value}") unless File.exist?(value)
|
87
|
-
|
87
|
+
extension = File.extname(value)
|
88
|
+
available_extensions = [".strings", ".xcstrings"]
|
89
|
+
UI.user_error!("Translation file must have any of these extensions: #{available_extensions}") unless available_extensions.include? extension
|
88
90
|
end
|
89
91
|
),
|
90
92
|
FastlaneCore::ConfigItem.new(
|
@@ -93,7 +95,9 @@ module Fastlane
|
|
93
95
|
description: "Path to the translation file to update",
|
94
96
|
verify_block: proc do |value|
|
95
97
|
UI.user_error!("Invalid file path: #{value}") unless File.exist?(value)
|
96
|
-
|
98
|
+
extension = File.extname(value)
|
99
|
+
available_extensions = [".strings", ".xcstrings"]
|
100
|
+
UI.user_error!("Translation file must have any of these extensions: #{available_extensions}") unless available_extensions.include? extension
|
97
101
|
end
|
98
102
|
),
|
99
103
|
FastlaneCore::ConfigItem.new(
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'fastlane_core/ui/ui'
|
2
|
-
require 'loco_strings'
|
2
|
+
require 'loco_strings/parsers/xcstrings_file'
|
3
3
|
require 'json'
|
4
|
+
# rubocop:disable all
|
4
5
|
|
5
6
|
module Fastlane
|
6
7
|
UI = FastlaneCore::UI unless Fastlane.const_defined?("UI")
|
@@ -16,13 +17,50 @@ module Fastlane
|
|
16
17
|
@timeout = params[:request_timeout]
|
17
18
|
end
|
18
19
|
|
19
|
-
|
20
|
-
|
20
|
+
def prepare_xcstrings()
|
21
|
+
@xcfile = LocoStrings::XCStringsFile.new @params[:source_file]
|
22
|
+
@output_hash = {}
|
23
|
+
@to_translate = @xcfile.read
|
24
|
+
|
25
|
+
if @params[:skip_translated] == true
|
26
|
+
@to_translate = @to_translate.reject { |k, original|
|
27
|
+
!check_value_for_translate(
|
28
|
+
@xcfile.unit(k, @params[:target_language]),
|
29
|
+
original
|
30
|
+
)
|
31
|
+
}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def check_value_for_translate(string, orignal_string)
|
36
|
+
return true unless string
|
37
|
+
if string.is_a? LocoStrings::LocoString
|
38
|
+
return false if orignal_string.value.nil? || orignal_string.value.empty?
|
39
|
+
return string.value.empty?
|
40
|
+
elsif string.is_a? LocoStrings::LocoVariantions
|
41
|
+
orignal_string.strings.each do |key, _|
|
42
|
+
return true unless string.strings.has_key?(key)
|
43
|
+
return true if string.strings[key].value.empty?
|
44
|
+
end
|
45
|
+
end
|
46
|
+
return false
|
47
|
+
end
|
48
|
+
|
49
|
+
def prepare_strings()
|
21
50
|
@input_hash = get_strings(@params[:source_file])
|
22
51
|
@output_hash = get_strings(@params[:target_file])
|
23
52
|
@to_translate = filter_translated(@params[:skip_translated], @input_hash, @output_hash)
|
24
53
|
end
|
25
54
|
|
55
|
+
# Get the strings from a file
|
56
|
+
def prepare_hashes()
|
57
|
+
if File.extname(@params[:source_file]) == ".xcstrings"
|
58
|
+
prepare_xcstrings()
|
59
|
+
else
|
60
|
+
prepare_strings()
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
26
64
|
# Log information about the input strings
|
27
65
|
def log_input(bunch_size)
|
28
66
|
@translation_count = @to_translate.size
|
@@ -66,8 +104,13 @@ module Fastlane
|
|
66
104
|
def translate_bunch_of_strings(bunch_size)
|
67
105
|
bunch_index = 0
|
68
106
|
number_of_bunches = (@translation_count / bunch_size.to_f).ceil
|
107
|
+
@keys_associations = {}
|
69
108
|
@to_translate.each_slice(bunch_size) do |bunch|
|
70
109
|
prompt = prepare_bunch_prompt bunch
|
110
|
+
if prompt.empty?
|
111
|
+
UI.important "Empty prompt, skipping bunch"
|
112
|
+
next
|
113
|
+
end
|
71
114
|
max_retries = 10
|
72
115
|
times_retried = 0
|
73
116
|
|
@@ -109,7 +152,7 @@ module Fastlane
|
|
109
152
|
def prepare_bunch_prompt(strings)
|
110
153
|
prompt = "I want you to act as a translator for a mobile application strings. " + \
|
111
154
|
"Try to keep length of the translated text. " + \
|
112
|
-
"You need to response with a JSON only with the translation and nothing else until I say to stop it."
|
155
|
+
"You need to response with a JSON only with the translation and nothing else until I say to stop it. "
|
113
156
|
if @params[:context] && !@params[:context].empty?
|
114
157
|
prompt += "This app is #{@params[:context]}. "
|
115
158
|
end
|
@@ -117,21 +160,46 @@ module Fastlane
|
|
117
160
|
|
118
161
|
json_hash = []
|
119
162
|
strings.each do |key, string|
|
163
|
+
UI.message "Translating #{key} - #{string}"
|
164
|
+
next if string.nil?
|
165
|
+
|
120
166
|
string_hash = {}
|
121
167
|
context = string.comment
|
122
|
-
if context && !context.empty?
|
123
|
-
|
168
|
+
string_hash["context"] = context if context && !context.empty?
|
169
|
+
|
170
|
+
key = transform_string(string.key)
|
171
|
+
@keys_associations[key] = string.key
|
172
|
+
string_hash["key"] = key
|
173
|
+
|
174
|
+
if string.is_a? LocoStrings::LocoString
|
175
|
+
next if string.value.nil? || string.value.empty?
|
176
|
+
string_hash["string_to_translate"] = string.value
|
177
|
+
elsif string.is_a? LocoStrings::LocoVariantions
|
178
|
+
variants = {}
|
179
|
+
string.strings.each do |key, variant|
|
180
|
+
next if variant.nil? || variant.value.nil? || variant.value.empty?
|
181
|
+
variants[key] = variant.value
|
182
|
+
end
|
183
|
+
string_hash["strings_to_translate"] = variants
|
184
|
+
else
|
185
|
+
UI.warning "Unknown type of string: #{string.key}"
|
124
186
|
end
|
125
|
-
string_hash["key"] = string.key
|
126
|
-
string_hash["string_to_translate"] = string.value
|
127
187
|
json_hash << string_hash
|
128
188
|
end
|
189
|
+
return '' if json_hash.empty?
|
129
190
|
prompt += "'''\n"
|
130
191
|
prompt += json_hash.to_json
|
131
192
|
prompt += "\n'''"
|
193
|
+
UI.message "Prompt: #{prompt}"
|
132
194
|
return prompt
|
133
195
|
end
|
134
196
|
|
197
|
+
def transform_string(input_string)
|
198
|
+
uppercased_string = input_string.upcase
|
199
|
+
escaped_string = uppercased_string.gsub(/[^0-9a-zA-Z]+/, '_')
|
200
|
+
return escaped_string
|
201
|
+
end
|
202
|
+
|
135
203
|
# Request a translation from the GPT API
|
136
204
|
def request_translate(key, string, prompt, index)
|
137
205
|
response = @client.chat(
|
@@ -195,12 +263,21 @@ module Fastlane
|
|
195
263
|
string_hash.delete("key")
|
196
264
|
string_hash.delete("context")
|
197
265
|
translated_string = string_hash.values.first
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
266
|
+
return unless key && !key.empty?
|
267
|
+
real_key = @keys_associations[key]
|
268
|
+
if translated_string.is_a? Hash
|
269
|
+
strings = {}
|
270
|
+
translated_string.each do |pl_key, value|
|
271
|
+
UI.message "#{index_log} Translating #{real_key} > #{pl_key} - #{value}"
|
272
|
+
strings[pl_key] = LocoStrings::LocoString.new(pl_key, value, context)
|
273
|
+
end
|
274
|
+
string = LocoStrings::LocoVariantions.new(real_key, strings, context)
|
275
|
+
elsif translated_string && !translated_string.empty?
|
276
|
+
UI.message "#{index_log} Translating #{real_key} - #{translated_string}"
|
277
|
+
string = LocoStrings::LocoString.new(real_key, translated_string, context)
|
203
278
|
end
|
279
|
+
@output_hash[real_key] = string
|
280
|
+
keys_to_translate.delete(key)
|
204
281
|
end
|
205
282
|
|
206
283
|
if keys_to_translate.length > 0
|
@@ -215,12 +292,26 @@ module Fastlane
|
|
215
292
|
target_string = Colorizer::colorize(@params[:target_file], :white)
|
216
293
|
UI.message "Writing #{number_of_strings} strings to #{target_string}..."
|
217
294
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
295
|
+
if @xcfile.nil?
|
296
|
+
file = LocoStrings.load(@params[:target_file])
|
297
|
+
file.read
|
298
|
+
@output_hash.each do |key, value|
|
299
|
+
file.update(key, value.value, value.comment)
|
300
|
+
end
|
301
|
+
file.write
|
302
|
+
else
|
303
|
+
@xcfile.update_file_path(@params[:target_file])
|
304
|
+
@output_hash.each do |key, value|
|
305
|
+
if value.is_a? LocoStrings::LocoString
|
306
|
+
@xcfile.update(key, value.value, value.comment, "translated", @params[:target_language])
|
307
|
+
elsif value.is_a? LocoStrings::LocoVariantions
|
308
|
+
value.strings.each do |pl_key, variant|
|
309
|
+
@xcfile.update_variation(key, pl_key, variant.value, variant.comment, "translated", @params[:target_language])
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
@xcfile.write
|
222
314
|
end
|
223
|
-
file.write
|
224
315
|
end
|
225
316
|
|
226
317
|
# Read the strings file into a hash
|
@@ -298,3 +389,5 @@ module Fastlane
|
|
298
389
|
end
|
299
390
|
end
|
300
391
|
end
|
392
|
+
|
393
|
+
# rubocop:enable all
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastlane-plugin-translate_gpt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aleksei Cherepanov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-02-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-openai
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.1.1
|
33
|
+
version: 0.1.4.1
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.1.1
|
40
|
+
version: 0.1.4.1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -212,7 +212,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
212
212
|
- !ruby/object:Gem::Version
|
213
213
|
version: '0'
|
214
214
|
requirements: []
|
215
|
-
rubygems_version: 3.4.
|
215
|
+
rubygems_version: 3.4.19
|
216
216
|
signing_key:
|
217
217
|
specification_version: 4
|
218
218
|
summary: This fastlane plugin provides an easy way to use the OpenAI GPT language
|