Skip to content

Commit 7c9fe4c

Browse files
authored
Merge pull request #47 from clickcaramel/feat/306-update-translations-if-descr-changed
[Polyglot] Run translation process from scratch for a text when context comment is changed #306
2 parents 6f1bdde + 35b2e27 commit 7c9fe4c

File tree

3 files changed

+109
-8
lines changed

3 files changed

+109
-8
lines changed

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,21 @@ Just add your translation to the desired localization file. If Polyglot encounte
274274

275275
But please note that if you have [premium](https://polyglot.rocks/#pricing) plan and you added your translation before AI-translation - you won't get our manual translation. If you want to replace your translation with the manual one, just delete the line with it from the localization file. The next time you run Polyglot, it will process this line as usual.
276276

277+
### How I can limit the translation length?
278+
279+
You can use `// polyglot:max_length:<number>` comment before the line. As an argument, specify the maximum length of the translation in characters. For example:
280+
281+
```bash
282+
// polyglot:max_length:15
283+
"Saved successfully" = "Saved successfully";
284+
```
285+
286+
AI will take this into account when translating, but there is no guarantee that it will fulfill the condition. The human will try to translate with the condition in mind. If he does not succeed, he will leave a comment along with the translation option as to why it is not possible. You will see the comment at the end of the translation line:
287+
288+
```bash
289+
"CUSTOM_STRING" = "Personnalisé"; // translator comment: "Condition is too hard"
290+
```
291+
277292
We hope this helps! If you have any other questions, please do not hesitate to ask.
278293

279294
## License

bin/polyglot

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ tenant_token="$1"
101101

102102
declare -A translations &>/dev/null;
103103
declare -A translators_comments &>/dev/null;
104+
declare -A descriptions &>/dev/null;
105+
declare -A desired_max_lengths &>/dev/null;
104106
if [ $? -eq 0 ]; then
105107
set_translation() {
106108
translations[`echo $1_$2_$3`]="$4"
@@ -110,13 +112,29 @@ if [ $? -eq 0 ]; then
110112
fi
111113
}
112114

115+
set_description() {
116+
descriptions["$1"]="$2"
117+
}
118+
119+
set_desired_max_len() {
120+
desired_max_lengths["$1"]="$2"
121+
}
122+
113123
get_translation() {
114124
echo ${translations[`echo $1_$2_$3`]}
115125
}
116126

117127
get_translator_comment() {
118128
echo ${translators_comments[`echo $1_$2`]}
119129
}
130+
131+
get_description() {
132+
echo ${descriptions["$1"]}
133+
}
134+
135+
get_desired_max_len() {
136+
echo ${desired_max_lengths["$1"]}
137+
}
120138
else
121139
warning "Your Bash version does not support associative arrays, indexing will be slow, we recommend updating your Bash to the newer version."
122140
translation_key() {
@@ -132,6 +150,16 @@ else
132150
fi
133151
}
134152

153+
set_description() {
154+
md5key="`calc_md5 \"$1\"`"
155+
printf -v "descriptions__${md5key}" %s "$2"
156+
}
157+
158+
set_desired_max_len() {
159+
md5key="`calc_md5 \"$1\"`"
160+
printf -v "desired_max_lengths__${md5key}" %s "$2"
161+
}
162+
135163
get_translation() {
136164
n="$1_translations__`translation_key \"$2\" \"$3\"`"
137165
echo ${!n}
@@ -141,6 +169,16 @@ else
141169
n="translators_comments__`translation_key \"$1\" \"$2\"`"
142170
echo ${!n}
143171
}
172+
173+
get_description() {
174+
n="descriptions__`calc_md5 \"$1\"`"
175+
echo ${!n}
176+
}
177+
178+
get_desired_max_len() {
179+
n="desired_max_lengths__`calc_md5 \"$1\"`"
180+
echo ${!n}
181+
}
144182
fi
145183

146184
BASEDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
@@ -198,6 +236,10 @@ escape_for_sed() {
198236
echo "$1" | sed -e 's/\\/\\\\/g; s/\//\\\//g; s/&/\\\&/g'
199237
}
200238

239+
restart_translation_info() {
240+
echo `info "Seems like $1 is changed for '$2' so we're starting translations from scratch for this string."`
241+
}
242+
201243
escape_for_grep() {
202244
sed 's/[][\.|$(){}?+*^]/&/g' <<< "$*"
203245
}
@@ -208,7 +250,7 @@ escape_line_breaks() {
208250

209251
response_to_js_map() {
210252
fixed_response=`echo "$1" | sed -e "s/$escaped_quote/$quote_placeholder/g"`
211-
echo "$fixed_response" | jq -r 'del(.[].description?) | map( { (.stringId|tostring): .translations } ) | add | del(.[].stringId)'
253+
echo "$fixed_response" | jq -r 'map( { (.stringId|tostring): (.translations + {description: .description, desiredMaxLength: .desiredMaxLength}) } ) | add | del(.[].stringId)'
212254
}
213255

214256
calc_md5() {
@@ -234,10 +276,14 @@ fill_translations_map() {
234276

235277
while read item ; do
236278
id="`echo $item | jq -r '.key'`"
279+
description="`echo $item | jq -r '.value.description? // empty'`"
280+
max_len="`echo $item | jq -r '.value.desiredMaxLength? // empty'`"
281+
set_description "$id" "$description"
282+
set_desired_max_len "$id" $max_len
237283
while IFS="~" read -r key value comment
238284
do
239285
set_translation "$1" "$id" "$key" "$value" "$comment"
240-
done < <(escape_line_breaks "$item" | jq -rc '.value|to_entries|map("\(.key)~\(.value.value)~\(.value.translatorComment)") | .[]' | sed -e "s/$quote_placeholder/$escaped_quote/g")
286+
done < <(escape_line_breaks "$item" | jq -rc '.value|del(.description, .desiredMaxLength)|to_entries|map("\(.key)~\(.value.value)~\(.value.translatorComment?)") | .[]' | sed -e "s/$quote_placeholder/$escaped_quote/g")
241287

242288
done < <(escape_line_breaks "$data")
243289
}
@@ -373,7 +419,6 @@ main() {
373419
[ -f "$prev_translations_file" ] || echo "{}" > "$prev_translations_file"
374420

375421
info "Downloading translations from the server"
376-
377422
api_response=$(curl -H "Accept: application/json" -H "Authorization: Bearer $tenant_token" -L "$api_url/products/$product_id/strings?manual=true" -s)
378423

379424
case `echo $api_response | jq -r '.message?'` in
@@ -514,11 +559,24 @@ main() {
514559
base_value=`echo "$base_value" | sed -e 's/;[ ]*\/\/.*/;/' -e 's/\"//' -e 's/\";$/;/'`
515560
base_value=`echo ${base_value//;}`
516561
manual_translation=`get_translation 'manual' "$id" "$language"`
517-
saved_base_value=`get_translation 'manual' "$id" "en"`
518-
if [ -n "$manual_translation" ] && [ "$saved_base_value" != "$base_value" ] ; then
519-
info "Seems like English string is changed for '$id' so we're starting translations from scratch for this string."
520-
manual_translation=""
562+
563+
if [ -n "$manual_translation" ]; then
564+
saved_base_value=`get_translation 'manual' "$id" "en"`
565+
prev_description=`get_description "$id"`
566+
prev_desired_max_len=`get_desired_max_len "$id"`
567+
568+
if [ "$saved_base_value" != "$base_value" ]; then
569+
restart_translation_info 'source string' "$id"
570+
manual_translation=''
571+
elif [ "$prev_description" != "$description" ]; then
572+
restart_translation_info 'description' "$id"
573+
manual_translation=''
574+
elif [ "$prev_desired_max_len" != "$desired_max_length" ]; then
575+
restart_translation_info 'max-length' "$id"
576+
manual_translation=''
577+
fi
521578
fi
579+
522580
old_record="\"$id\" = "
523581
escaped_old_record=`escape_for_grep "$old_record"`
524582
disabled_translation="`(echo $line ; grep \"$escaped_old_record\" $file) | grep "polyglot:disable:this"`"

tests/translate.spec.sh

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ test_base_is_not_included() {
203203

204204
test_translate_equal_strings_when_equal_line_count() {
205205
clear_db "$product_id"
206+
echo "$initial_data" > "$translations_path/en.lproj/$file_name"
206207
# x2 launch for getting manual_translations_changed == false
207208
output=`$script $tenant_token -p ../$app_name`
208209
output=`$script $tenant_token -p ../$app_name`
@@ -263,5 +264,32 @@ test_translate_string_with_spec_chars() {
263264
echo '"with_spec_chars" = "string with\nspecial\n \"chars\", now";' > $path
264265
output=`$script $tenant_token -p ../$app_name`
265266
translation=`grep 'with_spec_chars' $translations_path/de.lproj/$file_name | cut -d '=' -f 2`
266-
assert_multiple ' "Zeichenkette mit\nspeziellen\n \"Zeichen\", jetzt";' ' "Zeichenkette mit\nspeziellem\n \"Zeichen\", jetzt";' ' "Seil mit\nspeziell\n \"Zeichen\", jetzt";' ' "Seil mit\nspeziellen\n \"Zeichen\", jetzt";' "$translation"
267+
assert_multiple ' "Zeichenkette mit\nbesonderen\n \"Zeichen\", jetzt";' ' "Zeichenkette mit\nspeziellen\n \"Zeichen\", jetzt";' ' "Zeichenkette mit\nspeziellem\n \"Zeichen\", jetzt";' ' "Seil mit\nspeziell\n \"Zeichen\", jetzt";' ' "Seil mit\nspeziellen\n \"Zeichen\", jetzt";' "$translation"
268+
}
269+
270+
test_restart_translation_if_descr_changed() {
271+
curl -X PUT -H "Content-Type: application/json" -H "Accept: application/json" -H "Authorization: Bearer $tenant_token" -L "$api_url/products/$product_id/strings/fork" -d "{ \"translations\": { \"en\": \"fork\", \"fr\": \"fourche\", \"de\": \"gabel\" }, \"description\": \"working with the Github repository\" }" -s >> /dev/null
272+
path="$translations_path/en.lproj/$file_name";
273+
str_with_comment='// cutlery
274+
"fork" = "fork";'
275+
echo "$str_with_comment" > $path
276+
output=`$script $tenant_token -p ../$app_name`
277+
translation=`grep 'fork' $translations_path/fr.lproj/$file_name | cut -d '=' -f 2`
278+
description=`curl -H "Accept: application/json" -H "Authorization: Bearer $tenant_token" -L "$api_url/products/$product_id/strings/fork" -s | jq -r '.description'`
279+
assert_equals ' "fourchette";' "$translation"
280+
assert_equals 'cutlery' "$description"
281+
}
282+
283+
test_restart_translation_if_max_len_changed() {
284+
str_id='change_max_len_str'
285+
curl -X PUT -H "Content-Type: application/json" -H "Accept: application/json" -H "Authorization: Bearer $tenant_token" -L "$api_url/products/$product_id/strings/$str_id" -d "{ \"translations\": { \"en\": \"Not enough memory on your device\", \"fr\": \"Mémoire insuffisante sur votre appareil\", \"de\": \"Nicht genügend Speicher auf Ihrem Gerät\" }, \"desiredMaxLength\": 30 }" -s >> /dev/null
286+
path="$translations_path/en.lproj/$file_name";
287+
str_with_max_len="// polyglot:max_length:15
288+
\"$str_id\" = \"Not enough memory on your device\";"
289+
echo "$str_with_max_len" > $path
290+
output=`$script $tenant_token -p ../$app_name`
291+
translation=`grep "$str_id" $translations_path/de.lproj/$file_name | cut -d '=' -f 2`
292+
max_len=`curl -H "Accept: application/json" -H "Authorization: Bearer $tenant_token" -L "$api_url/products/$product_id/strings/$str_id" -s | jq -r '.desiredMaxLength'`
293+
assert_multiple ' "Nicht genug Speicher.";' ' "Nicht genug Speicher";' ' "Zu wenig Speicher";' "$translation"
294+
assert_equals 15 $max_len
267295
}

0 commit comments

Comments
 (0)