implement literate PGN export
This commit is contained in:
parent
d702766e76
commit
54fbb92d68
|
@ -54,7 +54,7 @@ object Analyse extends LilaController {
|
||||||
pov,
|
pov,
|
||||||
data,
|
data,
|
||||||
initialFen,
|
initialFen,
|
||||||
Env.analyse.annotator(pgn, analysis, pov.game.opening, pov.game.winnerColor, pov.game.status, pov.game.clock).toString,
|
Env.analyse.annotator(pgn, analysis, pov.game.opening, pov.game.winnerColor, pov.game.status).toString,
|
||||||
analysis,
|
analysis,
|
||||||
analysisInProgress,
|
analysisInProgress,
|
||||||
simul,
|
simul,
|
||||||
|
@ -104,7 +104,7 @@ object Analyse extends LilaController {
|
||||||
} yield Ok(html.analyse.replayBot(
|
} yield Ok(html.analyse.replayBot(
|
||||||
pov,
|
pov,
|
||||||
initialFen,
|
initialFen,
|
||||||
Env.analyse.annotator(pgn, analysis, pov.game.opening, pov.game.winnerColor, pov.game.status, pov.game.clock).toString,
|
Env.analyse.annotator(pgn, analysis, pov.game.opening, pov.game.winnerColor, pov.game.status).toString,
|
||||||
analysis,
|
analysis,
|
||||||
simul,
|
simul,
|
||||||
crosstable
|
crosstable
|
||||||
|
|
|
@ -72,14 +72,16 @@ object Game extends LilaController {
|
||||||
perfType = ~get("perfType", req) split "," flatMap { lila.rating.PerfType(_) } toSet,
|
perfType = ~get("perfType", req) split "," flatMap { lila.rating.PerfType(_) } toSet,
|
||||||
color = get("color", req) flatMap chess.Color.apply,
|
color = get("color", req) flatMap chess.Color.apply,
|
||||||
analysed = getBoolOpt("analysed", req),
|
analysed = getBoolOpt("analysed", req),
|
||||||
flags = requestPgnFlags(req, extended = false),
|
flags = requestPgnFlags(req, extended = false).copy(
|
||||||
|
literate = false
|
||||||
|
),
|
||||||
perSecond = MaxPerSecond(me match {
|
perSecond = MaxPerSecond(me match {
|
||||||
case Some(m) if m is user.id => 50
|
case Some(m) if m is user.id => 50
|
||||||
case Some(_) if oauth => 20 // bonus for oauth logged in only (not for XSRF)
|
case Some(_) if oauth => 20 // bonus for oauth logged in only (not for XSRF)
|
||||||
case _ => 10
|
case _ => 10
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
val date = (DateTimeFormat forPattern "yyyy-MM-dd") print new DateTime
|
val date = DateTimeFormat forPattern "yyyy-MM-dd" print new DateTime
|
||||||
Ok.chunked(Env.api.gameApiV2.exportByUser(config)).withHeaders(
|
Ok.chunked(Env.api.gameApiV2.exportByUser(config)).withHeaders(
|
||||||
CONTENT_TYPE -> gameContentType(config),
|
CONTENT_TYPE -> gameContentType(config),
|
||||||
CONTENT_DISPOSITION -> s"attachment; filename=lichess_${user.username}_$date.${format.toString.toLowerCase}"
|
CONTENT_DISPOSITION -> s"attachment; filename=lichess_${user.username}_$date.${format.toString.toLowerCase}"
|
||||||
|
@ -120,7 +122,8 @@ object Game extends LilaController {
|
||||||
tags = getBoolOpt("tags", req) | true,
|
tags = getBoolOpt("tags", req) | true,
|
||||||
clocks = getBoolOpt("clocks", req) | extended,
|
clocks = getBoolOpt("clocks", req) | extended,
|
||||||
evals = getBoolOpt("evals", req) | extended,
|
evals = getBoolOpt("evals", req) | extended,
|
||||||
opening = getBoolOpt("opening", req) | extended
|
opening = getBoolOpt("opening", req) | extended,
|
||||||
|
literate = getBoolOpt("literate", req) | false
|
||||||
)
|
)
|
||||||
|
|
||||||
private def gameContentType(config: GameApiV2.Config) = config.format match {
|
private def gameContentType(config: GameApiV2.Config) = config.format match {
|
||||||
|
|
|
@ -69,7 +69,7 @@ atom = atom.some) {
|
||||||
<div class="pgn_options">
|
<div class="pgn_options">
|
||||||
<strong>PGN</strong>
|
<strong>PGN</strong>
|
||||||
<div>
|
<div>
|
||||||
<a data-icon="x" class="text" rel="nofollow" href="@routes.Game.exportOne(game.id)">@trans.downloadAnnotated()</a>
|
<a data-icon="x" class="text" rel="nofollow" href="@routes.Game.exportOne(game.id)?literate=1">@trans.downloadAnnotated()</a>
|
||||||
<a data-icon="x" class="text" rel="nofollow" href="@routes.Game.exportOne(game.id)?evals=0&clocks=0">@trans.downloadRaw()</a>
|
<a data-icon="x" class="text" rel="nofollow" href="@routes.Game.exportOne(game.id)?evals=0&clocks=0">@trans.downloadRaw()</a>
|
||||||
@if(game.isPgnImport) {
|
@if(game.isPgnImport) {
|
||||||
<a data-icon="x" class="text" rel="nofollow" href="@routes.Game.exportOne(game.id)?imported=1">@trans.downloadImported()</a>
|
<a data-icon="x" class="text" rel="nofollow" href="@routes.Game.exportOne(game.id)?imported=1">@trans.downloadImported()</a>
|
||||||
|
|
|
@ -4,15 +4,14 @@ import chess.format.pgn.{ Pgn, Tag, Turn, Move, Glyphs }
|
||||||
import chess.opening._
|
import chess.opening._
|
||||||
import chess.{ Status, Color, Clock }
|
import chess.{ Status, Color, Clock }
|
||||||
|
|
||||||
private[analyse] final class Annotator(netDomain: String) {
|
final class Annotator(netDomain: String) {
|
||||||
|
|
||||||
def apply(
|
def apply(
|
||||||
p: Pgn,
|
p: Pgn,
|
||||||
analysis: Option[Analysis],
|
analysis: Option[Analysis],
|
||||||
opening: Option[FullOpening.AtPly],
|
opening: Option[FullOpening.AtPly],
|
||||||
winner: Option[Color],
|
winner: Option[Color],
|
||||||
status: Status,
|
status: Status
|
||||||
clock: Option[Clock]
|
|
||||||
): Pgn =
|
): Pgn =
|
||||||
annotateStatus(winner, status) {
|
annotateStatus(winner, status) {
|
||||||
annotateOpening(opening) {
|
annotateOpening(opening) {
|
||||||
|
@ -38,7 +37,7 @@ private[analyse] final class Annotator(netDomain: String) {
|
||||||
turn.update(advice.color, move =>
|
turn.update(advice.color, move =>
|
||||||
move.copy(
|
move.copy(
|
||||||
glyphs = Glyphs.fromList(advice.judgment.glyph :: Nil),
|
glyphs = Glyphs.fromList(advice.judgment.glyph :: Nil),
|
||||||
comments = List(advice.makeComment(true, true)),
|
comments = advice.makeComment(true, true) :: move.comments,
|
||||||
variations = makeVariation(turn, advice) :: Nil
|
variations = makeVariation(turn, advice) :: Nil
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ final class Env(
|
||||||
gamePgnDump: lila.game.PgnDump,
|
gamePgnDump: lila.game.PgnDump,
|
||||||
gameCache: lila.game.Cached,
|
gameCache: lila.game.Cached,
|
||||||
userEnv: lila.user.Env,
|
userEnv: lila.user.Env,
|
||||||
analyseEnv: lila.analyse.Env,
|
annotator: lila.analyse.Annotator,
|
||||||
lobbyEnv: lila.lobby.Env,
|
lobbyEnv: lila.lobby.Env,
|
||||||
setupEnv: lila.setup.Env,
|
setupEnv: lila.setup.Env,
|
||||||
getSimul: Simul.ID => Fu[Option[Simul]],
|
getSimul: Simul.ID => Fu[Option[Simul]],
|
||||||
|
@ -84,6 +84,7 @@ final class Env(
|
||||||
|
|
||||||
val pgnDump = new PgnDump(
|
val pgnDump = new PgnDump(
|
||||||
dumper = gamePgnDump,
|
dumper = gamePgnDump,
|
||||||
|
annotator = annotator,
|
||||||
getSimulName = getSimulName,
|
getSimulName = getSimulName,
|
||||||
getTournamentName = getTournamentName
|
getTournamentName = getTournamentName
|
||||||
)
|
)
|
||||||
|
@ -163,7 +164,7 @@ object Env {
|
||||||
settingStore = lila.memo.Env.current.settingStore,
|
settingStore = lila.memo.Env.current.settingStore,
|
||||||
renderer = lila.hub.Env.current.actor.renderer,
|
renderer = lila.hub.Env.current.actor.renderer,
|
||||||
userEnv = lila.user.Env.current,
|
userEnv = lila.user.Env.current,
|
||||||
analyseEnv = lila.analyse.Env.current,
|
annotator = lila.analyse.Env.current.annotator,
|
||||||
lobbyEnv = lila.lobby.Env.current,
|
lobbyEnv = lila.lobby.Env.current,
|
||||||
setupEnv = lila.setup.Env.current,
|
setupEnv = lila.setup.Env.current,
|
||||||
getSimul = lila.simul.Env.current.repo.find,
|
getSimul = lila.simul.Env.current.repo.find,
|
||||||
|
|
|
@ -12,6 +12,7 @@ import lila.game.{ Game, GameRepo, Query }
|
||||||
|
|
||||||
final class PgnDump(
|
final class PgnDump(
|
||||||
val dumper: lila.game.PgnDump,
|
val dumper: lila.game.PgnDump,
|
||||||
|
annotator: Annotator,
|
||||||
getSimulName: String => Fu[Option[String]],
|
getSimulName: String => Fu[Option[String]],
|
||||||
getTournamentName: String => Option[String]
|
getTournamentName: String => Option[String]
|
||||||
) {
|
) {
|
||||||
|
@ -23,7 +24,9 @@ final class PgnDump(
|
||||||
}
|
}
|
||||||
else fuccess(pgn)
|
else fuccess(pgn)
|
||||||
} map { pgn =>
|
} map { pgn =>
|
||||||
analysis.ifTrue(flags.evals).fold(pgn)(addEvals(pgn, _))
|
val evaled = analysis.ifTrue(flags.evals).fold(pgn)(addEvals(pgn, _))
|
||||||
|
if (flags.literate) annotator(evaled, analysis, game.opening, game.winnerColor, game.status)
|
||||||
|
else evaled
|
||||||
}
|
}
|
||||||
|
|
||||||
private def addEvals(p: Pgn, analysis: Analysis): Pgn = analysis.infos.foldLeft(p) {
|
private def addEvals(p: Pgn, analysis: Analysis): Pgn = analysis.infos.foldLeft(p) {
|
||||||
|
|
|
@ -138,7 +138,8 @@ object PgnDump {
|
||||||
moves: Boolean = true,
|
moves: Boolean = true,
|
||||||
tags: Boolean = true,
|
tags: Boolean = true,
|
||||||
evals: Boolean = true,
|
evals: Boolean = true,
|
||||||
opening: Boolean = true
|
opening: Boolean = true,
|
||||||
|
literate: Boolean = false
|
||||||
)
|
)
|
||||||
|
|
||||||
def result(game: Game) =
|
def result(game: Game) =
|
||||||
|
|
Loading…
Reference in a new issue