From 3958d1ddc2696fa8d5812b3b157ee9578038ff93 Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Fri, 31 Oct 2014 18:04:57 +0100 Subject: [PATCH] use board image creation in the og headers - through CDN --- .gitmodules | 3 ++ app/actor/Router.scala | 2 +- app/controllers/Analyse.scala | 24 -------------- app/controllers/Export.scala | 48 +++++++++++++++++++++++++++ app/templating/GameHelper.scala | 3 +- app/views/analyse/replay.scala.html | 8 ++--- bin/prod/deploy | 3 +- conf/routes | 5 +-- modules/game/src/main/Env.scala | 3 ++ modules/game/src/main/Game.scala | 2 +- modules/game/src/main/PngExport.scala | 18 ++++++++++ submodules/boardcreator | 1 + 12 files changed, 86 insertions(+), 34 deletions(-) create mode 100644 app/controllers/Export.scala create mode 100644 modules/game/src/main/PngExport.scala create mode 160000 submodules/boardcreator diff --git a/.gitmodules b/.gitmodules index f0e3e94943..ab991fea2c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "submodules/pdfexporter"] path = submodules/pdfexporter url = https://github.com/clarkerubber/lichessPDFExporter +[submodule "submodules/boardcreator"] + path = submodules/boardcreator + url = https://github.com/clarkerubber/board-creator diff --git a/app/actor/Router.scala b/app/actor/Router.scala index ec70be14ef..b7f6ac1360 100644 --- a/app/actor/Router.scala +++ b/app/actor/Router.scala @@ -31,7 +31,7 @@ private[app] final class Router( case User(username) => sender ! R.User.show(username).url case Player(fullId) => sender ! R.Round.player(fullId).url case Watcher(gameId, color) => sender ! R.Round.watcher(gameId, color).url - case Pgn(gameId) => sender ! R.Analyse.pgn(gameId).url + case Pgn(gameId) => sender ! R.Export.pgn(gameId).url case Tourney(tourId) => sender ! R.Tournament.show(tourId).url case Puzzle(id) => sender ! R.Puzzle.show(id).url diff --git a/app/controllers/Analyse.scala b/app/controllers/Analyse.scala index 4c67083c7d..f1f219715f 100644 --- a/app/controllers/Analyse.scala +++ b/app/controllers/Analyse.scala @@ -6,7 +6,6 @@ import akka.pattern.ask import play.api.http.ContentTypes import play.api.mvc._ import play.twirl.api.Html -import play.api.libs.iteratee.{ Iteratee, Enumerator } import lila.analyse.{ Analysis, TimeChart, AdvantageChart } import lila.api.Context @@ -77,29 +76,6 @@ object Analyse extends LilaController { } } - def pgn(id: String) = Open { implicit ctx => - OptionFuResult(GameRepo game id) { game => - (game.pgnImport.ifTrue(~get("as") == "imported") match { - case Some(i) => fuccess(i.pgn) - case None => for { - pgn ← Env.game.pgnDump(game) - analysis ← (~get("as") != "raw") ?? (env.analyser getDone game.id) - } yield Env.analyse.annotator(pgn, analysis, gameOpening(game), game.winnerColor, game.status, game.clock).toString - }) map { content => - Ok(content).withHeaders( - CONTENT_TYPE -> ContentTypes.TEXT, - CONTENT_DISPOSITION -> ("attachment; filename=" + (Env.game.pgnDump filename game))) - } - } - } - - def pdf(id: String) = Open { implicit ctx => - OptionResult(GameRepo game id) { game => - Ok.chunked(Enumerator.outputStream(Env.game.pdfExport(game.id))).withHeaders( - CONTENT_TYPE -> ContentTypes.withCharset("application/pdf")) - } - } - private def gameOpening(game: GameModel) = if (game.fromPosition || game.variant.exotic) none else chess.OpeningExplorer openingOf game.pgnMoves diff --git a/app/controllers/Export.scala b/app/controllers/Export.scala new file mode 100644 index 0000000000..f3a2f3a7d8 --- /dev/null +++ b/app/controllers/Export.scala @@ -0,0 +1,48 @@ +package controllers + +import play.api.mvc.Action + +import lila.app._ +import lila.game.{ Game => GameModel, GameRepo } +import play.api.http.ContentTypes +import play.api.libs.iteratee.{ Iteratee, Enumerator } +import views._ + +object Export extends LilaController { + + private def env = Env.game + + def pgn(id: String) = Open { implicit ctx => + OptionFuResult(GameRepo game id) { game => + (game.pgnImport.ifTrue(~get("as") == "imported") match { + case Some(i) => fuccess(i.pgn) + case None => for { + pgn ← Env.game.pgnDump(game) + analysis ← (~get("as") != "raw") ?? (Env.analyse.analyser getDone game.id) + } yield Env.analyse.annotator(pgn, analysis, gameOpening(game), game.winnerColor, game.status, game.clock).toString + }) map { content => + Ok(content).withHeaders( + CONTENT_TYPE -> ContentTypes.TEXT, + CONTENT_DISPOSITION -> ("attachment; filename=" + (Env.game.pgnDump filename game))) + } + } + } + + def pdf(id: String) = Open { implicit ctx => + OptionResult(GameRepo game id) { game => + Ok.chunked(Enumerator.outputStream(env.pdfExport(game.id))).withHeaders( + CONTENT_TYPE -> "application/pdf") + } + } + + def png(id: String) = Open { implicit ctx => + OptionResult(GameRepo game id) { game => + Ok.chunked(Enumerator.outputStream(env.pngExport(game))).withHeaders( + CONTENT_TYPE -> "image/png") + } + } + + private def gameOpening(game: GameModel) = + if (game.fromPosition || game.variant.exotic) none + else chess.OpeningExplorer openingOf game.pgnMoves +} diff --git a/app/templating/GameHelper.scala b/app/templating/GameHelper.scala index 684b08c6e8..c0df90744b 100644 --- a/app/templating/GameHelper.scala +++ b/app/templating/GameHelper.scala @@ -14,6 +14,7 @@ trait GameHelper { self: I18nHelper with UserHelper with AiHelper with StringHel def netBaseUrl: String def staticUrl(path: String): String + def cdnUrl(path: String): String def mandatorySecondsToMove = lila.game.Env.current.MandatorySecondsToMove @@ -22,7 +23,7 @@ trait GameHelper { self: I18nHelper with UserHelper with AiHelper with StringHel val variant = pov.game.variant.exotic ?? s" ${pov.game.variant.name}" Map( 'type -> "website", - 'image -> staticUrl("images/large_tile.png"), + 'image -> cdnUrl(routes.Export.png(pov.game.id).url), 'title -> s"$speed$variant Chess - ${playerText(pov.game.whitePlayer)} vs ${playerText(pov.game.blackPlayer)}", 'site_name -> "lichess.org", 'url -> s"$netBaseUrl${routes.Round.watcher(pov.game.id, pov.color.name).url}", diff --git a/app/views/analyse/replay.scala.html b/app/views/analyse/replay.scala.html index ffe2f14acd..9f44a740a5 100644 --- a/app/views/analyse/replay.scala.html +++ b/app/views/analyse/replay.scala.html @@ -138,14 +138,14 @@ openGraph = povOpenGraph(pov)) {

