lila/modules/simul/src/main/JsonView.scala

155 lines
4.7 KiB
Scala
Raw Normal View History

2015-04-01 14:22:28 -06:00
package lila.simul
import play.api.libs.json._
import lila.common.LightUser
import lila.common.Json._
2015-04-01 14:22:28 -06:00
import lila.game.{ Game, GameRepo }
2019-04-05 19:12:01 -06:00
import lila.user.User
2015-04-01 14:22:28 -06:00
2019-08-20 02:30:09 -06:00
final class JsonView(
2019-12-02 10:15:29 -07:00
gameRepo: GameRepo,
2019-08-20 02:30:09 -06:00
getLightUser: LightUser.Getter,
2019-12-02 10:15:29 -07:00
proxyRepo: lila.round.GameProxyRepo
)(implicit ec: scala.concurrent.ExecutionContext) {
2015-04-01 14:22:28 -06:00
2019-12-13 07:30:20 -07:00
implicit private val simulTeamWriter = Json.writes[SimulTeam]
2019-12-02 10:15:29 -07:00
2016-08-01 05:50:53 -06:00
private def fetchGames(simul: Simul) =
2019-12-02 10:15:29 -07:00
if (simul.isFinished) gameRepo gamesFromSecondary simul.gameIds
2019-12-08 22:43:59 -07:00
else simul.gameIds.map(proxyRepo.game).sequenceFu.dmap(_.flatten)
2016-08-01 05:50:53 -06:00
2019-12-13 07:30:20 -07:00
def apply(simul: Simul, team: Option[SimulTeam]): Fu[JsObject] =
for {
games <- fetchGames(simul)
lightHost <- getLightUser(simul.hostId)
applicants <- simul.applicants.sortBy(-_.player.rating).map(applicantJson).sequenceFu
2020-05-05 22:11:15 -06:00
pairingOptions <-
simul.pairings
.sortBy(-_.player.rating)
.map(pairingJson(games, simul.hostId))
.sequenceFu
2019-12-13 07:30:20 -07:00
pairings = pairingOptions.flatten
} yield baseSimul(simul, lightHost) ++ Json
.obj(
"applicants" -> applicants,
"pairings" -> pairings
)
.add("team", team)
.add("quote" -> simul.isCreated.option(lila.quote.Quote.one(simul.id)))
2019-10-17 09:28:51 -06:00
def api(simul: Simul): Fu[JsObject] =
getLightUser(simul.hostId) map { lightHost =>
baseSimul(simul, lightHost) ++ Json.obj(
"nbApplicants" -> simul.applicants.size,
2019-12-13 07:30:20 -07:00
"nbPairings" -> simul.pairings.size
2019-10-17 09:28:51 -06:00
)
}
def api(simuls: List[Simul]): Fu[JsArray] =
simuls.map(api).sequenceFu map JsArray.apply
2020-04-06 17:02:44 -06:00
def apiAll(
pending: List[Simul],
created: List[Simul],
started: List[Simul],
finished: List[Simul]
): Fu[JsObject] =
2019-12-13 07:30:20 -07:00
for {
2020-04-06 17:02:44 -06:00
pendingJson <- api(pending)
2019-12-13 07:30:20 -07:00
createdJson <- api(created)
startedJson <- api(started)
finishedJson <- api(finished)
} yield Json.obj(
2020-04-06 17:02:44 -06:00
"pending" -> pendingJson,
2019-12-13 07:30:20 -07:00
"created" -> createdJson,
"started" -> startedJson,
"finished" -> finishedJson
)
2019-10-17 09:28:51 -06:00
2020-05-05 22:11:15 -06:00
private def baseSimul(simul: Simul, lightHost: Option[LightUser]) =
Json.obj(
"id" -> simul.id,
"host" -> lightHost.map { host =>
Json
.obj(
"id" -> host.id,
"name" -> host.name,
"rating" -> simul.hostRating
)
2020-08-20 15:21:38 -06:00
.add("gameId" -> simul.hostGameId.ifTrue(simul.isRunning))
2020-05-05 22:11:15 -06:00
.add("title" -> host.title)
.add("patron" -> host.isPatron)
},
"name" -> simul.name,
"fullName" -> simul.fullName,
"variants" -> simul.variants.map(variantJson(chess.Speed(simul.clock.config.some))),
"isCreated" -> simul.isCreated,
"isRunning" -> simul.isRunning,
"isFinished" -> simul.isFinished,
"text" -> simul.text
)
private def variantJson(speed: chess.Speed)(v: chess.variant.Variant) =
Json.obj(
"key" -> v.key,
"icon" -> lila.game.PerfPicker.perfType(speed, v, none).map(_.iconChar.toString),
"name" -> v.name
)
2015-04-01 14:22:28 -06:00
2017-01-26 06:59:04 -07:00
private def playerJson(player: SimulPlayer): Fu[JsObject] =
getLightUser(player.user) map { light =>
2019-12-13 07:30:20 -07:00
Json
.obj(
2020-08-20 01:51:00 -06:00
"id" -> player.user,
"rating" -> player.rating
2019-12-13 07:30:20 -07:00
)
.add("name" -> light.map(_.name))
2017-07-08 05:58:31 -06:00
.add("title" -> light.map(_.title))
2019-10-17 15:37:23 -06:00
.add("provisional" -> ~player.provisional)
2017-07-08 05:58:31 -06:00
.add("patron" -> light.??(_.isPatron))
2017-01-26 06:59:04 -07:00
}
2015-04-01 14:22:28 -06:00
2017-01-26 06:59:04 -07:00
private def applicantJson(app: SimulApplicant): Fu[JsObject] =
playerJson(app.player) map { player =>
Json.obj(
2019-12-13 07:30:20 -07:00
"player" -> player,
2020-08-20 01:51:00 -06:00
"variant" -> app.player.variant.key,
"accepted" -> app.accepted
)
2017-01-26 06:59:04 -07:00
}
2015-04-01 14:22:28 -06:00
2020-05-05 22:11:15 -06:00
private def gameJson(hostId: User.ID, g: Game) =
2020-08-17 10:32:41 -06:00
Json
.obj(
"id" -> g.id,
"status" -> g.status.id,
"fen" -> (chess.format.Forsyth boardAndColor g.situation),
"lastMove" -> ~g.lastMoveKeys,
"orient" -> g.playerByUserId(hostId).map(_.color)
)
.add(
"clock" -> g.clock.ifTrue(g.isBeingPlayed).map { c =>
Json.obj(
"white" -> c.remainingTime(chess.White).roundSeconds,
"black" -> c.remainingTime(chess.Black).roundSeconds
)
}
)
.add("winner" -> g.winnerColor.map(_.name))
2015-04-01 14:22:28 -06:00
2019-04-05 19:12:01 -06:00
private def pairingJson(games: List[Game], hostId: String)(p: SimulPairing): Fu[Option[JsObject]] =
games.find(_.id == p.gameId) ?? { game =>
playerJson(p.player) map { player =>
2019-12-13 07:30:20 -07:00
Json
.obj(
2020-08-20 01:51:00 -06:00
"player" -> player,
"variant" -> p.player.variant.key,
"hostColor" -> p.hostColor,
"game" -> gameJson(hostId, game)
2019-12-13 07:30:20 -07:00
)
.some
2019-04-05 19:12:01 -06:00
}
2017-01-26 06:59:04 -07:00
}
2015-04-01 14:22:28 -06:00
}