add checkTranslations script and update all french translations

merge-requests/1/head
Julien Veyssier 2017-05-05 02:19:38 +02:00
parent d45aa4ca91
commit 9ad01e2454
6 changed files with 204 additions and 9 deletions

View File

@ -11,7 +11,9 @@ function addLogoLine(name){
$('div#extraSymbols table').append('<tr class="extraSymbol" id="'+nameWe+'">'+ $('div#extraSymbols table').append('<tr class="extraSymbol" id="'+nameWe+'">'+
'<td><img src="'+fullurl+'"></td><td><label> '+nameWe+' </label></td>'+ '<td><img src="'+fullurl+'"></td><td><label> '+nameWe+' </label></td>'+
'<td><button class="delExtraSymbol icon-delete icon" name="'+name+ '<td><button class="delExtraSymbol icon-delete icon" name="'+name+
'" title="'+t('gpxedit','Delete')+'"></button></td></tr>'); '" title="' +
t('gpxedit','Delete') +
'"></button></td></tr>');
} }
function deleteLogo(button){ function deleteLogo(button){

View File

@ -1176,7 +1176,8 @@
'<li style="display:none;" name="' + sname + '" title="' + '<li style="display:none;" name="' + sname + '" title="' +
surl + '">' + sname + ' <button>' + surl + '">' + sname + ' <button>' +
'<i class="fa fa-trash" aria-hidden="true" style="color:red;"></i> ' + '<i class="fa fa-trash" aria-hidden="true" style="color:red;"></i> ' +
t('gpxedit', 'Delete') + '</button></li>' t('gpxedit', 'Delete') +
'</button></li>'
); );
$('#tileserverlist ul li[name="' + sname + '"]').fadeIn('slow'); $('#tileserverlist ul li[name="' + sname + '"]').fadeIn('slow');
@ -1275,7 +1276,7 @@
optionsValues = response.values; optionsValues = response.values;
//alert('option values: '+optionsValues); //alert('option values: '+optionsValues);
}).fail(function() { }).fail(function() {
OC.dialogs.alert(t('gpxedit', 'failed to restore options values'), OC.dialogs.alert(t('gpxedit', 'Failed to restore options values'),
t('gpxedit', 'Error')); t('gpxedit', 'Error'));
}); });
optionsValues = $.parseJSON(optionsValues); optionsValues = $.parseJSON(optionsValues);
@ -1319,7 +1320,7 @@
}).done(function (response) { }).done(function (response) {
//alert(response); //alert(response);
}).fail(function() { }).fail(function() {
OC.dialogs.alert(t('gpxedit', 'failed to save options values'), OC.dialogs.alert(t('gpxedit', 'Failed to save options values'),
t('gpxedit', 'Error')); t('gpxedit', 'Error'));
}); });
} }
@ -1517,7 +1518,9 @@
} }
var type = $('select#loadtypeselect').val(); var type = $('select#loadtypeselect').val();
OC.dialogs.filepicker( OC.dialogs.filepicker(
t('gpxedit', 'Load folder ('+type+')'), t('gpxedit', 'Load folder') + ' (' +
t('gpxedit', type) +
')',
function(targetPath) { function(targetPath) {
loadFolderAction(targetPath); loadFolderAction(targetPath);
}, },
@ -1532,7 +1535,8 @@
else{ else{
var filename = $('#saveName').val(); var filename = $('#saveName').val();
OC.dialogs.filepicker( OC.dialogs.filepicker(
t('gpxedit', 'Where to save') + ' <b>' + filename + '</b>', t('gpxedit', 'Where to save') +
' <b>' + filename + '</b>',
function(targetPath) { function(targetPath) {
saveAction(targetPath); saveAction(targetPath);
}, },

View File

@ -1,6 +1,14 @@
OC.L10N.register( OC.L10N.register(
"gpxedit", "gpxedit",
{ {
"Lat" : "Lat",
"Lon" : "Lon",
"all" : "tout",
"Description" : "Description",
"Ok" : "Ok",
"Route" : "Route",
"Load folder" : "Charger un dossier",
"Unknown symbol" : "Symbole inconnu",
"Where to save" : "Où enregistrer", "Where to save" : "Où enregistrer",
"Track" : "Trace", "Track" : "Trace",
"Waypoint" : "Étape", "Waypoint" : "Étape",

View File

@ -1,4 +1,17 @@
{ "translations": { { "translations": {
"GpxEdit" : "GpxEdit",
"Options" : "Options",
"Shortcuts" : "Raccourcis clavier",
"Documentation" : "Documentation",
"toggle sidebar" : "montrer/cacher la barre latérale",
"toggle minimap" : "montrer/cacher la mini carte",
"Authors" : "Auteurs",
"Features" : "Fonctionnalités",
"exporting file to gpx" : "export en gpx",
"permanent" : "permanent",
"all files" : "tous les fichiers",
"Source management" : "Gestion des sources",
"saving file" : "sauvegarde du fichier",
"Load and save files" : "Charger et enregistrer des fichiers", "Load and save files" : "Charger et enregistrer des fichiers",
"loading file" : "chargement du fichier", "loading file" : "chargement du fichier",
"Choose directory and save" : "Choisir un dossier et sauver", "Choose directory and save" : "Choisir un dossier et sauver",
@ -6,8 +19,6 @@
"Load file" : "Charger un fichier", "Load file" : "Charger un fichier",
"Load directory" : "Charger un dossier", "Load directory" : "Charger un dossier",
"Save" : "Enregistrer", "Save" : "Enregistrer",
"Select a file to load it on the map" : "Sélectionner un fichier pour le charger sur la carte",
"Select a folder, set a name and click \"Save\" button" : "Sélectionner un dossier, entrer un nom et cliquer sur le bouton \"Enregistrer\"",
"File name" : "Nom de fichier", "File name" : "Nom de fichier",
"Description (optional)" : "Description (facultatif)", "Description (optional)" : "Description (facultatif)",
"Clear map" : "Vider la carte", "Clear map" : "Vider la carte",

View File

@ -24,7 +24,7 @@
<button id="loadButton"><i class="fa fa-file-o"></i> <?php p($l->t('Load file'));?></button> <button id="loadButton"><i class="fa fa-file-o"></i> <?php p($l->t('Load file'));?></button>
<button id="loadFolderButton"><i class="fa fa-folder-open-o"></i> <?php p($l->t('Load directory'));?></button> <button id="loadFolderButton"><i class="fa fa-folder-open-o"></i> <?php p($l->t('Load directory'));?></button>
<select id="loadtypeselect"> <select id="loadtypeselect">
<option value="all">all</option> <option value="all"><?php p($l->t('all files'));?></option>
<option value=".jpg">jpg</option> <option value=".jpg">jpg</option>
<option value=".gpx">gpx</option> <option value=".gpx">gpx</option>
<option value=".kml">kml</option> <option value=".kml">kml</option>

View File

@ -0,0 +1,170 @@
#!/usr/bin/env python3
#-*- coding: utf-8 -*-
import sys, os, re, json, codecs
def myUnescape(s):
return s.replace("\\'", "'").replace('\\"', '"')
class color:
PURPLE = '\033[95m'
CYAN = '\033[96m'
DARKCYAN = '\033[36m'
BLUE = '\033[94m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
RED = '\033[91m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
END = '\033[0m'
def findRecursiveByExt(topdir, ext):
pathList = []
for dirpath, dirnames, files in os.walk(topdir):
for name in files:
if name.lower().endswith(ext):
pathList.append(os.path.join(dirpath, name))
return pathList
def phpWhereIs(s, p):
ln = 1
f = codecs.open(p, 'r', 'utf-8')
for line in f:
if re.search('>t\s*\(\s*[\'"](%s)[\'"]\s*\)' % re.escape(s), line):
f.close()
return ln
ln += 1
f.close()
def jsWhereIs(s, p, appname):
ln = 1
f = codecs.open(p, 'r', 'utf-8')
for line in f:
if re.search('t\s*\(\s*[\'"]%s[\'"]\s*,\s*[\'"](%s)[\'"]\s*[,)]' % (appname, re.escape(s)), line):
f.close()
return ln
ln += 1
f.close()
def jsonWhereIs(s, p):
ln = 1
f = codecs.open(p, 'r', 'utf-8')
for line in f:
if re.search('"%s"' % re.escape(s), line):
f.close()
return ln
ln += 1
f.close()
if __name__ == '__main__':
lang = sys.argv[1]
apppath = sys.argv[2]
appname = sys.argv[3]
########## parse PHP files #################
phpPathList = findRecursiveByExt(apppath, '.php')
phpContents = {}
phpCodeTranslations = []
phpCodeTranslationsByFile = {}
phpCodeTranslationsCorresp = {}
for path in phpPathList:
f = codecs.open(path, 'r', 'utf-8')
tlist = list(set(re.findall('>t\s*\(\s*[\'"](.*)[\'"]\s*\)', f.read())))
f.close()
tlistUnesc = list(map(myUnescape, tlist))
phpCodeTranslations.extend(tlistUnesc)
phpCodeTranslationsByFile[path] = tlistUnesc
# find line numbers after
for i in range(len(tlist)):
phpCodeTranslationsCorresp[tlistUnesc[i]] = tlist[i]
phpCodeTranslations.sort()
jsonf = codecs.open('%s/l10n/%s.json'%(apppath, lang), 'r', 'utf-8')
jsonc = json.load(jsonf)
keys = list(jsonc['translations'].keys())
keys.sort()
phpTranslations = list(map(myUnescape, keys))
phpTranslationsLineNumbers = {}
for i in range(len(phpTranslations)):
ln = jsonWhereIs(keys[i], '%s/l10n/%s.json'%(apppath, lang))
transText = phpTranslations[i]
phpTranslationsLineNumbers[transText] = ln
########## parse JS files #################
jsPathList = findRecursiveByExt(apppath, '.js')
jsContents = {}
jsCodeTranslations = []
jsCodeTranslationsByFile = {}
jsCodeTranslationsCorresp = {}
for path in jsPathList:
f = codecs.open(path, 'r', 'utf-8')
tlist = list(set(re.findall('t\s*\(\s*[\'"]%s[\'"]\s*,\s*[\'"](.*)[\'"]\s*[,)]'%appname, f.read())))
f.close()
tlistUnesc = list(map(myUnescape, tlist))
jsCodeTranslations.extend(tlistUnesc)
jsCodeTranslationsByFile[path] = tlistUnesc
# to find line numbers after
for i in range(len(tlist)):
jsCodeTranslationsCorresp[tlistUnesc[i]] = tlist[i]
jsCodeTranslations.sort()
jsjsonf = codecs.open('%s/l10n/%s.js'%(apppath, lang), 'r', 'utf-8')
jsjsons = jsjsonf.read()
jsjsons = jsjsons.replace('\n', '')
jsjsons = re.sub('[^{]*({.*})[^}]*', '\\1', jsjsons)
jsjsonc = json.loads(jsjsons)
keys = list(jsjsonc.keys())
keys.sort()
jsTranslations = list(map(myUnescape, keys))
jsTranslationsLineNumbers = {}
for i in range(len(jsTranslations)):
ln = jsonWhereIs(keys[i], '%s/l10n/%s.js'%(apppath, lang))
transText = jsTranslations[i]
jsTranslationsLineNumbers[transText] = ln
print('########### useless PHP translations ###############\n')
for s in phpTranslations:
if s not in phpCodeTranslations:
print('%s%s.json%s:%s%s%s: %s%s"%s"%s is useless, it was not found in any php file' %
(color.PURPLE, lang, color.END,
color.GREEN, phpTranslationsLineNumbers[s], color.END,
color.BOLD, color.RED, s, color.END))
print('\n########### useless js translations ###############\n')
for s in jsTranslations:
if s not in jsCodeTranslations:
print('%s%s.js%s:%s%s%s: %s%s"%s"%s is useless, it was not found in any js file' %
(color.PURPLE, lang, color.END,
color.GREEN, jsTranslationsLineNumbers[s], color.END,
color.BOLD, color.RED, s, color.END))
print('\n########### missing php translations ###############\n')
for fpath in phpCodeTranslationsByFile:
for s in phpCodeTranslationsByFile[fpath]:
if s not in phpTranslations:
print('%s%s%s:%s%s%s: %s%s"%s"%s is not translated in %s%s%s.json%s' %
(color.PURPLE, fpath, color.END,
color.GREEN, phpWhereIs(phpCodeTranslationsCorresp[s], fpath), color.END,
color.BOLD, color.RED, s, color.END,
color.GREEN, color.BOLD, lang, color.END))
print('\n########### missing js translations ###############\n')
for fpath in jsCodeTranslationsByFile:
for s in jsCodeTranslationsByFile[fpath]:
if s not in jsTranslations:
print('%s%s%s:%s%s%s: %s%s"%s"%s is not translated in %s%s%s.js%s' %
(color.PURPLE, fpath, color.END,
color.GREEN, jsWhereIs(jsCodeTranslationsCorresp[s], fpath, appname), color.END,
color.BOLD, color.RED, s, color.END,
color.GREEN, color.BOLD, lang, color.END))