lila/app/controllers/Export.scala

88 lines
2.7 KiB
Scala
Raw Normal View History

package controllers
2019-12-04 16:39:16 -07:00
import akka.stream.scaladsl._
import akka.util.ByteString
2020-08-16 10:20:56 -06:00
import chess.Color
import chess.format.FEN
2020-02-26 11:19:19 -07:00
import play.api.mvc.Result
2020-08-16 10:20:56 -06:00
import scala.concurrent.duration._
import lila.app._
import lila.common.HTTPRequest
2020-03-04 02:40:27 -07:00
import lila.game.Pov
2019-12-04 16:39:16 -07:00
final class Export(env: Env) extends LilaController(env) {
2020-04-04 13:37:19 -06:00
private val ExportImageRateLimitGlobal = new lila.memo.RateLimit[String](
credits = 600,
2020-04-29 08:58:36 -06:00
duration = 1.minute,
2020-02-26 11:19:19 -07:00
key = "export.image.global"
)
2020-04-04 13:37:19 -06:00
private val ExportGifRateLimitGlobal = new lila.memo.RateLimit[String](
credits = 240,
2020-04-29 08:58:36 -06:00
duration = 1.minute,
2020-04-04 13:37:19 -06:00
key = "export.gif.global"
)
2016-08-13 08:25:09 -06:00
2020-05-05 22:11:15 -06:00
def gif(id: String, color: String) =
Open { implicit ctx =>
OnlyHumansAndFacebookOrTwitter {
ExportGifRateLimitGlobal("-", msg = HTTPRequest.lastRemoteAddress(ctx.req).value) {
OptionFuResult(env.game.gameRepo gameWithInitialFen id) {
case (game, initialFen) =>
val pov = Pov(game, Color(color) | Color.white)
env.game.gifExport.fromPov(pov, initialFen) map
stream("image/gif") map
gameImageCacheSeconds(game)
}
}(rateLimitedFu)
}
}
2020-05-05 22:11:15 -06:00
def legacyGameThumbnail(id: String) =
Action {
MovedPermanently(routes.Export.gameThumbnail(id).url)
}
2020-02-26 11:19:19 -07:00
2020-05-05 22:11:15 -06:00
def gameThumbnail(id: String) =
Open { implicit ctx =>
ExportImageRateLimitGlobal("-", msg = HTTPRequest.lastRemoteAddress(ctx.req).value) {
OptionFuResult(env.game.gameRepo game id) { game =>
env.game.gifExport.gameThumbnail(game) map
stream("image/gif") map
gameImageCacheSeconds(game)
}
}(rateLimitedFu)
2020-03-05 11:40:33 -07:00
}
2020-05-05 22:11:15 -06:00
def legacyPuzzleThumbnail(id: Int) =
Action {
MovedPermanently(routes.Export.puzzleThumbnail(id).url)
}
2020-03-05 11:40:33 -07:00
2020-05-05 22:11:15 -06:00
def puzzleThumbnail(id: Int) =
Open { implicit ctx =>
ExportImageRateLimitGlobal("-", msg = HTTPRequest.lastRemoteAddress(ctx.req).value) {
OptionFuResult(env.puzzle.api.puzzle find id) { puzzle =>
env.game.gifExport.thumbnail(
2020-08-16 10:20:56 -06:00
fen = puzzle.fenAfterInitialMove | FEN(puzzle.fen),
2020-05-05 22:11:15 -06:00
lastMove = puzzle.initialMove.uci.some,
orientation = puzzle.color
) map stream("image/gif") map { res =>
res.withHeaders(CACHE_CONTROL -> "max-age=86400")
}
2016-08-13 08:25:09 -06:00
}
}(rateLimitedFu)
}
2020-03-05 11:40:33 -07:00
private def gameImageCacheSeconds(game: lila.game.Game)(res: Result): Result = {
val cacheSeconds =
if (game.finishedOrAborted) 3600 * 24
else 10
res.withHeaders(CACHE_CONTROL -> s"max-age=$cacheSeconds")
}
2020-02-25 14:25:09 -07:00
private def stream(contentType: String)(stream: Source[ByteString, _]) =
2020-03-05 11:40:33 -07:00
Ok.chunked(stream).withHeaders(noProxyBufferHeader) as contentType
}