diff --git a/app/controllers/LilaController.scala b/app/controllers/LilaController.scala index a4c970d636..a1f8845100 100644 --- a/app/controllers/LilaController.scala +++ b/app/controllers/LilaController.scala @@ -168,6 +168,15 @@ private[controllers] trait LilaController protected def authorizationFailed(req: RequestHeader): SimpleResult = Forbidden("no permission") + private val AcceptApi = play.api.mvc.Accepting("application/vnd.lichess.v1+json") + protected def negotiate(html: => Fu[SimpleResult], api: => Fu[SimpleResult])(implicit ctx: Context): Fu[SimpleResult] = { + implicit val req = ctx.req + render.async { + case AcceptApi() => api + case _ => html + } + } + protected def reqToCtx(req: RequestHeader): Fu[HeaderContext] = restoreUser(req) map { lila.user.UserContext(req, _) } flatMap { ctx => pageDataBuilder(ctx) map { Context(ctx, _) } diff --git a/app/controllers/Lobby.scala b/app/controllers/Lobby.scala index c8990b58f3..8db6a63d92 100644 --- a/app/controllers/Lobby.scala +++ b/app/controllers/Lobby.scala @@ -27,7 +27,7 @@ object Lobby extends LilaController { def handleStatus(req: RequestHeader, status: Results.Status): Fu[SimpleResult] = reqToCtx(req) flatMap { ctx => renderHome(status)(ctx) } - def renderHome[A](status: Results.Status)(implicit ctx: Context): Fu[SimpleResult] = + def renderHome(status: Results.Status)(implicit ctx: Context): Fu[SimpleResult] = Env.current.preloader( posts = Env.forum.recent(ctx.me, Env.team.cached.teamIds), tours = Env.tournament enterable true, diff --git a/app/controllers/Setup.scala b/app/controllers/Setup.scala index 6586cd7247..b4ea2259f0 100644 --- a/app/controllers/Setup.scala +++ b/app/controllers/Setup.scala @@ -1,7 +1,7 @@ package controllers import play.api.data.Form -import play.api.mvc.{ SimpleResult, Call, RequestHeader } +import play.api.mvc.{ SimpleResult, Results, Call, RequestHeader, Accepting } import lila.api.{ Context, BodyContext } import lila.app._ @@ -10,14 +10,14 @@ import lila.game.{ GameRepo, Pov, AnonCookie } import lila.user.UserRepo import views._ -object Setup extends LilaController with TheftPrevention { +object Setup extends LilaController with TheftPrevention with play.api.http.ContentTypes { private def env = Env.setup def aiForm = Open { implicit ctx => if (HTTPRequest isXhr ctx.req) env.forms aiFilled get("fen") map { form => - html.setup.ai(form, Env.ai.aiPerfApi.intRatings ) + html.setup.ai(form, Env.ai.aiPerfApi.intRatings) } else fuccess { Redirect(routes.Lobby.home + "#ai") @@ -174,9 +174,15 @@ object Setup extends LilaController with TheftPrevention { OpenBody { implicit ctx => implicit val req = ctx.body form(ctx).bindFromRequest.fold( - f => fuloginfo(f.errors.toString) inject Redirect(routes.Lobby.home), - config => op(config)(ctx) map { - case (pov, call) => redirectPov(pov, call) + f => negotiate( + html = fuloginfo(f.errors.toString) >> Lobby.renderHome(Results.BadRequest), + api = fuccess(BadRequest(f.errorsAsJson)) + ), + config => op(config)(ctx) flatMap { + case (pov, call) => negotiate( + html = fuccess(redirectPov(pov, call)), + api = fuccess(Created(lila.api.Json.pov(pov)) as JSON) + ) } ) } diff --git a/modules/api/src/main/Json.scala b/modules/api/src/main/Json.scala new file mode 100644 index 0000000000..f0b89b535b --- /dev/null +++ b/modules/api/src/main/Json.scala @@ -0,0 +1,23 @@ +package lila.api + +import play.api.http.ContentTypes.JSON +import play.api.libs.json.{ JsObject, Json => J } +import play.api.mvc.Results.Ok + +import chess.format.Forsyth +import lila.game.{ Game, Pov } + +object Json { + + def pov(p: Pov) = J.obj( + "game" -> game(p.game), + "player" -> player(p)) + + private def game(g: Game) = J.obj( + "id" -> g.id, + "fen" -> (Forsyth >> g.toChess)) + + private def player(p: Pov) = J.obj( + "id" -> p.fullId, + "color" -> p.color.name) +}