From 773b9b7b1e08a47d00a87c65d4947f147ca940fc Mon Sep 17 00:00:00 2001 From: Claude Brisson Date: Tue, 20 Aug 2024 15:33:37 +0200 Subject: [PATCH] Sanitize character set in ISO exports --- .../jeudego/pairgoth/api/StandingsHandler.kt | 39 +++++++++++++++---- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/StandingsHandler.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/StandingsHandler.kt index 41bdbd8..55dfe39 100644 --- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/StandingsHandler.kt +++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/StandingsHandler.kt @@ -2,16 +2,13 @@ package org.jeudego.pairgoth.api import com.republicate.kson.Json import com.republicate.kson.toJsonArray -import org.jeudego.pairgoth.api.PairingHandler.dispatchEvent import org.jeudego.pairgoth.model.Criterion import org.jeudego.pairgoth.model.Criterion.* -import org.jeudego.pairgoth.model.Game.Result.* import org.jeudego.pairgoth.model.ID import org.jeudego.pairgoth.model.PairingType import org.jeudego.pairgoth.model.Tournament import org.jeudego.pairgoth.model.adjustedTime import org.jeudego.pairgoth.model.displayRank -import org.jeudego.pairgoth.model.getID import java.io.PrintWriter import java.time.format.DateTimeFormatter import javax.servlet.http.HttpServletRequest @@ -23,6 +20,9 @@ import org.jeudego.pairgoth.server.WebappManager import java.io.OutputStreamWriter import java.nio.charset.StandardCharsets import java.text.DecimalFormat +import java.text.Normalizer +import java.util.* +import kotlin.collections.ArrayList object StandingsHandler: PairgothApiHandler { override fun get(request: HttpServletRequest, response: HttpServletResponse): Json? { @@ -31,7 +31,7 @@ object StandingsHandler: PairgothApiHandler { val includePreliminary = request.getParameter("include_preliminary")?.let { it.toBoolean() } ?: false val sortedPairables = tournament.getSortedPairables(round, includePreliminary) - tournament.populateResultsArray(sortedPairables, round) + tournament.populateFrozenStandings(sortedPairables, round) val acceptHeader = request.getHeader("Accept") as String? val accept = acceptHeader?.substringBefore(";") @@ -123,13 +123,18 @@ ${ "${ player.getString("num")!!.padStart(4, ' ') } ${ - "${player.getString("name")} ${player.getString("firstname") ?: ""}".padEnd(30, ' ').take(30) + "${ + player.getString("name")?.toSnake(true) + + } ${ + player.getString("firstname")?.toSnake() ?: "" + }".padEnd(30, ' ').take(30) } ${ displayRank(player.getInt("rank")!!).uppercase().padStart(3, ' ') } ${ player.getString("country")?.uppercase() ?: "" } ${ - (player.getString("club") ?: "").padStart(4).take(4) + (player.getString("club") ?: "").toSnake().padStart(4).take(4) } ${ criteria.joinToString(" ") { numFormat.format(player.getDouble(it.name)!!).let { if (it.contains('.')) it else "$it " }.padStart(7, ' ') } } ${ @@ -143,6 +148,24 @@ ${ writer.println(ret) } + private fun String.toSnake(upper: Boolean = false): String { + val sanitized = sanitizeISO() + val parts = sanitized.trim().split(Regex("(?:\\s|\\xA0)+")) + val snake = parts.joinToString("_") { part -> + if (upper) part.uppercase(Locale.ROOT) + else part.capitalize() + } + return snake + } + + private fun String.sanitizeISO(): String { + val ret = Normalizer.normalize(this, Normalizer.Form.NFD) + return ret.replace(Regex("\\p{M}"), "") + // some non accented letters give problems in ISO, there may be other + .replace('Ð', 'D') + .replace('ø', 'o') + } + private fun exportToFFGFormat(tournament: Tournament<*>, lines: List, writer: PrintWriter) { val version = WebappManager.properties.getProperty("version")!! val ret = @@ -171,14 +194,14 @@ ${ "${ player.getString("num")!!.padStart(4, ' ') } ${ - "${player.getString("name")} ${player.getString("firstname") ?: ""}".padEnd(24, ' ').take(24) + "${player.getString("name")?.toSnake(true)} ${player.getString("firstname")?.toSnake() ?: ""}".padEnd(24, ' ').take(24) } ${ displayRank(player.getInt("rank")!!).uppercase().padStart(3, ' ') } ${ player.getString("ffg") ?: " " } ${ if (player.getString("country") == "FR") - (player.getString("club") ?: "").padEnd(4).take(4) + (player.getString("club") ?: "").toSnake().padEnd(4).take(4) else (player.getString("country") ?: "").padEnd(4).take(4) } ${