fastlane-plugin-translate_gpt 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d61950fe5af16ec1511687b4cab646b8397be0d4870a5e7c2a8d7f22adc06687
4
- data.tar.gz: a04a4b37ba73505bdfea8d6ca7a1b6b0b63cd95f8e2856c9d237a21f513d0a91
3
+ metadata.gz: d78d5a0107d725ae3b713c7e44f1b3aaca9eff005b1d5d2fb7e4ab75dbca40aa
4
+ data.tar.gz: 3b45a4747d8222ed5d0d9b7d04f178728e679609940e60dff556cbc7b65e1e99
5
5
  SHA512:
6
- metadata.gz: 15b62929364a8be8f709c950d728a22ee72179a65aeffcb7a1156a23d3883404daf36219101b9aab8c2f0c8b12e22316d93a60407c9addaa72fdac5a1a68ca42
7
- data.tar.gz: 6ac27ed65e2acca6a533ada325f1fe3e0756befd2fb803429b79864092a66eadaefff681a1eefd5fcd74e3f2b65bb87b301ded820a6541e628183df816a2a8ee
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. Defaults to `./Resources/Localizable.strings`. | `GPT_SOURCE_FILE` |
54
- | `target_file` | The path to the output file for the translated strings. Defaults to `./Resources/Localizable.strings.<target_language>`. | `GPT_TARGET_FILE` |
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 #{input_hash.size} strings..."
24
+ UI.message "Translating #{to_translate.size} strings..."
24
25
 
25
- to_translate.each do |key, value|
26
- prompt = "Translate the following string from #{params[:source_language]} to #{params[:target_language]}:\n#{value}"
27
- context = Helper::TranslateGptHelper.get_context(params[:source_file], key)
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
- output_hash[key] = target_string
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
- Helper::TranslateGptHelper.timeout params[:request_timeout]
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
- # write the output hash to the output file
59
- File.open(params[:target_file], "w") do |file|
60
- output_hash.each do |key, value|
61
- file.puts "\"#{key}\" = \"#{value}\";"
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
- # Read the strings file into a hash
13
- strings_file = File.read(localization_file)
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
- # read the localization file
30
- content = File.read(localization_file)
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
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module TranslateGpt
3
- VERSION = "0.1.0"
3
+ VERSION = "0.1.2"
4
4
  end
5
5
  end
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.0
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-04-23 00:00:00.000000000 Z
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