diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/ApiTools.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/ApiTools.kt index b79ea72..3ca47db 100644 --- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/ApiTools.kt +++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/ApiTools.kt @@ -2,6 +2,7 @@ package org.jeudego.pairgoth.api import com.republicate.kson.Json import org.jeudego.pairgoth.model.Criterion +import org.jeudego.pairgoth.model.DatabaseId import org.jeudego.pairgoth.model.MacMahon import org.jeudego.pairgoth.model.Pairable import org.jeudego.pairgoth.model.Pairable.Companion.MIN_RANK @@ -90,7 +91,7 @@ fun Tournament<*>.getSortedPairables(round: Int): List { val pairables = pairables.values.filter { it.final }.map { it.toMutableJson() } pairables.forEach { player -> for (crit in criteria) { - player[crit.first] = crit.second[player.getID()] ?: 0.0 + player[crit.first] = (crit.second[player.getID()] ?: 0.0).toInt() } player["results"] = Json.MutableArray(List(round) { "0=" }) } 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 10463a5..39500b6 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 @@ -101,6 +101,12 @@ object StandingsHandler: PairgothApiHandler { writer.flush() return null } + "text/csv" -> { + response.contentType = "text/csv;charset=${encoding}" + exportToCSVFormat(tournament, sortedPairables, writer) + writer.flush() + return null + } else -> ApiHandler.badRequest("invalid Accept header: $accept") } } @@ -224,6 +230,40 @@ ${ writer.println(ret) } + private fun exportToCSVFormat(tournament: Tournament<*>, lines: List, writer: PrintWriter) { + val fields = listOf( + Pair("num", false), + Pair("place", false), + // Pair("egf", false), TODO configure display of egf / ffg field + Pair("name", true), + Pair("firstname", true), + Pair("country", false), + Pair("club", true), + Pair("rank", false), + Pair("NBW", false) + ); + + // headers + writer.println("${ + fields.joinToString(";") { it.first } + };${ + (1..tournament.rounds).joinToString(";") { "R$it" } + };${ + tournament.pairing.placementParams.criteria.joinToString(";") { it.name } + }") + + // lines + lines.forEach { line -> + writer.println("${ + fields.joinToString(";") { if (it.second) "\"${line[it.first]}\"" else "${line[it.first]}" } + };${ + line.getArray("results")!!.joinToString(";") + };${ + tournament.pairing.placementParams.criteria.joinToString(";") { line.getString(it.name) ?: "" } + }") + } + } + private val numFormat = DecimalFormat("###0.#") private val frDate: DateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy") } diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/server/ApiServlet.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/server/ApiServlet.kt index 909895b..3991e6c 100644 --- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/server/ApiServlet.kt +++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/server/ApiServlet.kt @@ -235,7 +235,7 @@ class ApiServlet: HttpServlet() { // 2) there will be other content types: .tou, .h9, .html if (!isJson(accept) && (!isXml(accept) || !request.requestURI.matches(Regex("/api/tour/\\d+"))) && - (!accept.startsWith("application/ffg") && !accept.startsWith("application/egf") || !request.requestURI.matches(Regex("/api/tour/\\d+/standings/\\d+"))) + (!accept.startsWith("application/ffg") && !accept.startsWith("application/egf") && !accept.startsWith("text/csv") || !request.requestURI.matches(Regex("/api/tour/\\d+/standings/\\d+"))) ) throw ApiException( HttpServletResponse.SC_BAD_REQUEST, diff --git a/view-webapp/src/main/webapp/js/tour-standings.inc.js b/view-webapp/src/main/webapp/js/tour-standings.inc.js index 51ea9a5..f334e0d 100644 --- a/view-webapp/src/main/webapp/js/tour-standings.inc.js +++ b/view-webapp/src/main/webapp/js/tour-standings.inc.js @@ -3,7 +3,7 @@ function publish(format, extension) { let shortName = form.val('shortName'); let encoding = $('#encoding')[0].value; let hdrs = headers(); - hdrs['Accept'] = `application/${format};charset=${encoding}` + hdrs['Accept'] = `${format};charset=${encoding}` fetch(`api/tour/${tour_id}/standings/${activeRound}`, { headers: hdrs }).then(resp => { @@ -20,7 +20,6 @@ function publish(format, extension) { function publishHtml() { let html = $('#standings-table')[0].outerHTML; - console.log(html) let form = $('#tournament-infos')[0]; let shortName = form.val('shortName'); let blob = new Blob(['\uFEFF', html], {type: 'text/html;charset=utf-8'}); @@ -78,10 +77,13 @@ onLoad(() => { }); */ $('.publish-ffg').on('click', e => { - publish('ffg', 'tou'); + publish('application/ffg', 'tou'); }); $('.publish-egf').on('click', e => { - publish('egf', 'h9'); + publish('application/egf', 'h9'); + }); + $('.publish-csv').on('click', e => { + publish('text/csv', 'csv'); }); $('.publish-html').on('click', e => { publishHtml(); diff --git a/view-webapp/src/main/webapp/tour-standings.inc.html b/view-webapp/src/main/webapp/tour-standings.inc.html index c16f18d..0bf0032 100644 --- a/view-webapp/src/main/webapp/tour-standings.inc.html +++ b/view-webapp/src/main/webapp/tour-standings.inc.html @@ -112,6 +112,7 @@
+