From 731d798e24daa1ca256643c174debba3eb1163cf Mon Sep 17 00:00:00 2001 From: Claude Brisson Date: Sun, 18 Jun 2023 15:47:33 +0200 Subject: [PATCH] Fix view webapp translations --- view-webapp/pom.xml | 1 + .../org/jeudego/pairgoth/util/Translator.kt | 38 +++++++++++++------ .../org/jeudego/pairgoth/web/WebappManager.kt | 10 ++++- .../src/main/webapp/WEB-INF/translations/fr | 26 +++++++++++++ view-webapp/src/main/webapp/index.html | 2 +- .../src/main/webapp/tournament-form.inc.html | 34 ++++++++++++----- 6 files changed, 87 insertions(+), 24 deletions(-) diff --git a/view-webapp/pom.xml b/view-webapp/pom.xml index 9779fd1..00b5068 100644 --- a/view-webapp/pom.xml +++ b/view-webapp/pom.xml @@ -103,6 +103,7 @@ http://localhost:8085/api/ + dev ${project.basedir}/src/main/webapp,${project.build.directory}/generated-resources/ diff --git a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/util/Translator.kt b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/util/Translator.kt index 76a1e63..fce0ef5 100644 --- a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/util/Translator.kt +++ b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/util/Translator.kt @@ -7,12 +7,14 @@ import org.apache.velocity.runtime.parser.node.ASTText import org.apache.velocity.runtime.parser.node.SimpleNode import org.jeudego.pairgoth.web.WebappManager import org.slf4j.LoggerFactory +import java.io.File import java.io.PrintWriter import java.io.StringWriter import java.nio.charset.StandardCharsets import java.nio.file.Path import java.util.* import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.ConcurrentSkipListSet import java.util.regex.Pattern import kotlin.io.path.readLines import kotlin.io.path.useDirectoryEntries @@ -79,7 +81,7 @@ class Translator private constructor(private val iso: String) { if (groupStart > start) output.print(text.substring(start, groupStart)) val capture = matcher.group(group) var token: String = StringEscapeUtils.unescapeHtml4(capture) - if (StringUtils.containsOnly(token, "\r\n\t -;:.\"/<>\u00A00123456789€!")) output.print(capture) else { + if (StringUtils.containsOnly(token, "\r\n\t -;:.'\"/<>\u00A00123456789€[]!")) output.print(capture) else { token = normalize(token) token = translate(token) output.print(StringEscapeUtils.escapeHtml4(token)) @@ -104,17 +106,15 @@ class Translator private constructor(private val iso: String) { map[0] = (ignoring != null) while (pos < text.length) { if (ignoring == null) { - val nextIgnore = ignoredTags.map { tag -> - Pair(tag, text.indexOf("<$tag(?:>\\s)")) - }.filter { - it.second != -1 - }.sortedBy { - it.second - }.firstOrNull() + val nextIgnore = ignoredTags.mapNotNull { tag -> + Regex("<($tag)(?:>|\\s)").find(text) + }.minByOrNull { + it.range.first + } if (nextIgnore == null) pos = text.length else { - ignoring = nextIgnore.first - pos += nextIgnore.first.length + 2 + ignoring = nextIgnore.groupValues[1] + pos += ignoring.length + 2 } } else { val closingTag = text.indexOf("") @@ -132,9 +132,12 @@ class Translator private constructor(private val iso: String) { get() = textAccessor[this] as String set(value: String) { textAccessor[this] = value } + private val saveMissingTranslations = System.getProperty("pairgoth.env") == "dev" + private val missingTranslations: MutableSet = ConcurrentSkipListSet() + private fun reportMissingTranslation(enText: String) { logger.warn("missing translation towards {}: {}", iso, enText) - // CB TODO - create file + if (saveMissingTranslations) missingTranslations.add(enText) } companion object { @@ -165,5 +168,18 @@ class Translator private constructor(private val iso: String) { val providedLanguages = setOf("en", "fr") const val defaultLanguage = "en" + + internal fun notifyExiting() { + translators.values.filter { + it.saveMissingTranslations && it.missingTranslations.isNotEmpty() + }.forEach { + val missing = File("${it.iso}.missing") + logger.info("Saving missing translations for ${it.iso} to ${missing.canonicalPath}") + missing.printWriter().use { out -> + + out.println(it.missingTranslations.map { "${it}\t" }.joinToString("\n")) + } + } + } } } diff --git a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/web/WebappManager.kt b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/web/WebappManager.kt index 16566f0..1da1a42 100644 --- a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/web/WebappManager.kt +++ b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/web/WebappManager.kt @@ -2,6 +2,7 @@ package org.jeudego.pairgoth.web import com.republicate.mailer.SmtpLoop import org.apache.commons.lang3.tuple.Pair +import org.jeudego.pairgoth.util.Translator import org.slf4j.LoggerFactory import java.io.IOException import java.lang.IllegalAccessError @@ -51,7 +52,7 @@ class WebappManager : ServletContextListener, ServletContextAttributeListener, H /* ServletContextListener interface */ override fun contextInitialized(sce: ServletContextEvent) { context = sce.servletContext - logger.info("---------- Starting Pairgoth Web Client ----------") + logger.info("---------- Starting $WEBAPP_NAME ----------") context.setAttribute("manager", this) webappRoot = context.getRealPath("/") try { @@ -78,11 +79,15 @@ class WebappManager : ServletContextListener, ServletContextAttributeListener, H } override fun contextDestroyed(sce: ServletContextEvent) { - logger.info("---------- Stopping Web Application ----------") + logger.info("---------- Stopping $WEBAPP_NAME ----------") + + Translator.notifyExiting() val context = sce.servletContext for (service in webServices.keys) stopService(service, true) // ??? DriverManager.deregisterDriver(com.mysql.cj.jdbc.Driver ...); + + logger.info("---------- Stopped $WEBAPP_NAME ----------") } /* ServletContextAttributeListener interface */ @@ -95,6 +100,7 @@ class WebappManager : ServletContextListener, ServletContextAttributeListener, H override fun sessionDestroyed(se: HttpSessionEvent) {} companion object { + const val WEBAPP_NAME = "Pairgoth Web Client" const val PAIRGOTH_PROPERTIES_PREFIX = "pairgoth." lateinit var webappRoot: String lateinit var context: ServletContext diff --git a/view-webapp/src/main/webapp/WEB-INF/translations/fr b/view-webapp/src/main/webapp/WEB-INF/translations/fr index 5b58741..ee56b5a 100644 --- a/view-webapp/src/main/webapp/WEB-INF/translations/fr +++ b/view-webapp/src/main/webapp/WEB-INF/translations/fr @@ -1,2 +1,28 @@ New tournament Nouveau tournoi Open Ouvrir +Cancel Annuler +Infos Infos +Next Suivant +Pairing Appariement +Type Type +(pairgo / rengo) (pairgo / rengo) +(teams of individual players) (équipes de joueurs individuels) +MacMahon MacMahon +Number of rounds Nombre de rondes +Partner teams tournament of Tournoi d'équipes partenaires de +Standard tournament of individual players Tournoi standard de joueurs individuels +Swiss Suisse +Teams tournament of Tournoi par équipes de +Tournament dates Dates du tournoi +Tournament name Nom du tournoi +Tournament pairing Appariement du tournoi +Tournament short name Nom abbrégé du tournoi +Tournament type Type de tournoi +end date date de fin +from du +players joueurs +rounds rondes +short_name nom_tournoi +start date date de début +to au + diff --git a/view-webapp/src/main/webapp/index.html b/view-webapp/src/main/webapp/index.html index da67df0..9b2c99c 100644 --- a/view-webapp/src/main/webapp/index.html +++ b/view-webapp/src/main/webapp/index.html @@ -43,7 +43,7 @@
-#parse('tournament-form.inc.html') +#translate('tournament-form.inc.html')
diff --git a/view-webapp/src/main/webapp/tournament-form.inc.html b/view-webapp/src/main/webapp/tournament-form.inc.html index db1000c..71a22f9 100644 --- a/view-webapp/src/main/webapp/tournament-form.inc.html +++ b/view-webapp/src/main/webapp/tournament-form.inc.html @@ -1,20 +1,20 @@ -
+
- +
- +
- from to + from to
- rounds + rounds
@@ -23,7 +23,7 @@
@@ -31,7 +31,7 @@
@@ -39,7 +39,7 @@
@@ -52,7 +52,7 @@
@@ -60,7 +60,7 @@
@@ -68,3 +68,17 @@
+ + + +CB TODO : +s'il y a duplication du formulaire (pour nouveau/édition), il faut changer les ids en class, gérer les pbs d'init du date-range, etc. +sinon, il faut paramétrer la dialog (mais les steps 1/2/3 deviennent des tabs, etc.) + +Donc dans tous les cas il y a qqc à faire !