lila/app/controllers/Export.scala

124 lines
3.9 KiB
Scala
Raw Normal View History

package controllers
import play.api.mvc.Action
2016-08-13 08:25:09 -06:00
import scala.concurrent.duration._
import lila.app._
import lila.common.HTTPRequest
import lila.game.{ Game => GameModel, GameRepo }
import play.api.http.ContentTypes
import play.api.libs.iteratee.{ Iteratee, Enumerator }
import play.api.mvc.Result
import views._
object Export extends LilaController {
private def env = Env.game
def pgn(id: String) = Open { implicit ctx =>
lila.mon.export.pgn.game()
OptionFuResult(GameRepo game id) { game =>
gameToPgn(
game,
asImported = get("as") contains "imported",
asRaw = get("as").contains("raw")) map { content =>
Ok(content).withHeaders(
CONTENT_TYPE -> pgnContentType,
CONTENT_DISPOSITION -> ("attachment; filename=" + (Env.api.pgnDump filename game)))
} recover {
case err => NotFound(err.getMessage)
}
}
}
2016-09-04 05:40:37 -06:00
private def gameToPgn(from: GameModel, asImported: Boolean, asRaw: Boolean): Fu[String] = from match {
case game if game.playable => fufail("Can't export PGN of game in progress")
case game => (game.pgnImport.ifTrue(asImported) match {
case Some(i) => fuccess(i.pgn)
case None => for {
initialFen <- GameRepo initialFen game
pgn = Env.api.pgnDump(game, initialFen)
analysis !asRaw ?? (Env.analyse.analyser get game.id)
} yield Env.analyse.annotator(pgn, analysis, game.opening, game.winnerColor, game.status, game.clock).toString
})
}
2016-08-13 08:25:09 -06:00
private val PdfRateLimitGlobal = new lila.memo.RateLimit(
credits = 20,
duration = 1 minute,
2016-09-01 15:54:43 -06:00
name = "export PDF global",
key = "export.pdf.global")
2016-08-13 08:25:09 -06:00
def pdf(id: String) = Open { implicit ctx =>
2014-11-19 02:56:15 -07:00
OnlyHumans {
2016-08-13 08:25:09 -06:00
PdfRateLimitGlobal("-", msg = HTTPRequest lastRemoteAddress ctx.req) {
lila.mon.export.pdf()
OptionResult(GameRepo game id) { game =>
Ok.chunked(Enumerator.outputStream(env.pdfExport(game.id))).withHeaders(
CONTENT_TYPE -> "application/pdf",
CACHE_CONTROL -> "max-age=7200")
}
}
}
}
2016-08-13 08:25:09 -06:00
private val PngRateLimitGlobal = new lila.memo.RateLimit(
credits = 60,
duration = 1 minute,
2016-09-01 15:54:43 -06:00
name = "export PGN global",
key = "export.pgn.global")
2016-08-13 08:25:09 -06:00
def png(id: String) = Open { implicit ctx =>
2014-11-19 02:56:15 -07:00
OnlyHumansAndFacebook {
2016-08-13 08:25:09 -06:00
PngRateLimitGlobal("-", msg = HTTPRequest lastRemoteAddress ctx.req) {
lila.mon.export.png.game()
OptionFuResult(GameRepo game id) { game =>
env.pngExport fromGame game map { stream =>
Ok.chunked(stream).withHeaders(
CONTENT_TYPE -> "image/png",
CACHE_CONTROL -> "max-age=7200")
}
2016-08-13 08:25:09 -06:00
}
}
}
}
2016-09-04 05:40:37 -06:00
def visualizer(id: String) = Open { implicit ctx =>
2016-09-04 05:48:05 -06:00
OnlyHumans {
OptionFuResult(GameRepo game id) { game =>
gameToPgn(game, asImported = false, asRaw = false) map { pgn =>
2016-09-04 05:48:05 -06:00
lila.mon.export.visualizer()
Redirect {
import lila.api.Env.current.Net._
val base = s"$Protocol$AssetDomain/assets"
val encoded = java.net.URLEncoder.encode(pgn.toString, "UTF-8")
s"$base/visualizer/index_lichess.html?pgn=$encoded"
}
} recoverWith {
case _: Exception => notFound
2016-09-04 05:40:37 -06:00
}
}
}
}
def puzzlePng(id: Int) = Open { implicit ctx =>
OnlyHumansAndFacebook {
2016-08-13 08:25:09 -06:00
PngRateLimitGlobal("-", msg = HTTPRequest lastRemoteAddress ctx.req) {
lila.mon.export.png.puzzle()
OptionFuResult(Env.puzzle.api.puzzle find id) { puzzle =>
env.pngExport(
fen = chess.format.FEN(puzzle.fenAfterInitialMove | puzzle.fen),
lastMove = puzzle.initialMove.some,
check = none,
orientation = puzzle.color.some
) map { stream =>
Ok.chunked(stream).withHeaders(
CONTENT_TYPE -> "image/png",
CACHE_CONTROL -> "max-age=7200")
}
2016-08-13 08:25:09 -06:00
}
}
}
}
}