download arena tournament results as CSV - closes #8869

pull/8888/head
Thibault Duplessis 2021-05-06 13:33:55 +02:00
parent c8e280c51c
commit 63a89e6303
5 changed files with 61 additions and 9 deletions

View File

@ -235,15 +235,17 @@ final class Api(
def tournamentResults(id: String) =
Action.async { implicit req =>
env.tournament.tournamentRepo byId id flatMap {
val csv = HTTPRequest.acceptsCsv(req) || get("as", req).has("csv")
env.tournament.tournamentRepo byId id map {
_ ?? { tour =>
import lila.tournament.JsonView.playerResultWrites
val nb = getInt("nb", req) | Int.MaxValue
jsonStream {
val source =
env.tournament.api
.resultStream(tour, MaxPerSecond(40), nb)
.map(playerResultWrites.writes)
}.fuccess
.resultStream(tour, MaxPerSecond(40), getInt("nb", req) | Int.MaxValue)
val result =
if (csv) csvStream(lila.tournament.TournamentCsv(source))
else jsonStream(source.map(lila.tournament.JsonView.playerResultWrites.writes))
result.pipe(asAttachment(env.api.gameApiV2.filename(tour, if (csv) "csv" else "ndjson")))
}
}
}

View File

@ -79,12 +79,15 @@ final class GameApiV2(
}
def filename(tour: Tournament, format: Format): String =
filename(tour, format.toString.toLowerCase)
def filename(tour: Tournament, format: String): String =
fileR.replaceAllIn(
"lichess_tournament_%s_%s_%s.%s".format(
Tag.UTCDate.format.print(tour.startsAt),
tour.id,
lila.common.String.slugify(tour.name),
format.toString.toLowerCase
format
),
"_"
)

View File

@ -0,0 +1,37 @@
package lila.tournament
import akka.stream.scaladsl.Source
object TournamentCsv {
def apply(results: Source[Player.Result, _]): Source[String, _] =
Source(
List(
toCsv(
"Rank",
"Title",
"Username",
"Rating",
"Score",
"Performance",
"Team"
)
)
) concat
results.map(apply)
def apply(p: Player.Result): String = p match {
case Player.Result(player, user, rank) =>
toCsv(
rank.toString,
~user.title,
user.name,
player.rating.toString,
player.score.toString,
player.performanceOption.??(_.toString),
~player.team
)
}
private def toCsv(values: String*) = values mkString ","
}

View File

@ -227,7 +227,6 @@ function stats(ctrl: SwissCtrl): VNode | undefined {
const s = ctrl.data.stats,
noarg = ctrl.trans.noarg,
slots = ctrl.data.round * ctrl.data.nbPlayers;
console.log(ctrl.data);
return s
? h('div.swiss__stats', [
h('h2', noarg('tournamentComplete')),

View File

@ -72,7 +72,18 @@ function stats(data: TournamentData, trans: Trans): VNode {
download: true,
},
},
'Download results'
'Download results as NDJSON'
),
h(
'a.text',
{
attrs: {
'data-icon': 'x',
href: `/api/tournament/${data.id}/results?as=csv`,
download: true,
},
},
'Download results as CSV'
),
h('br'),
h(