FEN

PGN - Download annotated + Download annotated @if(analysis.isDefined) { / - Download raw + Download raw } @if(game.isPgnImport) { / - Download imported + Download imported }

@Html(nl2br(escape(pgn)))
@@ -173,7 +173,7 @@ openGraph = povOpenGraph(pov)) { } } FEN & PGN - Print + Print
@analysis.filter(_.old && ctx.isAuth).map { a =>
diff --git a/bin/prod/deploy b/bin/prod/deploy index 15bef1f794..82e3072017 100755 --- a/bin/prod/deploy +++ b/bin/prod/deploy @@ -74,7 +74,8 @@ fi lilalog "Rsync scripts, binaries and assets" stage="target/universal/stage" -rsync_command="rsync $RSYNC_OPTIONS bin $stage/bin $stage/lib public $REMOTE:$REMOTE_DIR" +include="bin $stage/bin $stage/lib public submodules" +rsync_command="rsync $RSYNC_OPTIONS $include $REMOTE:$REMOTE_DIR" echo "$rsync_command" $rsync_command echo "rsync complete" diff --git a/conf/routes b/conf/routes index 95ab7acb21..086826a0f9 100644 --- a/conf/routes +++ b/conf/routes @@ -136,9 +136,10 @@ POST /team/:id/kick controllers.Team.kick(id: String) POST /$gameId<\w{8}>/request-analysis controllers.Analyse.requestAnalysis(gameId: String) POST /$gameId<\w{8}>/better-analysis/$color controllers.Analyse.betterAnalysis(gameId: String, color: String) POST /$gameId<\w{8}>/post-analysis controllers.Analyse.postAnalysis(gameId: String) -GET /$gameId<\w{8}>/pgn controllers.Analyse.pgn(gameId: String) -GET /game/pdf/$gameId<\w{8}> controllers.Analyse.pdf(gameId: String) +GET /game/pgn/$gameId<\w{8}> controllers.Export.pgn(gameId: String) +GET /game/pdf/$gameId<\w{8}> controllers.Export.pdf(gameId: String) +GET /game/png/$gameId<\w{8}> controllers.Export.png(gameId: String) # Pref POST /pref/:name controllers.Pref.set(name: String) diff --git a/modules/game/src/main/Env.scala b/modules/game/src/main/Env.scala index e581cf7538..af843ab7a7 100644 --- a/modules/game/src/main/Env.scala +++ b/modules/game/src/main/Env.scala @@ -29,6 +29,7 @@ final class Env( val UciMemoTtl = config duration "uci_memo.ttl" val netBaseUrl = config getString "net.base_url" val PdfExecPath = config getString "pdf.exec_path" + val PngExecPath = config getString "png.exec_path" } import settings._ @@ -38,6 +39,8 @@ final class Env( lazy val pdfExport = PdfExport(PdfExecPath) _ + lazy val pngExport = PngExport(PngExecPath) _ + lazy val cached = new Cached(ttl = CachedNbTtl) lazy val paginator = new PaginatorBuilder( diff --git a/modules/game/src/main/Game.scala b/modules/game/src/main/Game.scala index ad0596cacf..1446e0c142 100644 --- a/modules/game/src/main/Game.scala +++ b/modules/game/src/main/Game.scala @@ -63,7 +63,7 @@ case class Game( def opponent(c: Color): Player = player(!c) - private lazy val firstColor = (whitePlayer before blackPlayer).fold(White, Black) + lazy val firstColor = (whitePlayer before blackPlayer).fold(White, Black) def firstPlayer = player(firstColor) def secondPlayer = player(!firstColor) diff --git a/modules/game/src/main/PngExport.scala b/modules/game/src/main/PngExport.scala new file mode 100644 index 0000000000..282f05b3b2 --- /dev/null +++ b/modules/game/src/main/PngExport.scala @@ -0,0 +1,18 @@ +package lila.game + +import chess.format.Forsyth +import java.io.{ File, OutputStream } +import scala.sys.process._ + +object PngExport { + + private val logger = ProcessLogger(_ => (), _ => ()) + + def apply(execPath: String)(game: Game)(out: OutputStream) { + val fen = (Forsyth >> game.toChess).split(' ').head + val color = game.firstColor.letter.toString + val lastMove = ~game.castleLastMoveTime.lastMoveString + val exec = Process(Seq("php", "board-creator.php", fen, color, lastMove), new File(execPath)) + exec #> out ! logger + } +} diff --git a/submodules/boardcreator b/submodules/boardcreator new file mode 160000 index 0000000000..a177efd0b4 --- /dev/null +++ b/submodules/boardcreator @@ -0,0 +1 @@ +Subproject commit a177efd0b4a023e09d8ce8f122c2b904ac312113