lila/app/controllers/Tournament.scala

210 lines
6.8 KiB
Scala
Raw Normal View History

2013-05-07 17:44:26 -06:00
package controllers
2013-07-30 15:02:12 -06:00
import play.api.data.Form
2015-01-04 08:43:17 -07:00
import play.api.libs.json._
2013-07-30 15:02:12 -06:00
import play.api.mvc._
2013-12-29 02:51:40 -07:00
import lila.api.Context
2013-07-30 15:02:12 -06:00
import lila.app._
2015-01-18 10:40:22 -07:00
import lila.common.HTTPRequest
import lila.game.{ Pov, GameRepo }
import lila.tournament.{ System, TournamentRepo, PairingRepo, Tournament => Tourney, VisibleTournaments }
2013-12-27 15:12:20 -07:00
import lila.user.UserRepo
2013-12-29 02:51:40 -07:00
import views._
2013-05-07 17:44:26 -06:00
object Tournament extends LilaController {
2013-05-12 09:02:45 -06:00
private def env = Env.tournament
private def repo = TournamentRepo
2013-05-12 16:48:48 -06:00
private def tournamentNotFound(implicit ctx: Context) = NotFound(html.tournament.notFound())
def home(page: Int) = Open { implicit ctx =>
2016-01-25 19:59:18 -07:00
negotiate(
2016-03-04 05:37:28 -07:00
html = Reasonable(page, 20) {
2016-01-25 19:59:18 -07:00
val finishedPaginator = repo.finishedPaginator(maxPerPage = 30, page = page)
if (HTTPRequest isXhr ctx.req) finishedPaginator map { pag =>
Ok(html.tournament.finishedPaginator(pag))
}
else env.api.fetchVisibleTournaments zip
repo.scheduledDedup zip
finishedPaginator zip
2016-10-17 10:07:10 -06:00
env.winners.all map {
case (((visible, scheduled), finished), winners) =>
Ok(html.tournament.home(scheduled, finished, winners, env scheduleJsonView visible))
2016-01-25 19:59:18 -07:00
} map NoCache
},
api = _ => env.api.fetchVisibleTournaments map { tours =>
Ok(env scheduleJsonView tours)
}
)
2013-05-12 09:02:45 -06:00
}
2014-07-23 15:08:59 -06:00
def help(sysStr: Option[String]) = Open { implicit ctx =>
val system = sysStr flatMap {
case "arena" => System.Arena.some
2015-01-04 02:17:04 -07:00
case _ => none
2014-07-23 15:08:59 -06:00
}
Ok(html.tournament.faqPage(system)).fuccess
}
2013-05-12 09:02:45 -06:00
2016-10-17 08:17:55 -06:00
def leaderboard = Open { implicit ctx =>
env.winners.all.map { winners =>
Ok(html.tournament.leaderboard(winners))
}
}
2014-02-17 02:12:19 -07:00
def show(id: String) = Open { implicit ctx =>
val page = getInt("page")
negotiate(
html = repo byId id flatMap {
_.fold(tournamentNotFound.fuccess) { tour =>
2016-06-18 04:32:55 -06:00
(env.api.verdicts(tour, ctx.me) zip
env.version(tour.id) zip {
ctx.noKid ?? Env.chat.api.userChat.findMine(tour.id, ctx.me).map(some)
}).flatMap {
2016-06-18 05:21:30 -06:00
case ((verdicts, version), chat) => env.jsonView(tour, page, ctx.me, none, version.some) map {
2016-06-18 04:32:55 -06:00
html.tournament.show(tour, verdicts, _, chat)
}
}.map { Ok(_) }.mon(_.http.response.tournament.show.website)
}
},
api = _ => repo byId id flatMap {
case None => NotFound(jsonError("No such tournament")).fuccess
2016-03-10 00:01:37 -07:00
case Some(tour) => {
get("playerInfo").?? { env.api.playerInfo(tour.id, _) } zip
getBool("socketVersion").??(env version tour.id map some) flatMap {
case (playerInfoExt, socketVersion) =>
2016-06-18 05:21:30 -06:00
env.jsonView(tour, page, ctx.me, playerInfoExt, socketVersion)
} map { Ok(_) }
2016-03-10 20:08:34 -07:00
}.mon(_.http.response.tournament.show.mobile)
} map (_ as JSON)
2015-06-19 09:36:31 -06:00
) map NoCache
}
def standing(id: String, page: Int) = Open { implicit ctx =>
OptionFuResult(repo byId id) { tour =>
env.jsonView.standing(tour, page) map { data =>
Ok(data) as JSON
2013-05-12 09:02:45 -06:00
}
}
}
def gameStanding(id: String) = Open { implicit ctx =>
2015-06-11 16:54:51 -06:00
env.api.miniStanding(id, true) map {
case Some(m) if !m.tour.isCreated => Ok(html.tournament.gameStanding(m))
case _ => NotFound
}
}
def userGameNbMini(id: String, user: String, nb: Int) = Open { implicit ctx =>
withUserGameNb(id, user, nb) { pov =>
Ok(html.tournament.miniGame(pov))
}
}
def userGameNbShow(id: String, user: String, nb: Int) = Open { implicit ctx =>
withUserGameNb(id, user, nb) { pov =>
Redirect(routes.Round.watcher(pov.game.id, pov.color.name))
}
}
private def withUserGameNb(id: String, user: String, nb: Int)(withPov: Pov => Result)(implicit ctx: Context): Fu[Result] = {
val userId = lila.user.User normalize user
OptionFuResult(PairingRepo.byTourUserNb(id, userId, nb)) { pairing =>
GameRepo game pairing.id map {
_.flatMap { Pov.ofUserId(_, userId) }.fold(Redirect(routes.Tournament show id))(withPov)
}
}
}
2015-10-02 16:29:56 -06:00
def player(id: String, userId: String) = Open { implicit ctx =>
JsonOk {
env.api.playerInfo(id, userId) flatMap {
2015-10-05 06:40:42 -06:00
_ ?? env.jsonView.playerInfo
2015-10-02 14:52:00 -06:00
}
}
}
def join(id: String) = AuthBody(BodyParsers.parse.json) { implicit ctx =>
2014-02-17 02:12:19 -07:00
implicit me =>
NoLame {
val password = ctx.body.body.\("p").asOpt[String]
2015-01-04 08:43:17 -07:00
negotiate(
2015-01-05 05:28:48 -07:00
html = repo enterableById id map {
case None => tournamentNotFound
2015-01-05 05:28:48 -07:00
case Some(tour) =>
env.api.join(tour.id, me, password)
2015-01-05 05:28:48 -07:00
Redirect(routes.Tournament.show(tour.id))
2015-01-04 08:43:17 -07:00
},
api = _ => OptionFuOk(repo enterableById id) { tour =>
env.api.join(tour.id, me, password)
2015-01-04 08:43:17 -07:00
fuccess(Json.obj("ok" -> true))
}
2015-01-04 08:43:17 -07:00
)
2013-05-12 09:02:45 -06:00
}
}
2014-02-17 02:12:19 -07:00
def withdraw(id: String) = Auth { implicit ctx =>
me =>
2015-01-04 08:43:17 -07:00
OptionResult(repo byId id) { tour =>
env.api.withdraw(tour.id, me.id)
2015-01-18 10:40:22 -07:00
if (HTTPRequest.isXhr(ctx.req)) Ok(Json.obj("ok" -> true)) as JSON
else Redirect(routes.Tournament.show(tour.id))
2013-05-12 09:02:45 -06:00
}
}
def terminate(id: String) = Secure(_.TerminateTournament) { implicit ctx =>
me =>
OptionResult(repo startedById id) { tour =>
env.api finish tour
2016-01-21 02:16:51 -07:00
Env.mod.logApi.terminateTournament(me.id, tour.fullName)
Redirect(routes.Tournament show tour.id)
}
}
2014-02-17 02:12:19 -07:00
def form = Auth { implicit ctx =>
me =>
NoLame {
2013-05-12 09:02:45 -06:00
Ok(html.tournament.form(env.forms.create, env.forms)).fuccess
}
}
2014-02-17 02:12:19 -07:00
def create = AuthBody { implicit ctx =>
implicit me =>
NoLame {
import play.api.i18n.Messages.Implicits._
import play.api.Play.current
2013-05-12 09:02:45 -06:00
implicit val req = ctx.body
negotiate (
html = env.forms.create.bindFromRequest.fold(
err => BadRequest(html.tournament.form(err, env.forms)).fuccess,
setup => env.api.createTournament(setup, me) map { tour =>
Redirect(routes.Tournament.show(tour.id))
}),
api = _ => env.forms.create.bindFromRequest.fold(
err => BadRequest(errorsAsJson(err)).fuccess,
setup => env.api.createTournament(setup, me) map { tour =>
Ok(Json.obj("id" -> tour.id))
})
)
2013-05-12 09:02:45 -06:00
}
}
def limitedInvitation = Auth { implicit ctx =>
me =>
env.api.fetchVisibleTournaments.flatMap { tours =>
lila.tournament.TournamentInviter.findNextFor(me, tours, env.verify.canEnter(me))
} map {
case None => Redirect(routes.Tournament.home(1))
case Some(t) => Redirect(routes.Tournament.show(t.id))
}
}
def websocket(id: String, apiVersion: Int) = SocketOption[JsValue] { implicit ctx =>
get("sri") ?? { uid =>
env.socketHandler.join(id, uid, ctx.me)
}
2013-05-12 09:02:45 -06:00
}
2013-05-07 17:44:26 -06:00
}