A CLI tool for localization resource management on Xcode. Built with Google Translator.

Overview

Awesome PyPI version License: GPL v3

    

Supported by Jetbrains Open Source License Program


Automatically translate and synchronize '.strings' files from the defined base language

The basic concept of this python CLI tool is straightforward file name based one-way synchronizer. If you are running, other localized resources will have the same key with automatically translated strings. Of course, string on the key that already exists will not be modified at all.

Requirements

Install

pip install strsync

Enable Google Cloud Translation Python API

Set your account and authentication credentials up with Google's guide for local envirnment.

https://cloud.google.com/translate/docs/reference/libraries#client-libraries-install-python

If you can't use Translation feature, use '-w' option to copy all items from Base language.

$ strsync ./myapp/Resources/Localizations -w

Update Python SSL packages if needed

this is not required for python-2.7.9+

pip install requests[security]

Usage

Naturally, this tool follow standard ISO639 1~2 codes or apple's official document or this tsv table

usage: strsync-runner.py [-h] [-b BASE_LANG_NAME]
                         [-x EXCLUDING_LANG_NAMES [EXCLUDING_LANG_NAMES ...]]
                         [-f [FORCE_TRANSLATE_KEYS [FORCE_TRANSLATE_KEYS ...]]]
                         [-o FOLLOWING_BASE_KEYS [FOLLOWING_BASE_KEYS ...]]
                         [-w [FOLLOWING_BASE_IF_NOT_EXISTS [FOLLOWING_BASE_IF_NOT_EXISTS ...]]]
                         [-l CUTTING_LENGTH_RATIO_WITH_BASE [CUTTING_LENGTH_RATIO_WITH_BASE ...]]
                         [-c [IGNORE_COMMENTS [IGNORE_COMMENTS ...]]]
                         [-v [VERIFY_RESULTS [VERIFY_RESULTS ...]]]
                         [-s [INCLUDE_SECONDARY_LANGUAGES [INCLUDE_SECONDARY_LANGUAGES ...]]]
                         [-i [IGNORE_UNVERIFIED_RESULTS [IGNORE_UNVERIFIED_RESULTS ...]]]
                         [target path] [only for keys [only for keys ...]]

Automatically translate and synchronize .strings files from defined base
language.

positional arguments:
  target path           Target localization resource path. (root path of
                        Base.lproj, default=./)
  only for keys         Some specified keys for exclusive work. All operations
                        will work for only that keys therefore other keys will
                        be ignored. Not specified by default. (default=None)

optional arguments:
  -h, --help            show this help message and exit
  -b BASE_LANG_NAME, --base-lang-name BASE_LANG_NAME
                        A base(or source) localizable resource
                        name.(default='Base'), (e.g. "Base" via 'Base.lproj',
                        "en" via 'en.lproj')
  -x EXCLUDING_LANG_NAMES [EXCLUDING_LANG_NAMES ...], --excluding-lang-names EXCLUDING_LANG_NAMES [EXCLUDING_LANG_NAMES ...]
                        A localizable resource name that you want to exclude.
                        (e.g. "Base" via 'Base.lproj', "en" via 'en.lproj')
  -f [FORCE_TRANSLATE_KEYS [FORCE_TRANSLATE_KEYS ...]], --force-translate-keys [FORCE_TRANSLATE_KEYS [FORCE_TRANSLATE_KEYS ...]]
                        Keys in the strings to update and translate by force.
                        (input nothing for all keys.)
  -o FOLLOWING_BASE_KEYS [FOLLOWING_BASE_KEYS ...], --following-base-keys FOLLOWING_BASE_KEYS [FOLLOWING_BASE_KEYS ...]
                        Keys in the strings to follow from "Base.
  -w [FOLLOWING_BASE_IF_NOT_EXISTS [FOLLOWING_BASE_IF_NOT_EXISTS ...]], --following-base-if-not-exists [FOLLOWING_BASE_IF_NOT_EXISTS [FOLLOWING_BASE_IF_NOT_EXISTS ...]]
                        With this option, all keys will be followed up with
                        base values if they does not exist.
  -l CUTTING_LENGTH_RATIO_WITH_BASE [CUTTING_LENGTH_RATIO_WITH_BASE ...], --cutting-length-ratio-with-base CUTTING_LENGTH_RATIO_WITH_BASE [CUTTING_LENGTH_RATIO_WITH_BASE ...]
                        Keys in the float as the ratio to compare the length
                        of "Base"
  -c [IGNORE_COMMENTS [IGNORE_COMMENTS ...]], --ignore-comments [IGNORE_COMMENTS [IGNORE_COMMENTS ...]]
                        Allows ignoring comment synchronization.
  -v [VERIFY_RESULTS [VERIFY_RESULTS ...]], --verify-results [VERIFY_RESULTS [VERIFY_RESULTS ...]]
                        Verify translated results via reversed results
  -s [INCLUDE_SECONDARY_LANGUAGES [INCLUDE_SECONDARY_LANGUAGES ...]], --include-secondary-languages [INCLUDE_SECONDARY_LANGUAGES [INCLUDE_SECONDARY_LANGUAGES ...]]
                        Include Additional Secondary Languages. (+63 language
                        codes)
  -i [IGNORE_UNVERIFIED_RESULTS [IGNORE_UNVERIFIED_RESULTS ...]], --ignore-unverified-results [IGNORE_UNVERIFIED_RESULTS [IGNORE_UNVERIFIED_RESULTS ...]]
                        Allows ignoring unverified results when appending
                        them.

