more relay integration

pull/625/head
Thibault Duplessis 2015-06-24 14:18:08 +02:00
parent f45fa62d83
commit 9acf56139d
16 changed files with 113 additions and 37 deletions

View File

@ -56,8 +56,9 @@ object Analyse extends LilaController {
else GameRepo initialFen pov.game.id flatMap { initialFen =>
(env.analyser get pov.game.id) zip
(pov.game.simulId ?? Env.simul.repo.find) zip
(pov.game.relayId ?? Env.relay.repo.byId) zip
Env.game.crosstableApi(pov.game) flatMap {
case ((analysis, simul), crosstable) =>
case (((analysis, simul), relay), crosstable) =>
val pgn = Env.game.pgnDump(pov.game, initialFen)
Env.api.roundApi.watcher(pov, lila.api.Mobile.Api.currentVersion,
tv = none,
@ -72,6 +73,7 @@ object Analyse extends LilaController {
analysis,
analysis filter (_.done) map { a => AdvantageChart(a.infoAdvices, pov.game.pgnMoves, pov.game.startedAtTurn) },
simul,
relay,
new TimeChart(pov.game, pov.game.pgnMoves),
crosstable,
userTv,
@ -84,8 +86,9 @@ object Analyse extends LilaController {
GameRepo initialFen pov.game.id flatMap { initialFen =>
(env.analyser get pov.game.id) zip
(pov.game.simulId ?? Env.simul.repo.find) zip
(pov.game.relayId ?? Env.relay.repo.byId) zip
Env.game.crosstableApi(pov.game) map {
case ((analysis, simul), crosstable) =>
case (((analysis, simul), relay), crosstable) =>
val pgn = Env.game.pgnDump(pov.game, initialFen)
Ok(html.analyse.replayBot(
pov,
@ -93,6 +96,7 @@ object Analyse extends LilaController {
Env.analyse.annotator(pgn, analysis, pov.game.opening, pov.game.winnerColor, pov.game.status, pov.game.clock).toString,
analysis,
simul,
relay,
crosstable))
}
}

View File

@ -152,10 +152,11 @@ object Round extends LilaController with TheftPrevention {
case None if HTTPRequest.isHuman(ctx.req) =>
myTour(pov.game.tournamentId, false) zip
(pov.game.simulId ?? Env.simul.repo.find) zip
(pov.game.relayId ?? Env.relay.repo.byId) zip
Env.game.crosstableApi(pov.game) zip
Env.api.roundApi.watcher(pov, lila.api.Mobile.Api.currentVersion, tv = none) map {
case (((tour, simul), crosstable), data) =>
Ok(html.round.watcher(pov, data, tour, simul, crosstable, userTv = userTv))
case ((((tour, simul), relay), crosstable), data) =>
Ok(html.round.watcher(pov, data, tour, simul, relay, crosstable, userTv = userTv))
}
case _ => // web crawlers don't need the full thing
GameRepo.initialFen(pov.game.id) zip

View File

@ -1,4 +1,4 @@
@(pov: Pov, data: play.api.libs.json.JsObject, initialFen: Option[String], pgn: String, analysis: Option[lila.analyse.Analysis], advantageChart: Option[String], simul: Option[lila.simul.Simul], timeChart: lila.analyse.TimeChart, cross: Option[lila.game.Crosstable], userTv: Option[User], division: chess.Division)(implicit ctx: Context)
@(pov: Pov, data: play.api.libs.json.JsObject, initialFen: Option[String], pgn: String, analysis: Option[lila.analyse.Analysis], advantageChart: Option[String], simul: Option[lila.simul.Simul], relay: Option[lila.relay.Relay], timeChart: lila.analyse.TimeChart, cross: Option[lila.game.Crosstable], userTv: Option[User], division: chess.Division)(implicit ctx: Context)
@import pov._
@ -45,7 +45,7 @@ userId: @Html(ctx.userId.fold("null")(id => s""""$id""""))
@analyse.layout(
title = title,
side = views.html.game.side(pov, initialFen, none, simul = simul, userTv = userTv).some,
side = views.html.game.side(pov, initialFen, none, simul = simul, relay = relay, userTv = userTv).some,
chat = base.chatDom(trans.spectatorRoom.str(), ctx.isAuth).some,
underchat = underchat.some,
moreCss = moreCss,

View File

@ -1,4 +1,4 @@
@(pov: Pov, initialFen: Option[String], pgn: String, analysis: Option[lila.analyse.Analysis], simul: Option[lila.simul.Simul], cross: Option[lila.game.Crosstable])(implicit ctx: Context)
@(pov: Pov, initialFen: Option[String], pgn: String, analysis: Option[lila.analyse.Analysis], simul: Option[lila.simul.Simul], relay: Option[lila.relay.Relay], cross: Option[lila.game.Crosstable])(implicit ctx: Context)
@import pov._
@ -37,7 +37,7 @@ orientation: "@pov.color.name"
@analyse.layout(
title = title,
side = views.html.game.side(pov, initialFen, none, simul = simul).some,
side = views.html.game.side(pov, initialFen, none, simul = simul, relay = relay).some,
chat = base.chatDom(trans.spectatorRoom.str(), ctx.isAuth).some,
underchat = underchat.some,
moreJs = moreJs,

View File

@ -1,4 +1,4 @@
@(pov: Pov, initialFen: Option[String], tour: Option[lila.tournament.MiniStanding], simul: Option[lila.simul.Simul], userTv: Option[User] = None)(implicit ctx: Context)
@(pov: Pov, initialFen: Option[String], tour: Option[lila.tournament.MiniStanding], simul: Option[lila.simul.Simul], relay: Option[lila.relay.Relay], userTv: Option[User] = None)(implicit ctx: Context)
@import pov._
@import lila.tournament.arena
@ -104,4 +104,9 @@
<p class="top text" data-icon="|"><a href="@routes.Simul.show(sim.id)">@sim.fullName</a></p>
</div>
}
@relay.map { rel =>
<div class="game_relay side_box no_padding">
<p class="top text" data-icon="n"><a href="@routes.Relay.show(rel.id, rel.slug)">@rel.name</a></p>
</div>
}
</div>

View File

@ -10,11 +10,11 @@
@jsAt(s"compiled/lichess.relay${isProd??(".min")}.js")
@embedJs {
lichess = lichess || {};
lichess.relay = LichessRelay(document.getElementById('relay'), {
lichess.relay = {
data: @Html(J.stringify(data)),
i18n: @jsI18n(),
socketVersion: @socketVersion
});
};
}
}

View File

@ -1,4 +1,4 @@
@(pov: Pov, data: play.api.libs.json.JsObject, tour: Option[lila.tournament.MiniStanding], simul: Option[lila.simul.Simul], cross: Option[lila.game.Crosstable], userTv: Option[User] = None)(implicit ctx: Context)
@(pov: Pov, data: play.api.libs.json.JsObject, tour: Option[lila.tournament.MiniStanding], simul: Option[lila.simul.Simul], relay: Option[lila.relay.Relay], cross: Option[lila.game.Crosstable], userTv: Option[User] = None)(implicit ctx: Context)
@title = @{ s"${playerText(pov.player)} vs ${playerText(pov.opponent)} in ${pov.gameId}" }
@ -17,7 +17,7 @@ i18n: @jsI18n()
@round.layout(
title = title,
side = views.html.game.side(pov, (data\"game"\"initialFen").asOpt[String], tour, simul = simul, userTv = userTv),
side = views.html.game.side(pov, (data\"game"\"initialFen").asOpt[String], tour, simul = simul, relay = relay, userTv = userTv),
chat = base.chatDom(trans.spectatorRoom.str()).some,
underchat = views.html.game.watchers().some,
moreJs = moreJs,

View File

@ -61,6 +61,7 @@ object BSONHandlers {
metadata = Metadata(
source = r intO source flatMap Source.apply,
pgnImport = r.getO[PgnImport](pgnImport)(PgnImport.pgnImportBSONHandler),
relay = r.getO[Relay](relay)(Relay.relayBSONHandler),
tournamentId = r strO tournamentId,
simulId = r strO simulId,
tvAt = r dateO tvAt,
@ -93,6 +94,7 @@ object BSONHandlers {
updatedAt -> o.updatedAt.map(w.date),
source -> o.metadata.source.map(_.id),
pgnImport -> o.metadata.pgnImport,
relay -> o.metadata.relay,
tournamentId -> o.metadata.tournamentId,
simulId -> o.metadata.simulId,
tvAt -> o.metadata.tvAt.map(w.date),

View File

@ -431,6 +431,10 @@ case class Game(
def pgnImport = metadata.pgnImport
def isPgnImport = pgnImport.isDefined
def relay = metadata.relay
def relayId = relay.map(_.id)
def isRelay = relay.isDefined
def resetTurns = copy(turns = 0, startedAtTurn = 0)
lazy val opening: Option[chess.OpeningExplorer.Opening] =
@ -486,6 +490,7 @@ object Game {
variant: Variant,
source: Source,
pgnImport: Option[PgnImport],
relay: Option[Relay] = None,
castles: Castles = Castles.init,
daysPerTurn: Option[Int] = None): Game = Game(
id = IdGenerator.game,
@ -505,6 +510,7 @@ object Game {
metadata = Metadata(
source = source.some,
pgnImport = pgnImport,
relay = relay,
tournamentId = none,
simulId = none,
tvAt = none,
@ -541,6 +547,7 @@ object Game {
val updatedAt = "ua"
val source = "so"
val pgnImport = "pgni"
val relay = "rel"
val tournamentId = "tid"
val simulId = "sid"
val tvAt = "tv"

View File

@ -7,6 +7,7 @@ import org.joda.time.DateTime
private[game] case class Metadata(
source: Option[Source],
pgnImport: Option[PgnImport],
relay: Option[Relay],
tournamentId: Option[String],
simulId: Option[String],
tvAt: Option[DateTime],
@ -21,7 +22,19 @@ private[game] case class Metadata(
private[game] object Metadata {
val empty = Metadata(None, None, None, None, None, false)
val empty = Metadata(None, None, None, None, None, None, false)
}
case class Relay(id: String, white: Relay.Player, black: Relay.Player)
object Relay {
case class Player(name: String, title: Option[String], rating: Option[Int])
import reactivemongo.bson.Macros
import ByteArray.ByteArrayBSONHandler
implicit val relayPlayerBSONHandler = Macros.handler[Relay.Player]
implicit val relayBSONHandler = Macros.handler[Relay]
}
case class PgnImport(

View File

@ -9,6 +9,7 @@ import lila.hub.SequentialActor
private[relay] final class GameActor(
fics: ActorRef,
ficsId: Int,
relayId: String,
getRelayGame: () => Fu[Option[Relay.Game]],
importer: Importer) extends SequentialActor {
@ -61,7 +62,7 @@ private[relay] final class GameActor(
}
def recover(data: command.Moves.Game) = withRelayGame { g =>
importer.full(g.id, data)
importer.full(relayId, g.id, data)
}
def withRelayGame[A](f: Relay.Game => Fu[A]): Funit = getRelayGame() flatMap {

View File

@ -17,7 +17,7 @@ final class Importer(
delay: FiniteDuration,
scheduler: akka.actor.Scheduler) {
def full(gameId: String, data: command.Moves.Game): Fu[Game] =
def full(relayId: String, gameId: String, data: command.Moves.Game): Fu[Game] =
chess.format.pgn.Reader.full(data.pgn).future flatMap { replay =>
GameRepo game gameId flatMap {
case Some(game) => fuccess(game)
@ -29,7 +29,12 @@ final class Importer(
mode = chess.Mode.Casual,
variant = replay.setup.board.variant,
source = Source.Relay,
pgnImport = none).withId(gameId).start
pgnImport = none,
relay = lila.game.Relay(
id = relayId,
white = toGamePlayer(data.white),
black = toGamePlayer(data.black)).some
).withId(gameId).start
(GameRepo insertDenormalized game) inject game
} flatMap { game =>
@ -90,4 +95,9 @@ final class Importer(
onFailure = println
))
}
private def toGamePlayer(p: command.Moves.Player) = lila.game.Relay.Player(
name = p.name,
title = p.title,
rating = p.rating)
}

View File

@ -12,14 +12,22 @@ final class JsonView {
"id" -> relay.id,
"name" -> relay.name,
"status" -> relay.status.id,
"games" -> games.map(gameJson)
)
"games" -> games.flatMap(gameJson))
}
private def gameJson(g: Game) = Json.obj(
"id" -> g.id,
"status" -> g.status.id,
"fen" -> (chess.format.Forsyth exportBoard g.toChess.board),
"lastMove" -> ~g.castleLastMoveTime.lastMoveString,
"orient" -> g.firstPlayer.color.name)
private def playerJson(p: lila.game.Relay.Player) = Json.obj(
"name" -> p.name,
"title" -> p.title,
"rating" -> p.rating)
private def gameJson(g: Game) = g.relay map { r =>
Json.obj(
"id" -> g.id,
"white" -> playerJson(r.white),
"black" -> playerJson(r.black),
"status" -> g.status.id,
"fen" -> (chess.format.Forsyth exportBoard g.toChess.board),
"lastMove" -> ~g.castleLastMoveTime.lastMoveString,
"orient" -> g.firstPlayer.color.name)
}
}

View File

@ -25,6 +25,7 @@ private[relay] final class TourneyActor(
new GameActor(
fics = fics,
ficsId = ficsId,
relayId = id,
getRelayGame = () => repo.gameByFicsId(id, ficsId),
importer = importer)
}

View File

@ -593,6 +593,7 @@ lichess.storage = {
else if (lichess.lobby) startLobby(document.getElementById('hooks_wrap'), lichess.lobby);
else if (lichess.tournament) startTournament(document.getElementById('tournament'), lichess.tournament);
else if (lichess.simul) startSimul(document.getElementById('simul'), lichess.simul);
else if (lichess.relay) startRelay(document.getElementById('relay'), lichess.relay);
document.body.classList.remove('preload');
@ -2027,6 +2028,30 @@ lichess.storage = {
simul = LichessSimul(element, cfg);
};
function startRelay(element, cfg) {
var $watchers = $("div.watchers").watchers();
if (typeof lichess_chat !== 'undefined') $('#chat').chat({
messages: lichess_chat
});
var relay;
lichess.socket = new lichess.StrongSocket(
'/watch/' + cfg.data.id + '/socket/v1', cfg.socketVersion, {
receive: function(t, d) {
relay.socketReceive(t, d)
},
events: {
crowd: function(data) {
$watchers.watchers("set", data);
}
},
options: {
name: "relay"
}
});
cfg.socketSend = lichess.socket.send.bind(lichess.socket);
relay = LichessRelay(element, cfg);
};
////////////////
// analyse.js //
////////////////

View File

@ -2,6 +2,15 @@ var m = require('mithril');
var boardContent = m('div.cg-board-wrap', m('div.cg-board'));
function player(p) {
return [
p.name,
m('br'),
p.title ? p.title + ' ' : '',
p.rating
]
}
function miniGame(game) {
return m('div', [
m('a', {
@ -16,18 +25,8 @@ function miniGame(game) {
}
}, boardContent),
m('div.vstext.clearfix', [
m('div.left', [
game.user1.name,
m('br'),
game.user1.title ? game.user1.title + ' ' : '',
game.user1.rating
]),
m('div.right', [
game.user2.name,
m('br'),
game.user2.rating,
game.user2.title ? ' ' + game.user2.title : ''
])
m('div.left', player(game.white)),
m('div.right', player(game.black))
])
]);
}