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: 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