Examples to use

~/Documents/myapp/myapp/Resources/Localizations$ strsync
~/Documents/myapp/myapp/Resources/Intents$ strsync

Define specific path you want. A parent path of *.lproj(s).

$ strsync ./myapp/Resources/Localizations
$ strsync ./myapp/Resources/Intents

Copy all items from Base language without translation.

$ strsync ./myapp/Resources/Localizations -w

All operations will work for only keys "exclusive key1" "exclusive key2" "exclusive key3". Other keys will be ignored.

$ strsync ./myapp/Resources/Localizations "exclusive key1" "exclusive key2" "exclusive key3"

Excluding japanese, spanish, finnish

$ strsync ./myapp/Resources/Localizations -x ja es fi

Forcefully translate and update by specific keys you want.

$ strsync -f Common.OK Common.Undo "Key name which contains white space"

Forcefully translate and update by All keys.

$ strsync -f  (input nothing)

When you want to accept the values in the 'Base'.

$ strsync -o autoenhance flashmode

#before
"flashmode" = "وضع الفلاش";
"flashmode.auto" = "السيارات";
"flashmode.on" = "على";
"autoenhance" = "تعزيز السيارات";

#after
"flashmode" = "Flash Mode";
"flashmode.auto" = "السيارات";
"flashmode.on" = "على";
"autoenhance" = "Auto-Enhance";

If you add an option -v or --verify-results, String similarity of the reversed translation result for each language will be displayed.

$ strsync (...) -v

el
  Hi: Hi -> Γεια σου -> Hi, Matched: 100%
fr-CA
  Hi: Hi -> Salut -> Hello, Matched: 50%
id
  Hi: Hi -> Hai -> Two, Matched: 0%
fr
  Hi: Hi -> Salut -> Hello, Matched: 50%
uk
  Hi: Hi -> Привіт -> Hi, Matched: 100%
hr
  Hi: Hi -> Bok -> Book, Matched: 0%
da
  Hi: Hi -> Hej -> Hi, Matched: 100%
ja
  Hi: Hi -> こんにちは -> Hello, Matched: 50%
he
  Hi: Hi -> היי -> Hey, Matched: 50%
ko
  Hi: Hi -> 안녕 -> Hi, Matched: 100%
sv
  Hi: Hi -> Hej -> Hi, Matched: 100%
es-MX
  Hi: Hi -> Hola -> Hello, Matched: 50%
sk
  Hi: Hi -> ahoj -> Hi, Matched: 100%
zh-CN
  Hi: Hi -> 你好 -> How are you doing, Matched: 50%

or if you add --ignore-unverified-results [Integer, Percentage (0~100) (default=0)], If the similarity of each reversed translation result is under the given value, that string will be skipped(ignored).

ex)

strings will be skipped if its text similarity from reversed translation result is under 50

$ strsync (...) --ignore-unverified-results 50

el
  Hi: Hi -> Γεια σου -> Hi, Matched: 100%
fr-CA
  (Ignored) Hi: Hi -> Salut -> Hello, Matched: 50%
id
  (Ignored) Hi: Hi -> Hai -> Two, Matched: 0%
fr
  (Ignored) Hi: Hi -> Salut -> Hello, Matched: 50%
uk
  Hi: Hi -> Привіт -> Hi, Matched: 100%
hr
  (Ignored) Hi: Hi -> Bok -> Book, Matched: 0%
da
  Hi: Hi -> Hej -> Hi, Matched: 100%
ja
  (Ignored) Hi: Hi -> こんにちは -> Hello, Matched: 50%
he
  (Ignored) Hi: Hi -> היי -> Hey, Matched: 50%
ko
  Hi: Hi -> 안녕 -> Hi, Matched: 100%
sv
  Hi: Hi -> Hej -> Hi, Matched: 100%
es-MX
  (Ignored) Hi: Hi -> Hola -> Hello, Matched: 50%
sk
  Hi: Hi -> ahoj -> Hi, Matched: 100%
zh-CN
  (Ignored) Hi: Hi -> 你好 -> How are you doing, Matched: 50%

Utilities

There are some additional scripts to help your workflow with strsync.

https://github.com/metasmile/strsync/tree/master/utils

