├── .gitignore ├── AppStringsTranslator.py ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask stuff: 57 | instance/ 58 | .webassets-cache 59 | 60 | # Scrapy stuff: 61 | .scrapy 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyBuilder 67 | target/ 68 | 69 | # IPython Notebook 70 | .ipynb_checkpoints 71 | 72 | # pyenv 73 | .python-version 74 | 75 | # celery beat schedule file 76 | celerybeat-schedule 77 | 78 | # dotenv 79 | .env 80 | 81 | # virtualenv 82 | venv/ 83 | ENV/ 84 | 85 | # Spyder project settings 86 | .spyderproject 87 | 88 | # Rope project settings 89 | .ropeproject 90 | -------------------------------------------------------------------------------- /AppStringsTranslator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | #-*- coding:utf-8 -*- 3 | 4 | # 百度翻译 API 文档:http://api.fanyi.baidu.com/api/trans/product/apidoc 5 | 6 | import httplib 7 | import md5 8 | import urllib 9 | import random 10 | import re 11 | import json 12 | import os 13 | import sys 14 | 15 | 16 | kBaiduAppID = 'Please generate from you Baidu developer center' # 百度开发管理后台申请的 AppID 17 | kBaiduSecretKey = 'Please generate from you Baidu developer center' # 百度开发管理后台申请的 SecretKey 18 | 19 | 20 | gStringsFileName = '' 21 | gStringsKeyList = [] 22 | gStringsValueList = [] 23 | gAllSupportedLangList = ['auto', 'zh', 'en', 'yue', 'wyw', 'jp', 'kor', 'fra', 'spa', 'th', 'ara', 'ru', 'pt', 'de', 'it', 'el', 'nl', 'pl', 'bul', 'est', 'dan', 'fin', 'cs', 'rom', 'slo', 'swe', 'hu', 'cht', 'vie'] 24 | 25 | 26 | reload(sys) 27 | sys.setdefaultencoding( "utf-8" ) 28 | 29 | 30 | def initStringsKeyValueFromFile(fileName): 31 | global gStringsFileName 32 | global gStringsKeyList 33 | global gStringsValueList 34 | 35 | gStringsFileName = fileName 36 | 37 | try: 38 | f = open(fileName, 'r') 39 | lines = f.readlines() 40 | except IOError as e: 41 | print e 42 | else: 43 | for line in lines: 44 | match = re.search(r'"(?P.*?)" = "(?P.*?)"', line) 45 | if match: 46 | gStringsKeyList.append(match.group('key')) 47 | gStringsValueList.append(match.group('value')) 48 | else: 49 | # 为了保存注释或空行到新的翻译文件 50 | gStringsKeyList.append(line) 51 | gStringsValueList.append('') 52 | finally: 53 | f.close() 54 | 55 | 56 | def translateToLanguageList(fromLang, toLangs): 57 | if fromLang not in gAllSupportedLangList: 58 | print fromLang + 'is not supported' 59 | return 60 | 61 | for toLang in toLangs: 62 | if toLang not in gAllSupportedLangList: 63 | print toLang + 'is not supported' 64 | break 65 | translateToLang(fromLang, toLang) 66 | 67 | 68 | def translateToLang(fromLang, toLang): 69 | httpClient = None 70 | myurl = '/api/trans/vip/translate' 71 | 72 | httpClient = httplib.HTTPConnection('api.fanyi.baidu.com') 73 | 74 | extension = os.path.splitext(gStringsFileName)[1] 75 | toFileName = gStringsFileName.replace(extension, '_' + toLang + extension) 76 | toFile = open(toFileName, 'w'); 77 | 78 | print 'Translating ' + toLang + ' to fileName: ' + toFileName 79 | 80 | for index,val in enumerate(gStringsValueList): 81 | q = val 82 | 83 | if q: 84 | salt = random.randint(32768, 65536) 85 | 86 | sign = kBaiduAppID + q + str(salt) + kBaiduSecretKey 87 | m1 = md5.new() 88 | m1.update(sign) 89 | sign = m1.hexdigest() 90 | myurl = myurl + '?appid=' + kBaiduAppID + '&q=' + urllib.quote(q) + '&from=' + fromLang + '&to=' + toLang + '&salt=' + str(salt) + '&sign=' + sign 91 | 92 | try: 93 | httpClient.request('GET', myurl) 94 | 95 | #response是HTTPResponse对象 96 | response = httpClient.getresponse() 97 | 98 | jsonData = json.loads(response.read()) 99 | dst = jsonData['trans_result'][0]['dst'] 100 | 101 | result = '"' + gStringsKeyList[index] + '" = "' + dst + '";\n' 102 | toFile.write(result) 103 | 104 | except Exception, e: 105 | print e 106 | 107 | else: 108 | # 不需要翻译,直接保存原来的 Key 109 | toFile.write(gStringsKeyList[index]) 110 | 111 | if httpClient: 112 | httpClient.close() 113 | 114 | if toFile: 115 | toFile.close() 116 | 117 | print 'Finished translating to ' + toLang 118 | 119 | 120 | fileName = raw_input('Enter a fileName: ') 121 | initStringsKeyValueFromFile(fileName) 122 | print 'Supports languages:' 123 | print gAllSupportedLangList 124 | fromLang = raw_input('Enter from language: ') 125 | toLangs = raw_input('Enter to language list, split by space: ') 126 | print 'Start' 127 | translateToLanguageList(fromLang, toLangs.split()) 128 | print 'All done!' 129 | 130 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 LS 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AppStringsTranslator 2 | Automatically translate iOS App language into multi-language, depends on Baidu translate. 依赖百度翻译,自动把 iOS App 语言文件翻译成多国语言。 3 | 4 | ## Usage 5 | 6 | 1. Modify `AppStringsTranslator.py`, fill your own Baidu `AppKey/SecretKey`, See [this](http://api.fanyi.baidu.com/api/trans/product/desktop?req=developer). 7 | 2. Run script from terminal. eg: `python AppStringsTranslator.py`. 8 | 3. Input strings file name. eg: `Localizable.strings` 9 | 4. Input from language. eg: `zh` 10 | 5. Input to language list, split by space. eg: `en cht jp kor` 11 | 6. Wait and done. 12 | 13 | ``` bash 14 | >> LSiMac:AppStringsTranslator $ python AppStringsTranslator.py 15 | >> Enter a fileName: Localizable.strings 16 | >> Supports languages: 17 | ['auto', 'zh', 'en', 'yue', 'wyw', 'jp', 'kor', 'fra', 'spa', 'th', 'ara', 'ru', 'pt', 'de', 'it', 'el', 'nl', 'pl', 'bul', 'est', 'dan', 'fin', 'cs', 'rom', 'slo', 'swe', 'hu', 'cht', 'vie'] 18 | >> Enter from language: zh 19 | >> Enter to language list, split by space: cht en jp kor 20 | >> Start 21 | Translating cht to fileName: Localizable_cht.strings 22 | Finished translating to cht 23 | Translating en to fileName: Localizable_en.strings 24 | Finished translating to en 25 | Translating jp to fileName: Localizable_jp.strings 26 | Finished translating to jp 27 | Translating kor to fileName: Localizable_kor.strings 28 | Finished translating to kor 29 | All done! 30 | 31 | ``` 32 | 33 | ## Feature 34 | 35 | - Translate all values in `xx.strings`. 36 | - Keep original keys, comments and empty lines. 37 | - Generate new strings file `xx_toLang.strings` in the same directory. 38 | 39 | ## Supports languages 40 | 41 | ``` bash 42 | 语言简写 名称 43 | auto 自动检测(可以作为源语言,但不能是目标语言) 44 | zh 中文 45 | en 英语 46 | yue 粤语 47 | wyw 文言文 48 | jp 日语 49 | kor 韩语 50 | fra 法语 51 | spa 西班牙语 52 | th 泰语 53 | ara 阿拉伯语 54 | ru 俄语 55 | pt 葡萄牙语 56 | de 德语 57 | it 意大利语 58 | el 希腊语 59 | nl 荷兰语 60 | pl 波兰语 61 | bul 保加利亚语 62 | est 爱沙尼亚语 63 | dan 丹麦语 64 | fin 芬兰语 65 | cs 捷克语 66 | rom 罗马尼亚语 67 | slo 斯洛文尼亚语 68 | swe 瑞典语 69 | hu 匈牙利语 70 | cht 繁体中文 71 | vie 越南语 72 | ``` 73 | 74 | ## Q & A 75 | 76 | Q: Why do not use Google translate? 77 | A: In China, Google's services are not stable. 78 | 79 | 80 | ## Reference 81 | 82 | 1. [Baidu Translate API](http://api.fanyi.baidu.com/api/trans/product/apidoc) --------------------------------------------------------------------------------