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

92 lines
2.8 KiB
Scala

package lila.relay
import play.api.libs.json._
import scala.concurrent.duration._
import lila.common.config.BaseUrl
import lila.common.Json.jodaWrites
import lila.study.Chapter
final class JsonView(baseUrl: BaseUrl, markup: RelayMarkup) {
import JsonView._
import lila.study.JsonView.chapterMetadataWrites
def apply(trs: RelayTour.WithRounds, withUrls: Boolean = false): JsObject =
Json
.obj(
"tour" -> Json
.obj(
"id" -> trs.tour.id,
"name" -> trs.tour.name,
"slug" -> trs.tour.slug,
"description" -> trs.tour.description
)
.add("markup" -> trs.tour.markup.map(markup(trs.tour)))
.add("url" -> withUrls.option(s"$baseUrl/broadcast/${trs.tour.slug}/${trs.tour.id}")),
"rounds" -> trs.rounds.map { round =>
if (withUrls) withUrl(round withTour trs.tour) else apply(round)
}
)
def apply(round: RelayRound): JsObject =
Json
.obj(
"id" -> round.id,
"name" -> round.name,
"slug" -> round.slug
)
.add("finished" -> round.finished)
.add("ongoing" -> (round.hasStarted && !round.finished))
.add("startsAt" -> round.startsAt.orElse(round.startedAt))
def withUrl(rt: RelayRound.WithTour): JsObject =
apply(rt.round).add("url" -> s"$baseUrl${rt.path}".some)
def withUrlAndGames(rt: RelayRound.WithTour, games: List[Chapter.Metadata]): JsObject =
withUrl(rt) ++ Json.obj("games" -> games.map { g =>
chapterMetadataWrites.writes(g) + ("url" -> JsString(s"$baseUrl${rt.path}/${g._id}"))
})
def sync(round: RelayRound) = syncWrites writes round.sync
def makeData(
trs: RelayTour.WithRounds,
currentRoundId: RelayRound.Id,
studyData: lila.study.JsonView.JsData,
canContribute: Boolean
) =
JsData(
relay = apply(trs)
.add("sync" -> (canContribute ?? trs.rounds.find(_.id == currentRoundId).map(_.sync))),
study = studyData.study,
analysis = studyData.analysis
)
}
object JsonView {
case class JsData(relay: JsObject, study: JsObject, analysis: JsObject)
implicit val syncLogEventWrites = Json.writes[SyncLog.Event]
implicit val roundIdWrites: Writes[RelayRound.Id] = Writes[RelayRound.Id] { id =>
JsString(id.value)
}
implicit val tourIdWrites: Writes[RelayTour.Id] = Writes[RelayTour.Id] { id =>
JsString(id.value)
}
implicit private val syncWrites: OWrites[RelayRound.Sync] = OWrites[RelayRound.Sync] { s =>
Json.obj(
"ongoing" -> s.ongoing,
"log" -> s.log.events
) ++
s.upstream.?? {
case url: RelayRound.Sync.UpstreamUrl => Json.obj("url" -> url.withRound.url)
case RelayRound.Sync.UpstreamIds(ids) => Json.obj("ids" -> ids)
}
}
}