Comments
  • [known issue] Translation may be unexpectedly stopped in case of a big file or many files being translated

    [known issue] Translation may be unexpectedly stopped in case of a big file or many files being translated

    If you have many .strings files and especially big ones, Google may eventually return a captcha page instead of translation. It will cause the tool to stop and exit, because the result is not a JSON and can't be parsed by decoder.py

    Workaround: run the tool once to translate as much as possible, then wait some time and run it again to translate more. Repeat until you have it all translated.

    Workaround 2: if you have a big file (about 1K and more lines), a repeated run might not always work. In this case just cut half of the file, run the tool once, wait a few seconds, then paste it back again and run the tool once again.

    An example log showing what happens:

    Translating...
    Traceback (most recent call last):
      File "/usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pdb.py", line 1314, in main
        pdb._runscript(mainpyfile)
      File "/usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pdb.py", line 1233, in _runscript
        self.run(statement)
      File "/usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/bdb.py", line 400, in run
        exec cmd in globals, locals
      File "<string>", line 1, in <module>
      File "/Users/vitaliy/Documents/Projects/Sporty/virtualenv_Environments(Python2)/for_strsync/as_script/strsync-master/strsync/strsync.py", line 5, in <module>
        from __future__ import print_function
      File "/Users/vitaliy/Documents/Projects/Sporty/virtualenv_Environments(Python2)/for_strsync/as_script/strsync-master/strsync/strsync.py", line 440, in main
        u, c, t, e, m = insert_or_translate(ext_file, lc)
      File "/Users/vitaliy/Documents/Projects/Sporty/virtualenv_Environments(Python2)/for_strsync/as_script/strsync-master/strsync/strsync.py", line 189, in insert_or_translate
        translated_kv = dict(zip(adding_keys, strtrans.translate([base_kv[k] for k in adding_keys], lc)))
      File "/Users/vitaliy/Documents/Projects/Sporty/virtualenv_Environments(Python2)/for_strsync/as_script/strsync-master/strsync/strtrans.py", line 95, in translate
        translated_items = __trans.translate([item.trans_input_text for item in pre_items], dest=to)
      File "/Users/vitaliy/Documents/Projects/Sporty/virtualenv_Environments(Python2)/for_strsync/lib/python2.7/site-packages/googletrans/client.py", line 167, in translate
        translated = self.translate(item, dest=dest, src=src)
      File "/Users/vitaliy/Documents/Projects/Sporty/virtualenv_Environments(Python2)/for_strsync/lib/python2.7/site-packages/googletrans/client.py", line 172, in translate
        data = self._translate(text, dest, src)
      File "/Users/vitaliy/Documents/Projects/Sporty/virtualenv_Environments(Python2)/for_strsync/lib/python2.7/site-packages/googletrans/client.py", line 81, in _translate
        data = utils.format_json(r.text)
      File "/Users/vitaliy/Documents/Projects/Sporty/virtualenv_Environments(Python2)/for_strsync/lib/python2.7/site-packages/googletrans/utils.py", line 62, in format_json
        converted = legacy_format_json(original)
      File "/Users/vitaliy/Documents/Projects/Sporty/virtualenv_Environments(Python2)/for_strsync/lib/python2.7/site-packages/googletrans/utils.py", line 54, in legacy_format_json
        converted = json.loads(text)
      File "/usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 339, in loads
        return _default_decoder.decode(s)
      File "/usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 364, in decode
        obj, end = self.raw_decode(s, idx=_w(s, 0).end())
      File "/usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 382, in raw_decode
        raise ValueError("No JSON object could be decoded")
    ValueError: No JSON object could be decoded
    Uncaught exception. Entering post mortem debugging
    Running 'cont' or 'step' will restart the program
    > /usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py(382)raw_decode()
    -> raise ValueError("No JSON object could be decoded")
    
    (Pdb) print s
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html DIR="LTR">
    <head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="viewport" content="initial-scale=1"><title>https://translate.google.com/translate_a/single?otf=1&amp;tsel=0&amp;hl=es&amp;dt=at&amp;dt=bd&amp;dt=ex&amp;dt=ld&amp;dt=md&amp;dt=qca&amp;dt=rw&amp;dt=rm&amp;dt=ss&amp;dt=t&amp;ie=UTF-8&amp;oe=UTF-8&amp;q=Couldn%27t+process+your+purchase&amp;tl=es&amp;client=t&amp;tk=47737.407936&amp;sl=auto&amp;ssel=0</title></head>
    <body style="font-family: arial, sans-serif; background-color: #fff; color: #000; padding:20px; font-size:18px;" onload="e=document.getElementById('captcha');if(e){e.focus();}">
    <div style="max-width:400px;">
    <hr noshade size="1" style="color:#ccc; background-color:#ccc;"><br>
    <form id="captcha-form" action="index" method="post">
    <script src="https://www.google.com/recaptcha/api.js" async defer></script>
    <script>var submitCallback = function(response) {document.getElementById('captcha-form').submit();};</script>
    <div id="recaptcha" class="g-recaptcha" data-sitekey="6LfwuyUTAAAAAOAmoS0fdqijC2PbbdH4kjq62Y1b" data-callback="submitCallback" data-s="qMq8X6FcHdvnYkeG9gMuI52DOQ-StzD_VFjtezarGL0_xoBraLfQc95Atgm5aqL9xdqne75PBV5w5zgAhJUuFfV3rTcn3ZHr9DqygWKZpdMKIzOYwa_e01ToXX-KPafvi2QaBchmHZqSjOf_lWoVRwE3oA4Vgx-wRc8vYSD2x5--s1MJ3HaEIKrElmxuHtCvmecgWkxo_jONiZ0oCwvVOuK4EGRWgZ2LkwNuz4i9TekNMWQuuPKPDZM"></div>
    <input type='hidden' name='q' value='EgRZ_AsrGJvC_9wFIhkA8aeDS5Z4WLuO26G9kKJY5Y-wv_4J-qv4MgFy'><input type="hidden" name="continue" value="https://translate.google.com/translate_a/single?otf=1&amp;tsel=0&amp;hl=es&amp;dt=at&amp;dt=bd&amp;dt=ex&amp;dt=ld&amp;dt=md&amp;dt=qca&amp;dt=rw&amp;dt=rm&amp;dt=ss&amp;dt=t&amp;ie=UTF-8&amp;oe=UTF-8&amp;q=Couldn%27t+process+your+purchase&amp;tl=es&amp;client=t&amp;tk=47737.407936&amp;sl=auto&amp;ssel=0">
    </form>
    <hr noshade size="1" style="color:#ccc; background-color:#ccc;">
    <div style="font-size:13px;">
    <b>Acerca de esta página</b><br><br>Nuestros sistemas han detectado tráfico inusual procedente de tu red de ordenadores. En esta página se comprueba si eres tú quien envía las solicitudes en lugar de un robot. <a href="#" onclick="document.getElementById('infoDiv').style.display='block';">¿A qué se debe esto?</a><br><br>
    <div id="infoDiv" style="display:none; background-color:#eee; padding:10px; margin:0 0 15px 0; line-height:1.4em;">
    Esta página aparece cuando Google detecta automáticamente solicitudes procedentes de tu red de ordenadores que parecen infringir las <a href="//www.google.com/policies/terms/">Condiciones del servicio</a>. El bloqueo caducará poco después de que se detengan esas solicitudes. Mientras tanto, si solucionas la prueba CAPTCHA de arriba, podrás seguir utilizando nuestros servicios.<br><br>Es posible que este tráfico proceda de software malintencionado, de un complemento del navegador o de una secuencia de comandos que envíe solicitudes automáticas. Si compartes tu conexión de red, pídele ayuda a tu administrador: puede que otro ordenador que utilice la misma dirección IP esté causando la incidencia. <a href="//support.google.com/websearch/answer/86640">Más información</a><br><br>En ocasiones, es posible que tengas que solucionar la prueba CAPTCHA si utilizas términos avanzados que emplean los robots o si envías solicitudes con gran rapidez.
    
    </div><br>
    Dirección IP: 11.111.11.11<br>Hora: 2018-09-17T17:15:08Z<br>URL: https://translate.google.com/translate_a/single?otf=1&amp;tsel=0&amp;hl=es&amp;dt=at&amp;dt=bd&amp;dt=ex&amp;dt=ld&amp;dt=md&amp;dt=qca&amp;dt=rw&amp;dt=rm&amp;dt=ss&amp;dt=t&amp;ie=UTF-8&amp;oe=UTF-8&amp;q=Couldn%27t+process+your+purchase&amp;tl=es&amp;client=t&amp;tk=47737.407936&amp;sl=auto&amp;ssel=0<br>
    </div></div>
    </body>
    </html>
    
    

    the returned html translated:

    <b> About this page </ b> <br> <br> Our systems have detected unusual traffic from your computer network. On this page it is checked if you are the one sending the requests instead of a robot. <a href="#" onclick="document.getElementById('infoDiv').style.display='block';"> What is this? </a> <br> <br>
    <div id = "infoDiv" style = "display: none; background-color: #eee; padding: 10px; margin: 0 0 15px 0; line-height: 1.4em;">
    This page appears when Google automatically detects requests from your computer network that appear to violate the <a href="//www.google.com/policies/terms/"> Terms of Service </a>. The blocking will expire shortly after those requests are stopped. In the meantime, if you solve the CAPTCHA test above, you can still use our services. <br> <br> This traffic may come from malicious software, from a browser add-on or from a script that you send automatic requests. If you share your network connection, ask your administrator for help: another computer that uses the same IP address may be causing the problem. <a href="//support.google.com/websearch/answer/86640"> Learn more </a> <br> <br> Occasionally, you may have to troubleshoot the CAPTCHA test if you use tea Advanced terms that robots use or if you send requests very quickly.
    
    opened by vitalii-tym 4
  • [Main Feature] Add a option to verify via reversed translation results.

    [Main Feature] Add a option to verify via reversed translation results.

    • The feature to translate twice(Forward + Backward) each languages.
    • Display approximate string matching percentage after run.
    • Display Google image searching result
    • If each reversed translation result's similarity is 60 or higher, apply them. Or apply base language's string.
    • Slack bot to report result
    • Similarity, as an integer, should display via translation comments.

    Hello -> مرحبا
    مرحبا -> Hello

    Success


    Hello -> مرحبا
    حبا -> dsfsdf

    Fail


    Hello -> مرحبا
    مرحبا -> Hi

    Simillar but different

    enhancement feature 
    opened by metasmile 3
  • A code mismatch for Norwegian language (`no` at Google, but `nb` at Apple)

    A code mismatch for Norwegian language (`no` at Google, but `nb` at Apple)

    The tool creates Norwegian translations with code no (a folder named no.lproj is created). This is supposedly because Google designates Norwegian under no (not sure which one it is, but I want to believe its a Bokmål).

    The problem is that Apple doesn't know about no. Norwegian Bokmål is designated under nb code and there are also other codes (see screenshot), but none of them matches no. So that the results of translation to Norwegian have to be moved from no to nb either manually or with an additional script.

    Not a big issue, but would be cool if it the tool could manage this small discrepancy out-of-box.

    bug 
    opened by vitalii-tym 1
  • Support switch to Azure portal

    Support switch to Azure portal

    ArgumentException: Invalid authentication token. Microsoft DataMarket is retired. Please subscribe to Microsoft Translator, in the Cognitive Services section at https://portal.azure.com. Please visit https://cognitive.uservoice.com/knowledgebase/articles/1128340-announcements-action-required-before-april-30-20 to find detailed instructions. : ID=1446.V2_Json.TranslateArray.37DC65CA T

    https://github.com/wronglink/mstranslator

    bug invalid 
    opened by metasmile 1
  • Fix for bugs #25 and #24

    Fix for bugs #25 and #24

    Without this break the tool correctly adds new strings and deletes removed strings for all translations. At least for me, while using it this way: strsync -b en -x el vi ca it ar cs id en-GB ru nl pt tr en-AU th zh_TW ro pt_PT pl fr zh_HK ms hr de hu hi fi da ja fr_CA he zh_CN ko sv sk

    opened by vitalii-tym 0
  • The tool translates only one .strings file from the target dir and skips the rest of files

    The tool translates only one .strings file from the target dir and skips the rest of files

    tried to debug it: it seems to be correctly making a list of files and starts to loop through them, but the break statement on line 342 goes out of the loop after the very first file added to base_dict.

    If I remove the break sentence - it seems to be taking all the files as expected. But I can't verify it works correctly yet because of one other bug. Will try to make a PR as soon as I'm sure it works.

    opened by vitalii-tym 1
  • When I enable translation for an additional storyboard and run the tool - it will delete .strings files for most of the previously translated storyboards

    When I enable translation for an additional storyboard and run the tool - it will delete .strings files for most of the previously translated storyboards

    If I already have storyboards with .strings files, which were previously generated by the tool and later I run the tool again, the previously generated files are converted from .strings to .strings.deleted

    screenshot 2018-09-13 12 03 42 screenshot 2018-09-13 12 04 37

    Maybe I'm using the tool not properly. Please advice how to correctly do incremental runs if that's the case?

    Example output in Terminal:

    vitaliy$ strsync -b en -x el vi ca it ar cs id en-GB ru nl pt tr en-AU th zh_TW ro pt_PT pl fr zh_HK ms hr de hu hi fi da ja fr_CA he zh_CN ko sv sk
    /Users/vitaliy/Documents/Projects/Sporty/virtualenv_Environments(Python2)/for_strsync/lib/python2.7/site-packages/fuzzywuzzy/fuzz.py:11: UserWarning: Using slow pure-python SequenceMatcher. Install python-Levenshtein to remove this warning
      warnings.warn('Using slow pure-python SequenceMatcher. Install python-Levenshtein to remove this warning')
    (i) Initializing for supported languages ...
    (i) Supported numbers of locale code : 38 
    ['el', 'vi', 'ca', 'it', 'ar', 'es_MX', 'cs', 'id', 'es', 'en-GB', 'ru', 'nl', 'pt', 'no', 'tr', 'en-AU', 'th', 'zh_TW', 'ro', 'pt_PT', 'pl', 'fr', 'zh_HK', 'ms', 'hr', 'de', 'hu', 'hi', 'fi', 'da', 'ja', 'fr_CA', 'he', 'zh_CN', 'ko', 'sv', 'sk', 'uk']
    (i) Fetching supported locale codes for ios9 ... 
    (i) Supported numbers of locale code : 731 
    Check and verifiy resources ...
    Start synchronizing...
    Target: Shared.strings
    Target: DoneView.strings
    Skip:  de
    Does not supported:  ur
    Skip:  he
    Does not supported:  yi
    Skip:  ar
    Skip:  el
    Skip:  ja
    Does not supported:  mi
    Does not supported:  fa
    Does not supported:  mr
    Does not supported:  mk
    Does not supported:  sq
    Does not supported:  eu
    Does not supported:  co
    Does not supported:  lb
    
     Analayzing localizables... uk (at ./uk.lproj)
    Removing File... ./uk.lproj/Profile.strings
    Removing File... ./uk.lproj/Main.strings
    Adding File... ./uk.lproj/DoneView.strings
    Translating...
    [Add] "xdX-bl-jJH.normalTitle" = "Готово" <- Done 
    (i) Changed Keys: Added 1, Updated 0, Removed 0 
    (i) Changed Files : Added 1, Updated 0, Removed 2, Error 0 
    Does not supported:  yo
    Does not supported:  gu
    
     Analayzing localizables... es (at ./es_MX.lproj)
    Adding File... ./es_MX.lproj/Shared.strings
    Translating...
    [Add] "BdO-Fv-a7B.text" = "<NOMBRE DE LA PÁGINA>" <- <PAGE NAME> 
    (i) Changed Keys: Added 1, Updated 0, Removed 0 
    Adding File... ./es_MX.lproj/DoneView.strings
    Translating...
    [Add] "xdX-bl-jJH.normalTitle" = "Hecho" <- Done 
    (i) Changed Keys: Added 1, Updated 0, Removed 0 
    (i) Changed Files : Added 2, Updated 0, Removed 0, Error 0 
    Does not supported:  ku
    Skip:  zh-cn
    Does not supported:  kn
    Does not supported:  mt
    Does not supported:  sn
    Does not supported:  nb
    Does not supported:  ny
    Does not supported:  pa
    Skip:  en
    Does not supported:  am
    
     Analayzing localizables... es (at ./es.lproj)
    Removing File... ./es.lproj/Profile.strings
    Removing File... ./es.lproj/Main.strings
    Adding File... ./es.lproj/DoneView.strings
    Translating...
    [Add] "xdX-bl-jJH.normalTitle" = "Hecho" <- Done 
    (i) Changed Keys: Added 1, Updated 0, Removed 0 
    (i) Changed Files : Added 1, Updated 0, Removed 2, Error 0 
    Does not supported:  sw
    Does not supported:  is
    Does not supported:  sl
    Skip:  da
    Does not supported:  gl
    Does not supported:  ha
    Does not supported:  eo
    Does not supported:  et
    Skip:  it
    Does not supported:  fy
    Does not supported:  bg
    Skip:  sk
    Does not supported:  kk
    Skip:  pt
    Does not supported:  sr
    Skip:  ms
    Does not supported:  si
    Does not supported:  ta
    Does not supported:  ne
    Does not supported:  sm
    Does not supported:  ml
    Skip:  sv
    Does not supported:  te
    Skip:  cs
    Does not supported:  km
    Skip:  ko
    Does not supported:  hy
    Does not supported:  Base
    Does not supported:  tg
    Does not supported:  so
    Does not supported:  mn
    Does not supported:  st
    Does not supported:  ig
    
     Analayzing localizables... no (at ./no.lproj)
    Removing File... ./no.lproj/Profile.strings
    Adding File... ./no.lproj/Shared.strings
    Translating...
    [Add] "BdO-Fv-a7B.text" = "<PAGE NAME>" <- <PAGE NAME> 
    (i) Changed Keys: Added 1, Updated 0, Removed 0 
    Adding File... ./no.lproj/DoneView.strings
    Translating...
    [Add] "xdX-bl-jJH.normalTitle" = "Ferdig" <- Done 
    (i) Changed Keys: Added 1, Updated 0, Removed 0 
    (i) Changed Files : Added 2, Updated 0, Removed 1, Error 0 
    Skip:  hu
    Skip:  zh-tw
    Does not supported:  ka
    Skip:  en
    Does not supported:  ga
    Skip:  tr
    Skip:  pl
    Skip:  zh-tw
    Does not supported:  ps
    Does not supported:  jw
    Skip:  vi
    Does not supported:  lv
    Does not supported:  lo
    Does not supported:  lt
    Skip:  ru
    Does not supported:  cy
    Does not supported:  af
    Skip:  fr
    Does not supported:  uz
    Skip:  fr
    Skip:  fi
    Does not supported:  xh
    Skip:  id
    Skip:  nl
    Skip:  th
    Does not supported:  az
    Skip:  pt
    Does not supported:  bn
    Does not supported:  zu
    Does not supported:  ht
    Skip:  ro
    Does not supported:  mg
    Does not supported:  sd
    Does not supported:  bs
    Does not supported:  tl
    Skip:  hr
    Skip:  hi
    Skip:  ca
    Does not supported:  gd
    Does not supported:  Base
    
    Added ./es.lproj/DoneView.strings
    Removed ./es.lproj/Profile.strings
    Removed ./es.lproj/Main.strings
    Added ./uk.lproj/DoneView.strings
    Removed ./uk.lproj/Profile.strings
    Removed ./uk.lproj/Main.strings
    Added ./no.lproj/Shared.strings
    Added ./no.lproj/DoneView.strings
    Removed ./no.lproj/Profile.strings
    
    
    Total New Translated Strings : 4
    Changed Files Total : Added 4, Updated 0, Removed 5, Skipped 0
    Synchronized.
    
    bug 
    opened by vitalii-tym 4
  • A small mess with Spanish language

    A small mess with Spanish language

    Lets say I want Ukrainian, Norwegian and Spanish. For this I make the following request:

    strsync -b en -x el vi ca it ar es_MX cs id en-GB ru nl pt tr en-AU th zh_TW ro pt_PT pl fr zh_HK ms hr de hu hi fi da ja fr_CA he zh_CN ko sv sk (uk, no, and es are absent in the -x parameter)

    Ukrainian and Norwegian translated, but Spanish not.

    If I remove es_MX form exceptions and put es instead - still no Spanish translation.

    Only if I remove both es_MX and es, I will get Spanish, but in the log it says:

    Analayzing localizables... es (at ./es_MX.lproj)
    Adding File... ./es_MX.lproj/Profile.strings
    Translating...
    

    and .strings files appear for both languages this time: es and es_MX in the project folder. However, both files seem to be equal (at least for a small test set of strings I tried), so I have no idea if they are in Spanish or in Mexican Spanish.

    Impossibility to get es without es_MX and vice versa isn't a big issue - extra strings can be deleted afterwards, but I'm afraid these two might have been mixed and it is not clear which one I get as result.

    Also it is possible, maybe, that Google doesn't support es_MX and everything is in Spanish?

    enhancement 
    opened by vitalii-tym 0
  • Is there a parameter to indicate only a small set of target languages?

    Is there a parameter to indicate only a small set of target languages?

    Hello, first of all thank you so much for this great tool. Its a big time saver.

    Please advice, how is it better to make a call if I want only 1 or 2 languages?

    My first attempt was to exclude all supported by default languages and include the ones I want, which are not in default set:

    strsync -b en -x el vi ca it ar es_MX cs id es en-GB ru nl pt no tr en-AU th zh_TW ro pt_PT pl fr zh_HK ms hr de hu hi fi da ja fr_CA he zh_CN ko sv sk uk -s nb_NO es_419

    But it resulted in the num of supported languages widened to 101:

    (i) Initializing for supported languages ...
    (i) Supported numbers of locale code : 101 
    ['gu', 'gd', 'ga', 'gl', 'en-GB', 'lb', 'ny', 'lo', 'tr', 'lv', 'tl', 'th', 'tg', 'te', 'pt_PT', 'ta', 'yi', 'zh_HK', 'yo', 'de', 'da', 'uz', 'el', 'eo', 'eu', 'zu', 'es', 'ru', 'ro', 'bg', 'uk', 'bn', 'jw', 'bs', 'ja', 'xh', 'co', 'ca', 'cy', 'fi', 'cs', 'ps', 'pt', 'lt', 'pa', 'pl', 'hy', 'hr', 'zh_TW', 'ht', 'hu', 'hi', 'ha', 'he', 'mg', 'zh_CN', 'ml', 'mn', 'mi', 'mk', 'ur', 'mt', 'ms', 'mr', 'af', 'vi', 'is', 'am', 'it', 'kn', 'ar', 'et', 'az', 'id', 'ig', 'nl', 'no', 'ne', 'en-AU', 'fr', 'ku', 'fy', 'fa', 'es_MX', 'fr_CA', 'ka', 'kk', 'sr', 'sq', 'ko', 'sv', 'km', 'st', 'sk', 'si', 'so', 'sn', 'sm', 'sl', 'sw', 'sd']
    

    Adding more languages in exclusion worked:

    strsync -b en -x gu gd ga gl en-GB lb ny lo tr lv tl th tg te pt_PT ta yi zh_HK yo de da uz el eo eu zu es ru ro bg uk bn jw bs ja xh co ca cy fi cs ps pt lt pa pl hy hr zh_TW ht hu hi ha he mg zh_CN ml mn mi mk ur mt ms mr af vi is am it kn ar et az id ig nl no ne en-AU fr ku fy fa es_MX fr_CA ka kk sr sq ko sv km st sk si so sn sm sl sw sd -s nb es_419

    But maybe there is a way to just indicate a small set of languages? Like this:

    strsync -b en -s nb es_419

    opened by vitalii-tym 1
