fastlane-plugin-translate_gpt 0.1.0 → 0.1.2
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: d78d5a0107d725ae3b713c7e44f1b3aaca9eff005b1d5d2fb7e4ab75dbca40aa
|
4
|
+
data.tar.gz: 3b45a4747d8222ed5d0d9b7d04f178728e679609940e60dff556cbc7b65e1e99
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e57f34690dea08a9eb24f7d1f975646c9500fccd983d933ff0b3a8809af91ce3b875e75691dfe7845f9aad88fcaeace425e8ead8dff3e09316c61d03ce5be682
|
7
|
+
data.tar.gz: e6e76c62b2ac4fe8b3b16d756bdd2acf4adb8d5ed35a626b9c0e5be3fb4e94511868e961f5261570af63640dafe714cf0d47fc8cc69f520b8e5b552ce27f67b2
|
data/README.md
CHANGED
@@ -15,7 +15,7 @@ fastlane add_plugin translate_gpt
|
|
15
15
|
|
16
16
|
## About translate-gpt
|
17
17
|
|
18
|
-
`translate-gpt` is a fastlane plugin that allows you to easily translate your iOS app's strings using the OpenAI GPT API.
|
18
|
+
`translate-gpt` is a fastlane plugin that allows you to easily translate your iOS and Android app's strings using the OpenAI GPT API.
|
19
19
|
|
20
20
|
|
21
21
|
## Features
|
@@ -50,8 +50,36 @@ The following options are available for `translate-gpt`:
|
|
50
50
|
| `skip_translated` | Whether to skip strings that have already been translated. Defaults to `true`. | `GPT_SKIP_TRANSLATED` |
|
51
51
|
| `source_language` | The source language of the strings to be translated. Defaults to auto-detection. | `GPT_SOURCE_LANGUAGE` |
|
52
52
|
| `target_language` | The target language of the translated strings. Required. | `GPT_TARGET_LANGUAGE` |
|
53
|
-
| `source_file` | The path to the `Localizable.strings` file to be translated.
|
54
|
-
| `target_file` | The path to the output file for the translated strings.
|
53
|
+
| `source_file` | The path to the `Localizable.strings` or `strings.xml` file to be translated. | `GPT_SOURCE_FILE` |
|
54
|
+
| `target_file` | The path to the output file for the translated strings. | `GPT_TARGET_FILE` |
|
55
|
+
| `context` | Common context for the translation | `GPT_COMMON_CONTEXT` |
|
56
|
+
|
57
|
+
## Providing context
|
58
|
+
|
59
|
+
The `TranslateGptAction` allows you to provide additional context for your translation requests in two ways:
|
60
|
+
|
61
|
+
### 1. Using a common context
|
62
|
+
|
63
|
+
You can provide a common context for your project that will be used in all translation requests. This can be done by setting the `common` property when calling the `TranslateGptAction`. The `common` property should be a string that describes the context of your project.
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
translate_gpt(
|
67
|
+
target_language: 'fr',
|
68
|
+
common: "This is a mobile app for ordering food online"
|
69
|
+
)
|
70
|
+
```
|
71
|
+
|
72
|
+
### 2. Adding comments for specific keys
|
73
|
+
|
74
|
+
You can also add comments to your Localizable.strings file for specific keys. These comments will be included in the translation request for that key. To add a comment for a specific key, simply include a comment before the key in your Localizable.strings file.
|
75
|
+
|
76
|
+
```text
|
77
|
+
/* This is a comment for KEY1 */
|
78
|
+
"KEY1" = "Value for KEY1";
|
79
|
+
```
|
80
|
+
|
81
|
+
When you run the `TranslateGptAction`, the comment will be included in the translation request for `KEY1`.
|
82
|
+
|
55
83
|
|
56
84
|
## Authentication
|
57
85
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'fastlane/action'
|
2
2
|
require 'openai'
|
3
3
|
require_relative '../helper/translate_gpt_helper'
|
4
|
+
require 'loco_strings'
|
4
5
|
|
5
6
|
module Fastlane
|
6
7
|
module Actions
|
@@ -20,14 +21,17 @@ module Fastlane
|
|
20
21
|
to_translate = input_hash
|
21
22
|
end
|
22
23
|
|
23
|
-
UI.message "Translating #{
|
24
|
+
UI.message "Translating #{to_translate.size} strings..."
|
24
25
|
|
25
|
-
to_translate.
|
26
|
-
prompt = "Translate the following string from #{params[:source_language]} to #{params[:target_language]}
|
27
|
-
context =
|
26
|
+
to_translate.each_with_index do |(key, string), index|
|
27
|
+
prompt = "Translate the following string from #{params[:source_language]} to #{params[:target_language]}: #{string.value}"
|
28
|
+
context = string.comment
|
28
29
|
if context && !context.empty?
|
29
30
|
prompt += "\n\nAdditional context:\n#{context}"
|
30
31
|
end
|
32
|
+
if params[:context] && !params[:context].empty?
|
33
|
+
prompt += "\n\nCommon context:\n#{params[:context]}"
|
34
|
+
end
|
31
35
|
# translate the source string to the target language
|
32
36
|
response = client.chat(
|
33
37
|
parameters: {
|
@@ -36,7 +40,6 @@ module Fastlane
|
|
36
40
|
temperature: params[:temperature],
|
37
41
|
}
|
38
42
|
)
|
39
|
-
#puts response
|
40
43
|
# extract the translated string from the response
|
41
44
|
error = response.dig("error", "message")
|
42
45
|
if error
|
@@ -44,23 +47,26 @@ module Fastlane
|
|
44
47
|
else
|
45
48
|
target_string = response.dig("choices", 0, "message", "content")
|
46
49
|
if target_string && !target_string.empty?
|
47
|
-
UI.message "Translating #{key} - #{value} -> #{target_string}"
|
48
|
-
|
50
|
+
UI.message "Translating #{key} - #{string.value} -> #{target_string}"
|
51
|
+
string.value = target_string
|
52
|
+
output_hash[key] = string
|
49
53
|
else
|
50
|
-
UI.warning "Unable to translate #{key} - #{value}"
|
54
|
+
UI.warning "Unable to translate #{key} - #{string.value}"
|
51
55
|
end
|
52
56
|
end
|
53
|
-
|
57
|
+
if index < to_translate.size - 1
|
58
|
+
Helper::TranslateGptHelper.timeout params[:request_timeout]
|
59
|
+
end
|
54
60
|
end
|
55
61
|
|
56
62
|
UI.message "Writing #{output_hash.size} strings to #{params[:target_file]}..."
|
57
63
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
end
|
64
|
+
file = LocoStrings.load(params[:target_file])
|
65
|
+
file.read
|
66
|
+
output_hash.each do |key, value|
|
67
|
+
file.update(key, value.value, value.comment)
|
63
68
|
end
|
69
|
+
file.write
|
64
70
|
end
|
65
71
|
|
66
72
|
#####################################################
|
@@ -138,7 +144,14 @@ module Fastlane
|
|
138
144
|
UI.user_error!("Invalid file path: #{value}") unless File.exist?(value)
|
139
145
|
UI.user_error!("Translation file must have .strings extension") unless File.extname(value) == ".strings"
|
140
146
|
end
|
141
|
-
),
|
147
|
+
),
|
148
|
+
FastlaneCore::ConfigItem.new(
|
149
|
+
key: :context,
|
150
|
+
env_name: "GPT_COMMON_CONTEXT",
|
151
|
+
description: "Common context for the translation",
|
152
|
+
optional: true,
|
153
|
+
type: String
|
154
|
+
)
|
142
155
|
]
|
143
156
|
end
|
144
157
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'fastlane_core/ui/ui'
|
2
|
+
require 'loco_strings'
|
2
3
|
|
3
4
|
module Fastlane
|
4
5
|
UI = FastlaneCore::UI unless Fastlane.const_defined?("UI")
|
@@ -9,16 +10,8 @@ module Fastlane
|
|
9
10
|
# @param localization_file [String] The path to the strings file
|
10
11
|
# @return [Hash] The strings file as a hash
|
11
12
|
def self.get_strings(localization_file)
|
12
|
-
|
13
|
-
|
14
|
-
strings_hash = strings_file.split(/\n/).reduce({}) do |hash, line|
|
15
|
-
match = line.match(/^"(.+)" = "(.+)";$/)
|
16
|
-
if match
|
17
|
-
hash[match[1]] = match[2]
|
18
|
-
end
|
19
|
-
hash
|
20
|
-
end
|
21
|
-
return strings_hash
|
13
|
+
file = LocoStrings.load(localization_file)
|
14
|
+
return file.read
|
22
15
|
end
|
23
16
|
|
24
17
|
# Get the context associated with a localization key
|
@@ -26,20 +19,9 @@ module Fastlane
|
|
26
19
|
# @param localization_key [String] The localization key
|
27
20
|
# @return [String] The context associated with the localization key
|
28
21
|
def self.get_context(localization_file, localization_key)
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
# search for the comments associated with the localization key
|
33
|
-
regex = /\/\*\*\n\s*\* @key\s+#{localization_key}\n((\s*\*.*\n)+)\s*\*\/\n\s*"#{localization_key}"/
|
34
|
-
match = content.match(regex)
|
35
|
-
|
36
|
-
# return the comments, if found
|
37
|
-
if match && match.captures.size > 0
|
38
|
-
comments = match.captures[0].strip
|
39
|
-
return comments.gsub(/\n\s*\*\s?/, "\n").strip
|
40
|
-
else
|
41
|
-
return nil
|
42
|
-
end
|
22
|
+
file = LocoStrings.load(localization_file)
|
23
|
+
string = file.read[localization_key]
|
24
|
+
return string.comment
|
43
25
|
end
|
44
26
|
|
45
27
|
# Sleep for a specified number of seconds, displaying a progress bar
|
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.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aleksei Cherepanov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-05-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-openai
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '3.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: loco_strings
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.1.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.1.1
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: bundler
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|