Split up application and internal api

pull/1/merge
Thibault Duplessis 2012-03-17 22:28:07 +01:00
parent 13101a42c1
commit 076211e0b4
8 changed files with 112 additions and 48 deletions

View File

@ -6,9 +6,14 @@ import play.api.data.Forms._
object DataForm {
val moveForm = Form(tuple(
"from" -> text,
"to" -> text,
"from" -> nonEmptyText,
"to" -> nonEmptyText,
"promotion" -> optional(text),
"b" -> optional(number)
))
val talkForm = Form(tuple(
"author" -> nonEmptyText,
"message" -> nonEmptyText
))
}

View File

@ -4,39 +4,21 @@ import lila.http._
import DataForm._
import play.api._
import play.api.mvc._
import com.codahale.jerkson.Json.{ generate => jsonify }
import mvc._
object Application extends Controller {
object Application extends LilaController {
val env = new HttpEnv(Play.unsafeApplication.configuration.underlying)
val json = "application/json"
private val syncer = env.syncer
private val server = env.server
def sync(id: String, color: String, version: Int, fullId: Option[String]) =
Action {
Ok(jsonify(
env.syncer.sync(id, color, version, fullId).unsafePerformIO
)) as json
JsonOk(env.syncer.sync(id, color, version, fullId).unsafePerformIO)
}
def move(fullId: String) = Action { implicit request
(moveForm.bindFromRequest.value toValid "Invalid move" flatMap { move =>
ValidOk(moveForm.bindFromRequest.value toValid "Invalid move" flatMap { move
env.server.play(fullId, move._1, move._2, move._3).unsafePerformIO
}).fold(
e BadRequest(e.list mkString "\n"),
_ Ok("ok")
)
})
}
def updateVersion(gameId: String) = Action {
env.server.updateVersion(gameId).unsafePerformIO
Ok("ok")
}
def endGame(gameId: String) = Action {
env.server.endGame(gameId).unsafePerformIO
Ok("ok")
}
def index = TODO
}

View File

@ -0,0 +1,26 @@
package controllers
import lila.http._
import DataForm._
import play.api._
import mvc._
object Internal extends LilaController {
private val api = env.internalApi
def talk(gameId: String) = Action { implicit request
ValidOk(talkForm.bindFromRequest.value toValid "Invalid talk" map { talk
api.talk(gameId, talk._1, talk._2).unsafePerformIO
})
}
def updateVersion(gameId: String) = Action {
IOk(api updateVersion gameId)
}
def endGame(gameId: String) = Action {
IOk(api endGame gameId)
}
}

View File

@ -0,0 +1,33 @@
package controllers
import lila.http._
import play.api._
import mvc._
import http._
import scala.io.Codec
import com.codahale.jerkson.Json
import scalaz.effects.IO
trait LilaController extends Controller {
val env = new HttpEnv(Play.unsafeApplication.configuration.underlying)
val json = "application/json"
def JsonOk(map: Map[String, Any]) = Ok(Json generate map) as json
def ValidOk(valid: Valid[Unit]) = valid.fold(
e BadRequest(e.list mkString "\n"),
_ Ok("ok")
)
def IOk(op: IO[Unit]) = Ok(op.unsafePerformIO)
// I like Unit requests.
implicit def wUnit: Writeable[Unit] =
Writeable[Unit](_ Codec toUTF8 "ok")
implicit def ctoUnit: ContentTypeOf[Unit] =
ContentTypeOf[Unit](Some(ContentTypes.TEXT))
}

View File

@ -2,12 +2,12 @@
# This file defines all application routes (Higher priority routes first)
# ~~~~
# Home page
GET / controllers.Application.index
POST /move/:fullId controllers.Application.move(fullId: String)
GET /sync/:id/:color/:version/:fullId controllers.Application.sync(id: String, color: String, version: Int, fullId: Option[String])
POST /update-version/:gameId controllers.Application.updateVersion(gameId: String)
POST /end-game/:gameId controllers.Application.endGame(gameId: String)
POST /internal/update-version/:gameId controllers.Internal.updateVersion(gameId: String)
POST /internal/end-game/:gameId controllers.Internal.endGame(gameId: String)
POST /internal/talk/:fullId controllers.Internal.talk(fullId: String)
# Map static resources from the /public folder to the /assets URL path
GET /assets/*file controllers.Assets.at(path="/public", file)

View File

@ -0,0 +1,25 @@
package lila.system
import model._
import memo._
import scalaz.effects._
final class InternalApi(repo: GameRepo, versionMemo: VersionMemo) {
def talk(gameId: String, author: String, message: String): IO[Unit] = for {
g1 repo game gameId
g2 = g1 withEvents List(MessageEvent(author, message))
_ repo.applyDiff(g1, g2)
_ versionMemo put g2
} yield ()
def endGame(gameId: String): IO[Unit] = for {
g1 repo game gameId
g2 = g1 withEvents List(EndEvent())
_ repo.applyDiff(g1, g2)
_ versionMemo put g2
} yield ()
def updateVersion(gameId: String): IO[Unit] =
repo game gameId flatMap versionMemo.put
}

View File

@ -11,7 +11,7 @@ final class Server(repo: GameRepo, ai: Ai, versionMemo: VersionMemo) {
def playMove(
fullId: String,
moveString: String,
promString: Option[String] = None): IO[Valid[Map[Pos, List[Pos]]]] =
promString: Option[String] = None): IO[Valid[Unit]] =
(decodeMoveString(moveString) toValid "Wrong move").fold(
e io(failure(e)),
move play(fullId, move._1, move._2, promString)
@ -21,26 +21,17 @@ final class Server(repo: GameRepo, ai: Ai, versionMemo: VersionMemo) {
fullId: String,
fromString: String,
toString: String,
promString: Option[String] = None): IO[Valid[Map[Pos, List[Pos]]]] =
repo playerGame fullId flatMap { game
purePlay(game, fromString, toString, promString).fold(
promString: Option[String] = None): IO[Valid[Unit]] =
repo playerGame fullId flatMap { g1
purePlay(g1, fromString, toString, promString).fold(
e io(failure(e)),
newGame for {
_ repo.applyDiff(game, newGame)
_ versionMemo put newGame
} yield success(newGame.toChess.situation.destinations)
g2 for {
_ repo.applyDiff(g1, g2)
_ versionMemo put g2
} yield success(Unit)
)
}
def updateVersion(gameId: String): IO[Unit] =
repo game gameId flatMap versionMemo.put
def endGame(gameId: String): IO[Unit] = for {
g1 repo game gameId
g2 = g1 withEvents List(EndEvent())
_ repo.applyDiff(g1, g2)
} yield ()
private def purePlay(
g1: DbGame,
origString: String,

View File

@ -13,6 +13,8 @@ trait SystemEnv {
def server = new Server(repo = gameRepo, ai = ai, versionMemo)
def internalApi = new InternalApi(repo = gameRepo, versionMemo)
def syncer = new Syncer(
repo = gameRepo,
versionMemo = versionMemo,