Releases(1.8)
  • 1.8(Dec 20, 2020)

  • 1.7(Dec 20, 2020)

    Add a second positional argument "only for keys"

    Some specified keys for exclusive work. All operations will work for only that keys, therefore, other keys will be ignored. Not specified by default. (default=None)

    Source code(tar.gz)
    Source code(zip)
  • 1.6.1(Nov 28, 2018)

  • 1.6(Sep 23, 2018)

  • 1.5(Sep 22, 2018)

  • 1.4.9(Sep 20, 2018)

  • 1.4.8(Sep 20, 2018)

  • 1.4.7(Sep 20, 2018)

  • 14.6(Aug 19, 2018)

    e.g.

    strsync ......... -l 1.5 
    

    It means that if the absolute Unicode character length of the translated l10n string is longer than Base.lproj's 1.5 times or more, it will be replaced(reverted) with the string of Base's

    Source code(tar.gz)
    Source code(zip)
  • 1.4.5(Jul 11, 2018)

  • 1.4.1(Apr 28, 2018)

    It will be paired with google translator's neural machine translation coverage. See for more details: https://cloud.google.com/translate/docs/languages

    Source code(tar.gz)
    Source code(zip)
  • 1.2(Dec 8, 2017)

    • Change translation api to Google Translation from Bing
    • Translation performance improvements.
    • No more account and api key will not be required.
    Source code(tar.gz)
    Source code(zip)
  • 1.1.3(Apr 26, 2017)

  • 1.1.2(Jan 31, 2017)

    • If users uses the option '-v' and multiple keys were added, the order of translation results might be reversed by alphabet ordering for its first character.
    Source code(tar.gz)
    Source code(zip)
  • 1.1.1(Dec 19, 2016)

    • Applied correct length of unicode text checker if use an option -fbl, --following-base-keys-if-length-longer for asian characters especially.
    • When use the option -iuv, --ignore-unverified-results, strsync will copy from base values if its condition satisfied. In the previous version that (unverified results) had not been added.
    Source code(tar.gz)
    Source code(zip)
  • 1.1(Dec 11, 2016)

    In this version strsync allows to verify approximate string matching percentage while working in translation.

    If user adds an option -v or --verify-results, String similarity of the reversed translation result for each languages will be displayed.

    $ strsync (...) -v
    
    el
      Hi: Hi -> Γεια σου -> Hi, Matched: 100%
    fr-CA
      Hi: Hi -> Salut -> Hello, Matched: 50%
    id
      Hi: Hi -> Hai -> Two, Matched: 0%
    fr
      Hi: Hi -> Salut -> Hello, Matched: 50%
    uk
      Hi: Hi -> Привіт -> Hi, Matched: 100%
    hr
      Hi: Hi -> Bok -> Book, Matched: 0%
    da
      Hi: Hi -> Hej -> Hi, Matched: 100%
    ja
      Hi: Hi -> こんにちは -> Hello, Matched: 50%
    he
      Hi: Hi -> היי -> Hey, Matched: 50%
    ko
      Hi: Hi -> 안녕 -> Hi, Matched: 100%
    sv
      Hi: Hi -> Hej -> Hi, Matched: 100%
    es-MX
      Hi: Hi -> Hola -> Hello, Matched: 50%
    sk
      Hi: Hi -> ahoj -> Hi, Matched: 100%
    zh-CN
      Hi: Hi -> 你好 -> How are you doing, Matched: 50%
    

    if user adds --ignore-unverified-results [Integer, Percentage (0~100) (default=0)], If the similarity of each reversed translation result is under the given value, that string will be skipped(ignored).

    strings will be skipped if its text similarity from reversed translation result is under 50 
    
    $ strsync (...) --ignore-unverified-results 50 
    
    el
      Hi: Hi -> Γεια σου -> Hi, Matched: 100%
    fr-CA
      (Ignored) Hi: Hi -> Salut -> Hello, Matched: 50%
    id
      (Ignored) Hi: Hi -> Hai -> Two, Matched: 0%
    fr
      (Ignored) Hi: Hi -> Salut -> Hello, Matched: 50%
    uk
      Hi: Hi -> Привіт -> Hi, Matched: 100%
    hr
      (Ignored) Hi: Hi -> Bok -> Book, Matched: 0%
    da
      Hi: Hi -> Hej -> Hi, Matched: 100%
    ja
      (Ignored) Hi: Hi -> こんにちは -> Hello, Matched: 50%
    he
      (Ignored) Hi: Hi -> היי -> Hey, Matched: 50%
    ko
      Hi: Hi -> 안녕 -> Hi, Matched: 100%
    sv
      Hi: Hi -> Hej -> Hi, Matched: 100%
    es-MX
      (Ignored) Hi: Hi -> Hola -> Hello, Matched: 50%
    sk
      Hi: Hi -> ahoj -> Hi, Matched: 100%
    zh-CN
      (Ignored) Hi: Hi -> 你好 -> How are you doing, Matched: 50%
    
    Source code(tar.gz)
    Source code(zip)
  • 1.0.6(Sep 10, 2016)

  • 1.0.4(Mar 4, 2016)

  • 1.0.3_hotfix(Nov 27, 2015)

  • 1.0.2(Nov 26, 2015)

  • 1.0.1(Nov 4, 2015)

