more tournament rewrite
This commit is contained in:
parent
6475aae264
commit
e90024a41c
|
@ -8,7 +8,7 @@ import lila.api.Context
|
||||||
import lila.app._
|
import lila.app._
|
||||||
import lila.common.HTTPRequest
|
import lila.common.HTTPRequest
|
||||||
import lila.game.{ Pov, GameRepo }
|
import lila.game.{ Pov, GameRepo }
|
||||||
import lila.tournament.{ System, TournamentRepo, Created, Started, Finished, Tournament => Tourney }
|
import lila.tournament.{ System, TournamentRepo, Tournament => Tourney }
|
||||||
import lila.user.UserRepo
|
import lila.user.UserRepo
|
||||||
import views._
|
import views._
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ object Tournament extends LilaController {
|
||||||
|
|
||||||
def gameStanding(id: String) = Open { implicit ctx =>
|
def gameStanding(id: String) = Open { implicit ctx =>
|
||||||
env.cached tour id map {
|
env.cached tour id map {
|
||||||
case Some(t: lila.tournament.StartedOrFinished) => Ok(html.tournament.gameStanding(t, true))
|
case Some(t) if !t.isCreated => Ok(html.tournament.gameStanding(t, true))
|
||||||
case _ => NotFound
|
case _ => NotFound
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import lila.game.Game
|
||||||
import lila.rating.PerfType
|
import lila.rating.PerfType
|
||||||
import lila.simul.Simul
|
import lila.simul.Simul
|
||||||
import lila.timeline.Entry
|
import lila.timeline.Entry
|
||||||
import lila.tournament.{ Enterable, Winner }
|
import lila.tournament.{ Tournament, Winner }
|
||||||
import lila.tv.{ Featured, StreamOnAir }
|
import lila.tv.{ Featured, StreamOnAir }
|
||||||
import lila.user.User
|
import lila.user.User
|
||||||
import lila.playban.TempBan
|
import lila.playban.TempBan
|
||||||
|
@ -24,11 +24,11 @@ final class Preload(
|
||||||
lobbyApi: lila.api.LobbyApi,
|
lobbyApi: lila.api.LobbyApi,
|
||||||
getPlayban: String => Fu[Option[TempBan]]) {
|
getPlayban: String => Fu[Option[TempBan]]) {
|
||||||
|
|
||||||
private type Response = (JsObject, List[Entry], List[MiniForumPost], List[Enterable], List[Simul], Option[Game], List[(User, PerfType)], List[Winner], Option[lila.puzzle.DailyPuzzle], List[StreamOnAir], List[lila.blog.MiniPost], Option[TempBan], Int)
|
private type Response = (JsObject, List[Entry], List[MiniForumPost], List[Tournament], List[Simul], Option[Game], List[(User, PerfType)], List[Winner], Option[lila.puzzle.DailyPuzzle], List[StreamOnAir], List[lila.blog.MiniPost], Option[TempBan], Int)
|
||||||
|
|
||||||
def apply(
|
def apply(
|
||||||
posts: Fu[List[MiniForumPost]],
|
posts: Fu[List[MiniForumPost]],
|
||||||
tours: Fu[List[Enterable]],
|
tours: Fu[List[Tournament]],
|
||||||
simuls: Fu[List[Simul]])(implicit ctx: Context): Fu[Response] =
|
simuls: Fu[List[Simul]])(implicit ctx: Context): Fu[Response] =
|
||||||
lobbyApi(ctx) zip
|
lobbyApi(ctx) zip
|
||||||
posts zip
|
posts zip
|
||||||
|
|
|
@ -87,7 +87,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@myTour match {
|
@myTour match {
|
||||||
case Some(t: lila.tournament.StartedOrFinished) => { @tournament.gameStanding(t, withTourStanding) }
|
case Some(t) if !t.isCreated => { @tournament.gameStanding(t, withTourStanding) }
|
||||||
case _ => {
|
case _ => {
|
||||||
@pov.game.tournamentId.map { tourId =>
|
@pov.game.tournamentId.map { tourId =>
|
||||||
<div class="game_tournament side_box no_padding">
|
<div class="game_tournament side_box no_padding">
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@(data: play.api.libs.json.JsObject, userTimeline: List[lila.timeline.Entry], forumRecent: List[lila.forum.MiniForumPost], tours: List[lila.tournament.Enterable], simuls: List[lila.simul.Simul], featured: Option[Game], leaderboard: List[(User, lila.rating.PerfType)], tournamentWinners: List[lila.tournament.Winner], puzzle: Option[lila.puzzle.DailyPuzzle], streams: List[lila.tv.StreamOnAir], lastPost: List[lila.blog.MiniPost], playban: Option[lila.playban.TempBan], nbRounds: Int)(implicit ctx: Context)
|
@(data: play.api.libs.json.JsObject, userTimeline: List[lila.timeline.Entry], forumRecent: List[lila.forum.MiniForumPost], tours: List[Tournament], simuls: List[lila.simul.Simul], featured: Option[Game], leaderboard: List[(User, lila.rating.PerfType)], tournamentWinners: List[lila.tournament.Winner], puzzle: Option[lila.puzzle.DailyPuzzle], streams: List[lila.tv.StreamOnAir], lastPost: List[lila.blog.MiniPost], playban: Option[lila.playban.TempBan], nbRounds: Int)(implicit ctx: Context)
|
||||||
@import play.api.libs.json.Json
|
@import play.api.libs.json.Json
|
||||||
|
|
||||||
@underchat = {
|
@underchat = {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@(tours: List[lila.tournament.Enterable])
|
@(tours: List[Tournament])
|
||||||
|
|
||||||
<table class="tournaments">
|
<table class="tournaments">
|
||||||
@tournament.enterableTable(tours, true)
|
@tournament.enterableTable(tours, true)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@(tours: List[lila.tournament.Enterable], scheduled: Boolean)
|
@(tours: List[Tournament], scheduled: Boolean)
|
||||||
|
|
||||||
@if(!scheduled && tours.isEmpty) {
|
@if(!scheduled && tours.isEmpty) {
|
||||||
<tr class="create">
|
<tr class="create">
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
@side = {
|
@side = {
|
||||||
<div class="tournament_links">
|
<div class="tournament_links">
|
||||||
<a href="@routes.Tournament.help("arena".some)">Arena tournament help</a>
|
<a href="@routes.Tournament.help("arena".some)">Arena tournament help</a>
|
||||||
<a href="@routes.Tournament.help("swiss".some)">Swiss tournament help</a>
|
*<a href="@routes.Tournament.help("swiss".some)">Swiss tournament help</a>*
|
||||||
<a href="@routes.Tournament.home()">Return to tournaments</a>
|
<a href="@routes.Tournament.home()">Return to tournaments</a>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,10 @@
|
||||||
@(t: lila.tournament.StartedOrFinished, withStanding: Boolean)(implicit ctx: Context)
|
@(t: Tournament, withStanding: Boolean)(implicit ctx: Context)
|
||||||
|
|
||||||
<div class="game_tournament side_box no_padding scroll-shadow-soft">
|
<div class="game_tournament side_box no_padding scroll-shadow-soft">
|
||||||
<p class="top text" data-icon="g"><a href="@routes.Tournament.show(t.id)">@t.fullName</a></p>
|
<p class="top text" data-icon="g"><a href="@routes.Tournament.show(t.id)">@t.fullName</a></p>
|
||||||
@t match {
|
|
||||||
case t: lila.tournament.Started => {
|
|
||||||
<div class="clock" data-time="@t.remainingSeconds">
|
<div class="clock" data-time="@t.remainingSeconds">
|
||||||
<div class="time text" data-icon="p">@t.clockStatus</div>
|
<div class="time text" data-icon="p">@t.clockStatus</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
case _ => {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@if(withStanding) {
|
@if(withStanding) {
|
||||||
<table class="slist standing">
|
<table class="slist standing">
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@(createds: List[lila.tournament.Created], starteds: List[lila.tournament.Started], finisheds: List[lila.tournament.Finished], scheduled: List[lila.tournament.Created], leaderboard: List[User])(implicit ctx: Context)
|
@(createds: List[Tournament], starteds: List[Tournament], finisheds: List[Tournament], scheduled: List[Tournament], leaderboard: List[User])(implicit ctx: Context)
|
||||||
|
|
||||||
@side = {
|
@side = {
|
||||||
<div class="tournament_links">
|
<div class="tournament_links">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@(createds: List[lila.tournament.Created], starteds: List[lila.tournament.Started], finisheds: List[lila.tournament.Finished])(implicit ctx: Context)
|
@(createds: List[Tournament], starteds: List[Tournament], finisheds: List[Tournament])(implicit ctx: Context)
|
||||||
|
|
||||||
@joinButton(tour: lila.tournament.Enterable) = {
|
@joinButton(tour: Tournament) = {
|
||||||
@ctx.me.map { me =>
|
@ctx.me.map { me =>
|
||||||
@if(tour isActive me) {
|
@if(tour isActive me) {
|
||||||
<span class="joined text" data-icon="E">JOINED</span>
|
<span class="joined text" data-icon="E">JOINED</span>
|
||||||
|
@ -12,13 +12,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@iconTd(tour: lila.tournament.Tournament) = {
|
@iconTd(tour: tournament.Tournament) = {
|
||||||
<td class="icon">
|
<td class="icon">
|
||||||
<span @if(tour.scheduled){class="is-gold"} data-icon="@tournamentIconChar(tour)"></span>
|
<span @if(tour.scheduled){class="is-gold"} data-icon="@tournamentIconChar(tour)"></span>
|
||||||
</td>
|
</td>
|
||||||
}
|
}
|
||||||
|
|
||||||
@tourTd(tour: lila.tournament.Tournament) = {
|
@tourTd(tour: tournament.Tournament) = {
|
||||||
<td class="header">
|
<td class="header">
|
||||||
<a href="@routes.Tournament.show(tour.id)">
|
<a href="@routes.Tournament.show(tour.id)">
|
||||||
<span class="name">
|
<span class="name">
|
||||||
|
|
|
@ -11,7 +11,7 @@ import lila.pref.Pref
|
||||||
import lila.round.JsonView
|
import lila.round.JsonView
|
||||||
import lila.security.Granter
|
import lila.security.Granter
|
||||||
import lila.simul.Simul
|
import lila.simul.Simul
|
||||||
import lila.tournament.{ RoundTournament, TournamentRepo }
|
import lila.tournament.{ TournamentRepo, Tournament }
|
||||||
import lila.user.User
|
import lila.user.User
|
||||||
|
|
||||||
private[api] final class RoundApi(
|
private[api] final class RoundApi(
|
||||||
|
@ -26,7 +26,7 @@ private[api] final class RoundApi(
|
||||||
jsonView.playerJson(pov, ctx.pref, apiVersion, ctx.me,
|
jsonView.playerJson(pov, ctx.pref, apiVersion, ctx.me,
|
||||||
initialFen = initialFen,
|
initialFen = initialFen,
|
||||||
withBlurs = ctx.me ?? Granter(_.ViewBlurs)) zip
|
withBlurs = ctx.me ?? Granter(_.ViewBlurs)) zip
|
||||||
(pov.game.tournamentId ?? TournamentRepo.roundView) zip
|
(pov.game.tournamentId ?? TournamentRepo.byId) zip
|
||||||
(pov.game.simulId ?? getSimul) zip
|
(pov.game.simulId ?? getSimul) zip
|
||||||
(ctx.me ?? (me => noteApi.get(pov.gameId, me.id))) map {
|
(ctx.me ?? (me => noteApi.get(pov.gameId, me.id))) map {
|
||||||
case (((json, tourOption), simulOption), note) => (
|
case (((json, tourOption), simulOption), note) => (
|
||||||
|
@ -48,7 +48,7 @@ private[api] final class RoundApi(
|
||||||
withBlurs = ctx.me ?? Granter(_.ViewBlurs),
|
withBlurs = ctx.me ?? Granter(_.ViewBlurs),
|
||||||
initialFen = initialFen,
|
initialFen = initialFen,
|
||||||
withMoveTimes = withMoveTimes) zip
|
withMoveTimes = withMoveTimes) zip
|
||||||
(pov.game.tournamentId ?? TournamentRepo.roundView) zip
|
(pov.game.tournamentId ?? TournamentRepo.byId) zip
|
||||||
(pov.game.simulId ?? getSimul) zip
|
(pov.game.simulId ?? getSimul) zip
|
||||||
(ctx.me ?? (me => noteApi.get(pov.gameId, me.id))) map {
|
(ctx.me ?? (me => noteApi.get(pov.gameId, me.id))) map {
|
||||||
case (((json, tourOption), simulOption), note) => (
|
case (((json, tourOption), simulOption), note) => (
|
||||||
|
@ -83,16 +83,16 @@ private[api] final class RoundApi(
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
private def withTournament(pov: Pov, tourOption: Option[RoundTournament])(json: JsObject) =
|
private def withTournament(pov: Pov, tourOption: Option[Tournament])(json: JsObject) =
|
||||||
tourOption.fold(json) { tour =>
|
tourOption.fold(json) { tour =>
|
||||||
json + ("tournament" -> Json.obj(
|
json + ("tournament" -> Json.obj(
|
||||||
"id" -> tour.id,
|
"id" -> tour.id,
|
||||||
"name" -> tour.name,
|
"name" -> tour.name,
|
||||||
"running" -> tour.isRunning,
|
"running" -> tour.isStarted,
|
||||||
"berserkable" -> tour.berserkable,
|
"berserkable" -> tour.berserkable
|
||||||
"berserk1" -> false, //pairing.map(_.berserk1).filter(0!=),
|
// "berserk1" -> false, //pairing.map(_.berserk1).filter(0!=),
|
||||||
"berserk2" -> false //pairing.map(_.berserk2).filter(0!=)
|
// "berserk2" -> false //pairing.map(_.berserk2).filter(0!=)
|
||||||
).noNull)
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
private def withSimul(pov: Pov, simulOption: Option[Simul])(json: JsObject) =
|
private def withSimul(pov: Pov, simulOption: Option[Simul])(json: JsObject) =
|
||||||
|
|
|
@ -35,16 +35,6 @@ object BSONHandlers {
|
||||||
private def readSystem(r: BSON.Reader) =
|
private def readSystem(r: BSON.Reader) =
|
||||||
r.intO("system").fold[System](System.default)(System.orDefault)
|
r.intO("system").fold[System](System.default)(System.orDefault)
|
||||||
|
|
||||||
implicit val roundTournamentHandler = new BSON[RoundTournament] {
|
|
||||||
def reads(r: BSON.Reader) = RoundTournament(
|
|
||||||
id = r str "_id",
|
|
||||||
name = r str "name",
|
|
||||||
status = r int "status",
|
|
||||||
system = readSystem(r),
|
|
||||||
clock = r.get[TournamentClock]("clock"))
|
|
||||||
def writes(w: BSON.Writer, o: RoundTournament) = sys error "RoundTournament view is read only!"
|
|
||||||
}
|
|
||||||
|
|
||||||
implicit val tournamentHandler = new BSON[Tournament] {
|
implicit val tournamentHandler = new BSON[Tournament] {
|
||||||
def reads(r: BSON.Reader) = Tournament(
|
def reads(r: BSON.Reader) = Tournament(
|
||||||
id = r str "_id",
|
id = r str "_id",
|
||||||
|
|
|
@ -10,10 +10,4 @@ private[tournament] final class Cached {
|
||||||
default = _ => none)
|
default = _ => none)
|
||||||
|
|
||||||
def name(id: String): Option[String] = nameCache get id
|
def name(id: String): Option[String] = nameCache get id
|
||||||
|
|
||||||
private val staleViewCache = lila.memo.AsyncCache[String, Option[Tournament]](
|
|
||||||
(id: String) => TournamentRepo byId id,
|
|
||||||
timeToLive = 2 seconds)
|
|
||||||
|
|
||||||
def tour(id: String): Fu[Option[Tournament]] = staleViewCache(id)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,63 +63,6 @@ case class Tournament(
|
||||||
|
|
||||||
case class EnterableTournaments(tours: List[Tournament], scheduled: List[Tournament])
|
case class EnterableTournaments(tours: List[Tournament], scheduled: List[Tournament])
|
||||||
|
|
||||||
// def userCurrentPairing(userId: String): Option[Pairing] = pairings find { p =>
|
|
||||||
// p.playing && p.contains(userId)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// def userCurrentPov(userId: String): Option[PovRef] =
|
|
||||||
// userCurrentPairing(userId) flatMap (_ povRef userId)
|
|
||||||
|
|
||||||
// def userCurrentPov(user: Option[User]): Option[PovRef] =
|
|
||||||
// user.flatMap(u => userCurrentPov(u.id))
|
|
||||||
|
|
||||||
// def finish = withPlayers(players.map(_.unWithdraw)).refreshPlayers |> { tour =>
|
|
||||||
// Finished(
|
|
||||||
// id = tour.id,
|
|
||||||
// data = tour.data,
|
|
||||||
// startedAt = tour.startedAt,
|
|
||||||
// players = tour.players.map(_.unWithdraw),
|
|
||||||
// // pairings = tour.pairings filterNot (_.playing),
|
|
||||||
// events = tour.events)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// def withdraw(userId: String): Valid[Started] = contains(userId).fold(
|
|
||||||
// withPlayers(players map {
|
|
||||||
// case p if p is userId => p.doWithdraw
|
|
||||||
// case p => p
|
|
||||||
// }).success,
|
|
||||||
// !!("User %s is not part of the tournament" format userId)
|
|
||||||
// )
|
|
||||||
|
|
||||||
// def quickLossStreak(user: String): Boolean =
|
|
||||||
// userPairings(user).takeWhile { pair => (pair lostBy user) && pair.quickFinish }.size >= 3
|
|
||||||
|
|
||||||
// def withPlayers(s: Players) = copy(players = s)
|
|
||||||
// def refreshPlayers = withPlayers(Player refresh this)
|
|
||||||
|
|
||||||
// def join(user: User) = joinNew(user) orElse joinBack(user)
|
|
||||||
|
|
||||||
// private def joinBack(user: User) = withdrawnPlayers.find(_ is user) match {
|
|
||||||
// case None => !!("User %s is already part of the tournament" format user.id)
|
|
||||||
// case Some(player) => withPlayers(players map {
|
|
||||||
// case p if p is player => p.unWithdraw
|
|
||||||
// case p => p
|
|
||||||
// }).success
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// case class Finished(
|
|
||||||
// id: String,
|
|
||||||
// data: Data,
|
|
||||||
// startedAt: DateTime,
|
|
||||||
// events: List[Event]) extends StartedOrFinished {
|
|
||||||
|
|
||||||
// override def isFinished = true
|
|
||||||
|
|
||||||
// // def withPlayers(s: Players) = copy(players = s)
|
|
||||||
// // def refreshPlayers = withPlayers(Player refresh this)
|
|
||||||
// }
|
|
||||||
|
|
||||||
object Tournament {
|
object Tournament {
|
||||||
|
|
||||||
val minPlayers = 3
|
val minPlayers = 3
|
||||||
|
|
|
@ -28,9 +28,6 @@ object TournamentRepo {
|
||||||
selectId(id) ++ BSONDocument("players.id" -> userId)
|
selectId(id) ++ BSONDocument("players.id" -> userId)
|
||||||
).one[Tournament]
|
).one[Tournament]
|
||||||
|
|
||||||
def roundView(id: String): Fu[Option[RoundTournament]] =
|
|
||||||
coll.find(selectId(id)).one[RoundTournament]
|
|
||||||
|
|
||||||
def createdById(id: String): Fu[Option[Tournament]] =
|
def createdById(id: String): Fu[Option[Tournament]] =
|
||||||
coll.find(selectId(id) ++ createdSelect).one[Tournament]
|
coll.find(selectId(id) ++ createdSelect).one[Tournament]
|
||||||
|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
package lila.tournament
|
|
||||||
|
|
||||||
case class RoundTournament(
|
|
||||||
id: String,
|
|
||||||
name: String,
|
|
||||||
status: Int,
|
|
||||||
system: System,
|
|
||||||
clock: TournamentClock) {
|
|
||||||
|
|
||||||
def isRunning = status == Status.Started.id
|
|
||||||
|
|
||||||
def berserkable = system.berserkable && clock.increment == 0
|
|
||||||
}
|
|
|
@ -24,6 +24,7 @@ object ApplicationBuild extends Build {
|
||||||
sources in doc in Compile := List(),
|
sources in doc in Compile := List(),
|
||||||
TwirlKeys.templateImports ++= Seq(
|
TwirlKeys.templateImports ++= Seq(
|
||||||
"lila.game.{ Game, Player, Pov }",
|
"lila.game.{ Game, Player, Pov }",
|
||||||
|
"lila.tournament.Tournament",
|
||||||
"lila.user.{ User, UserContext }",
|
"lila.user.{ User, UserContext }",
|
||||||
"lila.security.Permission",
|
"lila.security.Permission",
|
||||||
"lila.app.templating.Environment._",
|
"lila.app.templating.Environment._",
|
||||||
|
|
Loading…
Reference in a new issue