Related: tdf#149990 solenv/bin/desktop-translate.py readability
Satisfies many pylint suggestions and includes a formatting pass with Black.
Change-Id: I33794902ab303f63b52a3412e4e4d18b492cc74b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137101
Tested-by: Jenkins
Reviewed-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com>
diff --git a/solenv/bin/desktop-translate.py b/solenv/bin/desktop-translate.py
index 639fa89..edc377d 100644
--- a/solenv/bin/desktop-translate.py
+++ b/solenv/bin/desktop-translate.py
@@ -16,15 +16,18 @@
# the License at http://www.apache.org/licenses/LICENSE-2.0 .
#
#
# Translates multiple .desktop files at once with strings from .ulf
# files; if you add new translatable .ulf files please add them to
# l10ntools/source/localize.cxx
#
"""Translates multiple .desktop files at once with strings from .ulf
files; if you add new translatable .ulf files please add them to
l10ntools/source/localize.cxx in case the module is not already listed."""
import os, sys, argparse, io
import os
import sys
import argparse
import io
def encodeDesktopString(s):
def encode_desktop_string(s_value):
"""Function encoding strings to be used as values in .desktop files."""
# <https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-1.1.html#
# value-types> says "The escape sequences \s, \n, \t, \r, and \\ are supported for values of
# type string and localestring, meaning ASCII space, newline, tab, carriage return, and
@@ -36,71 +39,72 @@ def encodeDesktopString(s):
# supposed to relate, so just escape any U+000A LINE FEED as "\n" and any U+000D CARRIAGE RETURN
# as "\r"; it is unclear exactly which occurrences of U+0020 SPACE and U+0009 CHARACTER
# TABULATION would need to be escaped, so they are mostly left unescaped, for readability:
s = s.replace('\\', '\\\\').replace('\n', '\\n').replace('\r', '\\r');
if s.startswith(' '):
s_value = s_value.replace("\\", "\\\\").replace("\n", "\\n").replace("\r", "\\r")
if s_value.startswith(" "):
# <https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-1.1.html#
# entries> says "Space before and after the equals sign should be ignored", so escape a
# leading U+0020 SPACE as "\s" (while it is not clear whether "space" there means just
# U+0020 SPACE or any kind of white space, in which case at least a leading U+0009 CHARACTER
# TABULATION should similarly be escaped as "\t"; also, it is unclear whether such
# characters should also be escaped at the end):
s = '\\s' + s[1:]
return s
s_value = "\\s" + s_value[1:]
return s_value
parser = argparse.ArgumentParser()
parser.add_argument('-p', dest='productname', default='LibreOffice')
parser.add_argument('-d', dest='workdir', default='.')
parser.add_argument('--key', dest='key')
parser.add_argument('--prefix', dest='prefix', default='')
parser.add_argument('--ext', dest='ext')
parser.add_argument('--template-dir', dest='template_dir', default=None)
parser.add_argument('ifile')
parser.add_argument("-p", dest="productname", default="LibreOffice")
parser.add_argument("-d", dest="workdir", default=".")
parser.add_argument("--key", dest="key")
parser.add_argument("--prefix", dest="prefix", default="")
parser.add_argument("--ext", dest="ext")
parser.add_argument("--template-dir", dest="template_dir", default=None)
parser.add_argument("ifile")
o = parser.parse_args()
if o.template_dir is None:
template_dir = '{}/{}'.format(o.workdir, o.prefix)
template_dir = f"{o.workdir}/{o.prefix}"
else:
template_dir = o.template_dir
# hack for unity section
if o.key == "UnityQuickList":
outkey = "Name"
OUTKEY = "Name"
else:
outkey = o.key
OUTKEY = o.key
templates = {}
# open input file
source = io.open(o.ifile, encoding='utf-8')
source = io.open(o.ifile, encoding="utf-8")
template = None
# read ulf file
for line in source:
if line.strip() == '':
if line.strip() == "":
continue
if line[0] == "[":
template = line.split(']', 1)[0][1:]
template = line.split("]", 1)[0][1:]
entry = {}
# For every section in the specified ulf file there should exist
# a template file in $workdir ..
entry['outfile'] = "{}{}.{}".format(template_dir, template, o.ext)
entry['translations'] = {}
entry["outfile"] = f"{template_dir}{template}.{o.ext}"
entry["translations"] = {}
templates[template] = entry
else:
# split locale = "value" into 2 strings
if ' = ' not in line:
if " = " not in line:
continue
locale, value = line.split(' = ')
locale, value = line.split(" = ")
if locale != line:
# replace en-US with en
locale = locale.replace('en-US', 'en')
locale = locale.replace("en-US", "en")
# use just anything inside the ""
assert(value[0] == '"')
assert value[0] == '"'
# Some entries span multiple lines.
# An entry will always end on a double quote.
while not value.endswith('"\n'):
@@ -108,53 +112,55 @@ for line in source:
value = value[1:-2]
# replace resource placeholder
value = value.replace('%PRODUCTNAME', o.productname)
value = value.replace("%PRODUCTNAME", o.productname)
locale = locale.replace('-', '_')
locale = locale.replace("-", "_")
templates[template]['translations'][locale] = value
templates[template]["translations"][locale] = value
source.close()
processed = 0
# process templates
for template in templates:
outfilename = templates[template]['outfile']
for template, entries in templates.items():
outfilename = entries["outfile"]
# open the template file - ignore sections for which no
# templates exist
try:
template_file = io.open(outfilename, encoding='utf-8')
except Exception:
template_file = io.open(outfilename, encoding="utf-8")
except OSError:
# string files processed one by one
if o.ext == 'str':
if o.ext == "str":
continue
sys.exit("Warning: No template found for item '{}' : '{}' : '{}': $!\n".format(template, outfile, line))
sys.exit(
f"Warning: No template found for item '{template}' : '{outfilename}'\n"
)
processed += 1
# open output file
tmpfilename = '{}.tmp'.format(outfilename)
outfile = io.open(tmpfilename, 'w', encoding='utf-8')
tmpfilename = f"{outfilename}.tmp"
outfile = io.open(tmpfilename, "w", encoding="utf-8")
# emit the template to the output file
for line in template_file:
keyline = line
if keyline.startswith(o.key):
keyline = outkey + keyline[len(o.key):]
keyline = OUTKEY + keyline[len(o.key) :]
outfile.write(keyline)
if o.key in line:
translations = templates[template]['translations']
for locale in sorted (translations.keys()):
translations = entries["translations"]
for locale in sorted(translations.keys()):
value = translations.get(locale, None)
# print "locale is $locale\n";
# print "value is $value\n";
if value:
if o.ext == "desktop" or o.ext == "str":
if o.ext in ("desktop", "str"):
if o.ext == "desktop":
value = encodeDesktopString(value)
outfile.write(u"""{}[{}]={}\n""".format(outkey, locale, value))
value = encode_desktop_string(value)
outfile.write(f"{OUTKEY}[{locale}]={value}\n")
else:
outfile.write(u"""\t[{}]{}={}\n""".format(locale, outkey, value))
outfile.write(f"\t[{locale}]{OUTKEY}={value}\n")
template_file.close()
@@ -163,5 +169,5 @@ for template in templates:
os.unlink(outfilename)
os.rename(tmpfilename, outfilename)
if o.ext == 'str' and processed == 0:
if o.ext == "str" and processed == 0:
sys.exit("Warning: No matching templates processed")