Owner
gitmerge
gitmerge
transai is a localization tool on Android and iOS.

transai transai is a command line tool to help you do Android and iOS translation management. You can extract string files to csv format, or generate

Jintin 56 Nov 12, 2022
Localizations is an OS X app that manages your Xcode project localization files (.strings)

Localizations 0.2 Localizations is an OS X app that manages your Xcode project localization files (.strings). It focuses on keeping .strings files in

Arnaud Thiercelin 129 Jul 19, 2022
Semi-automated Text Translator for Websites and Apps

macOS/Ubuntu/Windows: attranslate is a semi-automated tool for "synchronizing" translation-files. attranslate is optimized for fast and smooth rollout

Felix Kirchengast 272 Dec 21, 2022
Localization/I18n: Incrementally update/translate your Strings files from .swift, .h, .m(m), .storyboard or .xib files.

Installation • Configuration • Usage • Build Script • Donation • Migration Guides • Issues • Contributing • License BartyCrouch BartyCrouch incrementa

Flinesoft 1.3k Jan 1, 2023
Localization of the application with ability to change language "on the fly" and support for plural form in any language.

L10n-swift is a simple framework that improves localization in swift app, providing cleaner syntax and in-app language switching. Overview ?? Features

Adrian Bobrowski 287 Dec 24, 2022
Swift friendly localization and i18n with in-app language switching

