lila/app/controllers/Tournament.scala

205 lines
6.6 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
import play.api.libs.json.JsValue
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._
2013-05-12 09:02:45 -06:00
import lila.game.{ Pov, GameRepo }
2014-07-23 15:08:59 -06:00
import lila.tournament.{ System, TournamentRepo, Created, Started, Finished, Tournament => Tourney }
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())
2014-02-17 02:12:19 -07:00
protected def TourOptionFuRedirect[A](fua: Fu[Option[A]])(op: A => Fu[Call])(implicit ctx: Context) =
2013-05-12 16:48:48 -06:00
fua flatMap {
2014-02-17 02:12:19 -07:00
_.fold(tournamentNotFound(ctx).fuccess)(a => op(a) map { b => Redirect(b) })
2013-05-12 16:48:48 -06:00
}
2014-02-17 02:12:19 -07:00
val home = Open { implicit ctx =>
2014-04-10 15:01:45 -06:00
fetchTournaments zip repo.scheduled zip UserRepo.allSortToints(10) map {
case ((((created, started), finished), scheduled), leaderboard) =>
Ok(html.tournament.home(created, started, finished, scheduled, leaderboard))
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
case "swiss" => System.Swiss.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
2014-02-17 02:12:19 -07:00
val homeReload = Open { implicit ctx =>
2014-04-10 15:01:45 -06:00
fetchTournaments map {
2014-02-17 02:12:19 -07:00
case ((created, started), finished) =>
2013-05-12 09:02:45 -06:00
Ok(html.tournament.homeInner(created, started, finished))
}
}
2014-04-10 15:01:45 -06:00
private def fetchTournaments =
2014-12-29 14:58:10 -07:00
env allCreatedSorted true zip repo.noPasswordStarted zip repo.finished(20)
2013-05-12 09:02:45 -06:00
2014-02-17 02:12:19 -07:00
def show(id: String) = Open { implicit ctx =>
2013-05-12 09:02:45 -06:00
repo byId id flatMap {
_ match {
2014-02-17 02:12:19 -07:00
case Some(tour: Created) => showCreated(tour) map { Ok(_) }
2014-04-21 08:44:49 -06:00
case Some(tour: Started) => showStarted(tour) map { Ok(_) }
2014-02-17 02:12:19 -07:00
case Some(tour: Finished) => showFinished(tour) map { Ok(_) }
case _ => tournamentNotFound.fuccess
2013-05-12 09:02:45 -06:00
}
}
}
private def showCreated(tour: Created)(implicit ctx: Context) =
2015-01-04 02:17:04 -07:00
env.jsonView(tour, Env.api.version) zip chatOf(tour) map {
case (data, chat) => html.tournament.showJs(tour, data, chat)
2014-02-01 01:57:40 -07:00
}
2013-05-12 09:02:45 -06:00
private def showStarted(tour: Started)(implicit ctx: Context) =
env.version(tour.id) zip
2014-02-01 01:57:40 -07:00
chatOf(tour) zip
2013-05-12 09:02:45 -06:00
GameRepo.games(tour recentGameIds 4) zip
tour.userCurrentPov(ctx.me).??(GameRepo.pov) map {
2014-02-17 02:12:19 -07:00
case (((version, chat), games), pov) =>
2014-02-01 01:57:40 -07:00
html.tournament.show.started(tour, version, chat, games, pov)
2013-05-12 09:02:45 -06:00
}
private def showFinished(tour: Finished)(implicit ctx: Context) =
2014-02-01 01:57:40 -07:00
env.version(tour.id) zip
chatOf(tour) zip
GameRepo.games(tour recentGameIds 4) map {
2014-02-17 02:12:19 -07:00
case ((version, chat), games) =>
2014-02-01 01:57:40 -07:00
html.tournament.show.finished(tour, version, chat, games)
2013-05-12 09:02:45 -06:00
}
2014-02-17 02:12:19 -07:00
def join(id: String) = AuthBody { implicit ctx =>
implicit me =>
2013-05-12 09:02:45 -06:00
NoEngine {
2014-04-13 02:46:28 -06:00
TourOptionFuRedirect(repo enterableById id) { tour =>
fuccess {
if (tour.hasPassword) routes.Tournament.joinPassword(id)
else {
env.api.join(tour, me, none)
routes.Tournament.show(tour.id)
}
}
2013-05-12 09:02:45 -06:00
}
}
}
2014-02-17 02:12:19 -07:00
def joinPasswordForm(id: String) = Auth { implicit ctx =>
implicit me => NoEngine {
2013-07-30 15:02:12 -06:00
repo createdById id flatMap {
2014-02-17 02:12:19 -07:00
_.fold(tournamentNotFound(ctx).fuccess) { tour =>
2013-07-30 15:02:12 -06:00
renderJoinPassword(tour, env.forms.joinPassword) map { Ok(_) }
}
}
}
}
2014-02-17 02:12:19 -07:00
def joinPassword(id: String) = AuthBody { implicit ctx =>
implicit me =>
2013-07-30 15:02:12 -06:00
NoEngine {
implicit val req = ctx.body
repo createdById id flatMap {
2014-02-17 02:12:19 -07:00
_.fold(tournamentNotFound(ctx).fuccess) { tour =>
2013-07-30 15:02:12 -06:00
env.forms.joinPassword.bindFromRequest.fold(
2014-02-17 02:12:19 -07:00
err => renderJoinPassword(tour, err) map { BadRequest(_) },
password => {
env.api.join(tour, me, password.some)
fuccess(Redirect(routes.Tournament.show(tour.id)))
})
2013-07-30 15:02:12 -06:00
}
}
}
}
private def renderJoinPassword(tour: Created, form: Form[_])(implicit ctx: Context) =
env version tour.id map { html.tournament.joinPassword(tour, form, _) }
2013-07-30 15:02:12 -06:00
2014-02-17 02:12:19 -07:00
def withdraw(id: String) = Auth { implicit ctx =>
me =>
TourOptionFuRedirect(repo byId id) { tour =>
env.api.withdraw(tour, me.id)
fuccess(routes.Tournament.show(tour.id))
2013-05-12 09:02:45 -06:00
}
}
2014-02-17 02:12:19 -07:00
def earlyStart(id: String) = Auth { implicit ctx =>
implicit me =>
TourOptionFuRedirect(repo.createdByIdAndCreator(id, me.id)) { tour =>
env.api startIfReady tour
fuccess(routes.Tournament show tour.id)
2013-05-12 09:02:45 -06:00
}
}
2014-02-17 02:12:19 -07:00
def reload(id: String) = Open { implicit ctx =>
2013-05-12 09:02:45 -06:00
OptionFuOk(repo byId id) {
2014-02-17 02:12:19 -07:00
case tour: Created => reloadCreated(tour)
case tour: Started => reloadStarted(tour)
case tour: Finished => reloadFinished(tour)
2013-05-12 09:02:45 -06:00
}
}
private def reloadCreated(tour: Created)(implicit ctx: Context) = fuccess {
html.tournament.show.inner(none)(html.tournament.show.createdInner(tour))
}
private def reloadStarted(tour: Started)(implicit ctx: Context) =
GameRepo.games(tour recentGameIds 4) zip
tour.userCurrentPov(ctx.me).??(GameRepo.pov) map {
2014-02-17 02:12:19 -07:00
case (games, pov) => {
2013-05-12 09:02:45 -06:00
val pairings = html.tournament.pairings(tour)
val inner = html.tournament.show.startedInner(tour, games, pov)
html.tournament.show.inner(pairings.some)(inner)
}
}
private def reloadFinished(tour: Finished)(implicit ctx: Context) =
2014-02-17 02:12:19 -07:00
GameRepo games (tour recentGameIds 4) map { games =>
2013-05-12 09:02:45 -06:00
val pairings = html.tournament.pairings(tour)
val inner = html.tournament.show.finishedInner(tour, games)
html.tournament.show.inner(pairings.some)(inner)
}
2014-02-17 02:12:19 -07:00
def form = Auth { implicit ctx =>
me =>
2013-05-12 09:02:45 -06:00
NoEngine {
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 =>
2013-05-12 09:02:45 -06:00
NoEngine {
implicit val req = ctx.body
env.forms.create.bindFromRequest.fold(
2014-02-17 02:12:19 -07:00
err => BadRequest(html.tournament.form(err, env.forms)).fuccess,
setup => env.api.createTournament(setup, me) map { tour =>
2013-05-12 09:02:45 -06:00
Redirect(routes.Tournament.show(tour.id))
})
}
}
2015-01-03 08:38:27 -07:00
def websocket(id: String, apiVersion: Int) = Socket[JsValue] { implicit ctx =>
2013-05-12 09:02:45 -06:00
~(getInt("version") |@| get("sri") apply {
2014-02-17 02:12:19 -07:00
case (version, uid) => env.socketHandler.join(id, version, uid, ctx.me)
2013-05-12 09:02:45 -06:00
})
}
2014-02-01 01:57:40 -07:00
private def chatOf(tour: lila.tournament.Tournament)(implicit ctx: Context) =
2014-02-01 02:05:27 -07:00
ctx.isAuth ?? {
Env.chat.api.userChat find tour.id map (_.forUser(ctx.me).some)
2014-02-01 02:05:27 -07:00
}
2013-05-07 17:44:26 -06:00
}