mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-01-18 09:09:47 +00:00
183 lines
6.8 KiB
Python
183 lines
6.8 KiB
Python
|
"""
|
||
|
po2nsi.py: Create multilingual NSIS script based on gettext
|
||
|
PO files
|
||
|
|
||
|
Copyright (C) 2021 huskee
|
||
|
(Original author: Dan Chowdhury)
|
||
|
|
||
|
This program is free software: you can redistribute it and/or modify
|
||
|
it under the terms of the GNU General Public License as published by
|
||
|
the Free Software Foundation, either version 3 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
This program is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
"""
|
||
|
|
||
|
import collections
|
||
|
import os
|
||
|
import polib
|
||
|
from optparse import OptionParser
|
||
|
|
||
|
parser = OptionParser()
|
||
|
parser.add_option("-i", "--input", dest="input",
|
||
|
help="NSIS script to be localized", metavar="script.nsi")
|
||
|
parser.add_option("-o", "--output", dest="output",
|
||
|
help="Localized script output location", metavar="script.nsi")
|
||
|
parser.add_option("-p", "--podir", dest="podir",
|
||
|
help="Directory containing PO files")
|
||
|
parser.add_option("-l", "--lang", dest="lang",
|
||
|
help="NSIS script default language (default is English)", default="English" )
|
||
|
parser.add_option("-v", "--verbose", action="store_true",
|
||
|
dest="verbose", help="Verbose output")
|
||
|
|
||
|
(options, args) = parser.parse_args()
|
||
|
|
||
|
|
||
|
# Define a dict to convert locale names to language names
|
||
|
localeToName = {
|
||
|
"af-ZA" : "Afrikaans",
|
||
|
"ar-SA" : "Arabic",
|
||
|
"ca-ES" : "Catalan",
|
||
|
"cs-CZ" : "Czech",
|
||
|
"da-DK" : "Danish",
|
||
|
"nl-NL" : "Dutch",
|
||
|
"en" : "English",
|
||
|
"eo-UY" : "Esperanto",
|
||
|
"fi-FI" : "Finnish",
|
||
|
"fr-FR" : "French",
|
||
|
"de-DE" : "German",
|
||
|
"el-GR" : "Greek",
|
||
|
"he-IL" : "Hebrew",
|
||
|
"hi-IN" : "Hindi",
|
||
|
"hu-HU" : "Hungarian",
|
||
|
"id-ID" : "Indonesian",
|
||
|
"it-IT" : "Italian",
|
||
|
"ja-JP" : "Japanese",
|
||
|
"ko-KR" : "Korean",
|
||
|
"lv-LV" : "Latvian",
|
||
|
"no-NO" : "Norwegian",
|
||
|
"pl-PL" : "Polish",
|
||
|
"pt-PT" : "Portuguese",
|
||
|
"pt-BR" : "PortugueseBR",
|
||
|
"ro-RO" : "Romanian",
|
||
|
"ru-RU" : "Russian",
|
||
|
"sr-SP" : "Serbian",
|
||
|
"zh-CN" : "SimpChinese",
|
||
|
"es-ES" : "Spanish",
|
||
|
"sv-SE" : "Swedish",
|
||
|
"zh-TW" : "TradChinese",
|
||
|
"tr-TR" : "Turkish",
|
||
|
"uk-UA" : "Ukrainian",
|
||
|
"vi-VN" : "Vietnamese",
|
||
|
}
|
||
|
|
||
|
localeRTL = [ "ar-SA", "he-IL" ]
|
||
|
|
||
|
def escapeNSIS(st):
|
||
|
return st.replace('\\', r'$\\')\
|
||
|
.replace('\t', r'$\t')\
|
||
|
.replace('\r', r'\r')\
|
||
|
.replace('\n', r'\n')\
|
||
|
.replace('\"', r'$\"')\
|
||
|
.replace('$$\\', '$\\')
|
||
|
|
||
|
translationCache = {}
|
||
|
|
||
|
# The purpose of this loop is to go to the podir scanning for PO files for each locale name
|
||
|
# Once we've found a PO file, we use PO lib to read every translated entry
|
||
|
# Using this, for each each language, we store a dict of entries - { nsilabel (comment) : translation (msgstr) }
|
||
|
# For untranslated entries, we use msgid instead of msgstr (i.e. default English string)
|
||
|
for root,dirs,files in os.walk(options.podir):
|
||
|
for file in files:
|
||
|
filename,ext = os.path.splitext(file)
|
||
|
if ext == ".po":
|
||
|
# Valid locale filename (fr.po, de.po etc)?
|
||
|
if filename not in localeToName:
|
||
|
print("%s: invalid filename, must be xx-YY language code" %(filename))
|
||
|
else:
|
||
|
if options.verbose:
|
||
|
print("Valid filename found")
|
||
|
language = localeToName[filename]
|
||
|
translationCache[language] = collections.OrderedDict()
|
||
|
# Let's add a default LANGUAGE_CODE LangString to be read
|
||
|
translationCache[language]["LANGUAGE_CODE"] = filename
|
||
|
if options.verbose:
|
||
|
print("Language: %s (%s)" %(language, translationCache[language]["LANGUAGE_CODE"]))
|
||
|
|
||
|
# Are we RTL? Mark that down too as a LangString
|
||
|
if filename in localeRTL:
|
||
|
translationCache[language]["LANGUAGE_RTL"] = "1"
|
||
|
if options.verbose:
|
||
|
print("RTL language")
|
||
|
else:
|
||
|
if options.verbose:
|
||
|
print("Non RTL language")
|
||
|
|
||
|
po = polib.pofile(os.path.join(root,file))
|
||
|
for entry in po.translated_entries():
|
||
|
# Loop through all our labels and add translation (each translation may have multiple labels)
|
||
|
for label in entry.comment.split():
|
||
|
translationCache[language][label] = escapeNSIS(entry.msgstr)
|
||
|
if options.verbose:
|
||
|
print("msgstr added, " + translationCache[language][label])
|
||
|
# For untranslated strings, let's add the English entry
|
||
|
for entry in po.untranslated_entries():
|
||
|
for label in entry.comment.split():
|
||
|
print("Warning: Label '%s' for language %s remains untranslated"%(label,language))
|
||
|
translationCache[language][label] = escapeNSIS(entry.msgid)
|
||
|
if options.verbose:
|
||
|
print('\n')
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
# Open our source NSI, dump it to a list and close it
|
||
|
NSISourceFile = open(options.input,"r")
|
||
|
if options.verbose:
|
||
|
print("Opened source file")
|
||
|
NSISourceLines = NSISourceFile.readlines()
|
||
|
if options.verbose:
|
||
|
print("Read source file lines")
|
||
|
NSISourceFile.close()
|
||
|
if options.verbose:
|
||
|
print("Closed source file")
|
||
|
NSINewLines = []
|
||
|
|
||
|
|
||
|
# Here we scan for ";@INSERT_TRANSLATIONS@" in the NSIS, and add MUI_LANGUAGE macros and LangString's for translation languages
|
||
|
lineNo = 1
|
||
|
print('\n')
|
||
|
for line in NSISourceLines:
|
||
|
x = line.find(";@INSERT_TRANSLATIONS@")
|
||
|
if x != -1:
|
||
|
if options.verbose:
|
||
|
print("INSERT_TRANSLATIONS found")
|
||
|
NSINewLines.append('\n')
|
||
|
for language,translations in translationCache.items():
|
||
|
count = 0
|
||
|
# if the language isn't the default, we add our MUI_LANGUAGE macro
|
||
|
if language.upper() != options.lang.upper():
|
||
|
NSINewLines.append(' !insertmacro MUI_LANGUAGE "%s"\n'%language)
|
||
|
# For every translation we grabbed from the .po, let's add our LangString
|
||
|
for label,value in translations.items():
|
||
|
NSINewLines.append(' LangString %s ${LANG_%s} "%s"\n' % (label,language,value))
|
||
|
count += 1
|
||
|
NSINewLines.append('\n')
|
||
|
print ("%i translations merged for language %s" %(count,language))
|
||
|
else:
|
||
|
NSINewLines.append (line)
|
||
|
|
||
|
# Finally, let's write our new .nsi to the desired target file
|
||
|
NSIWorkingFile = open(options.output,"w",encoding='utf-8')
|
||
|
NSIWorkingFile.writelines(NSINewLines)
|
||
|
NSIWorkingFile.close()
|
||
|
|
||
|
print ("%s: NSIS script successfully localized" %options.output)
|