1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-01-18 09:09:47 +00:00
Pixelorama/installer/utils/po2nsi.py

183 lines
6.8 KiB
Python
Raw Permalink Normal View History

"""
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)