Localize-Swift Localize-Swift is a simple framework that improves i18n and localization in Swift iOS apps - providing cleaner syntax and in-app langua

Roy Marmelstein 2.9k Dec 29, 2022
iOS localization swift code generation project

code-gen-library - localization-swift module code-gen-library - localization-swift module with Python bash script execute to localization swift files(

umut boz 0 Oct 26, 2021
A micro framework for integrating with the Google Translate api

GoogleTranslateSwift About This is a micro library for integrating with the Google Cloud Translation API. I currently only use it for personal project

Daniel Saidi 7 Dec 19, 2022
A tool for finding missing and unused NSLocalizedStrings

nslocalizer This is a command line tool that is used for discovering missing and unused localization strings in Xcode projects. Contributing and Code

Samantha Demi 155 Sep 17, 2022
Xcode plugin for quickly creating localized strings

Extractor Localizable Strings Extractor Localizable Strings is a open source plug-in for Xcode. It lets you extract localizable strings without openin

Vinícius Oliveira 220 Jun 29, 2022
Android/iOS Apps created to practice with different iOS/Android Tech. These apps were built to have similar feature sets using native Android/iOS.

AgilityFitTodayApp Android/iOS Apps created to practice with different iOS/Android Tech. These apps were built to have similar feature sets using nati

Lauren Yew 1 Feb 25, 2022
Screen translator for macOS with Apple Vision API and IBM Watson, Google Cloud Translator

Swifty-OCR-Translator Screen translator for macOS with Apple Vision API and IBM Watson, Google Cloud Translator Usage Select Translator Fill in the AP

Kwangmin Bae 21 Sep 13, 2022
Will Powell 1.2k Dec 29, 2022
transai is a localization tool on Android and iOS.

transai transai is a command line tool to help you do Android and iOS translation management. You can extract string files to csv format, or generate

Jintin 56 Nov 12, 2022
Localizations is an OS X app that manages your Xcode project localization files (.strings)

Localizations 0.2 Localizations is an OS X app that manages your Xcode project localization files (.strings). It focuses on keeping .strings files in

Arnaud Thiercelin 129 Jul 19, 2022
Semi-automated Text Translator for Websites and Apps

macOS/Ubuntu/Windows: attranslate is a semi-automated tool for "synchronizing" translation-files. attranslate is optimized for fast and smooth rollout

Felix Kirchengast 272 Dec 21, 2022
Open Source iOS Translator.

About LiTranslate is an application which purpose is a convenient use of open source translation technology. Download on the App Store! For developers

Viktor 6 Dec 30, 2022
Command line program that detects unused resource strings in an iOS or OS X application.

Abandoned Resource String Detection This command line program detects unused resource strings in an iOS or OS X application. Updated to Swift 3, thank

Josh Smith 360 Nov 26, 2022
Resource monitor - A flutter plugin for Android and IOS to monitor CPU and RAM usage of device.

resource_monitor A flutter plugin for Android and IOS to monitor CPU and RAM usage of device. TODO Implement Android Side of this plugin. Add listener

Skandar Munir 1 Nov 11, 2022
Respresso is a centralized resource manager for shared Android, iOS and Web frontend projects

Introduction Respresso is a centralized resource manager for shared Android, iOS and Web frontend projects. It allows you to simply import the latest

Respresso 10 Nov 8, 2022